Files
MeyCan/Software/UPSoftware/MeyCan.cpp
Martin Linkwitz - NUC ae80aacfa9 Initial commit
2026-04-02 14:25:39 +02:00

149 lines
3.2 KiB
C++

#include <iterator>
#include "esp32-hal-gpio.h"
#include "MeyCan.h";
#include "driver/twai.h"
PinState *MeyPin = NULL;
uint16_t myDeviceId = 0;
byte _deviceTypeId = 0;
byte _majorHardwareVersion = 0;
byte _minorHardwareVersion = 0;
void SetupMeyPin(PinState *state) {
if (state->is_input) {
pinMode(state->pin_id, INPUT_PULLUP);
state->pin_state = digitalRead(state->pin_id);
} else {
pinMode(state->pin_id, OUTPUT);
digitalWrite(state->pin_id, LOW);
state->pin_state = true;
}
}
void SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId) {
_majorHardwareVersion = majorHardwareVersion;
_minorHardwareVersion = minorHardwareVersion;
_deviceTypeId = deviceTypeId;
if (MeyPin != NULL)
MeyPin->ForEach(SetupMeyPin);
}
void SetDevicedId(byte high, byte low) {
myDeviceId = (high << 8) | low;
}
void SetMeyPin(byte meyPinId, byte pinId) {
PinState *newState = new PinState();
newState->Init(pinId, (byte)meyPinId);
if (MeyPin == NULL)
MeyPin = newState;
else
MeyPin->AddPinState(newState);
}
bool ReadPin(PinState *state) {
return digitalRead(state->pin_id);
}
void SendSwitchedTriggeredCanPackage(byte pinId, int state) {
twai_message_t message;
message.extd = 1;
message.rtr = 0;
message.ss = 0;
message.self = 0;
message.dlc_non_comp = 0;
message.identifier = CreateCanId(SWITCH_TRIGGERED_CAN_ID);
message.data_length_code = 2;
message.data[0] = pinId;
message.data[1] = state;
DoSendCanPkg(&message);
}
void CheckPinStatus(PinState *state) {
if (!state->is_input)
return;
bool newValue = ReadPin(state);
if (newValue != state->pin_state) {
delay(10);
newValue = ReadPin(state);
if (newValue != state->pin_state) {
state->pin_state = newValue;
SendSwitchedTriggeredCanPackage(state->meyPinId, state->pin_state);
}
}
return;
}
void CheckMeyPinsTriggered() {
MeyPin->ForEach(CheckPinStatus);
}
uint16_t GetDeviceId(uint32_t canFrameId) {
return canFrameId & 0xFFFF;
}
uint16_t GetPackageType(uint32_t canFrameId) {
return (canFrameId / 0x10000) & 0xFFF;
}
uint32_t CreateCanId(uint16_t commandId) {
return ((((uint32_t)commandId) & 0xFFF) * 0x10000) | myDeviceId;
}
void HandleTriggerMeypinCanPackage(twai_message_t *frame) {
if (GetPackageType(frame->identifier) == TRIGGER_SWITCH_CAN_ID) {
uint16_t adressedDeviceId = ((uint16_t)frame->data[0] << 8) | frame->data[1];
if (adressedDeviceId != myDeviceId) return;
byte meyPinId = frame->data[2];
bool state = frame->data[3] > 0;
PinState *adressedPin = MeyPin->Find(meyPinId);
if (adressedPin != NULL) {
if (adressedPin->is_input == true) {
pinMode(adressedPin->pin_id, OUTPUT);
adressedPin->is_input = false;
}
bool pinChanged = adressedPin->pin_state != state;
adressedPin->pin_state = state;
if (pinChanged) {
digitalWrite(adressedPin->pin_id, state);
SendSwitchedTriggeredCanPackage(adressedPin->meyPinId, state);
}
}
}
}
void HandleFrame(twai_message_t *frame) {
HandleTriggerMeypinCanPackage(frame);
}
void DoSendCanPkg(twai_message_t *frame) {
esp_err_t ret = twai_transmit(frame, pdMS_TO_TICKS(1000));
}