149 lines
3.2 KiB
C++
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));
|
|
}
|