256 lines
7.0 KiB
C++
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);
|
|
} |