#include "effects/Circular.h" #include "effects/Static.h" #include "effects/AlexaSwipe.h" #include "effects/ReverseSwipe.h" #include "effects/RandomTwoColorInterpolation.h" #include "effects/SwipeAndChange.h" #include "Arduino.h" #include constexpr uint32_t MAGIC_TOKEN_HOST_TO_FW = 0x1d6379e3; constexpr uint32_t MAGIC_TOKEN_FW_TO_HOST = 0x10c65631; template struct ClassToMessageType { }; enum class MessageFwToHost : uint8_t { RFID_TOKEN_READ = 0, ROTARY_ENCODER = 1, TOUCH_BUTTON_PRESS = 2, TOUCH_BUTTON_RELEASE = 3, BUTTON_EVENT = 4, }; enum class TouchButton : uint8_t { LEFT_FOOT = 0, RIGHT_FOOT = 1, LEFT_EAR = 2, RIGHT_EAR = 3 }; #pragma pack(push, 1) struct MsgRfidTokenRead { uint8_t tagId[5]; }; struct MsgRotaryEncoder { int32_t position; uint8_t direction; }; struct MsgTouchButtonPress { TouchButton button; }; struct MsgTouchButtonRelease { TouchButton button; }; struct MsgButtonEvent { uint8_t buttonNr; uint8_t eventType; }; #pragma pack(pop) template <> struct ClassToMessageType { static constexpr auto msgType = MessageFwToHost::RFID_TOKEN_READ; }; template <> struct ClassToMessageType { static constexpr auto msgType = MessageFwToHost::ROTARY_ENCODER; }; template <> struct ClassToMessageType { static constexpr auto msgType = MessageFwToHost::TOUCH_BUTTON_PRESS; }; template <> struct ClassToMessageType { static constexpr auto msgType = MessageFwToHost::TOUCH_BUTTON_RELEASE; }; template <> struct ClassToMessageType { static constexpr auto msgType = MessageFwToHost::BUTTON_EVENT; }; //---------------------------------------------------------------------------------------------------- enum class MessageHostToFw : uint8_t { LED_WHEEL_EFFECT_STATIC = 0, LED_WHEEL_EFFECT_ALEXA_SWIPE = 1, LED_WHEEL_EFFECT_CIRCULAR = 2, LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 3, LED_WHEEL_EFFECT_SWIPE_AND_CHANGE = 4, LED_WHEEL_EFFECT_REVERSE_SWIPE = 5, MOUSE_LED_EFFECT_STATIC = 6, MOUSE_LED_EFFECT_CIRCULAR = 7, MOUSE_LED_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 8, MOUSE_LED_EFFECT_SWIPE_AND_CHANGE = 9, MOUSE_LED_EFFECT_REVERSE_SWIPE = 10, PREV_BUTTON_LED = 20, NEXT_BUTTON_LED = 21, }; template <> struct ClassToMessageType { static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_STATIC; }; template <> struct ClassToMessageType { static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE; }; template <> struct ClassToMessageType { static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_CIRCULAR; }; template <> struct ClassToMessageType { static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION; }; template <> struct ClassToMessageType { static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_SWIPE_AND_CHANGE; }; //---------------------------------------------------------------------------------------------------- template void sendMessageToHost(const TMessage &msg) { Serial.write((uint8_t *)&MAGIC_TOKEN_FW_TO_HOST, sizeof(MAGIC_TOKEN_FW_TO_HOST)); MessageFwToHost msgType = ClassToMessageType::msgType; Serial.write((uint8_t *)&msgType, sizeof(msgType)); uint16_t msgSize = sizeof(msg); Serial.write((uint8_t *)&msgSize, sizeof(msgSize)); Serial.write((uint8_t *)&msg, sizeof(msg)); } template inline void handleIncomingMessagesFromHost(LedTask1 *ledTaskCircle, LedTask2 *ledTaskMouse, uint8_t ledChannelLeft, uint8_t ledChannelRight) { if (Serial.available() < sizeof(MAGIC_TOKEN_FW_TO_HOST) + sizeof(MessageHostToFw) + sizeof(uint16_t)) return; uint32_t token; Serial.readBytes((uint8_t *)(&token), sizeof(token)); if (token != MAGIC_TOKEN_HOST_TO_FW) { Serial.println("Received invalid message"); return; } MessageHostToFw msgType; Serial.readBytes((uint8_t *)(&msgType), sizeof(msgType)); uint16_t msgSize; Serial.readBytes((uint8_t *)(&msgSize), sizeof(msgSize)); static constexpr int maxIncomingBufferSize = 1024; static uint8_t msgBuffer[maxIncomingBufferSize]; if (msgSize < maxIncomingBufferSize) { Serial.readBytes(msgBuffer, msgSize); if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_STATIC) { auto cfg = reinterpret_cast(msgBuffer); ledTaskCircle->startEffect(*cfg); } else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE) { auto cfg = reinterpret_cast(msgBuffer); ledTaskCircle->startEffect(*cfg); } else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_CIRCULAR) { auto cfg = reinterpret_cast(msgBuffer); ledTaskCircle->startEffect(*cfg); } else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION) { auto cfg = reinterpret_cast(msgBuffer); ledTaskCircle->startEffect(*cfg); } else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_SWIPE_AND_CHANGE) { auto cfg = reinterpret_cast(msgBuffer); ledTaskCircle->startEffect(*cfg); } else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_REVERSE_SWIPE) { auto cfg = reinterpret_cast(msgBuffer); ledTaskCircle->startEffect(*cfg); } // else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_STATIC) { auto cfg = reinterpret_cast(msgBuffer); ledTaskMouse->startEffect(*cfg); } else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_CIRCULAR) { auto cfg = reinterpret_cast(msgBuffer); ledTaskMouse->startEffect(*cfg); } else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION) { auto cfg = reinterpret_cast(msgBuffer); ledTaskMouse->startEffect(*cfg); } else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_SWIPE_AND_CHANGE) { auto cfg = reinterpret_cast(msgBuffer); ledTaskMouse->startEffect(*cfg); } else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_REVERSE_SWIPE) { auto cfg = reinterpret_cast(msgBuffer); ledTaskMouse->startEffect(*cfg); } else if (msgType == MessageHostToFw::PREV_BUTTON_LED) { float *val = reinterpret_cast(msgBuffer); ledcWrite(ledChannelLeft, uint32_t(255 * (*val))); } else if (msgType == MessageHostToFw::NEXT_BUTTON_LED) { float *val = reinterpret_cast(msgBuffer); ledcWrite(ledChannelRight, uint32_t(255 * (*val))); } else Serial.println("Unknown message type"); } else Serial.printf("Incoming message too large (or invalid) %d\n", msgSize); }