musicmouse/espmusicmouse/src/Messages.h

256 lines
7.0 KiB
C++

#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 <cstdint>
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,
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<MsgRfidTokenRead>
{
static constexpr auto msgType = MessageFwToHost::RFID_TOKEN_READ;
};
template <>
struct ClassToMessageType<MsgRotaryEncoder>
{
static constexpr auto msgType = MessageFwToHost::ROTARY_ENCODER;
};
template <>
struct ClassToMessageType<MsgTouchButtonPress>
{
static constexpr auto msgType = MessageFwToHost::TOUCH_BUTTON_PRESS;
};
template <>
struct ClassToMessageType<MsgTouchButtonRelease>
{
static constexpr auto msgType = MessageFwToHost::TOUCH_BUTTON_RELEASE;
};
template <>
struct ClassToMessageType<MsgButtonEvent>
{
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<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;
};
template <>
struct ClassToMessageType<EffectSwipeAndChangeConfig>
{
static constexpr auto msgType = MessageHostToFw::LED_WHEEL_EFFECT_SWIPE_AND_CHANGE;
};
//----------------------------------------------------------------------------------------------------
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 LedTask1, typename LedTask2>
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<EffectStaticConfig *>(msgBuffer);
ledTaskCircle->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE)
{
auto cfg = reinterpret_cast<EffectAlexaSwipeConfig *>(msgBuffer);
ledTaskCircle->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_CIRCULAR)
{
auto cfg = reinterpret_cast<EffectCircularConfig *>(msgBuffer);
ledTaskCircle->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION)
{
auto cfg = reinterpret_cast<EffectRandomTwoColorInterpolationConfig *>(msgBuffer);
ledTaskCircle->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_SWIPE_AND_CHANGE)
{
auto cfg = reinterpret_cast<EffectSwipeAndChangeConfig *>(msgBuffer);
ledTaskCircle->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::LED_WHEEL_EFFECT_REVERSE_SWIPE)
{
auto cfg = reinterpret_cast<EffectReverseSwipeConfig *>(msgBuffer);
ledTaskCircle->startEffect(*cfg);
}
//
else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_STATIC)
{
auto cfg = reinterpret_cast<EffectStaticConfig *>(msgBuffer);
ledTaskMouse->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_CIRCULAR)
{
auto cfg = reinterpret_cast<EffectCircularConfig *>(msgBuffer);
ledTaskMouse->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION)
{
auto cfg = reinterpret_cast<EffectRandomTwoColorInterpolationConfig *>(msgBuffer);
ledTaskMouse->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_SWIPE_AND_CHANGE)
{
auto cfg = reinterpret_cast<EffectSwipeAndChangeConfig *>(msgBuffer);
ledTaskMouse->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::MOUSE_LED_EFFECT_REVERSE_SWIPE)
{
auto cfg = reinterpret_cast<EffectReverseSwipeConfig *>(msgBuffer);
ledTaskMouse->startEffect(*cfg);
}
else if (msgType == MessageHostToFw::PREV_BUTTON_LED)
{
float *val = reinterpret_cast<float *>(msgBuffer);
ledcWrite(ledChannelLeft, uint32_t(255 * (*val)));
}
else if (msgType == MessageHostToFw::NEXT_BUTTON_LED)
{
float *val = reinterpret_cast<float *>(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);
}