The unpinned platform had moved to Arduino core 3, which the firmware no longer built against. Pinned now: pioarduino's platform 55.03.312-1 (Arduino core 3.3.12, ESP-IDF 5.5.5) - PlatformIO's own espressif32 platform still ships core 2 - plus MFRC522 1.4.12, AceButton 1.10.1 and native 1.2.1. - LED strips: the legacy RMT driver is replaced by the new rmt_tx API with a bytes encoder, at the same 50 ns tick, bit timings and byte order. ESP-IDF 5 aborts at boot when both drivers are linked, and the driver now picks the channel itself, so Esp32DriverRGBW::begin() takes only the pin. - Button backlights: ledcAttach instead of ledcSetup/ledcAttachPin, and ledcWrite is addressed by pin rather than channel. - Rotary encoder: gpio_reset_pin instead of the removed gpio_pad_select_gpio. The touch pads stay on the legacy touch driver: on the plain ESP32 it only warns, its conflict check passes as long as the new driver is not linked (it is not), and moving would change the raw counts the thresholds were tuned against. src_filter is build_src_filter now. Not yet tried on the device. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
253 lines
8.7 KiB
C++
253 lines
8.7 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 "effects/SegmentSelect.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;
|
|
int32_t increment;
|
|
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,
|
|
|
|
SHELF_LED_EFFECT_STATIC = 15,
|
|
SHELF_LED_EFFECT_CIRCULAR = 16,
|
|
SHELF_LED_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION = 17,
|
|
SHELF_LED_EFFECT_SWIPE_AND_CHANGE = 18,
|
|
SHELF_LED_EFFECT_REVERSE_SWIPE = 19,
|
|
SHELF_LED_EFFECT_STATIC_DETAILED = 20,
|
|
|
|
PREV_BUTTON_LED = 21,
|
|
NEXT_BUTTON_LED = 22,
|
|
|
|
LED_WHEEL_EFFECT_SEGMENT_SELECT = 23,
|
|
};
|
|
|
|
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 TEffectConfig, typename TLedTask>
|
|
inline bool handleLedEffect(TLedTask *ledTask, MessageHostToFw msgType, MessageHostToFw incomingMsgType, uint8_t *msgBuffer)
|
|
{
|
|
if (msgType == incomingMsgType)
|
|
{
|
|
auto cfg = reinterpret_cast<TEffectConfig *>(msgBuffer);
|
|
ledTask->startEffect(*cfg);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
template <typename LedTask1, typename LedTask2, typename LedTaskShelf>
|
|
inline void handleIncomingMessagesFromHost(LedTask1 *ledTaskCircle, LedTask2 *ledTaskMouse, LedTaskShelf *ledTaskShelf, uint8_t ledPinLeft, uint8_t ledPinRight)
|
|
{
|
|
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);
|
|
|
|
// clang-format off
|
|
// LED Circle
|
|
if(handleLedEffect<EffectStaticConfig >(ledTaskCircle, MessageHostToFw::LED_WHEEL_EFFECT_STATIC, msgType, msgBuffer)) {}
|
|
else if(handleLedEffect<EffectAlexaSwipeConfig >(ledTaskCircle, MessageHostToFw::LED_WHEEL_EFFECT_ALEXA_SWIPE, msgType, msgBuffer)) {}
|
|
else if(handleLedEffect<EffectCircularConfig >(ledTaskCircle, MessageHostToFw::LED_WHEEL_EFFECT_CIRCULAR, msgType, msgBuffer)) {}
|
|
else if(handleLedEffect<EffectRandomTwoColorInterpolationConfig>(ledTaskCircle, MessageHostToFw::LED_WHEEL_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION, msgType, msgBuffer)) {}
|
|
else if(handleLedEffect<EffectSwipeAndChangeConfig >(ledTaskCircle, MessageHostToFw::LED_WHEEL_EFFECT_SWIPE_AND_CHANGE, msgType, msgBuffer)) {}
|
|
else if(handleLedEffect<EffectReverseSwipeConfig >(ledTaskCircle, MessageHostToFw::LED_WHEEL_EFFECT_REVERSE_SWIPE, msgType, msgBuffer)) {}
|
|
else if(handleLedEffect<EffectSegmentSelectConfig >(ledTaskCircle, MessageHostToFw::LED_WHEEL_EFFECT_SEGMENT_SELECT, msgType, msgBuffer)) {}
|
|
|
|
// Mouse LEDs
|
|
else if(handleLedEffect<EffectStaticConfig >(ledTaskMouse, MessageHostToFw::MOUSE_LED_EFFECT_STATIC, msgType, msgBuffer)) {}
|
|
else if(handleLedEffect<EffectCircularConfig >(ledTaskMouse, MessageHostToFw::MOUSE_LED_EFFECT_CIRCULAR, msgType, msgBuffer)) {}
|
|
else if(handleLedEffect<EffectRandomTwoColorInterpolationConfig>(ledTaskMouse, MessageHostToFw::MOUSE_LED_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION, msgType, msgBuffer)) {}
|
|
else if(handleLedEffect<EffectSwipeAndChangeConfig >(ledTaskMouse, MessageHostToFw::MOUSE_LED_EFFECT_SWIPE_AND_CHANGE, msgType, msgBuffer)) {}
|
|
else if(handleLedEffect<EffectReverseSwipeConfig >(ledTaskMouse, MessageHostToFw::MOUSE_LED_EFFECT_REVERSE_SWIPE, msgType, msgBuffer)) {}
|
|
|
|
// Shelf LEDs
|
|
else if (handleLedEffect<EffectStaticConfig >(ledTaskShelf, MessageHostToFw::SHELF_LED_EFFECT_STATIC, msgType, msgBuffer)) {}
|
|
else if (handleLedEffect<EffectCircularConfig >(ledTaskShelf, MessageHostToFw::SHELF_LED_EFFECT_CIRCULAR, msgType, msgBuffer)) {}
|
|
else if (handleLedEffect<EffectRandomTwoColorInterpolationConfig>(ledTaskShelf, MessageHostToFw::SHELF_LED_EFFECT_RANDOM_TWO_COLOR_INTERPOLATION, msgType, msgBuffer)) {}
|
|
else if (handleLedEffect<EffectSwipeAndChangeConfig >(ledTaskShelf, MessageHostToFw::SHELF_LED_EFFECT_SWIPE_AND_CHANGE, msgType, msgBuffer)) {}
|
|
else if (handleLedEffect<EffectReverseSwipeConfig >(ledTaskShelf, MessageHostToFw::SHELF_LED_EFFECT_REVERSE_SWIPE, msgType, msgBuffer)) {}
|
|
else if (handleLedEffect<EffectStaticDetailedConfig >(ledTaskShelf, MessageHostToFw::SHELF_LED_EFFECT_STATIC_DETAILED, msgType, msgBuffer)) {}
|
|
// clang-format on
|
|
|
|
else if (msgType == MessageHostToFw::PREV_BUTTON_LED)
|
|
{
|
|
float *val = reinterpret_cast<float *>(msgBuffer);
|
|
ledcWrite(ledPinLeft, uint32_t(255 * (*val)));
|
|
}
|
|
else if (msgType == MessageHostToFw::NEXT_BUTTON_LED)
|
|
{
|
|
float *val = reinterpret_cast<float *>(msgBuffer);
|
|
ledcWrite(ledPinRight, uint32_t(255 * (*val)));
|
|
}
|
|
else
|
|
Serial.println("Unknown message type");
|
|
}
|
|
else
|
|
Serial.printf("Incoming message too large (or invalid) %d\n", msgSize);
|
|
} |