musicmouse/espmusicmouse/src/Messages.h

139 lines
3.8 KiB
C
Raw Normal View History

2021-11-25 22:20:04 +01:00
#include "effects/Circular.h"
#include "effects/Static.h"
#include "effects/AlexaSwipe.h"
#include "effects/RandomTwoColorInterpolation.h"
#include "Arduino.h"
#include <cstdint>
#pragma pack(push, 1)
constexpr uint32_t MAGIC_TOKEN_HOST_TO_FW = 0x1d6379e3;
constexpr uint32_t MAGIC_TOKEN_FW_TO_HOST = 0x10c65631;
template <typename T>
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<MsgRfidTokenRead>
{
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<EffectStaticConfig>
{
static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_STATIC;
};
template <>
struct ClassToMessageType<EffectAlexaSwipeConfig>
{
static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE;
};
template <>
struct ClassToMessageType<EffectCircularConfig>
{
static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_CIRCULAR;
};
template <>
struct ClassToMessageType<EffectRandomTwoColorInterpolationConfig>
{
static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION;
};
#pragma pack(pop)
//----------------------------------------------------------------------------------------------------
template <typename TMessage>
void sendMessageToHost(const TMessage &msg)
{
Serial.write((uint8_t *)&MAGIC_TOKEN_FW_TO_HOST, sizeof(MAGIC_TOKEN_FW_TO_HOST));
MessageFwToHost msgType = ClassToMessageType<TMessage>::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 <typename LedTask>
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<EffectStaticConfig *>(msgBuffer);
ledTask->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE)
{
Serial.println("Alexa swipe");
auto cfg = reinterpret_cast<EffectAlexaSwipeConfig *>(msgBuffer);
ledTask->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_CIRCULAR)
{
auto cfg = reinterpret_cast<EffectCircularConfig *>(msgBuffer);
ledTask->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION)
{
auto cfg = reinterpret_cast<EffectRandomTwoColorInterpolationConfig *>(msgBuffer);
ledTask->startEffect(*cfg);
}
else
Serial.println("Unknown message type");
}
else
Serial.printf("Incoming message too large (or invalid) %d\n", msgSize);
}