From ad72be85b1cc32f95bda59f8237f159f7cbbfe41 Mon Sep 17 00:00:00 2001 From: Meydin87 Date: Tue, 18 Jul 2023 07:31:20 +0200 Subject: [PATCH] Software for V7 refactored --- Software/Switch/MeyCan.cpp | 135 ++++++++++++++++++++++++--------- Software/Switch/MeyCan.h | 81 +++++++++++++++++--- Software/Switch/Switch.ino | 34 +++------ Software/UPSoftware/MeyCan.cpp | 47 ++++++++---- Software/UPSoftware/MeyCan.h | 45 ++++++++--- 5 files changed, 248 insertions(+), 94 deletions(-) diff --git a/Software/Switch/MeyCan.cpp b/Software/Switch/MeyCan.cpp index 9310596..273aacf 100644 --- a/Software/Switch/MeyCan.cpp +++ b/Software/Switch/MeyCan.cpp @@ -3,47 +3,119 @@ #include ; -PinState MeyPins[8]; -MCP2515* canInterfaces[4]; +PinState *MeyPin = NULL; +CanInterface *CanBusses = NULL; uint16_t myDeviceId; +void SetupMeyPin(PinState *state) +{ + pinMode(state->pin_id, OUTPUT); + digitalWrite(state->pin_id, LOW); + state->pin_state = false; +} + +void InitCanInterface(MCP2515 *interface, can_frame *frame) // can_frame is NULL. Reuse ForEach Method for smaller footprint +{ + interface->reset(); + interface->setBitrate(CAN_500KBPS, MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz + interface->setNormalMode(); + SendVersionPackage(interface); +} + +void ForEachCanInterface(void (*handle)(MCP2515 *canInterace)) +{ + CanBusses->ForEachInterface(handle); +} void SetupMeyCan() { - for (int i = 0; i < sizeof(MeyPins) / sizeof(PinState); i++) - { - pinMode(MeyPins[i].pin_id, OUTPUT); - digitalWrite(MeyPins[i].pin_id, LOW); - MeyPins[i].pin_state = false; - } CalculateMyDeviceId(); - for (int i = 0; i < sizeof(canInterfaces) / sizeof(MCP2515*); i++) { + if (MeyPin != NULL); + MeyPin->ForEach(SetupMeyPin); - canInterfaces[i]->reset(); - canInterfaces[i]->setBitrate(CAN_500KBPS, MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz - canInterfaces[i]->setNormalMode(); - - - SendVersionPackage(canInterfaces[i]); + if (CanBusses != NULL) + { + CanBusses->ForEach(InitCanInterface, NULL); } } -void SetCanInterface(byte index, byte pinId) +void AddCanInterface(byte pinId) { - canInterfaces[index] = new MCP2515(pinId); + MCP2515* newCanInterface = new MCP2515(pinId); + CanInterface* canInterface = new CanInterface(); + canInterface->interface = newCanInterface; + + if (CanBusses == NULL) + CanBusses = canInterface; + else + CanBusses->AddCanInterface(canInterface); } void SetMeyPin(byte index, byte meyPinId, byte pinId) { - MeyPins[index] = PinState(); - MeyPins[index].Init(pinId, (byte) meyPinId); + PinState* newState = new PinState(); + newState->Init(pinId, (byte) meyPinId); - canInterfaces[index] = new MCP2515(pinId); + if (MeyPin == NULL) + MeyPin = newState; + else + MeyPin->AddPinState(newState); } -void HandleFrame(can_frame *frame) + +bool CheckPinStatus(PinState * state) { + if (!state->is_input) + return false; + + 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 false; +} + +void CheckMeyPinsTriggered() +{ + MeyPin->ForEach(CheckPinStatus); +} + +bool ReadPin(PinState * state) +{ + if (state->pin_id == PIN_PD2) + return digitalReadFast(PIN_PD2); + else if (state->pin_id == PIN_PC7) + return digitalReadFast(PIN_PC7); + else if (state->pin_id == PIN_PD1) + return digitalReadFast(PIN_PD1); + else if (state->pin_id == PIN_PD0) + return digitalReadFast(PIN_PD0); + else if (state->pin_id == PIN_PD6) + return digitalReadFast(PIN_PD6); + else if (state->pin_id == PIN_PD5) + return digitalReadFast(PIN_PD5); + else if (state->pin_id == PIN_PD4) + return digitalReadFast(PIN_PD4); + else if (state->pin_id == PIN_PD3) + return digitalReadFast(PIN_PD3); + else + return digitalRead(state->pin_id); +} + + +void HandleFrame(can_frame *frame, MCP2515 *source) +{ + CanBusses->ForEach(DoSendCanPkg, frame, source); HandleTriggerMeypinCanPackage(frame); } @@ -55,16 +127,10 @@ void HandleTriggerMeypinCanPackage(can_frame *frame) if (adressedDeviceId != myDeviceId) return; - int meyPinId = frame->data[2]; + byte meyPinId = frame->data[2]; bool state = frame->data[3] > 0; - PinState *adressedPin = NULL; - for (int i = 0; i < sizeof(MeyPins) / sizeof(PinState); i++) - if (MeyPins[i].meyPinId == meyPinId) - { - adressedPin = &MeyPins[i]; - break; - } + PinState *adressedPin = MeyPin->Find(meyPinId); if (adressedPin != NULL) { @@ -135,7 +201,7 @@ void SendVersionPackage(MCP2515 *interface) toSend.data[4] = (myDeviceId >> 8) & 0xFF; toSend.data[5] = myDeviceId & 0xFF; - DoSendCanPkg(interface, &toSend); + DoSendCanPkg(interface, &toSend); } void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state) @@ -149,8 +215,7 @@ void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte sta toSend.data[2] = pinId; toSend.data[3] = state; - DoSendCanPkg(&toSend); - HandleFrame(&toSend); + HandleFrame(&toSend, NULL); } void SendSwitchedTriggeredCanPackage(byte pinId, int state) @@ -166,11 +231,11 @@ void SendSwitchedTriggeredCanPackage(byte pinId, int state) void DoSendCanPkg(can_frame *frame) { - for (int i = 0; i < sizeof(canInterfaces) / sizeof(MCP2515*); i++) - DoSendCanPkg(canInterfaces[i], frame); + if (CanBusses != NULL) + CanBusses->ForEach(DoSendCanPkg, frame); } -void DoSendCanPkg(MCP2515* interface, can_frame *frame) +void DoSendCanPkg(MCP2515 *interface, can_frame *frame) { byte cnt = 0; while (interface->sendMessage(frame)) diff --git a/Software/Switch/MeyCan.h b/Software/Switch/MeyCan.h index fde38c3..1eaa696 100644 --- a/Software/Switch/MeyCan.h +++ b/Software/Switch/MeyCan.h @@ -4,13 +4,48 @@ #include #include +typedef struct CanInterface +{ + MCP2515 *interface; + CanInterface *next = NULL; -typedef struct + void ForEachInterface(void (*handle)( MCP2515 *interface)) + { + if (this->interface != NULL) + handle(this->interface); + + if (this->next != NULL) + this->next->ForEachInterface(handle); + } + + void ForEach(void (*handle)( MCP2515 *interface, can_frame *frame), can_frame *frame, MCP2515* exclude = NULL) + { + if (this->interface != NULL && this->interface != exclude) + handle(this->interface, frame); + + if (this->next != NULL) + this->next->ForEach(handle, frame); + } + + void AddCanInterface(CanInterface *newCanInterface) + { + if (next == NULL) + { + this->next = newCanInterface; + newCanInterface->next = NULL; + } else { + next->AddCanInterface(newCanInterface); + } + } +}; + +typedef struct PinState { int pin_id; bool pin_state; bool is_input; byte meyPinId; + PinState *next = NULL; PinState() {} void Init(int pin_id, byte meyPinId) @@ -20,10 +55,37 @@ typedef struct this->is_input = true; this->meyPinId = meyPinId; } -} PinState; + void AddPinState(PinState *nextPinState) + { + if (next == NULL) + { + this->next = nextPinState; + nextPinState->next = NULL; + } else { + next->AddPinState(nextPinState); + } + } + + PinState* Find(byte meyPinId) + { + if (this->meyPinId == meyPinId) + return this; + + if (this->next != NULL) + return this->next->Find(meyPinId); + + return NULL; + } + + void ForEach(void (*handle)(PinState *theState)) + { + handle(this); + if (this->next != NULL) + this->next->ForEach(handle); + } +}; -/* START MEYCAN */ const byte SOFTWARE_VERSION_HIGH = 5; const byte SOFTWARE_VERSION_LOW = 0; @@ -34,14 +96,16 @@ const uint16_t HELP_PACKAGE_CAN_ID = 0x0FFFUL; const uint16_t SWITCH_TRIGGERED_CAN_ID = 0x0050; const uint16_t TRIGGER_SWITCH_CAN_ID = 0x0055; -extern MCP2515* canInterfaces[4]; - -void SetCanInterface(byte index, byte pinId); +void AddCanInterface(byte pinId); void SetMeyPin(byte index, byte meyPinId, byte pinId); void SetupMeyCan(); -void HandleFrame(can_frame *frame); +void ForEachCanInterface(void (*handle)(MCP2515 *canInterace)); +bool ReadPin(PinState *state); +bool CheckPinStatus(PinState * state); +void CheckMeyPinsTriggered(); /* checks weather a meypin triggered and sends a can pkg is neccessary */ +void HandleFrame(can_frame *frame, MCP2515 *source); void HandleTriggerMeypinCanPackage(can_frame *frame); byte CircularShift(byte b); uint16_t GetDeviceId(uint32_t canFrameId); @@ -61,7 +125,4 @@ void DoSendCanPkg(MCP2515 *interface, can_frame *frame); void CalculateMyDeviceId(); -/* STOP MEYCAN */ - - #endif diff --git a/Software/Switch/Switch.ino b/Software/Switch/Switch.ino index 3b6936d..5055283 100644 --- a/Software/Switch/Switch.ino +++ b/Software/Switch/Switch.ino @@ -1,11 +1,8 @@ -#include ; -#include ; #include ; #include ; #include "MeyCan.h"; #include "MeyRule.h"; - struct can_frame incomingCanFrame; void setup() { @@ -28,8 +25,7 @@ void setup() { AddToggle(0x0196, 3, 0x9829, 1); // Flurlicht von Papas Büro AddToggle(0x0632, 1, 0x9829, 5); // Flurlicht von Papas Büro - - // _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL.MCLKCTRLA | 1 << 7); + _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL.MCLKCTRLA | 1 << 7); delay(10); // a bit delay for mcp2515 to get the clock @@ -42,10 +38,10 @@ void setup() { SetMeyPin(6, 7, PIN_PC1); SetMeyPin(7, 8, PIN_PC0); - SetCanInterface(0, PIN_PA2); - SetCanInterface(1, PIN_PA3); - SetCanInterface(2, PIN_PB0); - SetCanInterface(3, PIN_PB1); + AddCanInterface(PIN_PA2); + AddCanInterface(PIN_PA3); + AddCanInterface(PIN_PB0); + AddCanInterface(PIN_PB1); SetupMeyCan(); @@ -54,19 +50,13 @@ void setup() { void loop() { - for (int i = 0; i < sizeof(canInterfaces) / sizeof(MCP2515*); i++) - { - if (canInterfaces[i]->readMessage(&incomingCanFrame) == MCP2515::ERROR_OK) - { - // A received CAN Frame is forwarded to all other MCPs given, but not to the receiving one (no echo ) - for (int j = 0; j < sizeof(canInterfaces) / sizeof(MCP2515*); j++) - { - if (j == i) continue; // thats for the echo - DoSendCanPkg(canInterfaces[j], &incomingCanFrame); - } + ForEachCanInterface(CheckCanInterface); +} - HandleFrame(&incomingCanFrame); - // HandleRules(&incomingCanFrame); - } +void CheckCanInterface(MCP2515 *interface) +{ + if (interface->readMessage(&incomingCanFrame) == MCP2515::ERROR_OK) + { + HandleFrame(&incomingCanFrame, interface); } } diff --git a/Software/UPSoftware/MeyCan.cpp b/Software/UPSoftware/MeyCan.cpp index 99398e9..167fedf 100644 --- a/Software/UPSoftware/MeyCan.cpp +++ b/Software/UPSoftware/MeyCan.cpp @@ -4,8 +4,7 @@ PinState *MeyPin = NULL; -CanInterface *Interfaces = NULL; -MCP2515* canInterfaces[4]; +CanInterface *CanBusses = NULL; uint16_t myDeviceId; void SetupMeyPin(PinState *state) @@ -15,6 +14,20 @@ void SetupMeyPin(PinState *state) state->pin_state = false; } +void InitCanInterface(MCP2515 *interface, can_frame *frame) // can_frame is NULL. Reuse ForEach Method for smaller footprint +{ + interface->reset(); + interface->setBitrate(CAN_500KBPS, MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz + interface->setNormalMode(); + + SendVersionPackage(interface); +} + +void ForEachCanInterface(void (*handle)(MCP2515 *canInterace)) +{ + CanBusses->ForEach(handle); +} + void SetupMeyCan() { CalculateMyDeviceId(); @@ -22,19 +35,21 @@ void SetupMeyCan() if (MeyPin != NULL); MeyPin->ForEach(SetupMeyPin); - for (int i = 0; i < sizeof(canInterfaces) / sizeof(MCP2515*); i++) { - - canInterfaces[i]->reset(); - canInterfaces[i]->setBitrate(CAN_500KBPS, MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz - canInterfaces[i]->setNormalMode(); - - SendVersionPackage(canInterfaces[i]); + if (CanBusses != NULL) + { + CanBusses->ForEach(InitCanInterface, NULL); } } void SetCanInterface(byte index, byte pinId) { - canInterfaces[index] = new MCP2515(pinId); + MCP2515* newCanInterface = new MCP2515(pinId); + CanInterface* canInterface = new CanInterface(); + + if (CanBusses == NULL) + CanBusses = canInterface; + else + CanBusses->AddCanInterface(canInterface); } void SetMeyPin(byte index, byte meyPinId, byte pinId) @@ -98,8 +113,9 @@ bool ReadPin(PinState * state) } -void HandleFrame(can_frame *frame) +void HandleFrame(can_frame *frame, MCP2515 *source) { + CanBusses->ForEach(DoSendCanPkg, frame, source); HandleTriggerMeypinCanPackage(frame); } @@ -199,8 +215,7 @@ void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte sta toSend.data[2] = pinId; toSend.data[3] = state; - DoSendCanPkg(&toSend); - HandleFrame(&toSend); + HandleFrame(&toSend, NULL); } void SendSwitchedTriggeredCanPackage(byte pinId, int state) @@ -216,11 +231,11 @@ void SendSwitchedTriggeredCanPackage(byte pinId, int state) void DoSendCanPkg(can_frame *frame) { - for (int i = 0; i < sizeof(canInterfaces) / sizeof(MCP2515*); i++) - DoSendCanPkg(canInterfaces[i], frame); + if (CanBusses != NULL) + CanBusses->ForEach(DoSendCanPkg, frame); } -void DoSendCanPkg(MCP2515* interface, can_frame *frame) +void DoSendCanPkg(MCP2515 *interface, can_frame *frame) { byte cnt = 0; while (interface->sendMessage(frame)) diff --git a/Software/UPSoftware/MeyCan.h b/Software/UPSoftware/MeyCan.h index 11238f0..5720ea3 100644 --- a/Software/UPSoftware/MeyCan.h +++ b/Software/UPSoftware/MeyCan.h @@ -6,8 +6,37 @@ typedef struct CanInterface { - MCP2515 *Interface; - MCP2515 *Next; + MCP2515 *interface; + CanInterface *next = NULL; + + void ForEach(void (*handle)( MCP2515 *interface)) + { + if (this->interface != NULL) + handle(this->interface); + + if (this->next != NULL) + this->next->ForEach(handle); + } + + void ForEach(void (*handle)( MCP2515 *interface, can_frame *frame), can_frame *frame, MCP2515* exclude = NULL) + { + if (this->interface != NULL && this->interface != exclude) + handle(this->interface, frame); + + if (this->next != NULL) + this->next->ForEach(handle, frame); + } + + void AddCanInterface(CanInterface *newCanInterface) + { + if (next == NULL) + { + this->next = newCanInterface; + newCanInterface->next = NULL; + } else { + next->AddCanInterface(newCanInterface); + } + } }; typedef struct PinState @@ -55,11 +84,9 @@ typedef struct PinState if (this->next != NULL) this->next->ForEach(handle); } -} ; +}; -/* START MEYCAN */ - const byte SOFTWARE_VERSION_HIGH = 5; const byte SOFTWARE_VERSION_LOW = 0; const byte HARDWARE_VERSION_HIGH = 7; @@ -69,17 +96,16 @@ const uint16_t HELP_PACKAGE_CAN_ID = 0x0FFFUL; const uint16_t SWITCH_TRIGGERED_CAN_ID = 0x0050; const uint16_t TRIGGER_SWITCH_CAN_ID = 0x0055; -extern MCP2515* canInterfaces[4]; - void SetCanInterface(byte index, byte pinId); void SetMeyPin(byte index, byte meyPinId, byte pinId); void SetupMeyCan(); +void ForEachCanInterface(void (*handle)(MCP2515 *canInterace)); bool ReadPin(PinState *state); bool CheckPinStatus(PinState * state); void CheckMeyPinsTriggered(); /* checks weather a meypin triggered and sends a can pkg is neccessary */ -void HandleFrame(can_frame *frame); +void HandleFrame(can_frame *frame, MCP2515 *source); void HandleTriggerMeypinCanPackage(can_frame *frame); byte CircularShift(byte b); uint16_t GetDeviceId(uint32_t canFrameId); @@ -99,7 +125,4 @@ void DoSendCanPkg(MCP2515 *interface, can_frame *frame); void CalculateMyDeviceId(); -/* STOP MEYCAN */ - - #endif