#include "effects/Circular.h" #include "effects/Static.h" #include "effects/AlexaSwipe.h" #include "effects/RandomTwoColorInterpolation.h" #include "Arduino.h" #include #pragma pack(push, 1) 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, BUTTON_NORMAL_PRESS = 1, ROTARY_ENCODER = 2, }; struct MsgRfidTokenRead { uint8_t tagId[5]; }; template <> struct ClassToMessageType { static constexpr auto msgType = MessageFwToHost::RFID_TOKEN_READ; }; //---------------------------------------------------------------------------------------------------- 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 }; 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; }; #pragma pack(pop) //---------------------------------------------------------------------------------------------------- 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(LedTask *ledTask) { 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) { Serial.println("Static color"); auto cfg = reinterpret_cast(msgBuffer); ledTask->startEffect(*cfg); } else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE) { Serial.println("Alexa swipe"); auto cfg = reinterpret_cast(msgBuffer); ledTask->startEffect(*cfg); } else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_CIRCULAR) { auto cfg = reinterpret_cast(msgBuffer); ledTask->startEffect(*cfg); } else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION) { auto cfg = reinterpret_cast(msgBuffer); ledTask->startEffect(*cfg); } else Serial.println("Unknown message type"); } else Serial.printf("Incoming message too large (or invalid) %d\n", msgSize); }