Initial commit
This commit is contained in:
@@ -1,49 +1,67 @@
|
||||
MeyCan: PROTOCOL
|
||||
|
||||
|
||||
|
||||
ArbitartionID:
|
||||
|<-- 13 bits -->| |<-- 16 bits -->|
|
||||
COMMAND DEVICE_ID
|
||||
ABC 0x14 6A
|
||||
|
||||
|
||||
COMMAND: The Command or data type transfered. -> 2^11 = 2048 Package-Types
|
||||
DEVICE_ID: A unique id for the device within the CAN Network (Home) -> 2^18 bit = 65.536 devices allowed
|
||||
|
||||
Packages
|
||||
---------------------------------
|
||||
0xF00: HELLO->ADOPT
|
||||
Payload:
|
||||
2 bytes | Byte -> Software-Version (1.0)
|
||||
2 bytes | Byte -> Hw Version (4.0)
|
||||
2 bytes | DeviceId -> DeviceId Explicit
|
||||
|
||||
0x050: Input Switch Triggered
|
||||
-> Broadcast
|
||||
---------------------------------
|
||||
Payload:
|
||||
1 byte| PinId -> Id of the pin of the local board.
|
||||
1 byte| State -> 1 for Switched, 0 for Unswitched
|
||||
|
||||
0x055: Command Set Switch
|
||||
-> Broadcast
|
||||
---------------------------------
|
||||
2 bytes | TargetDeviceId -> The id of the device to set the pin of
|
||||
1 byte | PinId -> Idof the pin of the board
|
||||
1 byte | state -> 1 to swtich on, 0 to switch off
|
||||
|
||||
|
||||
|
||||
0x010: Request Remote Pin State
|
||||
-> Broadcast
|
||||
---------------------------------
|
||||
2 bytes | TargetDeviceId -> The id of the board to request the remote pin states from. This needs to be a control device (not UP)
|
||||
1 byte | 0: Request
|
||||
| 1: Response
|
||||
DAT |
|
||||
-- n Items of format ------------
|
||||
* 2 byte: DeviceId
|
||||
* 1 byte: The State
|
||||
|
||||
|
||||
MeyCan: PROTOCOL
|
||||
|
||||
|
||||
|
||||
ArbitartionID:
|
||||
|<-- 13 bits -->| |<-- 16 bits -->|
|
||||
COMMAND DEVICE_ID
|
||||
ABC 0x14 6A
|
||||
|
||||
|
||||
COMMAND: The Command or data type transfered. -> 2^11 = 2048 Package-Types
|
||||
DEVICE_ID: A unique id for the device within the CAN Network (Home) -> 2^18 bit = 65.536 devices allowed
|
||||
|
||||
Packages
|
||||
---------------------------------
|
||||
0xF00: HELLO->ADOPT
|
||||
Payload:
|
||||
2 bytes | Byte -> Software-Version (1.0)
|
||||
2 bytes | Byte -> Hw Version (4.0)
|
||||
1 bytes | DeviceTypeId
|
||||
| 1: Switch
|
||||
| 2: Switch + Rule
|
||||
| 3: UP
|
||||
|
||||
0x050: Input Switch Triggered
|
||||
-> Broadcast
|
||||
---------------------------------
|
||||
Payload:
|
||||
1 byte| PinId -> Id of the pin of the local board.
|
||||
1 byte| State -> 1 for Switched, 0 for Unswitched
|
||||
|
||||
0x055: Command Set Switch
|
||||
-> Broadcast
|
||||
---------------------------------
|
||||
2 bytes | TargetDeviceId -> The id of the device to set the pin of
|
||||
1 byte | PinId -> Idof the pin of the board
|
||||
1 byte | state -> 1 to swtich on, 0 to switch off
|
||||
|
||||
|
||||
|
||||
0x010: Request Remote Pin State
|
||||
-> Broadcast
|
||||
---------------------------------
|
||||
2 bytes | TargetDeviceId -> The id of the board to request the remote pin states from. This needs to be a control device (not UP)
|
||||
1 byte | 0: Request
|
||||
| 1: Response
|
||||
DAT |
|
||||
-- n Items of format ------------
|
||||
* 2 byte: DeviceId
|
||||
* 1 byte: The State
|
||||
|
||||
0x009: Debug
|
||||
-> Debug Package
|
||||
----------------------------------
|
||||
some debug information
|
||||
|
||||
|
||||
|
||||
0xAA AudioStream #1
|
||||
0xAB AudioStream #2
|
||||
0xBA AudioStream #3
|
||||
0xBB AudioStream #4
|
||||
0xAAXX -> XX = Sequence Counter
|
||||
0xY -> Reserve - Flag
|
||||
|
||||
|<-- 4 bits -->| |<-- 24 bits -->|
|
||||
-> 3 Byte / Paket
|
||||
|
||||
BIN
Software/Switch/.MeyRule.cpp.swp
Normal file
BIN
Software/Switch/.MeyRule.cpp.swp
Normal file
Binary file not shown.
12
Software/Switch/.vscode/arduino.json
vendored
12
Software/Switch/.vscode/arduino.json
vendored
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"configuration": "pinout=48pin_standard,eeprom=keep,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader",
|
||||
"board": "MegaCoreX:megaavr:809",
|
||||
"sketch": "Switch.ino",
|
||||
"port": "COM6",
|
||||
"programmer": "jtag2updi"
|
||||
{
|
||||
"configuration": "pinout=48pin_standard,eeprom=keep,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader",
|
||||
"board": "MegaCoreX:megaavr:809",
|
||||
"sketch": "Switch.ino",
|
||||
"port": "COM6",
|
||||
"programmer": "jtag2updi"
|
||||
}
|
||||
1078
Software/Switch/.vscode/c_cpp_properties.json
vendored
1078
Software/Switch/.vscode/c_cpp_properties.json
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,255 +1,232 @@
|
||||
#include "MeyCan.h";
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
|
||||
|
||||
PinState *MeyPin = NULL;
|
||||
CanInterface *CanBusses = NULL;
|
||||
uint16_t myDeviceId;
|
||||
byte _deviceTypeId = 0;
|
||||
byte _majorHardwareVersion = 0;
|
||||
byte _minorHardwareVersion = 0;
|
||||
|
||||
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(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId)
|
||||
{
|
||||
_majorHardwareVersion = majorHardwareVersion;
|
||||
_minorHardwareVersion = minorHardwareVersion;
|
||||
_deviceTypeId = deviceTypeId;
|
||||
CalculateMyDeviceId();
|
||||
|
||||
if (MeyPin != NULL);
|
||||
MeyPin->ForEach(SetupMeyPin);
|
||||
|
||||
if (CanBusses != NULL)
|
||||
{
|
||||
CanBusses->ForEach(InitCanInterface, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void AddCanInterface(byte 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)
|
||||
{
|
||||
PinState* newState = new PinState();
|
||||
newState->Init(pinId, (byte) meyPinId);
|
||||
|
||||
if (MeyPin == NULL)
|
||||
MeyPin = newState;
|
||||
else
|
||||
MeyPin->AddPinState(newState);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void HandleTriggerMeypinCanPackage(can_frame *frame)
|
||||
{
|
||||
if (GetPackageType(frame->can_id) == 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte CircularShift(byte b)
|
||||
{
|
||||
return (b << 1) | (b >> 7 & 1);
|
||||
}
|
||||
|
||||
uint16_t GetDeviceId(uint32_t canFrameId)
|
||||
{
|
||||
return canFrameId & 0xFFFF;
|
||||
}
|
||||
|
||||
uint16_t GetPackageType(uint32_t canFrameId)
|
||||
{
|
||||
return (canFrameId / 0x10000) & 0xFFF;
|
||||
}
|
||||
|
||||
byte GetDeviceIdLow() {
|
||||
return (SIGROW.SERNUM0 ^
|
||||
CircularShift(SIGROW.SERNUM2) << 1 ^
|
||||
CircularShift( CircularShift(SIGROW.SERNUM4)) ^
|
||||
CircularShift( CircularShift( CircularShift(SIGROW.SERNUM6))) ^
|
||||
CircularShift( CircularShift( CircularShift( CircularShift(SIGROW.SERNUM8)))));
|
||||
}
|
||||
|
||||
byte GetDeviceIdHigh() {
|
||||
return (SIGROW.SERNUM1 ^
|
||||
CircularShift(SIGROW.SERNUM3) << 1 ^
|
||||
CircularShift( CircularShift(SIGROW.SERNUM5)) ^
|
||||
CircularShift( CircularShift( CircularShift(SIGROW.SERNUM7))) ^
|
||||
CircularShift( CircularShift( CircularShift( CircularShift(SIGROW.SERNUM9)))));
|
||||
}
|
||||
|
||||
uint32_t CreateCanId(uint16_t commandId)
|
||||
{
|
||||
return ((((uint32_t)commandId) & 0xFFF) * 0x10000) | myDeviceId | CAN_EFF_FLAG;
|
||||
}
|
||||
|
||||
void SendVersionPackage(MCP2515 *interface)
|
||||
{
|
||||
can_frame toSend;
|
||||
toSend.can_id = CreateCanId(HELP_PACKAGE_CAN_ID);
|
||||
toSend.can_dlc = 5;
|
||||
|
||||
toSend.data[0] = SOFTWARE_VERSION_HIGH;
|
||||
toSend.data[1] = SOFTWARE_VERSION_LOW;
|
||||
toSend.data[2] = _majorHardwareVersion;
|
||||
toSend.data[3] = _minorHardwareVersion;
|
||||
toSend.data[4] = _deviceTypeId;
|
||||
|
||||
DoSendCanPkg(interface, &toSend);
|
||||
}
|
||||
|
||||
void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state)
|
||||
{
|
||||
can_frame toSend;
|
||||
|
||||
toSend.can_id = CreateCanId(TRIGGER_SWITCH_CAN_ID);
|
||||
toSend.can_dlc = 4;
|
||||
toSend.data[0] = (targetCanId & 0xFF00) >> 8;
|
||||
toSend.data[1] = targetCanId & 0xFF;
|
||||
toSend.data[2] = pinId;
|
||||
toSend.data[3] = state;
|
||||
|
||||
HandleFrame(&toSend, NULL);
|
||||
}
|
||||
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state)
|
||||
{
|
||||
can_frame toSend;
|
||||
toSend.can_id = CreateCanId(SWITCH_TRIGGERED_CAN_ID);
|
||||
toSend.can_dlc = 2;
|
||||
toSend.data[0] = pinId;
|
||||
toSend.data[1] = state;
|
||||
|
||||
DoSendCanPkg(&toSend);
|
||||
}
|
||||
|
||||
void DoSendCanPkg(can_frame *frame)
|
||||
{
|
||||
if (CanBusses != NULL)
|
||||
CanBusses->ForEach(DoSendCanPkg, frame);
|
||||
}
|
||||
|
||||
void DoSendCanPkg(MCP2515 *interface, can_frame *frame)
|
||||
{
|
||||
byte cnt = 0;
|
||||
while (interface->sendMessage(frame))
|
||||
{
|
||||
if (++cnt > 10) return;
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateMyDeviceId()
|
||||
{
|
||||
myDeviceId = (GetDeviceIdHigh() << 8) | GetDeviceIdLow();
|
||||
}
|
||||
#include "MeyCan.h";
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
|
||||
|
||||
PinState *MeyPin = NULL;
|
||||
CanInterface *CanBusses = NULL;
|
||||
uint16_t myDeviceId;
|
||||
byte _deviceTypeId = 0;
|
||||
byte _majorHardwareVersion = 0;
|
||||
byte _minorHardwareVersion = 0;
|
||||
void (*LocalPinChangedHandler)(can_frame *frame);
|
||||
|
||||
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_1000KBPS, 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(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId) {
|
||||
_majorHardwareVersion = majorHardwareVersion;
|
||||
_minorHardwareVersion = minorHardwareVersion;
|
||||
_deviceTypeId = deviceTypeId;
|
||||
|
||||
if (MeyPin != NULL)
|
||||
;
|
||||
MeyPin->ForEach(SetupMeyPin);
|
||||
|
||||
if (CanBusses != NULL) {
|
||||
CanBusses->ForEach(InitCanInterface, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void AddCanInterface(byte pinId) {
|
||||
MCP2515 *newCanInterface = new MCP2515(pinId);
|
||||
CanInterface *canInterface = new CanInterface();
|
||||
canInterface->interface = newCanInterface;
|
||||
|
||||
if (CanBusses == NULL)
|
||||
CanBusses = canInterface;
|
||||
else
|
||||
CanBusses->AddCanInterface(canInterface);
|
||||
}
|
||||
|
||||
void AddLocalPinChangedHandler(void (*localPinChangedHandler)(can_frame *frame)) {
|
||||
LocalPinChangedHandler = localPinChangedHandler;
|
||||
}
|
||||
|
||||
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 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) {
|
||||
return digitalRead(state->pin_id);
|
||||
}
|
||||
|
||||
|
||||
void HandleFrame(can_frame *frame, MCP2515 *source) {
|
||||
CanBusses->ForEach(DoSendCanPkg, frame, source);
|
||||
HandleTriggerMeypinCanPackage(frame);
|
||||
}
|
||||
|
||||
void HandleTriggerMeypinCanPackage(can_frame *frame) {
|
||||
|
||||
|
||||
if (GetPackageType(frame->can_id) == 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte CircularShift(byte b) {
|
||||
return (b << 1) | (b >> 7 & 1);
|
||||
}
|
||||
|
||||
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 | CAN_EFF_FLAG;
|
||||
}
|
||||
|
||||
void SendVersionPackage(MCP2515 *interface) {
|
||||
can_frame toSend;
|
||||
toSend.can_id = CreateCanId(HELP_PACKAGE_CAN_ID);
|
||||
toSend.can_dlc = 5;
|
||||
|
||||
toSend.data[0] = SOFTWARE_VERSION_HIGH;
|
||||
toSend.data[1] = SOFTWARE_VERSION_LOW;
|
||||
toSend.data[2] = _majorHardwareVersion;
|
||||
toSend.data[3] = _minorHardwareVersion;
|
||||
toSend.data[4] = _deviceTypeId;
|
||||
|
||||
DoSendCanPkg(interface, &toSend);
|
||||
}
|
||||
|
||||
void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state) {
|
||||
can_frame toSend;
|
||||
|
||||
toSend.can_id = CreateCanId(TRIGGER_SWITCH_CAN_ID);
|
||||
toSend.can_dlc = 4;
|
||||
toSend.data[0] = (targetCanId & 0xFF00) >> 8;
|
||||
toSend.data[1] = targetCanId & 0xFF;
|
||||
toSend.data[2] = pinId;
|
||||
toSend.data[3] = state;
|
||||
|
||||
HandleFrame(&toSend, NULL);
|
||||
}
|
||||
|
||||
void BroadcastDebugPackage(uint8_t length, byte *data) {
|
||||
can_frame toSend;
|
||||
|
||||
toSend.can_id = CreateCanId(DEBUG_PKG_CAN_ID);
|
||||
toSend.can_dlc = length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
toSend.data[i] = data[i];
|
||||
}
|
||||
|
||||
HandleFrame(&toSend, NULL);
|
||||
}
|
||||
void BroadcastDebugPackage(byte b0, byte b1) {
|
||||
byte data[2];
|
||||
data[0] = b0;
|
||||
data[1] = b1;
|
||||
BroadcastDebugPackage(2, data);
|
||||
}
|
||||
void BroadcastDebugPackage(byte b0, byte b1, byte b2) {
|
||||
byte data[3];
|
||||
data[0] = b0;
|
||||
data[1] = b1;
|
||||
data[2] = b2;
|
||||
BroadcastDebugPackage(3, data);
|
||||
}
|
||||
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state) {
|
||||
can_frame toSend;
|
||||
toSend.can_id = CreateCanId(SWITCH_TRIGGERED_CAN_ID);
|
||||
toSend.can_dlc = 2;
|
||||
toSend.data[0] = pinId;
|
||||
toSend.data[1] = state;
|
||||
|
||||
DoSendCanPkg(&toSend);
|
||||
if (LocalPinChangedHandler) {
|
||||
LocalPinChangedHandler(&toSend);
|
||||
}
|
||||
}
|
||||
|
||||
void DoSendCanPkg(can_frame *frame) {
|
||||
if (CanBusses != NULL)
|
||||
CanBusses->ForEach(DoSendCanPkg, frame);
|
||||
}
|
||||
|
||||
void DoSendCanPkg(MCP2515 *interface, can_frame *frame) {
|
||||
byte cnt = 0;
|
||||
while (interface->sendMessage(frame)) {
|
||||
if (++cnt > 10) return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,128 +1,139 @@
|
||||
#ifndef MEYCAN_H
|
||||
#define MEYCAN_H
|
||||
|
||||
#include <SPI.h>
|
||||
#include <mcp2515.h>
|
||||
|
||||
typedef struct CanInterface
|
||||
{
|
||||
MCP2515 *interface;
|
||||
CanInterface *next = NULL;
|
||||
|
||||
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, exclude);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
this->pin_id = pin_id;
|
||||
this->pin_state = true;
|
||||
this->is_input = true;
|
||||
this->meyPinId = meyPinId;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const byte SOFTWARE_VERSION_HIGH = 5;
|
||||
const byte SOFTWARE_VERSION_LOW = 0;
|
||||
const byte HARDWARE_VERSION_HIGH = 7;
|
||||
const byte HARDWARE_VERSION_LOW = 0;
|
||||
|
||||
const uint16_t HELP_PACKAGE_CAN_ID = 0x0FFFUL;
|
||||
const uint16_t SWITCH_TRIGGERED_CAN_ID = 0x0050;
|
||||
const uint16_t TRIGGER_SWITCH_CAN_ID = 0x0055;
|
||||
|
||||
void AddCanInterface(byte pinId);
|
||||
void SetMeyPin(byte index, byte meyPinId, byte pinId);
|
||||
|
||||
void SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId);
|
||||
|
||||
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);
|
||||
uint16_t GetPackageType(uint32_t canFrameId);
|
||||
byte GetDeviceIdLow();
|
||||
|
||||
byte GetDeviceIdHigh();
|
||||
|
||||
uint32_t CreateCanId(uint16_t commandId);
|
||||
void SendVersionPackage(MCP2515 *interface);
|
||||
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state);
|
||||
void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state);
|
||||
|
||||
void DoSendCanPkg(can_frame *frame);
|
||||
void DoSendCanPkg(MCP2515 *interface, can_frame *frame);
|
||||
|
||||
void CalculateMyDeviceId();
|
||||
|
||||
#endif
|
||||
#ifndef MEYCAN_H
|
||||
#define MEYCAN_H
|
||||
|
||||
#include <SPI.h>
|
||||
#include <mcp2515.h>
|
||||
|
||||
typedef struct CanInterface
|
||||
{
|
||||
MCP2515 *interface;
|
||||
CanInterface *next = NULL;
|
||||
|
||||
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, exclude);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
this->pin_id = pin_id;
|
||||
this->pin_state = true;
|
||||
this->is_input = true;
|
||||
this->meyPinId = meyPinId;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const byte SOFTWARE_VERSION_HIGH = 5;
|
||||
const byte SOFTWARE_VERSION_LOW = 0;
|
||||
const byte HARDWARE_VERSION_HIGH = 7;
|
||||
const byte HARDWARE_VERSION_LOW = 0;
|
||||
|
||||
const uint16_t HELP_PACKAGE_CAN_ID = 0x0FFFUL;
|
||||
const uint16_t SWITCH_TRIGGERED_CAN_ID = 0x0050;
|
||||
const uint16_t TRIGGER_SWITCH_CAN_ID = 0x0055;
|
||||
const uint16_t DEBUG_PKG_CAN_ID = 0x0009;
|
||||
|
||||
void SetDevicedId(byte high, byte low);
|
||||
void SetMeyPin(byte meyPinId, byte pinId);
|
||||
|
||||
// we need to put the local change to the rules engine. otherwise local changes on a pin will not come to the rules state.
|
||||
void AddLocalPinChangedHandler(void (*localPinChangedHandler)(can_frame *frame));
|
||||
|
||||
|
||||
void AddCanInterface(byte pinId);
|
||||
|
||||
void SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId);
|
||||
|
||||
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);
|
||||
uint16_t GetPackageType(uint32_t canFrameId);
|
||||
byte GetDeviceIdLow();
|
||||
|
||||
byte GetDeviceIdHigh();
|
||||
|
||||
uint32_t CreateCanId(uint16_t commandId);
|
||||
void SendVersionPackage(MCP2515 *interface);
|
||||
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state);
|
||||
|
||||
|
||||
void BroadcastDebugPackage(byte b0, byte b1);
|
||||
void BroadcastDebugPackage(byte b0, byte b1, byte b2);
|
||||
void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state);
|
||||
|
||||
void DoSendCanPkg(can_frame *frame);
|
||||
void DoSendCanPkg(MCP2515 *interface, can_frame *frame);
|
||||
|
||||
void CalculateMyDeviceId();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,114 +1,117 @@
|
||||
#include "MeyRule.h"
|
||||
#include "MeyCan.h"
|
||||
#include <Arduino.h>
|
||||
#include <mcp2515.h>;
|
||||
|
||||
RemotePinInfo remotePinInfo = RemotePinInfo();
|
||||
Rule *rules = NULL;
|
||||
|
||||
void PutRule(Rule *rule)
|
||||
{
|
||||
if (rules == NULL)
|
||||
rules = rule;
|
||||
else
|
||||
rules->AddRule(rule);
|
||||
}
|
||||
|
||||
void AddSimple(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId)
|
||||
{
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->targetDevId = targetDevId;
|
||||
rule->targetMeyPinId = targetMeyPinId;
|
||||
rule->toggle = false;
|
||||
rule->inverse = false;
|
||||
rule->lastPinState = false;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
void AddToggle(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId)
|
||||
{
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->targetDevId = targetDevId;
|
||||
rule->targetMeyPinId = targetMeyPinId;
|
||||
rule->toggle = true;
|
||||
rule->inverse = false;
|
||||
rule->lastPinState = false;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
void AddToggleInverse(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId)
|
||||
{
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->targetDevId = targetDevId;
|
||||
rule->targetMeyPinId = targetMeyPinId;
|
||||
rule->toggle = true;
|
||||
rule->inverse = true;
|
||||
rule->lastPinState = false;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CheckRule(uint16_t deviceId, uint8_t dt, uint8_t state, Rule *rule)
|
||||
{
|
||||
RemotePinInfo *currentRemotePinInfo = remotePinInfo.FindOrAdd(rule->targetDevId);
|
||||
if (currentRemotePinInfo == NULL) return;
|
||||
|
||||
// check the new state with the last one. Needs to be done, as the UP switch might
|
||||
// send it multiple times like "01 01" "01 01" for a single tip.(antibeat)
|
||||
bool lastPinState = rule->lastPinState;
|
||||
bool pinState = dt > 0;
|
||||
|
||||
if (rule->triggeredOnce && lastPinState == pinState) return;
|
||||
rule->lastPinState = pinState;
|
||||
rule->triggeredOnce = true;
|
||||
|
||||
if (rule->inverse)
|
||||
pinState = !pinState;
|
||||
|
||||
if (rule->toggle)
|
||||
pinState = (currentRemotePinInfo->getPinState(rule->targetMeyPinId) ^ true);
|
||||
|
||||
BroadcastTriggerMeyPinCanPackage(rule->targetDevId, rule->targetMeyPinId, pinState);
|
||||
currentRemotePinInfo->setPinState(rule->targetMeyPinId, pinState);
|
||||
}
|
||||
|
||||
void HandleTriggered(can_frame *frame)
|
||||
{
|
||||
if (GetPackageType(frame->can_id) == SWITCH_TRIGGERED_CAN_ID)
|
||||
{
|
||||
RemotePinInfo *currentPinState = remotePinInfo.FindOrAdd(GetDeviceId(frame->can_id) );
|
||||
|
||||
if (currentPinState == NULL)
|
||||
return;
|
||||
|
||||
currentPinState->setPinState(frame->data[0], frame->data[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleRules(can_frame *frame)
|
||||
{
|
||||
HandleTriggered(frame);
|
||||
|
||||
if (rules == NULL) return;
|
||||
if (GetPackageType(frame->can_id) == SWITCH_TRIGGERED_CAN_ID)
|
||||
{
|
||||
uint16_t deviceId = GetDeviceId(frame->can_id);
|
||||
uint8_t dt = frame->data[1];
|
||||
uint8_t state = frame->data[0];
|
||||
|
||||
rules->Traverse(deviceId, dt, state, CheckRule);
|
||||
}
|
||||
}
|
||||
#include "MeyRule.h"
|
||||
#include "MeyCan.h"
|
||||
#include <Arduino.h>
|
||||
#include <mcp2515.h>;
|
||||
|
||||
RemotePinInfo remotePinInfo = RemotePinInfo();
|
||||
Rule *rules = NULL;
|
||||
|
||||
void PutRule(Rule *rule) {
|
||||
if (rules == NULL)
|
||||
rules = rule;
|
||||
else
|
||||
rules->AddRule(rule);
|
||||
}
|
||||
|
||||
void AddSimple(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId) {
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->target.devId = targetDevId;
|
||||
rule->target.meyPinId = targetMeyPinId;
|
||||
rule->target.lastPinState = false;
|
||||
rule->toggle = false;
|
||||
rule->inverse = false;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
void AddToggle(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId) {
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->target.devId = targetDevId;
|
||||
rule->target.meyPinId = targetMeyPinId;
|
||||
rule->target.lastPinState = false;
|
||||
rule->toggle = true;
|
||||
rule->inverse = false;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
void AddToggleInverse(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId) {
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->target.devId = targetDevId;
|
||||
rule->target.meyPinId = targetMeyPinId;
|
||||
rule->target.lastPinState = false;
|
||||
rule->toggle = true;
|
||||
rule->inverse = true;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CheckRule(uint16_t deviceId, uint8_t dt, uint8_t state, Rule *rule) {
|
||||
|
||||
|
||||
RemotePinInfo *currentRemotePinInfo = remotePinInfo.FindOrAdd(rule->target.devId);
|
||||
|
||||
if (currentRemotePinInfo == NULL) return;
|
||||
|
||||
// check the new state with the last one. Needs to be done, as the UP switch might
|
||||
// send it multiple times like "01 01" "01 01" for a single tip.(antibeat)
|
||||
bool lastPinState = rule->target.lastPinState;
|
||||
bool pinState = dt > 0;
|
||||
|
||||
if (rule->triggeredOnce && lastPinState == pinState) return;
|
||||
|
||||
rule->target.lastPinState = pinState;
|
||||
rule->triggeredOnce = true;
|
||||
|
||||
if (rule->inverse)
|
||||
pinState = !pinState;
|
||||
|
||||
if (rule->toggle)
|
||||
pinState = (currentRemotePinInfo->getPinState(rule->target.meyPinId) ^ true);
|
||||
|
||||
currentRemotePinInfo->setPinState(rule->target.meyPinId, pinState);
|
||||
BroadcastTriggerMeyPinCanPackage(rule->target.devId, rule->target.meyPinId, pinState);
|
||||
}
|
||||
|
||||
void HandleTriggered(can_frame *frame) {
|
||||
if (GetPackageType(frame->can_id) == SWITCH_TRIGGERED_CAN_ID) {
|
||||
RemotePinInfo *currentPinState = remotePinInfo.FindOrAdd(GetDeviceId(frame->can_id));
|
||||
|
||||
if (currentPinState == NULL) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
currentPinState->setPinState(frame->data[0], frame->data[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void SetLocalPinState(can_frame *frame)
|
||||
{
|
||||
HandleTriggered(frame);
|
||||
}
|
||||
|
||||
void HandleRules(can_frame *frame) {
|
||||
|
||||
if (rules != NULL) {
|
||||
if (GetPackageType(frame->can_id) == SWITCH_TRIGGERED_CAN_ID) {
|
||||
uint16_t deviceId = GetDeviceId(frame->can_id);
|
||||
uint8_t dt = frame->data[1];
|
||||
uint8_t state = frame->data[0];
|
||||
|
||||
rules->Traverse(deviceId, dt, state, CheckRule);
|
||||
}
|
||||
}
|
||||
HandleTriggered(frame);
|
||||
}
|
||||
|
||||
@@ -1,113 +1,107 @@
|
||||
#ifndef MEYRULE_H
|
||||
#define MEYRULE_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <mcp2515.h>;
|
||||
|
||||
struct Rule
|
||||
{
|
||||
uint16_t sourceDevId;
|
||||
byte sourceMeyPinId;
|
||||
uint16_t targetDevId;
|
||||
byte targetMeyPinId;
|
||||
bool toggle;
|
||||
bool inverse;
|
||||
Rule *nextRule = NULL;
|
||||
bool lastPinState = false;
|
||||
bool triggeredOnce = false;
|
||||
|
||||
void AddRule(Rule *rule)
|
||||
{
|
||||
if (this->nextRule == NULL)
|
||||
{
|
||||
this->nextRule = rule;
|
||||
rule->nextRule = NULL;
|
||||
} else {
|
||||
this->nextRule->AddRule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
void Traverse( uint16_t deviceId, uint8_t dt, uint8_t state, void (*handle)(uint16_t, uint8_t, uint8_t, Rule*))
|
||||
{
|
||||
|
||||
if ( this->sourceDevId == deviceId && this->sourceMeyPinId == state)
|
||||
handle(deviceId, dt, state, this);
|
||||
|
||||
if (this->nextRule != NULL)
|
||||
this->nextRule->Traverse(deviceId, dt, state, handle);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef struct RemotePinInfo
|
||||
{
|
||||
const byte MAX_REMOTE_PIN_COUNT = 64;
|
||||
uint16_t DeviceId = 0; // the id of the device
|
||||
uint8_t pinState = 0; // bitmap of 8 MeyPin states of the device. 0000 0100, MeyPin #3 is HIGH in this example
|
||||
RemotePinInfo *next = NULL;
|
||||
|
||||
bool getPinState(byte meyPin)
|
||||
{
|
||||
return (this->pinState >> (meyPin - 1)) & 1;
|
||||
}
|
||||
|
||||
void setPinState(byte meyPin, bool state)
|
||||
{
|
||||
if (state)
|
||||
this->pinState = this->pinState | (1 << (meyPin - 1)); // 0001 0000
|
||||
else
|
||||
this->pinState = this->pinState & (~(1 << (meyPin - 1))); // 1110 1111 -> not
|
||||
}
|
||||
|
||||
|
||||
int16_t Count()
|
||||
{
|
||||
if (this->next == NULL) return 1;
|
||||
return this->next->Count() + 1;
|
||||
}
|
||||
|
||||
RemotePinInfo* FindOrAdd(uint16_t deviceId, byte count = 0)
|
||||
{
|
||||
if (count > MAX_REMOTE_PIN_COUNT)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (this->DeviceId == 0 && this->pinState == 0)
|
||||
{
|
||||
this->DeviceId = deviceId;
|
||||
this->pinState = 0;
|
||||
}
|
||||
|
||||
if (this->DeviceId == deviceId)
|
||||
{
|
||||
//ToggleDebug();
|
||||
return this;
|
||||
}
|
||||
|
||||
if (next != NULL)
|
||||
{
|
||||
return next->FindOrAdd(deviceId, count + 1);
|
||||
}
|
||||
|
||||
RemotePinInfo *theNext = new RemotePinInfo;
|
||||
theNext->DeviceId = deviceId;
|
||||
theNext->pinState = 0;
|
||||
theNext->next = NULL;
|
||||
|
||||
this->next = theNext;
|
||||
return this->next;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern RemotePinInfo remotePinInfo;
|
||||
extern Rule *rules;
|
||||
|
||||
void AddSimple(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void AddToggle(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void AddToggleInverse(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void HandleRules(can_frame *frame);
|
||||
void PutRule(Rule *rule);
|
||||
void CheckRule(uint16_t deviceId, uint8_t dt, uint8_t state, Rule *rule);
|
||||
#endif
|
||||
#ifndef MEYRULE_H
|
||||
#define MEYRULE_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <mcp2515.h>;
|
||||
|
||||
struct TargetPin{
|
||||
uint16_t devId;
|
||||
byte meyPinId;
|
||||
bool lastPinState = false;
|
||||
|
||||
};
|
||||
|
||||
struct Rule {
|
||||
uint16_t sourceDevId;
|
||||
byte sourceMeyPinId;
|
||||
TargetPin target = TargetPin();
|
||||
bool toggle;
|
||||
bool inverse;
|
||||
Rule *nextRule = NULL;
|
||||
bool triggeredOnce = false;
|
||||
|
||||
void AddRule(Rule *rule) {
|
||||
if (this->nextRule == NULL) {
|
||||
this->nextRule = rule;
|
||||
rule->nextRule = NULL;
|
||||
} else {
|
||||
this->nextRule->AddRule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
void Traverse(uint16_t deviceId, uint8_t dt, uint8_t state, void (*handle)(uint16_t, uint8_t, uint8_t, Rule *)) {
|
||||
|
||||
if (this->sourceDevId == deviceId && this->sourceMeyPinId == state)
|
||||
handle(deviceId, dt, state, this);
|
||||
|
||||
if (this->nextRule != NULL)
|
||||
this->nextRule->Traverse(deviceId, dt, state, handle);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef struct RemotePinInfo {
|
||||
const byte MAX_REMOTE_PIN_COUNT = 64;
|
||||
uint16_t DeviceId = 0; // the id of the device
|
||||
uint8_t pinState = 0; // bitmap of 8 MeyPin states of the device. 0000 0100, MeyPin #3 is HIGH in this example
|
||||
RemotePinInfo *next = NULL;
|
||||
|
||||
bool getPinState(byte meyPin) {
|
||||
return (this->pinState >> (meyPin - 1)) & 1;
|
||||
}
|
||||
|
||||
void setPinState(byte meyPin, bool state) {
|
||||
if (state)
|
||||
this->pinState = this->pinState | (1 << (meyPin - 1)); // 0001 0000
|
||||
else
|
||||
this->pinState = this->pinState & (~(1 << (meyPin - 1))); // 1110 1111 -> not
|
||||
}
|
||||
|
||||
|
||||
int16_t Count() {
|
||||
if (this->next == NULL) return 1;
|
||||
return this->next->Count() + 1;
|
||||
}
|
||||
|
||||
RemotePinInfo *FindOrAdd(uint16_t deviceId, byte count = 0) {
|
||||
if (count > MAX_REMOTE_PIN_COUNT)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (this->DeviceId == 0 && this->pinState == 0) {
|
||||
this->DeviceId = deviceId;
|
||||
this->pinState = 0;
|
||||
}
|
||||
|
||||
if (this->DeviceId == deviceId) {
|
||||
//ToggleDebug();
|
||||
return this;
|
||||
}
|
||||
|
||||
if (next != NULL) {
|
||||
return next->FindOrAdd(deviceId, count + 1);
|
||||
}
|
||||
|
||||
RemotePinInfo *theNext = new RemotePinInfo;
|
||||
theNext->DeviceId = deviceId;
|
||||
theNext->pinState = 0;
|
||||
theNext->next = NULL;
|
||||
|
||||
this->next = theNext;
|
||||
return this->next;
|
||||
}
|
||||
};
|
||||
|
||||
extern RemotePinInfo remotePinInfo;
|
||||
extern Rule *rules;
|
||||
|
||||
void SetLocalPinState(can_frame *frame);
|
||||
|
||||
void AddSimple(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void AddToggle(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void AddToggleInverse(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void HandleRules(can_frame *frame);
|
||||
void PutRule(Rule *rule);
|
||||
void CheckRule(uint16_t deviceId, uint8_t dt, uint8_t state, Rule *rule);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,96 +1,114 @@
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
#include "MeyCan.h";
|
||||
#include "MeyRule.h";
|
||||
|
||||
const int16_t SW_FLUR = 0XD238;
|
||||
const int16_t SW_ANBAU = 0x87A9;
|
||||
const int16_t SW_WOHNZIMMER = 0x87CA;
|
||||
|
||||
const int16_t UP_WOHNZIMMER_TUER = 0x051F;
|
||||
const int16_t UP_WOHNZIMMER_TERASSE = 0x05df;
|
||||
const int16_t UP_FLUR_EINGANG = 0x0769;
|
||||
const int16_t UP_BUERO = 0x1177;
|
||||
const int16_t UP_FLUR_BUERO = 0x05A1;
|
||||
const int16_t UP_FLUR_KUECHE = 0x01EF;
|
||||
const int16_t UP_KINDERZIMMER = 0x0196;
|
||||
const int16_t UP_FLUR_ELTERN = 0x0632;
|
||||
const int16_t UP_KUECHE_FLUR = 0x07F5;
|
||||
const int16_t UP_KUECHE_BAD = 0x0585;
|
||||
|
||||
struct can_frame incomingCanFrame;
|
||||
|
||||
void setup() {
|
||||
SPI.begin();
|
||||
|
||||
|
||||
// AddToggleInverse(UP_WOHNZIMMER_TUER, 5, SW_WOHNZIMMER, 4); // Lichtschalter Wohnzimmer Licht 1
|
||||
// AddToggleInverse(UP_WOHNZIMMER_TUER, 5, SW_WOHNZIMMER, 3); // Lichtschalter Wohnzimmer Licht 2
|
||||
// AddToggle(UP_WOHNZIMMER_TERASSE, 1, SW_WOHNZIMMER, 4); // Licht 1 von Terassenschalter
|
||||
// AddToggle(UP_WOHNZIMMER_TERASSE, 1, SW_WOHNZIMMER, 3); // Licht 2 von Terassenschalter
|
||||
//
|
||||
// AddToggle(0x0769, 1, SW_WOHNZIMMER, 7); // Eingangstür Flur Licht 2
|
||||
// AddToggle(0x0769, 1, SW_FLUR, 1); //Eingangstür Flur Licht 1
|
||||
//
|
||||
// AddToggle(UP_WOHNZIMMER_TUER, 3, SW_WOHNZIMMER, 1); // Licht 1 Wochzimmer Eingangstür
|
||||
// AddToggle(UP_WOHNZIMMER_TUER, 4, SW_WOHNZIMMER, 2); // Licht 2 Wochzimmer Eingangstür
|
||||
//
|
||||
// AddToggle(0x1177, 1, SW_WOHNZIMMER, 6); // Licht Papa Büro
|
||||
// AddToggle(0x05A1, 1, SW_WOHNZIMMER, 7); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x05A1, 1, SW_FLUR, 1); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x01EF, 1, SW_WOHNZIMMER, 7); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x01EF, 1, SW_FLUR, 1); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x0196, 3, SW_WOHNZIMMER, 7); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x0196, 3, SW_FLUR, 1); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x0632, 1, SW_FLUR, 5); // Flurlicht von Papas Büro
|
||||
//
|
||||
// AddToggle(UP_WOHNZIMMER_TUER, 2, SW_FLUR, 2); // Linus Zimmer hoch aus Wohnzimmer
|
||||
// AddToggle(UP_WOHNZIMMER_TUER, 1, SW_FLUR, 3); // Linus Zimmer runter hoch aus Wohnzimmer
|
||||
//
|
||||
// AddToggle(0x0769, 2, SW_FLUR, 4); // Linus Zimmer runter hoch aus Wohnzimmer
|
||||
//
|
||||
//
|
||||
// AddToggle(UP_KUECHE_FLUR, 1, SW_ANBAU, 2);
|
||||
// AddToggle(UP_KUECHE_FLUR, 2, SW_ANBAU, 3);
|
||||
// AddToggle(UP_KUECHE_BAD, 1, SW_ANBAU, 2);
|
||||
// AddToggle(UP_KUECHE_BAD, 3, SW_ANBAU, 1);
|
||||
// AddToggle(UP_KUECHE_BAD, 2, SW_ANBAU, 4);
|
||||
|
||||
|
||||
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL.MCLKCTRLA | 1 << 7);
|
||||
|
||||
delay(10); // a bit delay for mcp2515 to get the clock
|
||||
|
||||
|
||||
SetMeyPin(0, 1, PIN_PC7);
|
||||
SetMeyPin(1, 2, PIN_PC6);
|
||||
SetMeyPin(2, 3, PIN_PC5);
|
||||
SetMeyPin(3, 4, PIN_PC4);
|
||||
SetMeyPin(4, 5, PIN_PC3);
|
||||
SetMeyPin(5, 6, PIN_PC2);
|
||||
SetMeyPin(6, 7, PIN_PC1);
|
||||
SetMeyPin(7, 8, PIN_PC0);
|
||||
|
||||
AddCanInterface(PIN_PA2);
|
||||
AddCanInterface(PIN_PA3);
|
||||
AddCanInterface(PIN_PB0);
|
||||
AddCanInterface(PIN_PB1);
|
||||
|
||||
|
||||
SetupMeyCan(7, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
ForEachCanInterface(CheckCanInterface);
|
||||
}
|
||||
|
||||
void CheckCanInterface(MCP2515 *interface)
|
||||
{
|
||||
if (interface->readMessage(&incomingCanFrame) == MCP2515::ERROR_OK)
|
||||
{
|
||||
HandleFrame(&incomingCanFrame, interface);
|
||||
HandleRules(&incomingCanFrame);
|
||||
}
|
||||
}
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
#include "MeyCan.h";
|
||||
#include "MeyRule.h";
|
||||
|
||||
#define PIN8 8
|
||||
#define PIN9 9
|
||||
|
||||
const int16_t SW_FLUR = 0XD238;
|
||||
const int16_t SW_ANBAU = 0x87A9;
|
||||
const int16_t SW_WOHNZIMMER = 0x87CA;
|
||||
const int16_t SW_TERRASSE = 0x618A;
|
||||
|
||||
|
||||
const int16_t UP_WOHNZIMMER_TUER = 0x051F; // [X X]
|
||||
const int16_t UP_WOHNZIMMER_TERASSE = 0x05df;
|
||||
const int16_t UP_FLUR_EINGANG = 0x0769; // [X]
|
||||
const int16_t UP_BUERO = 0x1177;
|
||||
const int16_t UP_FLUR_BUERO = 0x05A1; // [X]
|
||||
const int16_t UP_FLUR_KUECHE = 0x01EF;
|
||||
const int16_t UP_KINDERZIMMER = 0x0196; // [X X]
|
||||
const int16_t UP_FLUR_ELTERN = 0x0632;
|
||||
const int16_t UP_ELTERN = 0x08AE;
|
||||
const int16_t UP_KUECHE_FLUR = 0x07F5; // [X]
|
||||
const int16_t UP_KUECHE_BAD = 0x0585; // [X X]
|
||||
|
||||
struct can_frame incomingCanFrame;
|
||||
|
||||
/*
|
||||
Software matching Hardware of meycan v8.1
|
||||
*/
|
||||
void setup() {
|
||||
SPI.begin();
|
||||
|
||||
|
||||
AddToggle(UP_WOHNZIMMER_TUER, 1, SW_WOHNZIMMER, 5);
|
||||
AddToggle(UP_WOHNZIMMER_TUER, 1, SW_WOHNZIMMER, 6);
|
||||
AddSimple(UP_WOHNZIMMER_TUER, 2, SW_WOHNZIMMER, 7);
|
||||
AddSimple(UP_WOHNZIMMER_TUER, 3, SW_WOHNZIMMER, 8);
|
||||
|
||||
|
||||
AddToggle(UP_KINDERZIMMER, 3, SW_FLUR, 6);
|
||||
AddToggle(UP_KINDERZIMMER, 3, SW_WOHNZIMMER, 2);
|
||||
AddToggle(UP_KINDERZIMMER, 2, SW_FLUR, 3);
|
||||
AddSimple(UP_KINDERZIMMER, 4, SW_FLUR, 4);
|
||||
AddSimple(UP_KINDERZIMMER, 1, SW_FLUR, 5);
|
||||
|
||||
|
||||
AddToggle(UP_FLUR_EINGANG, 1, SW_FLUR, 1);
|
||||
AddToggle(UP_FLUR_EINGANG, 2, SW_FLUR, 6);
|
||||
AddToggle(UP_FLUR_EINGANG, 2, SW_WOHNZIMMER, 2);
|
||||
|
||||
AddToggle(UP_ELTERN, 1, SW_FLUR, 2);
|
||||
|
||||
AddToggle(UP_BUERO, 1, SW_WOHNZIMMER, 3);
|
||||
|
||||
AddToggle(UP_FLUR_BUERO, 1, SW_FLUR, 6);
|
||||
AddToggle(UP_FLUR_BUERO, 1, SW_WOHNZIMMER, 2);
|
||||
|
||||
AddToggle (UP_WOHNZIMMER_TERASSE, 1, SW_WOHNZIMMER, 7); // Licht 1 von Terassenschalter
|
||||
AddToggle (UP_WOHNZIMMER_TERASSE, 2, SW_WOHNZIMMER, 8); // Licht
|
||||
AddToggle (UP_WOHNZIMMER_TERASSE, 3, SW_TERRASSE, 2); // Pergola
|
||||
|
||||
/// RULE FOR SWITCH WOHNZIMMER (BOTH) OF TERASSE
|
||||
// AddSimple (UP_WOHNZIMMER_TERASSE, 3, SW_WOHNZIMMER, 5); // Eingangstür Flur Licht 2
|
||||
// AddSimple (UP_WOHNZIMMER_TERASSE, 3, SW_WOHNZIMMER, 6); // Eingangstür Flur Licht 2
|
||||
|
||||
|
||||
AddToggle(UP_KUECHE_FLUR, 1, SW_ANBAU, 3);
|
||||
AddToggle(UP_KUECHE_FLUR, 2, SW_ANBAU, 2);
|
||||
AddToggle(UP_KUECHE_BAD, 1, SW_ANBAU, 3);
|
||||
AddToggle(UP_KUECHE_BAD, 2, SW_ANBAU, 1);
|
||||
AddToggle(UP_KUECHE_BAD, 3, SW_ANBAU, 4);
|
||||
|
||||
AddToggle(UP_FLUR_KUECHE, 1, SW_FLUR, 6);
|
||||
AddToggle(UP_FLUR_KUECHE, 1, SW_WOHNZIMMER, 2);
|
||||
|
||||
|
||||
SetMeyPin(1, PIN3);
|
||||
SetMeyPin(2, PIN5);
|
||||
SetMeyPin(3, PIN7);
|
||||
SetMeyPin(4, PIN9);
|
||||
SetMeyPin(5, PIN8);
|
||||
SetMeyPin(6, PIN6);
|
||||
SetMeyPin(7, PIN4);
|
||||
SetMeyPin(8, PIN2);
|
||||
|
||||
SetDevicedId(0x87, 0xCA);
|
||||
AddLocalPinChangedHandler(SetLocalPinStateAdapter);
|
||||
|
||||
AddCanInterface(PIN_A0);
|
||||
AddCanInterface(PIN_A1);
|
||||
AddCanInterface(PIN_A2);
|
||||
AddCanInterface(PIN_A3);
|
||||
|
||||
SetupMeyCan(8, 0, 2);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
ForEachCanInterface(CheckCanInterface);
|
||||
}
|
||||
|
||||
|
||||
void SetLocalPinStateAdapter(can_frame *frame)
|
||||
{
|
||||
SetLocalPinState(frame);
|
||||
}
|
||||
|
||||
void CheckCanInterface(MCP2515 *interface) {
|
||||
if (interface->readMessage(&incomingCanFrame) == MCP2515::ERROR_OK) {
|
||||
HandleFrame(&incomingCanFrame, interface);
|
||||
HandleRules(&incomingCanFrame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
Testfälle Meycan Switch
|
||||
|
||||
PreCons for each:
|
||||
GIVEN XX XX is the deviceId of the target device
|
||||
GIVEN YY YY is another device id, which is NOT XX XX
|
||||
GIVEN 2nd CAN Debug Device on another CanBus of switch
|
||||
|
||||
1) A MeyPin can be triggered directly (repeat Test for all MeyPins and each CAN Bus Interface specified)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01 -> (MeyPin1 Should switch to on)
|
||||
THEN The MeyPin 1 should trigger
|
||||
THEN you receive a message 00 50 XX XX | 01 01
|
||||
THEN 2nd device should receive 2 messages
|
||||
* 00 50 XX XX | 01 01
|
||||
* 00 55 11 11 | XX XX 01 01
|
||||
|
||||
1a) A MeyPin trigger is effecltess, if only set
|
||||
GIVEN the above testcast
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01
|
||||
THEN Nothing changed
|
||||
THEN you dont receive a message
|
||||
THEN 2nd device should receive 00 55 11 11 | XX XX 01 01
|
||||
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 00 -> (MeyPin1 Should switch to off)
|
||||
THEN The MeyPin 1 should switch to OFF
|
||||
THEN you receive a message 00 50 XX XX | 01 00
|
||||
THEN 2nd device should receive 2 messages
|
||||
* 00 50 XX XX | 01 00
|
||||
* 00 55 11 11 | XX XX 01 00
|
||||
|
||||
|
||||
2) A MeyPin is not triggered, if the device id dont match
|
||||
WHEN Send CAN Pkg 00 55 11 11 | YY YY 01 01
|
||||
THEN None of the pins of the device triggered
|
||||
THEN you receive no message
|
||||
THEN 2nd device should receive 1 messages
|
||||
* 00 55 11 11 | XX XX 01 01
|
||||
|
||||
|
||||
3) A MeyPin is not triggered, if the Package Type dont match
|
||||
WHEN Send CAN Pkg 50 00 11 11 | YY YY 01 01
|
||||
THEN None of the pins of the device triggered
|
||||
THEN you receive no message
|
||||
THEN 2nd device should receive 1 messages
|
||||
* 50 00 11 11 | XX XX 01 01
|
||||
|
||||
3) A MeyPin is not triggered, if the MeyPin is above 8 (max pins)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 09 01
|
||||
THEN None of the pins of the device triggered
|
||||
THEN you receive no message
|
||||
THEN 2nd device should receive 1 messages
|
||||
* 00 55 11 11 | XX XX 09 01
|
||||
THEN you can execute any other testcase, as the switch didnt crash
|
||||
|
||||
4) All MeyPins can be activated more than 15 minutes in parallel(Activate each port for at least 15 mins)
|
||||
GIVE You have a relais connected to each of the ports
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01 -> (MeyPin1 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 02 01 -> (MeyPin2 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 03 01 -> (MeyPin3 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 04 01 -> (MeyPin4 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 05 01 -> (MeyPin5 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 06 01 -> (MeyPin6 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 07 01 -> (MeyPin7 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 08 01 -> (MeyPin8 Should switch to on)
|
||||
THEN you should only receive the packages from above.
|
||||
THEN you should NOT receive a VersionPackage
|
||||
WHEN you wait 15 Minutes
|
||||
THEN nothing should be send
|
||||
Testfälle Meycan Switch
|
||||
|
||||
PreCons for each:
|
||||
GIVEN XX XX is the deviceId of the target device
|
||||
GIVEN YY YY is another device id, which is NOT XX XX
|
||||
GIVEN 2nd CAN Debug Device on another CanBus of switch
|
||||
|
||||
1) A MeyPin can be triggered directly (repeat Test for all MeyPins and each CAN Bus Interface specified)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01 -> (MeyPin1 Should switch to on)
|
||||
THEN The MeyPin 1 should trigger
|
||||
THEN you receive a message 00 50 XX XX | 01 01
|
||||
THEN 2nd device should receive 2 messages
|
||||
* 00 50 XX XX | 01 01
|
||||
* 00 55 11 11 | XX XX 01 01
|
||||
|
||||
1a) A MeyPin trigger is effecltess, if only set
|
||||
GIVEN the above testcast
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01
|
||||
THEN Nothing changed
|
||||
THEN you dont receive a message
|
||||
THEN 2nd device should receive 00 55 11 11 | XX XX 01 01
|
||||
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 00 -> (MeyPin1 Should switch to off)
|
||||
THEN The MeyPin 1 should switch to OFF
|
||||
THEN you receive a message 00 50 XX XX | 01 00
|
||||
THEN 2nd device should receive 2 messages
|
||||
* 00 50 XX XX | 01 00
|
||||
* 00 55 11 11 | XX XX 01 00
|
||||
|
||||
|
||||
2) A MeyPin is not triggered, if the device id dont match
|
||||
WHEN Send CAN Pkg 00 55 11 11 | YY YY 01 01
|
||||
THEN None of the pins of the device triggered
|
||||
THEN you receive no message
|
||||
THEN 2nd device should receive 1 messages
|
||||
* 00 55 11 11 | XX XX 01 01
|
||||
|
||||
|
||||
3) A MeyPin is not triggered, if the Package Type dont match
|
||||
WHEN Send CAN Pkg 50 00 11 11 | YY YY 01 01
|
||||
THEN None of the pins of the device triggered
|
||||
THEN you receive no message
|
||||
THEN 2nd device should receive 1 messages
|
||||
* 50 00 11 11 | XX XX 01 01
|
||||
|
||||
3) A MeyPin is not triggered, if the MeyPin is above 8 (max pins)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 09 01
|
||||
THEN None of the pins of the device triggered
|
||||
THEN you receive no message
|
||||
THEN 2nd device should receive 1 messages
|
||||
* 00 55 11 11 | XX XX 09 01
|
||||
THEN you can execute any other testcase, as the switch didnt crash
|
||||
|
||||
4) All MeyPins can be activated more than 15 minutes in parallel(Activate each port for at least 15 mins)
|
||||
GIVE You have a relais connected to each of the ports
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01 -> (MeyPin1 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 02 01 -> (MeyPin2 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 03 01 -> (MeyPin3 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 04 01 -> (MeyPin4 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 05 01 -> (MeyPin5 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 06 01 -> (MeyPin6 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 07 01 -> (MeyPin7 Should switch to on)
|
||||
WHEN Send CAN Pkg 00 55 11 11 | XX XX 08 01 -> (MeyPin8 Should switch to on)
|
||||
THEN you should only receive the packages from above.
|
||||
THEN you should NOT receive a VersionPackage
|
||||
WHEN you wait 15 Minutes
|
||||
THEN nothing should be send
|
||||
THEN the Pins should not trigger
|
||||
7
Software/Testsender/.vscode/arduino.json
vendored
Normal file
7
Software/Testsender/.vscode/arduino.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"configuration": "pinout=48pin_standard,eeprom=keep,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader",
|
||||
"board": "MegaCoreX:megaavr:809",
|
||||
"sketch": "Switch.ino",
|
||||
"port": "COM6",
|
||||
"programmer": "jtag2updi"
|
||||
}
|
||||
540
Software/Testsender/.vscode/c_cpp_properties.json
vendored
Normal file
540
Software/Testsender/.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,540 @@
|
||||
{
|
||||
"version": 4,
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Arduino",
|
||||
"compilerPath": "C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7\\bin\\avr-g++",
|
||||
"compilerArgs": [
|
||||
"-w",
|
||||
"-std=gnu++17",
|
||||
"-fpermissive",
|
||||
"-fno-exceptions",
|
||||
"-ffunction-sections",
|
||||
"-fdata-sections",
|
||||
"-fno-threadsafe-statics",
|
||||
"-Wno-error=narrowing"
|
||||
],
|
||||
"intelliSenseMode": "gcc-x64",
|
||||
"includePath": [
|
||||
"C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\MegaCoreX\\hardware\\megaavr\\1.1.0\\cores\\coreX-corefiles\\api\\deprecated",
|
||||
"C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\MegaCoreX\\hardware\\megaavr\\1.1.0\\cores\\coreX-corefiles",
|
||||
"C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\MegaCoreX\\hardware\\megaavr\\1.1.0\\variants\\48pin-standard",
|
||||
"C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\MegaCoreX\\hardware\\megaavr\\1.1.0\\libraries\\SPI\\src",
|
||||
"C:\\Users\\Martin\\Documents\\Arduino\\libraries\\autowp-mcp2515",
|
||||
"c:\\users\\martin\\appdata\\local\\arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7\\lib\\gcc\\avr\\7.3.0\\include",
|
||||
"c:\\users\\martin\\appdata\\local\\arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7\\lib\\gcc\\avr\\7.3.0\\include-fixed",
|
||||
"c:\\users\\martin\\appdata\\local\\arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7\\avr\\include"
|
||||
],
|
||||
"forcedInclude": [
|
||||
"C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\MegaCoreX\\hardware\\megaavr\\1.1.0\\cores\\coreX-corefiles\\Arduino.h"
|
||||
],
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"defines": [
|
||||
"F_CPU=8000000L",
|
||||
"ARDUINO=10607",
|
||||
"ARDUINO_AVR_ATmega809",
|
||||
"ARDUINO_ARCH_MEGAAVR",
|
||||
"__DBL_MIN_EXP__=(-125)",
|
||||
"__HQ_FBIT__=15",
|
||||
"__cpp_attributes=200809",
|
||||
"__UINT_LEAST16_MAX__=0xffffU",
|
||||
"__ATOMIC_ACQUIRE=2",
|
||||
"__SFRACT_IBIT__=0",
|
||||
"__FLT_MIN__=1.17549435e-38F",
|
||||
"__GCC_IEC_559_COMPLEX=0",
|
||||
"__BUILTIN_AVR_SLEEP=1",
|
||||
"__BUILTIN_AVR_COUNTLSULLK=1",
|
||||
"__cpp_aggregate_nsdmi=201304",
|
||||
"__BUILTIN_AVR_COUNTLSULLR=1",
|
||||
"__UFRACT_MAX__=0XFFFFP-16UR",
|
||||
"__UINT_LEAST8_TYPE__=unsigned char",
|
||||
"__DQ_FBIT__=63",
|
||||
"__INTMAX_C(c)=c ## LL",
|
||||
"__ULFRACT_FBIT__=32",
|
||||
"__SACCUM_EPSILON__=0x1P-7HK",
|
||||
"__CHAR_BIT__=8",
|
||||
"__USQ_IBIT__=0",
|
||||
"__UINT8_MAX__=0xff",
|
||||
"__ACCUM_FBIT__=15",
|
||||
"__WINT_MAX__=0x7fff",
|
||||
"__FLT32_MIN_EXP__=(-125)",
|
||||
"__cpp_static_assert=200410",
|
||||
"__USFRACT_FBIT__=8",
|
||||
"__ORDER_LITTLE_ENDIAN__=1234",
|
||||
"__SIZE_MAX__=0xffffU",
|
||||
"__WCHAR_MAX__=0x7fff",
|
||||
"__LACCUM_IBIT__=32",
|
||||
"__DBL_DENORM_MIN__=double(1.40129846e-45L)",
|
||||
"__GCC_ATOMIC_CHAR_LOCK_FREE=1",
|
||||
"__GCC_IEC_559=0",
|
||||
"__FLT_EVAL_METHOD__=0",
|
||||
"__BUILTIN_AVR_LLKBITS=1",
|
||||
"__cpp_binary_literals=201304",
|
||||
"__LLACCUM_MAX__=0X7FFFFFFFFFFFFFFFP-47LLK",
|
||||
"__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
|
||||
"__BUILTIN_AVR_HKBITS=1",
|
||||
"__BUILTIN_AVR_BITSLLK=1",
|
||||
"__FRACT_FBIT__=15",
|
||||
"__BUILTIN_AVR_BITSLLR=1",
|
||||
"__cpp_variadic_templates=200704",
|
||||
"__UINT_FAST64_MAX__=0xffffffffffffffffULL",
|
||||
"__SIG_ATOMIC_TYPE__=char",
|
||||
"__BUILTIN_AVR_UHKBITS=1",
|
||||
"__UACCUM_FBIT__=16",
|
||||
"__DBL_MIN_10_EXP__=(-37)",
|
||||
"__FINITE_MATH_ONLY__=0",
|
||||
"__cpp_variable_templates=201304",
|
||||
"__LFRACT_IBIT__=0",
|
||||
"__GNUC_PATCHLEVEL__=0",
|
||||
"__FLT32_HAS_DENORM__=1",
|
||||
"__LFRACT_MAX__=0X7FFFFFFFP-31LR",
|
||||
"__UINT_FAST8_MAX__=0xff",
|
||||
"__has_include(STR)=__has_include__(STR)",
|
||||
"__DEC64_MAX_EXP__=385",
|
||||
"__INT8_C(c)=c",
|
||||
"__INT_LEAST8_WIDTH__=8",
|
||||
"__UINT_LEAST64_MAX__=0xffffffffffffffffULL",
|
||||
"__SA_FBIT__=15",
|
||||
"__SHRT_MAX__=0x7fff",
|
||||
"__LDBL_MAX__=3.40282347e+38L",
|
||||
"__FRACT_MAX__=0X7FFFP-15R",
|
||||
"__UFRACT_FBIT__=16",
|
||||
"__UFRACT_MIN__=0.0UR",
|
||||
"__UINT_LEAST8_MAX__=0xff",
|
||||
"__GCC_ATOMIC_BOOL_LOCK_FREE=1",
|
||||
"__UINTMAX_TYPE__=long long unsigned int",
|
||||
"__LLFRACT_EPSILON__=0x1P-63LLR",
|
||||
"__BUILTIN_AVR_DELAY_CYCLES=1",
|
||||
"__DEC32_EPSILON__=1E-6DF",
|
||||
"__FLT_EVAL_METHOD_TS_18661_3__=0",
|
||||
"__UINT32_MAX__=0xffffffffUL",
|
||||
"__GXX_EXPERIMENTAL_CXX0X__=1",
|
||||
"__ULFRACT_MAX__=0XFFFFFFFFP-32ULR",
|
||||
"__TA_IBIT__=16",
|
||||
"__LDBL_MAX_EXP__=128",
|
||||
"__WINT_MIN__=(-__WINT_MAX__ - 1)",
|
||||
"__INT_LEAST16_WIDTH__=16",
|
||||
"__ULLFRACT_MIN__=0.0ULLR",
|
||||
"__SCHAR_MAX__=0x7f",
|
||||
"__WCHAR_MIN__=(-__WCHAR_MAX__ - 1)",
|
||||
"__INT64_C(c)=c ## LL",
|
||||
"__DBL_DIG__=6",
|
||||
"__GCC_ATOMIC_POINTER_LOCK_FREE=1",
|
||||
"__AVR_HAVE_SPH__=1",
|
||||
"__LLACCUM_MIN__=(-0X1P15LLK-0X1P15LLK)",
|
||||
"__BUILTIN_AVR_KBITS=1",
|
||||
"__BUILTIN_AVR_ABSK=1",
|
||||
"__BUILTIN_AVR_ABSR=1",
|
||||
"__SIZEOF_INT__=2",
|
||||
"__SIZEOF_POINTER__=2",
|
||||
"__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
|
||||
"__USACCUM_IBIT__=8",
|
||||
"__USER_LABEL_PREFIX__",
|
||||
"__STDC_HOSTED__=1",
|
||||
"__LDBL_HAS_INFINITY__=1",
|
||||
"__LFRACT_MIN__=(-0.5LR-0.5LR)",
|
||||
"__HA_IBIT__=8",
|
||||
"__FLT32_DIG__=6",
|
||||
"__TQ_IBIT__=0",
|
||||
"__FLT_EPSILON__=1.19209290e-7F",
|
||||
"__GXX_WEAK__=1",
|
||||
"__SHRT_WIDTH__=16",
|
||||
"__USFRACT_IBIT__=0",
|
||||
"__LDBL_MIN__=1.17549435e-38L",
|
||||
"__FRACT_MIN__=(-0.5R-0.5R)",
|
||||
"__AVR_SFR_OFFSET__=0x20",
|
||||
"__DEC32_MAX__=9.999999E96DF",
|
||||
"__cpp_threadsafe_static_init=200806",
|
||||
"__DA_IBIT__=32",
|
||||
"__INT32_MAX__=0x7fffffffL",
|
||||
"__UQQ_FBIT__=8",
|
||||
"__INT_WIDTH__=16",
|
||||
"__SIZEOF_LONG__=4",
|
||||
"__UACCUM_MAX__=0XFFFFFFFFP-16UK",
|
||||
"__UINT16_C(c)=c ## U",
|
||||
"__PTRDIFF_WIDTH__=16",
|
||||
"__DECIMAL_DIG__=9",
|
||||
"__LFRACT_EPSILON__=0x1P-31LR",
|
||||
"__AVR_2_BYTE_PC__=1",
|
||||
"__ULFRACT_MIN__=0.0ULR",
|
||||
"__INTMAX_WIDTH__=64",
|
||||
"__has_include_next(STR)=__has_include_next__(STR)",
|
||||
"__BUILTIN_AVR_ULLRBITS=1",
|
||||
"__LDBL_HAS_QUIET_NAN__=1",
|
||||
"__ULACCUM_IBIT__=32",
|
||||
"__UACCUM_EPSILON__=0x1P-16UK",
|
||||
"__BUILTIN_AVR_SEI=1",
|
||||
"__GNUC__=7",
|
||||
"__ULLACCUM_MAX__=0XFFFFFFFFFFFFFFFFP-48ULLK",
|
||||
"__cpp_delegating_constructors=200604",
|
||||
"__HQ_IBIT__=0",
|
||||
"__BUILTIN_AVR_SWAP=1",
|
||||
"__FLT_HAS_DENORM__=1",
|
||||
"__SIZEOF_LONG_DOUBLE__=4",
|
||||
"__BIGGEST_ALIGNMENT__=1",
|
||||
"__STDC_UTF_16__=1",
|
||||
"__UINT24_MAX__=16777215UL",
|
||||
"__BUILTIN_AVR_NOP=1",
|
||||
"__GNUC_STDC_INLINE__=1",
|
||||
"__DQ_IBIT__=0",
|
||||
"__FLT32_HAS_INFINITY__=1",
|
||||
"__DBL_MAX__=double(3.40282347e+38L)",
|
||||
"__ULFRACT_IBIT__=0",
|
||||
"__cpp_raw_strings=200710",
|
||||
"__INT_FAST32_MAX__=0x7fffffffL",
|
||||
"__DBL_HAS_INFINITY__=1",
|
||||
"__INT64_MAX__=0x7fffffffffffffffLL",
|
||||
"__ACCUM_IBIT__=16",
|
||||
"__DEC32_MIN_EXP__=(-94)",
|
||||
"__BUILTIN_AVR_UKBITS=1",
|
||||
"__INTPTR_WIDTH__=16",
|
||||
"__BUILTIN_AVR_FMULSU=1",
|
||||
"__LACCUM_MAX__=0X7FFFFFFFFFFFFFFFP-31LK",
|
||||
"__INT_FAST16_TYPE__=int",
|
||||
"__LDBL_HAS_DENORM__=1",
|
||||
"__BUILTIN_AVR_BITSK=1",
|
||||
"__BUILTIN_AVR_BITSR=1",
|
||||
"__cplusplus=201402L",
|
||||
"__cpp_ref_qualifiers=200710",
|
||||
"__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
|
||||
"__INT_LEAST32_MAX__=0x7fffffffL",
|
||||
"__USING_SJLJ_EXCEPTIONS__=1",
|
||||
"__DEC32_MIN__=1E-95DF",
|
||||
"__ACCUM_MAX__=0X7FFFFFFFP-15K",
|
||||
"__DEPRECATED=1",
|
||||
"__cpp_rvalue_references=200610",
|
||||
"__DBL_MAX_EXP__=128",
|
||||
"__USACCUM_EPSILON__=0x1P-8UHK",
|
||||
"__WCHAR_WIDTH__=16",
|
||||
"__FLT32_MAX__=3.40282347e+38F32",
|
||||
"__DEC128_EPSILON__=1E-33DL",
|
||||
"__SFRACT_MAX__=0X7FP-7HR",
|
||||
"__FRACT_IBIT__=0",
|
||||
"__PTRDIFF_MAX__=0x7fff",
|
||||
"__UACCUM_MIN__=0.0UK",
|
||||
"__UACCUM_IBIT__=16",
|
||||
"__BUILTIN_AVR_NOPS=1",
|
||||
"__BUILTIN_AVR_WDR=1",
|
||||
"__FLT32_HAS_QUIET_NAN__=1",
|
||||
"__GNUG__=7",
|
||||
"__LONG_LONG_MAX__=0x7fffffffffffffffLL",
|
||||
"__SIZEOF_SIZE_T__=2",
|
||||
"__ULACCUM_MAX__=0XFFFFFFFFFFFFFFFFP-32ULK",
|
||||
"__cpp_rvalue_reference=200610",
|
||||
"__cpp_nsdmi=200809",
|
||||
"__SIZEOF_WINT_T__=2",
|
||||
"__LONG_LONG_WIDTH__=64",
|
||||
"__cpp_initializer_lists=200806",
|
||||
"__FLT32_MAX_EXP__=128",
|
||||
"__SA_IBIT__=16",
|
||||
"__ULLACCUM_MIN__=0.0ULLK",
|
||||
"__BUILTIN_AVR_ROUNDUHK=1",
|
||||
"__BUILTIN_AVR_ROUNDUHR=1",
|
||||
"__cpp_hex_float=201603",
|
||||
"__GXX_ABI_VERSION=1011",
|
||||
"__INT24_MAX__=8388607L",
|
||||
"__UTA_FBIT__=48",
|
||||
"__FLT_MIN_EXP__=(-125)",
|
||||
"__USFRACT_MAX__=0XFFP-8UHR",
|
||||
"__UFRACT_IBIT__=0",
|
||||
"__BUILTIN_AVR_ROUNDFX=1",
|
||||
"__BUILTIN_AVR_ROUNDULK=1",
|
||||
"__BUILTIN_AVR_ROUNDULR=1",
|
||||
"__cpp_lambdas=200907",
|
||||
"__BUILTIN_AVR_COUNTLSLLK=1",
|
||||
"__BUILTIN_AVR_COUNTLSLLR=1",
|
||||
"__BUILTIN_AVR_ROUNDHK=1",
|
||||
"__INT_FAST64_TYPE__=long long int",
|
||||
"__BUILTIN_AVR_ROUNDHR=1",
|
||||
"__DBL_MIN__=double(1.17549435e-38L)",
|
||||
"__BUILTIN_AVR_COUNTLSK=1",
|
||||
"__BUILTIN_AVR_ROUNDLK=1",
|
||||
"__BUILTIN_AVR_COUNTLSR=1",
|
||||
"__BUILTIN_AVR_ROUNDLR=1",
|
||||
"__LACCUM_MIN__=(-0X1P31LK-0X1P31LK)",
|
||||
"__ULLACCUM_FBIT__=48",
|
||||
"__BUILTIN_AVR_LKBITS=1",
|
||||
"__ULLFRACT_EPSILON__=0x1P-64ULLR",
|
||||
"__DEC128_MIN__=1E-6143DL",
|
||||
"__REGISTER_PREFIX__",
|
||||
"__UINT16_MAX__=0xffffU",
|
||||
"__DBL_HAS_DENORM__=1",
|
||||
"__BUILTIN_AVR_ULKBITS=1",
|
||||
"__ACCUM_MIN__=(-0X1P15K-0X1P15K)",
|
||||
"__AVR_ARCH__=2",
|
||||
"__SQ_IBIT__=0",
|
||||
"__FLT32_MIN__=1.17549435e-38F32",
|
||||
"__UINT8_TYPE__=unsigned char",
|
||||
"__BUILTIN_AVR_ROUNDUK=1",
|
||||
"__BUILTIN_AVR_ROUNDUR=1",
|
||||
"__UHA_FBIT__=8",
|
||||
"__NO_INLINE__=1",
|
||||
"__SFRACT_MIN__=(-0.5HR-0.5HR)",
|
||||
"__UTQ_FBIT__=128",
|
||||
"__FLT_MANT_DIG__=24",
|
||||
"__LDBL_DECIMAL_DIG__=9",
|
||||
"__VERSION__=\"7.3.0\"",
|
||||
"__UINT64_C(c)=c ## ULL",
|
||||
"__ULLFRACT_FBIT__=64",
|
||||
"__cpp_unicode_characters=200704",
|
||||
"__FRACT_EPSILON__=0x1P-15R",
|
||||
"__ULACCUM_MIN__=0.0ULK",
|
||||
"__UDA_FBIT__=32",
|
||||
"__cpp_decltype_auto=201304",
|
||||
"__LLACCUM_EPSILON__=0x1P-47LLK",
|
||||
"__GCC_ATOMIC_INT_LOCK_FREE=1",
|
||||
"__FLT32_MANT_DIG__=24",
|
||||
"__BUILTIN_AVR_BITSUHK=1",
|
||||
"__BUILTIN_AVR_BITSUHR=1",
|
||||
"__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
|
||||
"__USFRACT_MIN__=0.0UHR",
|
||||
"__BUILTIN_AVR_BITSULK=1",
|
||||
"__ULLACCUM_IBIT__=16",
|
||||
"__BUILTIN_AVR_BITSULR=1",
|
||||
"__UQQ_IBIT__=0",
|
||||
"__BUILTIN_AVR_LLRBITS=1",
|
||||
"__SCHAR_WIDTH__=8",
|
||||
"__BUILTIN_AVR_BITSULLK=1",
|
||||
"__BUILTIN_AVR_BITSULLR=1",
|
||||
"__INT32_C(c)=c ## L",
|
||||
"__DEC64_EPSILON__=1E-15DD",
|
||||
"__ORDER_PDP_ENDIAN__=3412",
|
||||
"__DEC128_MIN_EXP__=(-6142)",
|
||||
"__UHQ_FBIT__=16",
|
||||
"__LLACCUM_FBIT__=47",
|
||||
"__FLT32_MAX_10_EXP__=38",
|
||||
"__BUILTIN_AVR_ROUNDULLK=1",
|
||||
"__BUILTIN_AVR_ROUNDULLR=1",
|
||||
"__INT_FAST32_TYPE__=long int",
|
||||
"__BUILTIN_AVR_HRBITS=1",
|
||||
"__UINT_LEAST16_TYPE__=unsigned int",
|
||||
"__BUILTIN_AVR_UHRBITS=1",
|
||||
"__INT16_MAX__=0x7fff",
|
||||
"__SIZE_TYPE__=unsigned int",
|
||||
"__UINT64_MAX__=0xffffffffffffffffULL",
|
||||
"__UDQ_FBIT__=64",
|
||||
"__INT8_TYPE__=signed char",
|
||||
"__cpp_digit_separators=201309",
|
||||
"__ELF__=1",
|
||||
"__ULFRACT_EPSILON__=0x1P-32ULR",
|
||||
"__LLFRACT_FBIT__=63",
|
||||
"__FLT_RADIX__=2",
|
||||
"__INT_LEAST16_TYPE__=int",
|
||||
"__BUILTIN_AVR_ABSFX=1",
|
||||
"__LDBL_EPSILON__=1.19209290e-7L",
|
||||
"__UINTMAX_C(c)=c ## ULL",
|
||||
"__INT24_MIN__=(-__INT24_MAX__-1)",
|
||||
"__SACCUM_MAX__=0X7FFFP-7HK",
|
||||
"__BUILTIN_AVR_ABSHR=1",
|
||||
"__SIG_ATOMIC_MAX__=0x7f",
|
||||
"__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
|
||||
"__cpp_sized_deallocation=201309",
|
||||
"__SIZEOF_PTRDIFF_T__=2",
|
||||
"__AVR=1",
|
||||
"__BUILTIN_AVR_ABSLK=1",
|
||||
"__BUILTIN_AVR_ABSLR=1",
|
||||
"__LACCUM_EPSILON__=0x1P-31LK",
|
||||
"__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
|
||||
"__INT_FAST16_MAX__=0x7fff",
|
||||
"__UINT_FAST32_MAX__=0xffffffffUL",
|
||||
"__UINT_LEAST64_TYPE__=long long unsigned int",
|
||||
"__USACCUM_MAX__=0XFFFFP-8UHK",
|
||||
"__SFRACT_EPSILON__=0x1P-7HR",
|
||||
"__FLT_HAS_QUIET_NAN__=1",
|
||||
"__FLT_MAX_10_EXP__=38",
|
||||
"__LONG_MAX__=0x7fffffffL",
|
||||
"__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
|
||||
"__FLT_HAS_INFINITY__=1",
|
||||
"__cpp_unicode_literals=200710",
|
||||
"__USA_FBIT__=16",
|
||||
"__UINT_FAST16_TYPE__=unsigned int",
|
||||
"__DEC64_MAX__=9.999999999999999E384DD",
|
||||
"__INT_FAST32_WIDTH__=32",
|
||||
"__BUILTIN_AVR_RBITS=1",
|
||||
"__CHAR16_TYPE__=unsigned int",
|
||||
"__PRAGMA_REDEFINE_EXTNAME=1",
|
||||
"__SIZE_WIDTH__=16",
|
||||
"__INT_LEAST16_MAX__=0x7fff",
|
||||
"__DEC64_MANT_DIG__=16",
|
||||
"__UINT_LEAST32_MAX__=0xffffffffUL",
|
||||
"__SACCUM_FBIT__=7",
|
||||
"__FLT32_DENORM_MIN__=1.40129846e-45F32",
|
||||
"__GCC_ATOMIC_LONG_LOCK_FREE=1",
|
||||
"__SIG_ATOMIC_WIDTH__=8",
|
||||
"__INT_LEAST64_TYPE__=long long int",
|
||||
"__INT16_TYPE__=int",
|
||||
"__INT_LEAST8_TYPE__=signed char",
|
||||
"__SQ_FBIT__=31",
|
||||
"__DEC32_MAX_EXP__=97",
|
||||
"__INT_FAST8_MAX__=0x7f",
|
||||
"__INTPTR_MAX__=0x7fff",
|
||||
"__QQ_FBIT__=7",
|
||||
"__cpp_range_based_for=200907",
|
||||
"__UTA_IBIT__=16",
|
||||
"__AVR_ERRATA_SKIP__=1",
|
||||
"__FLT32_MIN_10_EXP__=(-37)",
|
||||
"__LDBL_MANT_DIG__=24",
|
||||
"__SFRACT_FBIT__=7",
|
||||
"__SACCUM_MIN__=(-0X1P7HK-0X1P7HK)",
|
||||
"__DBL_HAS_QUIET_NAN__=1",
|
||||
"__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
|
||||
"AVR=1",
|
||||
"__BUILTIN_AVR_FMULS=1",
|
||||
"__cpp_return_type_deduction=201304",
|
||||
"__INTPTR_TYPE__=int",
|
||||
"__UINT16_TYPE__=unsigned int",
|
||||
"__WCHAR_TYPE__=int",
|
||||
"__SIZEOF_FLOAT__=4",
|
||||
"__AVR__=1",
|
||||
"__BUILTIN_AVR_INSERT_BITS=1",
|
||||
"__USQ_FBIT__=32",
|
||||
"__UINTPTR_MAX__=0xffffU",
|
||||
"__INT_FAST64_WIDTH__=64",
|
||||
"__DEC64_MIN_EXP__=(-382)",
|
||||
"__cpp_decltype=200707",
|
||||
"__FLT32_DECIMAL_DIG__=9",
|
||||
"__INT_FAST64_MAX__=0x7fffffffffffffffLL",
|
||||
"__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
|
||||
"__FLT_DIG__=6",
|
||||
"__UINT_FAST64_TYPE__=long long unsigned int",
|
||||
"__BUILTIN_AVR_BITSHK=1",
|
||||
"__BUILTIN_AVR_BITSHR=1",
|
||||
"__INT_MAX__=0x7fff",
|
||||
"__LACCUM_FBIT__=31",
|
||||
"__USACCUM_MIN__=0.0UHK",
|
||||
"__UHA_IBIT__=8",
|
||||
"__INT64_TYPE__=long long int",
|
||||
"__BUILTIN_AVR_BITSLK=1",
|
||||
"__BUILTIN_AVR_BITSLR=1",
|
||||
"__FLT_MAX_EXP__=128",
|
||||
"__UTQ_IBIT__=0",
|
||||
"__DBL_MANT_DIG__=24",
|
||||
"__cpp_inheriting_constructors=201511",
|
||||
"__BUILTIN_AVR_ULLKBITS=1",
|
||||
"__INT_LEAST64_MAX__=0x7fffffffffffffffLL",
|
||||
"__DEC64_MIN__=1E-383DD",
|
||||
"__WINT_TYPE__=int",
|
||||
"__UINT_LEAST32_TYPE__=long unsigned int",
|
||||
"__SIZEOF_SHORT__=2",
|
||||
"__ULLFRACT_IBIT__=0",
|
||||
"__LDBL_MIN_EXP__=(-125)",
|
||||
"__UDA_IBIT__=32",
|
||||
"__WINT_WIDTH__=16",
|
||||
"__INT_LEAST8_MAX__=0x7f",
|
||||
"__LFRACT_FBIT__=31",
|
||||
"__LDBL_MAX_10_EXP__=38",
|
||||
"__ATOMIC_RELAXED=0",
|
||||
"__DBL_EPSILON__=double(1.19209290e-7L)",
|
||||
"__BUILTIN_AVR_BITSUK=1",
|
||||
"__BUILTIN_AVR_BITSUR=1",
|
||||
"__UINT8_C(c)=c",
|
||||
"__INT_LEAST32_TYPE__=long int",
|
||||
"__BUILTIN_AVR_URBITS=1",
|
||||
"__SIZEOF_WCHAR_T__=2",
|
||||
"__LLFRACT_MAX__=0X7FFFFFFFFFFFFFFFP-63LLR",
|
||||
"__TQ_FBIT__=127",
|
||||
"__INT_FAST8_TYPE__=signed char",
|
||||
"__ULLACCUM_EPSILON__=0x1P-48ULLK",
|
||||
"__BUILTIN_AVR_ROUNDK=1",
|
||||
"__BUILTIN_AVR_ROUNDR=1",
|
||||
"__UHQ_IBIT__=0",
|
||||
"__LLACCUM_IBIT__=16",
|
||||
"__FLT32_EPSILON__=1.19209290e-7F32",
|
||||
"__DBL_DECIMAL_DIG__=9",
|
||||
"__STDC_UTF_32__=1",
|
||||
"__INT_FAST8_WIDTH__=8",
|
||||
"__DEC_EVAL_METHOD__=2",
|
||||
"__TA_FBIT__=47",
|
||||
"__UDQ_IBIT__=0",
|
||||
"__ORDER_BIG_ENDIAN__=4321",
|
||||
"__cpp_runtime_arrays=198712",
|
||||
"__WITH_AVRLIBC__=1",
|
||||
"__UINT64_TYPE__=long long unsigned int",
|
||||
"__ACCUM_EPSILON__=0x1P-15K",
|
||||
"__UINT32_C(c)=c ## UL",
|
||||
"__BUILTIN_AVR_COUNTLSUHK=1",
|
||||
"__INTMAX_MAX__=0x7fffffffffffffffLL",
|
||||
"__cpp_alias_templates=200704",
|
||||
"__BUILTIN_AVR_COUNTLSUHR=1",
|
||||
"__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
|
||||
"__FLT_DENORM_MIN__=1.40129846e-45F",
|
||||
"__LLFRACT_IBIT__=0",
|
||||
"__INT8_MAX__=0x7f",
|
||||
"__LONG_WIDTH__=32",
|
||||
"__UINT_FAST32_TYPE__=long unsigned int",
|
||||
"__CHAR32_TYPE__=long unsigned int",
|
||||
"__BUILTIN_AVR_COUNTLSULK=1",
|
||||
"__BUILTIN_AVR_COUNTLSULR=1",
|
||||
"__FLT_MAX__=3.40282347e+38F",
|
||||
"__cpp_constexpr=201304",
|
||||
"__USACCUM_FBIT__=8",
|
||||
"__BUILTIN_AVR_COUNTLSFX=1",
|
||||
"__INT32_TYPE__=long int",
|
||||
"__SIZEOF_DOUBLE__=4",
|
||||
"__FLT_MIN_10_EXP__=(-37)",
|
||||
"__UFRACT_EPSILON__=0x1P-16UR",
|
||||
"__INT_LEAST32_WIDTH__=32",
|
||||
"__BUILTIN_AVR_COUNTLSHK=1",
|
||||
"__BUILTIN_AVR_COUNTLSHR=1",
|
||||
"__INTMAX_TYPE__=long long int",
|
||||
"__BUILTIN_AVR_ABSLLK=1",
|
||||
"__BUILTIN_AVR_ABSLLR=1",
|
||||
"__DEC128_MAX_EXP__=6145",
|
||||
"__AVR_HAVE_16BIT_SP__=1",
|
||||
"__ATOMIC_CONSUME=1",
|
||||
"__GNUC_MINOR__=3",
|
||||
"__INT_FAST16_WIDTH__=16",
|
||||
"__UINTMAX_MAX__=0xffffffffffffffffULL",
|
||||
"__DEC32_MANT_DIG__=7",
|
||||
"__HA_FBIT__=7",
|
||||
"__BUILTIN_AVR_COUNTLSLK=1",
|
||||
"__BUILTIN_AVR_COUNTLSLR=1",
|
||||
"__BUILTIN_AVR_CLI=1",
|
||||
"__DBL_MAX_10_EXP__=38",
|
||||
"__LDBL_DENORM_MIN__=1.40129846e-45L",
|
||||
"__INT16_C(c)=c",
|
||||
"__cpp_generic_lambdas=201304",
|
||||
"__STDC__=1",
|
||||
"__PTRDIFF_TYPE__=int",
|
||||
"__LLFRACT_MIN__=(-0.5LLR-0.5LLR)",
|
||||
"__BUILTIN_AVR_LRBITS=1",
|
||||
"__ATOMIC_SEQ_CST=5",
|
||||
"__DA_FBIT__=31",
|
||||
"__UINT32_TYPE__=long unsigned int",
|
||||
"__BUILTIN_AVR_ROUNDLLK=1",
|
||||
"__UINTPTR_TYPE__=unsigned int",
|
||||
"__BUILTIN_AVR_ROUNDLLR=1",
|
||||
"__USA_IBIT__=16",
|
||||
"__BUILTIN_AVR_ULRBITS=1",
|
||||
"__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
|
||||
"__DEC128_MANT_DIG__=34",
|
||||
"__LDBL_MIN_10_EXP__=(-37)",
|
||||
"__BUILTIN_AVR_COUNTLSUK=1",
|
||||
"__BUILTIN_AVR_COUNTLSUR=1",
|
||||
"__SIZEOF_LONG_LONG__=8",
|
||||
"__ULACCUM_EPSILON__=0x1P-32ULK",
|
||||
"__cpp_user_defined_literals=200809",
|
||||
"__SACCUM_IBIT__=8",
|
||||
"__GCC_ATOMIC_LLONG_LOCK_FREE=1",
|
||||
"__LDBL_DIG__=6",
|
||||
"__FLT_DECIMAL_DIG__=9",
|
||||
"__UINT_FAST16_MAX__=0xffffU",
|
||||
"__GCC_ATOMIC_SHORT_LOCK_FREE=1",
|
||||
"__BUILTIN_AVR_ABSHK=1",
|
||||
"__BUILTIN_AVR_FLASH_SEGMENT=1",
|
||||
"__INT_LEAST64_WIDTH__=64",
|
||||
"__ULLFRACT_MAX__=0XFFFFFFFFFFFFFFFFP-64ULLR",
|
||||
"__UINT_FAST8_TYPE__=unsigned char",
|
||||
"__USFRACT_EPSILON__=0x1P-8UHR",
|
||||
"__ULACCUM_FBIT__=32",
|
||||
"__QQ_IBIT__=0",
|
||||
"__cpp_init_captures=201304",
|
||||
"__ATOMIC_ACQ_REL=4",
|
||||
"__ATOMIC_RELEASE=3",
|
||||
"__BUILTIN_AVR_FMUL=1",
|
||||
"USBCON"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
52
Software/Testsender/Testsender.ino
Normal file
52
Software/Testsender/Testsender.ino
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
|
||||
struct can_frame frame;
|
||||
|
||||
MCP2515 mcp2515(10);
|
||||
/*
|
||||
Software matching Hardware of meycan v8.1
|
||||
*/
|
||||
void setup() {
|
||||
SPI.begin();
|
||||
Serial.begin(9600);
|
||||
|
||||
|
||||
|
||||
pinMode(PD3, OUTPUT);
|
||||
digitalWrite(PD3, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(PD3, LOW);
|
||||
delay(2000);
|
||||
|
||||
mcp2515.reset();
|
||||
mcp2515.setBitrate(CAN_1000KBPS, MCP_8MHZ);
|
||||
mcp2515.setNormalMode();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
if (mcp2515.readMessage(&frame) == MCP2515::ERROR_OK) {
|
||||
// frame contains received message
|
||||
|
||||
Serial.print(" Id: ");
|
||||
Serial.print(frame.can_id, HEX);
|
||||
Serial.print(" [");
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Serial.print(frame.data[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("]");
|
||||
|
||||
digitalWrite(PD3, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(PD3, LOW);
|
||||
delay(50);
|
||||
|
||||
mcp2515.sendMessage(&frame);
|
||||
mcp2515.sendMessage(&frame);
|
||||
mcp2515.sendMessage(&frame);
|
||||
mcp2515.sendMessage(&frame);
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,45 @@
|
||||
#include <iterator>
|
||||
#include "esp32-hal-gpio.h"
|
||||
#include "MeyCan.h";
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
|
||||
#include "driver/twai.h"
|
||||
|
||||
PinState *MeyPin = NULL;
|
||||
CanInterface *CanBusses = NULL;
|
||||
uint16_t myDeviceId;
|
||||
uint16_t myDeviceId = 0;
|
||||
byte _deviceTypeId = 0;
|
||||
byte _majorHardwareVersion = 0;
|
||||
byte _minorHardwareVersion = 0;
|
||||
|
||||
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->ForEach(handle);
|
||||
}
|
||||
|
||||
void SetupMeyCan()
|
||||
{
|
||||
CalculateMyDeviceId();
|
||||
|
||||
if (MeyPin != NULL);
|
||||
MeyPin->ForEach(SetupMeyPin);
|
||||
|
||||
if (CanBusses != NULL)
|
||||
{
|
||||
CanBusses->ForEach(InitCanInterface, NULL);
|
||||
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 SetCanInterface(byte index, byte pinId)
|
||||
{
|
||||
MCP2515* newCanInterface = new MCP2515(pinId);
|
||||
CanInterface* canInterface = new CanInterface();
|
||||
|
||||
if (CanBusses == NULL)
|
||||
CanBusses = canInterface;
|
||||
else
|
||||
CanBusses->AddCanInterface(canInterface);
|
||||
|
||||
void SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId) {
|
||||
_majorHardwareVersion = majorHardwareVersion;
|
||||
_minorHardwareVersion = minorHardwareVersion;
|
||||
_deviceTypeId = deviceTypeId;
|
||||
|
||||
if (MeyPin != NULL)
|
||||
MeyPin->ForEach(SetupMeyPin);
|
||||
}
|
||||
|
||||
void SetMeyPin(byte index, byte meyPinId, byte pinId)
|
||||
{
|
||||
PinState* newState = new PinState();
|
||||
newState->Init(pinId, (byte) meyPinId);
|
||||
|
||||
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;
|
||||
@@ -64,66 +48,69 @@ void SetMeyPin(byte index, byte meyPinId, byte pinId)
|
||||
}
|
||||
|
||||
|
||||
bool CheckPinStatus(PinState * state)
|
||||
{
|
||||
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 false;
|
||||
return;
|
||||
|
||||
bool newValue = ReadPin(state);
|
||||
|
||||
|
||||
if (newValue != state->pin_state)
|
||||
{
|
||||
if (newValue != state->pin_state) {
|
||||
delay(10);
|
||||
newValue = ReadPin(state);
|
||||
if (newValue != state->pin_state)
|
||||
{
|
||||
if (newValue != state->pin_state) {
|
||||
state->pin_state = newValue;
|
||||
SendSwitchedTriggeredCanPackage(state->meyPinId, state->pin_state);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
void CheckMeyPinsTriggered()
|
||||
{
|
||||
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);
|
||||
|
||||
uint16_t GetDeviceId(uint32_t canFrameId) {
|
||||
return canFrameId & 0xFFFF;
|
||||
}
|
||||
|
||||
|
||||
void HandleFrame(can_frame *frame, MCP2515 *source)
|
||||
{
|
||||
CanBusses->ForEach(DoSendCanPkg, frame, source);
|
||||
HandleTriggerMeypinCanPackage(frame);
|
||||
uint16_t GetPackageType(uint32_t canFrameId) {
|
||||
return (canFrameId / 0x10000) & 0xFFF;
|
||||
}
|
||||
|
||||
void HandleTriggerMeypinCanPackage(can_frame *frame)
|
||||
{
|
||||
if (GetPackageType(frame->can_id) == TRIGGER_SWITCH_CAN_ID)
|
||||
{
|
||||
uint16_t adressedDeviceId = ((uint16_t )frame->data[0] << 8) | frame->data[1] ;
|
||||
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;
|
||||
|
||||
|
||||
@@ -132,10 +119,8 @@ void HandleTriggerMeypinCanPackage(can_frame *frame)
|
||||
|
||||
PinState *adressedPin = MeyPin->Find(meyPinId);
|
||||
|
||||
if (adressedPin != NULL)
|
||||
{
|
||||
if (adressedPin->is_input == true)
|
||||
{
|
||||
if (adressedPin != NULL) {
|
||||
if (adressedPin->is_input == true) {
|
||||
pinMode(adressedPin->pin_id, OUTPUT);
|
||||
adressedPin->is_input = false;
|
||||
}
|
||||
@@ -147,104 +132,17 @@ void HandleTriggerMeypinCanPackage(can_frame *frame)
|
||||
digitalWrite(adressedPin->pin_id, state);
|
||||
SendSwitchedTriggeredCanPackage(adressedPin->meyPinId, state);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte CircularShift(byte b)
|
||||
{
|
||||
return (b << 1) | (b >> 7 & 1);
|
||||
|
||||
void HandleFrame(twai_message_t *frame) {
|
||||
HandleTriggerMeypinCanPackage(frame);
|
||||
}
|
||||
|
||||
uint16_t GetDeviceId(uint32_t canFrameId)
|
||||
{
|
||||
return canFrameId & 0xFFFF;
|
||||
}
|
||||
|
||||
uint16_t GetPackageType(uint32_t canFrameId)
|
||||
{
|
||||
return (canFrameId / 0x10000) & 0xFFF;
|
||||
}
|
||||
|
||||
byte GetDeviceIdLow() {
|
||||
return (SIGROW.SERNUM0 ^
|
||||
CircularShift(SIGROW.SERNUM2) << 1 ^
|
||||
CircularShift( CircularShift(SIGROW.SERNUM4)) ^
|
||||
CircularShift( CircularShift( CircularShift(SIGROW.SERNUM6))) ^
|
||||
CircularShift( CircularShift( CircularShift( CircularShift(SIGROW.SERNUM8)))));
|
||||
}
|
||||
|
||||
byte GetDeviceIdHigh() {
|
||||
return (SIGROW.SERNUM1 ^
|
||||
CircularShift(SIGROW.SERNUM3) << 1 ^
|
||||
CircularShift( CircularShift(SIGROW.SERNUM5)) ^
|
||||
CircularShift( CircularShift( CircularShift(SIGROW.SERNUM7))) ^
|
||||
CircularShift( CircularShift( CircularShift( CircularShift(SIGROW.SERNUM9)))));
|
||||
}
|
||||
|
||||
uint32_t CreateCanId(uint16_t commandId)
|
||||
{
|
||||
return ((((uint32_t)commandId) & 0xFFF) * 0x10000) | myDeviceId | CAN_EFF_FLAG;
|
||||
}
|
||||
|
||||
void SendVersionPackage(MCP2515 *interface)
|
||||
{
|
||||
can_frame toSend;
|
||||
toSend.can_id = CreateCanId(HELP_PACKAGE_CAN_ID);
|
||||
toSend.can_dlc = 6;
|
||||
|
||||
toSend.data[0] = SOFTWARE_VERSION_HIGH;
|
||||
toSend.data[1] = SOFTWARE_VERSION_LOW;
|
||||
toSend.data[2] = HARDWARE_VERSION_HIGH;
|
||||
toSend.data[3] = HARDWARE_VERSION_LOW;
|
||||
toSend.data[4] = (myDeviceId >> 8) & 0xFF;
|
||||
toSend.data[5] = myDeviceId & 0xFF;
|
||||
|
||||
DoSendCanPkg(interface, &toSend);
|
||||
}
|
||||
|
||||
void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state)
|
||||
{
|
||||
can_frame toSend;
|
||||
|
||||
toSend.can_id = CreateCanId(TRIGGER_SWITCH_CAN_ID);
|
||||
toSend.can_dlc = 4;
|
||||
toSend.data[0] = (targetCanId & 0xFF00) >> 8;
|
||||
toSend.data[1] = targetCanId & 0xFF;
|
||||
toSend.data[2] = pinId;
|
||||
toSend.data[3] = state;
|
||||
|
||||
HandleFrame(&toSend, NULL);
|
||||
}
|
||||
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state)
|
||||
{
|
||||
can_frame toSend;
|
||||
toSend.can_id = CreateCanId(SWITCH_TRIGGERED_CAN_ID);
|
||||
toSend.can_dlc = 2;
|
||||
toSend.data[0] = pinId;
|
||||
toSend.data[1] = state;
|
||||
|
||||
DoSendCanPkg(&toSend);
|
||||
}
|
||||
|
||||
void DoSendCanPkg(can_frame *frame)
|
||||
{
|
||||
if (CanBusses != NULL)
|
||||
CanBusses->ForEach(DoSendCanPkg, frame);
|
||||
}
|
||||
|
||||
void DoSendCanPkg(MCP2515 *interface, can_frame *frame)
|
||||
{
|
||||
byte cnt = 0;
|
||||
while (interface->sendMessage(frame))
|
||||
{
|
||||
if (++cnt > 10) return;
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateMyDeviceId()
|
||||
{
|
||||
myDeviceId = (GetDeviceIdHigh() << 8) | GetDeviceIdLow();
|
||||
|
||||
|
||||
void DoSendCanPkg(twai_message_t *frame) {
|
||||
esp_err_t ret = twai_transmit(frame, pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
@@ -1,128 +1,80 @@
|
||||
#ifndef MEYCAN_H
|
||||
#define MEYCAN_H
|
||||
|
||||
#include <SPI.h>
|
||||
#include <mcp2515.h>
|
||||
|
||||
typedef struct CanInterface
|
||||
{
|
||||
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
|
||||
{
|
||||
int pin_id;
|
||||
bool pin_state;
|
||||
bool is_input;
|
||||
byte meyPinId;
|
||||
PinState *next = NULL;
|
||||
|
||||
PinState() {}
|
||||
void Init(int pin_id, byte meyPinId)
|
||||
{
|
||||
this->pin_id = pin_id;
|
||||
this->pin_state = true;
|
||||
this->is_input = true;
|
||||
this->meyPinId = meyPinId;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const byte SOFTWARE_VERSION_HIGH = 5;
|
||||
const byte SOFTWARE_VERSION_LOW = 0;
|
||||
const byte HARDWARE_VERSION_HIGH = 7;
|
||||
const byte HARDWARE_VERSION_LOW = 0;
|
||||
|
||||
const uint16_t HELP_PACKAGE_CAN_ID = 0x0FFFUL;
|
||||
const uint16_t SWITCH_TRIGGERED_CAN_ID = 0x0050;
|
||||
const uint16_t TRIGGER_SWITCH_CAN_ID = 0x0055;
|
||||
|
||||
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, MCP2515 *source);
|
||||
void HandleTriggerMeypinCanPackage(can_frame *frame);
|
||||
byte CircularShift(byte b);
|
||||
uint16_t GetDeviceId(uint32_t canFrameId);
|
||||
uint16_t GetPackageType(uint32_t canFrameId);
|
||||
byte GetDeviceIdLow();
|
||||
|
||||
byte GetDeviceIdHigh();
|
||||
|
||||
uint32_t CreateCanId(uint16_t commandId);
|
||||
void SendVersionPackage(MCP2515 *interface);
|
||||
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state);
|
||||
void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state);
|
||||
|
||||
void DoSendCanPkg(can_frame *frame);
|
||||
void DoSendCanPkg(MCP2515 *interface, can_frame *frame);
|
||||
|
||||
void CalculateMyDeviceId();
|
||||
|
||||
#endif
|
||||
#ifndef MEYCAN_H
|
||||
#define MEYCAN_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#include "driver/twai.h"
|
||||
|
||||
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)
|
||||
{
|
||||
this->pin_id = pin_id;
|
||||
this->pin_state = true;
|
||||
this->is_input = true;
|
||||
this->meyPinId = meyPinId;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const byte SOFTWARE_VERSION_HIGH = 6;
|
||||
const byte SOFTWARE_VERSION_LOW = 0;
|
||||
const byte HARDWARE_VERSION_HIGH = 8;
|
||||
const byte HARDWARE_VERSION_LOW = 1;
|
||||
|
||||
const uint16_t HELP_PACKAGE_CAN_ID = 0x0FFFUL;
|
||||
const uint16_t SWITCH_TRIGGERED_CAN_ID = 0x0050;
|
||||
const uint16_t TRIGGER_SWITCH_CAN_ID = 0x0055;
|
||||
|
||||
|
||||
|
||||
void SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId);
|
||||
uint32_t CreateCanId(uint16_t commandId);
|
||||
void SetDevicedId(byte high, byte low);
|
||||
void SetMeyPin(byte meyPinId, byte pinId);
|
||||
uint16_t GetDeviceId(uint32_t canFrameId);
|
||||
uint16_t GetPackageType(uint32_t canFrameId);
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state);
|
||||
|
||||
void HandleFrame(twai_message_t *frame);
|
||||
void CheckPinStatus(PinState *state);
|
||||
void CheckMeyPinsTriggered(); /* checks weather a meypin triggered and sends a can pkg is neccessary */
|
||||
|
||||
void DoSendCanPkg(twai_message_t *frame) ;
|
||||
#endif
|
||||
|
||||
@@ -1,32 +1,82 @@
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
#include "MeyCan.h";
|
||||
|
||||
|
||||
void setup() {
|
||||
return;
|
||||
SPI.begin();
|
||||
|
||||
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL.MCLKCTRLA | 1 << 7);
|
||||
delay(10); // a bit delay for mcp2515 to get the clock
|
||||
|
||||
SetMeyPin(0, 1, PIN_PD0);
|
||||
SetMeyPin(1, 2, PIN_PC7);
|
||||
SetMeyPin(2, 3, PIN_PD2);
|
||||
SetMeyPin(3, 4, PIN_PD1);
|
||||
SetMeyPin(4, 5, PIN_PD5);
|
||||
SetMeyPin(5, 6, PIN_PD3);
|
||||
SetMeyPin(6, 7, PIN_PD7);
|
||||
SetMeyPin(7, 8, PIN_PD6);
|
||||
|
||||
delay(20);
|
||||
|
||||
SetCanInterface(0, PIN_PD4);
|
||||
SetupMeyCan();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
CheckMeyPinsTriggered();
|
||||
}
|
||||
#include <Arduino.h>
|
||||
#include "driver/twai.h"
|
||||
#include "MeyCan.h"
|
||||
|
||||
// https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino
|
||||
|
||||
#define RX_PIN 2
|
||||
#define TX_PIN 3
|
||||
|
||||
void DebugBlink(int d) {
|
||||
pinMode(20, OUTPUT);
|
||||
while (true) {
|
||||
|
||||
digitalWrite(20, HIGH);
|
||||
delay(d);
|
||||
digitalWrite(20, LOW);
|
||||
delay(d);
|
||||
}
|
||||
}
|
||||
|
||||
bool driver_installed = false;
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
SPI.begin();
|
||||
|
||||
// Explicit GND for LED and Input
|
||||
pinMode(21, OUTPUT);
|
||||
digitalWrite(21, LOW);
|
||||
|
||||
// Initialize configuration structures using macro initializers
|
||||
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_NORMAL);
|
||||
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_1MBITS(); //Look in the api-reference for other speed sets.
|
||||
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
|
||||
|
||||
|
||||
if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
|
||||
Serial.println("Driver installed");
|
||||
} else {
|
||||
DebugBlink(100);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
esp_err_t e = twai_start();
|
||||
// Start TWAI driver
|
||||
if (e == ESP_OK) {
|
||||
driver_installed = true;
|
||||
} else {
|
||||
DebugBlink(500);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SetDevicedId(0x05, 0x1F);
|
||||
|
||||
SetMeyPin(1, 5);
|
||||
SetMeyPin(2, 6);
|
||||
SetMeyPin(3, 7);
|
||||
SetMeyPin(4, 8);
|
||||
SetMeyPin(5, 9);
|
||||
SetMeyPin(6, 10);
|
||||
SetMeyPin(7, 20);
|
||||
|
||||
SetupMeyCan(8, 1, 3);
|
||||
}
|
||||
|
||||
twai_message_t frame;
|
||||
void loop() {
|
||||
|
||||
if (!driver_installed) {
|
||||
// Driver not installed
|
||||
DebugBlink(2000);
|
||||
return;
|
||||
}
|
||||
|
||||
CheckMeyPinsTriggered();
|
||||
if (twai_receive(&frame, 0) == ESP_OK) {
|
||||
|
||||
HandleFrame(&frame);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user