diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c index cce27bfa08..b787fb31c2 100644 --- a/src/main/cli/cli.c +++ b/src/main/cli/cli.c @@ -1648,14 +1648,14 @@ static void cliLed(char *cmdline) const char *ptr; if (isEmpty(cmdline)) { - printLed(DUMP_MASTER, ledStripConfig()->ledConfigs, NULL); + printLed(DUMP_MASTER, ledStripStatusModeConfig()->ledConfigs, NULL); } else { ptr = cmdline; i = atoi(ptr); if (i < LED_MAX_STRIP_LENGTH) { ptr = nextArg(cmdline); if (parseLedStripConfig(i, ptr)) { - generateLedConfig((ledConfig_t *)&ledStripConfig()->ledConfigs[i], ledConfigBuffer, sizeof(ledConfigBuffer)); + generateLedConfig((ledConfig_t *)&ledStripStatusModeConfig()->ledConfigs[i], ledConfigBuffer, sizeof(ledConfigBuffer)); cliDumpPrintLinef(0, false, format, i, ledConfigBuffer); } else { cliShowParseError(); @@ -1685,14 +1685,14 @@ static void cliColor(char *cmdline) { const char *format = "color %u %d,%u,%u"; if (isEmpty(cmdline)) { - printColor(DUMP_MASTER, ledStripConfig()->colors, NULL); + printColor(DUMP_MASTER, ledStripStatusModeConfig()->colors, NULL); } else { const char *ptr = cmdline; const int i = atoi(ptr); if (i < LED_CONFIGURABLE_COLOR_COUNT) { ptr = nextArg(cmdline); if (parseColor(i, ptr)) { - const hsvColor_t *color = &ledStripConfig()->colors[i]; + const hsvColor_t *color = &ledStripStatusModeConfig()->colors[i]; cliDumpPrintLinef(0, false, format, i, color->h, color->s, color->v); } else { cliShowParseError(); @@ -1703,12 +1703,12 @@ static void cliColor(char *cmdline) } } -static void printModeColor(uint8_t dumpMask, const ledStripConfig_t *ledStripConfig, const ledStripConfig_t *defaultLedStripConfig) +static void printModeColor(uint8_t dumpMask, const ledStripStatusModeConfig_t *ledStripStatusModeConfig, const ledStripStatusModeConfig_t *defaultLedStripConfig) { const char *format = "mode_color %u %u %u"; for (uint32_t i = 0; i < LED_MODE_COUNT; i++) { for (uint32_t j = 0; j < LED_DIRECTION_COUNT; j++) { - int colorIndex = ledStripConfig->modeColors[i].color[j]; + int colorIndex = ledStripStatusModeConfig->modeColors[i].color[j]; bool equalsDefault = false; if (defaultLedStripConfig) { int colorIndexDefault = defaultLedStripConfig->modeColors[i].color[j]; @@ -1720,7 +1720,7 @@ static void printModeColor(uint8_t dumpMask, const ledStripConfig_t *ledStripCon } for (uint32_t j = 0; j < LED_SPECIAL_COLOR_COUNT; j++) { - const int colorIndex = ledStripConfig->specialColors.color[j]; + const int colorIndex = ledStripStatusModeConfig->specialColors.color[j]; bool equalsDefault = false; if (defaultLedStripConfig) { const int colorIndexDefault = defaultLedStripConfig->specialColors.color[j]; @@ -1730,7 +1730,7 @@ static void printModeColor(uint8_t dumpMask, const ledStripConfig_t *ledStripCon cliDumpPrintLinef(dumpMask, equalsDefault, format, LED_SPECIAL, j, colorIndex); } - const int ledStripAuxChannel = ledStripConfig->ledstrip_aux_channel; + const int ledStripAuxChannel = ledStripStatusModeConfig->ledstrip_aux_channel; bool equalsDefault = false; if (defaultLedStripConfig) { const int ledStripAuxChannelDefault = defaultLedStripConfig->ledstrip_aux_channel; @@ -1743,7 +1743,7 @@ static void printModeColor(uint8_t dumpMask, const ledStripConfig_t *ledStripCon static void cliModeColor(char *cmdline) { if (isEmpty(cmdline)) { - printModeColor(DUMP_MASTER, ledStripConfig(), NULL); + printModeColor(DUMP_MASTER, ledStripStatusModeConfig(), NULL); } else { enum {MODE = 0, FUNCTION, COLOR, ARGS_COUNT}; int args[ARGS_COUNT]; @@ -4738,13 +4738,13 @@ static void printConfig(char *cmdline, bool doDiff) #ifdef USE_LED_STRIP_STATUS_MODE cliPrintHashLine("led"); - printLed(dumpMask, ledStripConfig_Copy.ledConfigs, ledStripConfig()->ledConfigs); + printLed(dumpMask, ledStripStatusModeConfig_Copy.ledConfigs, ledStripStatusModeConfig()->ledConfigs); cliPrintHashLine("color"); - printColor(dumpMask, ledStripConfig_Copy.colors, ledStripConfig()->colors); + printColor(dumpMask, ledStripStatusModeConfig_Copy.colors, ledStripStatusModeConfig()->colors); cliPrintHashLine("mode_color"); - printModeColor(dumpMask, &ledStripConfig_Copy, ledStripConfig()); + printModeColor(dumpMask, &ledStripStatusModeConfig_Copy, ledStripStatusModeConfig()); #endif cliPrintHashLine("aux"); diff --git a/src/main/cms/cms_menu_ledstrip.c b/src/main/cms/cms_menu_ledstrip.c index ed3fba012a..31d86dca5e 100644 --- a/src/main/cms/cms_menu_ledstrip.c +++ b/src/main/cms/cms_menu_ledstrip.c @@ -86,6 +86,7 @@ static long cmsx_Ledstrip_OnExit(const OSD_Entry *self) if (cmsx_FeatureLedstrip) { featureEnable(FEATURE_LED_STRIP); + ledStripEnable(); } else { ledStripDisable(); featureDisable(FEATURE_LED_STRIP); diff --git a/src/main/drivers/light_ws2811strip.c b/src/main/drivers/light_ws2811strip.c index 36005fc4ce..1735f37b18 100644 --- a/src/main/drivers/light_ws2811strip.c +++ b/src/main/drivers/light_ws2811strip.c @@ -100,9 +100,9 @@ void ws2811LedStripInit(ioTag_t ioTag) memset(ledStripDMABuffer, 0, sizeof(ledStripDMABuffer)); ws2811LedStripHardwareInit(ioTag); - const hsvColor_t hsv_white = { 0, 255, 255 }; - setStripColor(&hsv_white); - // RGB or GRB ordering doesn't matter for white + const hsvColor_t hsv_black = { 0, 0, 0 }; + setStripColor(&hsv_black); + // RGB or GRB ordering doesn't matter for black ws2811UpdateStrip(LED_RGB); } diff --git a/src/main/fc/config.c b/src/main/fc/config.c index e45dfdd885..d3cdb768ef 100644 --- a/src/main/fc/config.c +++ b/src/main/fc/config.c @@ -145,7 +145,7 @@ static void activateConfig(void) imuConfigure(throttleCorrectionConfig()->throttle_correction_angle, throttleCorrectionConfig()->throttle_correction_value); -#ifdef USE_LED_STRIP +#if defined(USE_LED_STRIP_STATUS_MODE) reevaluateLedConfig(); #endif } diff --git a/src/main/fc/init.c b/src/main/fc/init.c index b0a66e6707..98364e5b1d 100644 --- a/src/main/fc/init.c +++ b/src/main/fc/init.c @@ -649,6 +649,8 @@ void init(void) #ifdef USE_LED_STRIP ledStripInit(); + delayMicroseconds(50); + if (featureIsEnabled(FEATURE_LED_STRIP)) { ledStripEnable(); } diff --git a/src/main/io/ledstrip.c b/src/main/io/ledstrip.c index c19b455cef..2edade98a0 100644 --- a/src/main/io/ledstrip.c +++ b/src/main/io/ledstrip.c @@ -78,20 +78,11 @@ #include "telemetry/telemetry.h" -PG_REGISTER_WITH_RESET_FN(ledStripConfig_t, ledStripConfig, PG_LED_STRIP_CONFIG, 0); - #define COLOR_UNDEFINED 255 -hsvColor_t *colors; -const modeColorIndexes_t *modeColors; -specialColorIndexes_t specialColors; - -static bool ledStripInitialised = false; static bool ledStripEnabled = false; static uint8_t previousProfileColorIndex = COLOR_UNDEFINED; -void ledStripDisable(void); - #define HZ_TO_US(hz) ((int32_t)((1000 * 1000) / (hz))) #define MAX_TIMER_DELAY (5 * 1000 * 1000) @@ -127,6 +118,32 @@ const hsvColor_t hsv[] = { // macro to save typing on default colors #define HSV(color) (hsv[COLOR_ ## color]) +PG_REGISTER_WITH_RESET_FN(ledStripConfig_t, ledStripConfig, PG_LED_STRIP_CONFIG, 1); + +void pgResetFn_ledStripConfig(ledStripConfig_t *ledStripConfig) +{ + ledStripConfig->ledstrip_visual_beeper = 0; +#ifdef USE_LED_STRIP_STATUS_MODE + ledStripConfig->ledstrip_profile = LED_PROFILE_STATUS; +#else + ledStripConfig->ledstrip_profile = LED_PROFILE_RACE; +#endif + ledStripConfig->ledstrip_race_color = COLOR_ORANGE; + ledStripConfig->ledstrip_beacon_color = COLOR_WHITE; + ledStripConfig->ledstrip_beacon_period_ms = 500; // 0.5 second (2hz) + ledStripConfig->ledstrip_beacon_percent = 50; // 50% duty cycle + ledStripConfig->ledstrip_beacon_armed_only = false; // blink always + ledStripConfig->ledstrip_visual_beeper_color = VISUAL_BEEPER_COLOR; +#ifndef UNIT_TEST + ledStripConfig->ioTag = timerioTagGetByUsage(TIM_USE_LED, 0); +#endif +} + +#ifdef USE_LED_STRIP_STATUS_MODE +const hsvColor_t *colors; +const modeColorIndexes_t *modeColors; +specialColorIndexes_t specialColors; + STATIC_UNIT_TESTED uint8_t ledGridRows; // grid offsets STATIC_UNIT_TESTED int8_t highestYValueForNorth; @@ -157,38 +174,41 @@ static const specialColorIndexes_t defaultSpecialColors[] = { }} }; -void pgResetFn_ledStripConfig(ledStripConfig_t *ledStripConfig) +PG_REGISTER_WITH_RESET_FN(ledStripStatusModeConfig_t, ledStripStatusModeConfig, PG_LED_STRIP_STATUS_MODE_CONFIG, 0); + +void pgResetFn_ledStripStatusModeConfig(ledStripStatusModeConfig_t *ledStripStatusModeConfig) { - memset(ledStripConfig->ledConfigs, 0, LED_MAX_STRIP_LENGTH * sizeof(ledConfig_t)); + memset(ledStripStatusModeConfig->ledConfigs, 0, LED_MAX_STRIP_LENGTH * sizeof(ledConfig_t)); // copy hsv colors as default - memset(ledStripConfig->colors, 0, ARRAYLEN(hsv) * sizeof(hsvColor_t)); + memset(ledStripStatusModeConfig->colors, 0, ARRAYLEN(hsv) * sizeof(hsvColor_t)); STATIC_ASSERT(LED_CONFIGURABLE_COLOR_COUNT >= ARRAYLEN(hsv), LED_CONFIGURABLE_COLOR_COUNT_invalid); for (unsigned colorIndex = 0; colorIndex < ARRAYLEN(hsv); colorIndex++) { - ledStripConfig->colors[colorIndex] = hsv[colorIndex]; + ledStripStatusModeConfig->colors[colorIndex] = hsv[colorIndex]; } - memcpy_fn(&ledStripConfig->modeColors, &defaultModeColors, sizeof(defaultModeColors)); - memcpy_fn(&ledStripConfig->specialColors, &defaultSpecialColors, sizeof(defaultSpecialColors)); - ledStripConfig->ledstrip_visual_beeper = 0; - ledStripConfig->ledstrip_aux_channel = THROTTLE; -#ifdef USE_LED_STRIP_STATUS_MODE - ledStripConfig->ledstrip_profile = LED_PROFILE_STATUS; -#else - ledStripConfig->ledstrip_profile = LED_PROFILE_RACE; -#endif - ledStripConfig->ledstrip_race_color = COLOR_ORANGE; - ledStripConfig->ledstrip_beacon_color = COLOR_WHITE; - ledStripConfig->ledstrip_beacon_period_ms = 500; // 0.5 second (2hz) - ledStripConfig->ledstrip_beacon_percent = 50; // 50% duty cycle - ledStripConfig->ledstrip_beacon_armed_only = false; // blink always - ledStripConfig->ledstrip_visual_beeper_color = VISUAL_BEEPER_COLOR; -#ifndef UNIT_TEST - ledStripConfig->ioTag = timerioTagGetByUsage(TIM_USE_LED, 0); -#endif + memcpy_fn(&ledStripStatusModeConfig->modeColors, &defaultModeColors, sizeof(defaultModeColors)); + memcpy_fn(&ledStripStatusModeConfig->specialColors, &defaultSpecialColors, sizeof(defaultSpecialColors)); + ledStripStatusModeConfig->ledstrip_aux_channel = THROTTLE; } -#ifdef USE_LED_STRIP_STATUS_MODE -static void updateLedRingCounts(void); -#endif +#define ROTATION_SEQUENCE_LED_COUNT 6 // 2 on, 4 off +#define ROTATION_SEQUENCE_LED_WIDTH 2 // 2 on + +static void updateLedRingCounts(void) +{ + int seqLen; + // try to split in segments/rings of exactly ROTATION_SEQUENCE_LED_COUNT leds + if ((ledCounts.ring % ROTATION_SEQUENCE_LED_COUNT) == 0) { + seqLen = ROTATION_SEQUENCE_LED_COUNT; + } else { + seqLen = ledCounts.ring; + // else split up in equal segments/rings of at most ROTATION_SEQUENCE_LED_COUNT leds + // TODO - improve partitioning (15 leds -> 3x5) + while ((seqLen > ROTATION_SEQUENCE_LED_COUNT) && ((seqLen % 2) == 0)) { + seqLen /= 2; + } + } + ledCounts.ringSeqLen = seqLen; +} STATIC_UNIT_TESTED void updateDimensions(void) { @@ -198,7 +218,7 @@ STATIC_UNIT_TESTED void updateDimensions(void) int minY = LED_XY_MASK; for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[ledIndex]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; int ledX = ledGetX(ledConfig); maxX = MAX(ledX, maxX); @@ -232,7 +252,7 @@ STATIC_UNIT_TESTED void updateLedCount(void) int count = 0, countRing = 0, countScanner= 0; for (int ledIndex = 0; ledIndex < LED_MAX_STRIP_LENGTH; ledIndex++) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[ledIndex]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; if (!(*ledConfig)) break; @@ -255,26 +275,21 @@ void reevaluateLedConfig(void) { updateLedCount(); updateDimensions(); -#ifdef USE_LED_STRIP_STATUS_MODE updateLedRingCounts(); updateRequiredOverlay(); -#endif } -#ifdef USE_LED_STRIP_STATUS_MODE // get specialColor by index static const hsvColor_t* getSC(ledSpecialColorIds_e index) { - return &ledStripConfig()->colors[ledStripConfig()->specialColors.color[index]]; + return &ledStripStatusModeConfig()->colors[ledStripStatusModeConfig()->specialColors.color[index]]; } static const char directionCodes[LED_DIRECTION_COUNT] = { 'N', 'E', 'S', 'W', 'U', 'D' }; static const char baseFunctionCodes[LED_BASEFUNCTION_COUNT] = { 'C', 'F', 'A', 'L', 'S', 'G', 'R' }; static const char overlayCodes[LED_OVERLAY_COUNT] = { 'T', 'O', 'B', 'V', 'I', 'W' }; -#endif #define CHUNK_BUFFER_SIZE 11 -#ifdef USE_LED_STRIP_STATUS_MODE bool parseLedStripConfig(int ledIndex, const char *config) { if (ledIndex >= LED_MAX_STRIP_LENGTH) @@ -290,7 +305,7 @@ bool parseLedStripConfig(int ledIndex, const char *config) }; static const char chunkSeparators[PARSE_STATE_COUNT] = {',', ':', ':', ':', '\0'}; - ledConfig_t *ledConfig = &ledStripConfigMutable()->ledConfigs[ledIndex]; + ledConfig_t *ledConfig = &ledStripStatusModeConfigMutable()->ledConfigs[ledIndex]; memset(ledConfig, 0, sizeof(ledConfig_t)); int x = 0, y = 0, color = 0; // initialize to prevent warnings @@ -401,7 +416,7 @@ typedef enum { static quadrant_e getLedQuadrant(const int ledIndex) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[ledIndex]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; int x = ledGetX(ledConfig); int y = ledGetY(ledConfig); @@ -421,12 +436,12 @@ static quadrant_e getLedQuadrant(const int ledIndex) static hsvColor_t* getDirectionalModeColor(const int ledIndex, const modeColorIndexes_t *modeColors) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[ledIndex]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; const int ledDirection = ledGetDirection(ledConfig); for (unsigned i = 0; i < LED_DIRECTION_COUNT; i++) { if (ledDirection & (1 << i)) { - return &ledStripConfigMutable()->colors[modeColors->color[i]]; + return &ledStripStatusModeConfigMutable()->colors[modeColors->color[i]]; } } @@ -451,7 +466,7 @@ static const struct { static void applyLedFixedLayers(void) { for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[ledIndex]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; hsvColor_t color = *getSC(LED_SCOLOR_BACKGROUND); int fn = ledGetFunction(ledConfig); @@ -459,13 +474,13 @@ static void applyLedFixedLayers(void) switch (fn) { case LED_FUNCTION_COLOR: - color = ledStripConfig()->colors[ledGetColor(ledConfig)]; + color = ledStripStatusModeConfig()->colors[ledGetColor(ledConfig)]; - hsvColor_t nextColor = ledStripConfig()->colors[(ledGetColor(ledConfig) + 1 + LED_CONFIGURABLE_COLOR_COUNT) % LED_CONFIGURABLE_COLOR_COUNT]; - hsvColor_t previousColor = ledStripConfig()->colors[(ledGetColor(ledConfig) - 1 + LED_CONFIGURABLE_COLOR_COUNT) % LED_CONFIGURABLE_COLOR_COUNT]; + hsvColor_t nextColor = ledStripStatusModeConfig()->colors[(ledGetColor(ledConfig) + 1 + LED_CONFIGURABLE_COLOR_COUNT) % LED_CONFIGURABLE_COLOR_COUNT]; + hsvColor_t previousColor = ledStripStatusModeConfig()->colors[(ledGetColor(ledConfig) - 1 + LED_CONFIGURABLE_COLOR_COUNT) % LED_CONFIGURABLE_COLOR_COUNT]; if (ledGetOverlayBit(ledConfig, LED_OVERLAY_THROTTLE)) { //smooth fade with selected Aux channel of all HSV values from previousColor through color to nextColor - const int auxInput = rcData[ledStripConfig()->ledstrip_aux_channel]; + const int auxInput = rcData[ledStripStatusModeConfig()->ledstrip_aux_channel]; int centerPWM = (PWM_RANGE_MIN + PWM_RANGE_MAX) / 2; if (auxInput < centerPWM) { color.h = scaleRange(auxInput, PWM_RANGE_MIN, centerPWM, previousColor.h, color.h); @@ -483,7 +498,7 @@ static void applyLedFixedLayers(void) case LED_FUNCTION_FLIGHT_MODE: for (unsigned i = 0; i < ARRAYLEN(flightModeToLed); i++) if (!flightModeToLed[i].flightMode || FLIGHT_MODE(flightModeToLed[i].flightMode)) { - const hsvColor_t *directionalColor = getDirectionalModeColor(ledIndex, &ledStripConfig()->modeColors[flightModeToLed[i].ledMode]); + const hsvColor_t *directionalColor = getDirectionalModeColor(ledIndex, &ledStripStatusModeConfig()->modeColors[flightModeToLed[i].ledMode]); if (directionalColor) { color = *directionalColor; } @@ -511,7 +526,7 @@ static void applyLedFixedLayers(void) } if ((fn != LED_FUNCTION_COLOR) && ledGetOverlayBit(ledConfig, LED_OVERLAY_THROTTLE)) { - const int auxInput = rcData[ledStripConfig()->ledstrip_aux_channel]; + const int auxInput = rcData[ledStripStatusModeConfig()->ledstrip_aux_channel]; hOffset += scaleRange(auxInput, PWM_RANGE_MIN, PWM_RANGE_MAX, 0, HSV_HUE_MAX + 1); } @@ -523,7 +538,7 @@ static void applyLedFixedLayers(void) static void applyLedHsv(uint32_t mask, const hsvColor_t *color) { for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[ledIndex]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; if ((*ledConfig & mask) == mask) setLedHsv(ledIndex, color); } @@ -642,7 +657,7 @@ static void applyLedVtxLayer(bool updateNow, timeUs_t *timer) if (showSettings) { // show settings uint8_t vtxLedCount = 0; for (int i = 0; i < ledCounts.count && vtxLedCount < 6; ++i) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[i]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[i]; if (ledGetOverlayBit(ledConfig, LED_OVERLAY_VTX)) { if (vtxLedCount == 0) { color.h = HSV(GREEN).h; @@ -684,7 +699,7 @@ static void applyLedVtxLayer(bool updateNow, timeUs_t *timer) } else { colorIndex = COLOR_DEEP_PINK; } - hsvColor_t color = ledStripConfig()->colors[colorIndex]; + hsvColor_t color = ledStripStatusModeConfig()->colors[colorIndex]; color.v = pit ? (blink ? 15 : 0) : 255; // blink when in pit mode applyLedHsv(LED_MOV_OVERLAY(LED_FLAG_OVERLAY(LED_OVERLAY_VTX)), &color); } @@ -792,11 +807,9 @@ static void applyLedGpsLayer(bool updateNow, timeUs_t *timer) applyLedHsv(LED_MOV_FUNCTION(LED_FUNCTION_GPS), gpsColor); } #endif -#endif #define INDICATOR_DEADBAND 25 -#ifdef USE_LED_STRIP_STATUS_MODE static void applyLedIndicatorLayer(bool updateNow, timeUs_t *timer) { static bool flash = 0; @@ -832,7 +845,7 @@ static void applyLedIndicatorLayer(bool updateNow, timeUs_t *timer) } for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[ledIndex]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; if (ledGetOverlayBit(ledConfig, LED_OVERLAY_INDICATOR)) { if (getLedQuadrant(ledIndex) & quadrants) setLedHsv(ledIndex, flashColor); @@ -840,26 +853,6 @@ static void applyLedIndicatorLayer(bool updateNow, timeUs_t *timer) } } -#define ROTATION_SEQUENCE_LED_COUNT 6 // 2 on, 4 off -#define ROTATION_SEQUENCE_LED_WIDTH 2 // 2 on - -static void updateLedRingCounts(void) -{ - int seqLen; - // try to split in segments/rings of exactly ROTATION_SEQUENCE_LED_COUNT leds - if ((ledCounts.ring % ROTATION_SEQUENCE_LED_COUNT) == 0) { - seqLen = ROTATION_SEQUENCE_LED_COUNT; - } else { - seqLen = ledCounts.ring; - // else split up in equal segments/rings of at most ROTATION_SEQUENCE_LED_COUNT leds - // TODO - improve partitioning (15 leds -> 3x5) - while ((seqLen > ROTATION_SEQUENCE_LED_COUNT) && ((seqLen % 2) == 0)) { - seqLen /= 2; - } - } - ledCounts.ringSeqLen = seqLen; -} - static void applyLedThrustRingLayer(bool updateNow, timeUs_t *timer) { static uint8_t rotationPhase; @@ -873,7 +866,7 @@ static void applyLedThrustRingLayer(bool updateNow, timeUs_t *timer) } for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[ledIndex]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; if (ledGetFunction(ledConfig) == LED_FUNCTION_THRUST_RING) { bool applyColor; @@ -884,7 +877,7 @@ static void applyLedThrustRingLayer(bool updateNow, timeUs_t *timer) } if (applyColor) { - const hsvColor_t *ringColor = &ledStripConfig()->colors[ledGetColor(ledConfig)]; + const hsvColor_t *ringColor = &ledStripStatusModeConfig()->colors[ledGetColor(ledConfig)]; setLedHsv(ledIndex, ringColor); } @@ -943,7 +936,7 @@ static void applyLarsonScannerLayer(bool updateNow, timeUs_t *timer) int scannerLedIndex = 0; for (unsigned i = 0; i < ledCounts.count; i++) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[i]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[i]; if (ledGetOverlayBit(ledConfig, LED_OVERLAY_LARSON_SCANNER)) { hsvColor_t ledColor; @@ -972,7 +965,7 @@ static void applyLedBlinkLayer(bool updateNow, timeUs_t *timer) bool ledOn = (blinkMask & 1); // b_b_____... if (!ledOn) { for (int i = 0; i < ledCounts.count; ++i) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[i]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[i]; if (ledGetOverlayBit(ledConfig, LED_OVERLAY_BLINK)) { setLedHsv(i, getSC(LED_SCOLOR_BLINKBACKGROUND)); @@ -1004,7 +997,6 @@ static uint16_t disabledTimerMask; STATIC_ASSERT(timTimerCount <= sizeof(disabledTimerMask) * 8, disabledTimerMask_too_small); -#ifdef USE_LED_STRIP_STATUS_MODE // function to apply layer. // function must replan self using timer pointer // when updateNow is true (timer triggered), state must be updated first, @@ -1027,12 +1019,11 @@ static applyLayerFn_timed* layerTable[] = { [timIndicator] = &applyLedIndicatorLayer, [timRing] = &applyLedThrustRingLayer }; -#endif bool isOverlayTypeUsed(ledOverlayId_e overlayType) { for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[ledIndex]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; if (ledGetOverlayBit(ledConfig, overlayType)) { return true; } @@ -1082,8 +1073,107 @@ static void applyStatusProfile(timeUs_t now) { } ws2811UpdateStrip((ledStripFormatRGB_e) ledStripConfig()->ledstrip_grb_rgb); } + +bool parseColor(int index, const char *colorConfig) +{ + const char *remainingCharacters = colorConfig; + + hsvColor_t *color = &ledStripStatusModeConfigMutable()->colors[index]; + + bool result = true; + static const uint16_t hsv_limit[HSV_COLOR_COMPONENT_COUNT] = { + [HSV_HUE] = HSV_HUE_MAX, + [HSV_SATURATION] = HSV_SATURATION_MAX, + [HSV_VALUE] = HSV_VALUE_MAX, + }; + for (int componentIndex = 0; result && componentIndex < HSV_COLOR_COMPONENT_COUNT; componentIndex++) { + int val = atoi(remainingCharacters); + if (val > hsv_limit[componentIndex]) { + result = false; + break; + } + switch (componentIndex) { + case HSV_HUE: + color->h = val; + break; + case HSV_SATURATION: + color->s = val; + break; + case HSV_VALUE: + color->v = val; + break; + } + remainingCharacters = strchr(remainingCharacters, ','); + if (remainingCharacters) { + remainingCharacters++; // skip separator + } else { + if (componentIndex < HSV_COLOR_COMPONENT_COUNT - 1) { + result = false; + } + } + } + + if (!result) { + memset(color, 0, sizeof(*color)); + } + + return result; +} + +/* + * Redefine a color in a mode. + * */ +bool setModeColor(ledModeIndex_e modeIndex, int modeColorIndex, int colorIndex) +{ + // check color + if (colorIndex < 0 || colorIndex >= LED_CONFIGURABLE_COLOR_COUNT) + return false; + if (modeIndex < LED_MODE_COUNT) { // modeIndex_e is unsigned, so one-sided test is enough + if (modeColorIndex < 0 || modeColorIndex >= LED_DIRECTION_COUNT) + return false; + ledStripStatusModeConfigMutable()->modeColors[modeIndex].color[modeColorIndex] = colorIndex; + } else if (modeIndex == LED_SPECIAL) { + if (modeColorIndex < 0 || modeColorIndex >= LED_SPECIAL_COLOR_COUNT) + return false; + ledStripStatusModeConfigMutable()->specialColors.color[modeColorIndex] = colorIndex; + } else if (modeIndex == LED_AUX_CHANNEL) { + if (modeColorIndex < 0 || modeColorIndex >= 1) + return false; + ledStripStatusModeConfigMutable()->ledstrip_aux_channel = colorIndex; + } else { + return false; + } + return true; +} #endif +void ledStripEnable(void) +{ + ledStripEnabled = true; +} + +void ledStripDisable(void) +{ + ledStripEnabled = false; + previousProfileColorIndex = COLOR_UNDEFINED; + setStripColor(&HSV(BLACK)); + + ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb); +} + +void ledStripInit(void) +{ +#if defined(USE_LED_STRIP_STATUS_MODE) + colors = ledStripStatusModeConfig()->colors; + modeColors = ledStripStatusModeConfig()->modeColors; + specialColors = ledStripStatusModeConfig()->specialColors; + + reevaluateLedConfig(); +#endif + + ws2811LedStripInit(ledStripConfig()->ioTag); +} + static uint8_t selectVisualBeeperColor(uint8_t colorIndex) { if (ledStripConfig()->ledstrip_visual_beeper && isBeeperOn()) { @@ -1154,14 +1244,14 @@ void ledStripUpdate(timeUs_t currentTimeUs) UNUSED(currentTimeUs); #endif - if (!featureIsEnabled(FEATURE_LED_STRIP) || !ledStripInitialised || !isWS2811LedStripReady()) { + if (!isWS2811LedStripReady()) { return; } if (ledStripEnabled && IS_RC_MODE_ACTIVE(BOXLEDLOW)) { ledStripDisable(); } else if (!IS_RC_MODE_ACTIVE(BOXLEDLOW)) { - ledStripEnabled = true; + ledStripEnable(); } if (ledStripEnabled) { @@ -1184,108 +1274,6 @@ void ledStripUpdate(timeUs_t currentTimeUs) } } -bool parseColor(int index, const char *colorConfig) -{ - const char *remainingCharacters = colorConfig; - - hsvColor_t *color = &ledStripConfigMutable()->colors[index]; - - bool result = true; - static const uint16_t hsv_limit[HSV_COLOR_COMPONENT_COUNT] = { - [HSV_HUE] = HSV_HUE_MAX, - [HSV_SATURATION] = HSV_SATURATION_MAX, - [HSV_VALUE] = HSV_VALUE_MAX, - }; - for (int componentIndex = 0; result && componentIndex < HSV_COLOR_COMPONENT_COUNT; componentIndex++) { - int val = atoi(remainingCharacters); - if (val > hsv_limit[componentIndex]) { - result = false; - break; - } - switch (componentIndex) { - case HSV_HUE: - color->h = val; - break; - case HSV_SATURATION: - color->s = val; - break; - case HSV_VALUE: - color->v = val; - break; - } - remainingCharacters = strchr(remainingCharacters, ','); - if (remainingCharacters) { - remainingCharacters++; // skip separator - } else { - if (componentIndex < HSV_COLOR_COMPONENT_COUNT - 1) { - result = false; - } - } - } - - if (!result) { - memset(color, 0, sizeof(*color)); - } - - return result; -} - -#ifdef USE_LED_STRIP_STATUS_MODE -/* - * Redefine a color in a mode. - * */ -bool setModeColor(ledModeIndex_e modeIndex, int modeColorIndex, int colorIndex) -{ - // check color - if (colorIndex < 0 || colorIndex >= LED_CONFIGURABLE_COLOR_COUNT) - return false; - if (modeIndex < LED_MODE_COUNT) { // modeIndex_e is unsigned, so one-sided test is enough - if (modeColorIndex < 0 || modeColorIndex >= LED_DIRECTION_COUNT) - return false; - ledStripConfigMutable()->modeColors[modeIndex].color[modeColorIndex] = colorIndex; - } else if (modeIndex == LED_SPECIAL) { - if (modeColorIndex < 0 || modeColorIndex >= LED_SPECIAL_COLOR_COUNT) - return false; - ledStripConfigMutable()->specialColors.color[modeColorIndex] = colorIndex; - } else if (modeIndex == LED_AUX_CHANNEL) { - if (modeColorIndex < 0 || modeColorIndex >= 1) - return false; - ledStripConfigMutable()->ledstrip_aux_channel = colorIndex; - } else { - return false; - } - return true; -} -#endif - -void ledStripInit(void) -{ - colors = ledStripConfigMutable()->colors; - modeColors = ledStripConfig()->modeColors; - specialColors = ledStripConfig()->specialColors; - ledStripInitialised = false; -} - -void ledStripEnable(void) -{ - reevaluateLedConfig(); - ledStripInitialised = true; - - ws2811LedStripInit(ledStripConfig()->ioTag); - ledStripEnabled = true; -} - -void ledStripDisable(void) -{ - ledStripEnabled = false; - previousProfileColorIndex = COLOR_UNDEFINED; - setStripColor(&HSV(BLACK)); - if (ledStripInitialised) { - ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb); - } -} - - uint8_t getLedProfile(void) { return ledStripConfig()->ledstrip_profile; diff --git a/src/main/io/ledstrip.h b/src/main/io/ledstrip.h index 0acdc496d4..b3d36aecb3 100644 --- a/src/main/io/ledstrip.h +++ b/src/main/io/ledstrip.h @@ -172,12 +172,7 @@ typedef struct ledCounts_s { } ledCounts_t; typedef struct ledStripConfig_s { - ledConfig_t ledConfigs[LED_MAX_STRIP_LENGTH]; - hsvColor_t colors[LED_CONFIGURABLE_COLOR_COUNT]; - modeColorIndexes_t modeColors[LED_MODE_COUNT]; - specialColorIndexes_t specialColors; uint8_t ledstrip_visual_beeper; - uint8_t ledstrip_aux_channel; ioTag_t ioTag; ledStripFormatRGB_e ledstrip_grb_rgb; ledProfile_e ledstrip_profile; @@ -191,9 +186,17 @@ typedef struct ledStripConfig_s { PG_DECLARE(ledStripConfig_t, ledStripConfig); -extern hsvColor_t *colors; -extern const modeColorIndexes_t *modeColors; -extern specialColorIndexes_t specialColors; +#if defined(USE_LED_STRIP_STATUS_MODE) +typedef struct ledStripStatusModeConfig_s { + ledConfig_t ledConfigs[LED_MAX_STRIP_LENGTH]; + hsvColor_t colors[LED_CONFIGURABLE_COLOR_COUNT]; + modeColorIndexes_t modeColors[LED_MODE_COUNT]; + specialColorIndexes_t specialColors; + uint8_t ledstrip_aux_channel; +} ledStripStatusModeConfig_t; + +PG_DECLARE(ledStripStatusModeConfig_t, ledStripStatusModeConfig); +#endif #define LF(name) LED_FUNCTION_ ## name #define LO(name) LED_FLAG_OVERLAY(LED_OVERLAY_ ## name) diff --git a/src/main/msp/msp.c b/src/main/msp/msp.c index da943af006..d3d4904518 100644 --- a/src/main/msp/msp.c +++ b/src/main/msp/msp.c @@ -1209,7 +1209,7 @@ static bool mspProcessOutCommand(uint8_t cmdMSP, sbuf_t *dst) #ifdef USE_LED_STRIP_STATUS_MODE case MSP_LED_COLORS: for (int i = 0; i < LED_CONFIGURABLE_COLOR_COUNT; i++) { - const hsvColor_t *color = &ledStripConfig()->colors[i]; + const hsvColor_t *color = &ledStripStatusModeConfig()->colors[i]; sbufWriteU16(dst, color->h); sbufWriteU8(dst, color->s); sbufWriteU8(dst, color->v); @@ -1221,7 +1221,7 @@ static bool mspProcessOutCommand(uint8_t cmdMSP, sbuf_t *dst) case MSP_LED_STRIP_CONFIG: for (int i = 0; i < LED_MAX_STRIP_LENGTH; i++) { #ifdef USE_LED_STRIP_STATUS_MODE - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[i]; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[i]; sbufWriteU32(dst, *ledConfig); #else sbufWriteU32(dst, 0); @@ -1246,19 +1246,19 @@ static bool mspProcessOutCommand(uint8_t cmdMSP, sbuf_t *dst) for (int j = 0; j < LED_DIRECTION_COUNT; j++) { sbufWriteU8(dst, i); sbufWriteU8(dst, j); - sbufWriteU8(dst, ledStripConfig()->modeColors[i].color[j]); + sbufWriteU8(dst, ledStripStatusModeConfig()->modeColors[i].color[j]); } } for (int j = 0; j < LED_SPECIAL_COLOR_COUNT; j++) { sbufWriteU8(dst, LED_MODE_COUNT); sbufWriteU8(dst, j); - sbufWriteU8(dst, ledStripConfig()->specialColors.color[j]); + sbufWriteU8(dst, ledStripStatusModeConfig()->specialColors.color[j]); } sbufWriteU8(dst, LED_AUX_CHANNEL); sbufWriteU8(dst, 0); - sbufWriteU8(dst, ledStripConfig()->ledstrip_aux_channel); + sbufWriteU8(dst, ledStripStatusModeConfig()->ledstrip_aux_channel); break; #endif @@ -2363,7 +2363,7 @@ static mspResult_e mspProcessInCommand(uint8_t cmdMSP, sbuf_t *src) #ifdef USE_LED_STRIP_STATUS_MODE case MSP_SET_LED_COLORS: for (int i = 0; i < LED_CONFIGURABLE_COLOR_COUNT; i++) { - hsvColor_t *color = &ledStripConfigMutable()->colors[i]; + hsvColor_t *color = &ledStripStatusModeConfigMutable()->colors[i]; color->h = sbufReadU16(src); color->s = sbufReadU8(src); color->v = sbufReadU8(src); @@ -2379,7 +2379,7 @@ static mspResult_e mspProcessInCommand(uint8_t cmdMSP, sbuf_t *src) return MSP_RESULT_ERROR; } #ifdef USE_LED_STRIP_STATUS_MODE - ledConfig_t *ledConfig = &ledStripConfigMutable()->ledConfigs[i]; + ledConfig_t *ledConfig = &ledStripStatusModeConfigMutable()->ledConfigs[i]; *ledConfig = sbufReadU32(src); reevaluateLedConfig(); #else diff --git a/src/main/pg/pg_ids.h b/src/main/pg/pg_ids.h index dcb12a80cd..ec82bdb65e 100644 --- a/src/main/pg/pg_ids.h +++ b/src/main/pg/pg_ids.h @@ -139,7 +139,8 @@ #define PG_RX_SPEKTRUM_SPI_CONFIG 542 #define PG_SERIAL_UART_CONFIG 543 #define PG_RPM_FILTER_CONFIG 544 -#define PG_BETAFLIGHT_END 544 +#define PG_LED_STRIP_STATUS_MODE_CONFIG 545 // Used to hold the configuration for the LED_STRIP status mode (not built on targets with limited flash) +#define PG_BETAFLIGHT_END 545 // OSD configuration (subject to change) diff --git a/src/main/target/COLIBRI_RACE/i2c_bst.c b/src/main/target/COLIBRI_RACE/i2c_bst.c index f17a078b83..bf74e48e5f 100644 --- a/src/main/target/COLIBRI_RACE/i2c_bst.c +++ b/src/main/target/COLIBRI_RACE/i2c_bst.c @@ -400,17 +400,15 @@ static bool bstSlaveProcessFeedbackCommand(uint8_t bstRequest) #ifdef USE_LED_STRIP case BST_LED_COLORS: for (i = 0; i < LED_CONFIGURABLE_COLOR_COUNT; i++) { - hsvColor_t *color = &ledStripConfigMutable()->colors[i]; - bstWrite16(color->h); - bstWrite8(color->s); - bstWrite8(color->v); + bstWrite16(0); + bstWrite8(0); + bstWrite8(0); } break; case BST_LED_STRIP_CONFIG: for (i = 0; i < LED_MAX_STRIP_LENGTH; i++) { - const ledConfig_t *ledConfig = &ledStripConfig()->ledConfigs[i]; - bstWrite32(*ledConfig); + bstWrite32(0); } break; #endif @@ -583,11 +581,10 @@ static bool bstSlaveProcessWriteCommand(uint8_t bstWriteCommand) case BST_SET_LED_COLORS: //for (i = 0; i < CONFIGURABLE_COLOR_COUNT; i++) { { - i = bstRead8(); - hsvColor_t *color = &ledStripConfigMutable()->colors[i]; - color->h = bstRead16(); - color->s = bstRead8(); - color->v = bstRead8(); + bstRead8(); + bstRead16(); + bstRead8(); + bstRead8(); } break; case BST_SET_LED_STRIP_CONFIG: @@ -597,9 +594,11 @@ static bool bstSlaveProcessWriteCommand(uint8_t bstWriteCommand) ret = BST_FAILED; break; } - ledConfig_t *ledConfig = &ledStripConfigMutable()->ledConfigs[i]; +#if defined(USE_LED_STRIP_STATUS_MODE) + ledConfig_t *ledConfig = &ledStripStatusModeConfigMutable()->ledConfigs[i]; *ledConfig = bstRead32(); reevaluateLedConfig(); +#endif } break; #endif diff --git a/src/test/unit/cli_unittest.cc b/src/test/unit/cli_unittest.cc index 9940b60cf0..3db56345c1 100644 --- a/src/test/unit/cli_unittest.cc +++ b/src/test/unit/cli_unittest.cc @@ -66,6 +66,7 @@ extern "C" { PG_REGISTER(osdConfig_t, osdConfig, PG_OSD_CONFIG, 0); PG_REGISTER(batteryConfig_t, batteryConfig, PG_BATTERY_CONFIG, 0); PG_REGISTER(ledStripConfig_t, ledStripConfig, PG_LED_STRIP_CONFIG, 0); + PG_REGISTER(ledStripStatusModeConfig_t, ledStripStatusModeConfig, PG_LED_STRIP_STATUS_MODE_CONFIG, 0); PG_REGISTER(systemConfig_t, systemConfig, PG_SYSTEM_CONFIG, 0); PG_REGISTER(pilotConfig_t, pilotConfig, PG_PILOT_CONFIG, 0); PG_REGISTER_ARRAY(adjustmentRange_t, MAX_ADJUSTMENT_RANGE_COUNT, adjustmentRanges, PG_ADJUSTMENT_RANGE_CONFIG, 0); diff --git a/src/test/unit/ledstrip_unittest.cc b/src/test/unit/ledstrip_unittest.cc index 8e3af573da..5d5e522b52 100644 --- a/src/test/unit/ledstrip_unittest.cc +++ b/src/test/unit/ledstrip_unittest.cc @@ -73,7 +73,7 @@ extern "C" { TEST(LedStripTest, parseLedStripConfig) { // given - memset(&ledStripConfigMutable()->ledConfigs, 0, LED_MAX_STRIP_LENGTH); + memset(&ledStripStatusModeConfigMutable()->ledConfigs, 0, LED_MAX_STRIP_LENGTH); // and static const ledConfig_t expectedLedStripConfig[WS2811_LED_STRIP_LENGTH] = { @@ -178,7 +178,7 @@ TEST(LedStripTest, parseLedStripConfig) #ifdef DEBUG_LEDSTRIP printf("iteration: %d\n", index); #endif - EXPECT_EQ(expectedLedStripConfig[index], ledStripConfig()->ledConfigs[index]); + EXPECT_EQ(expectedLedStripConfig[index], ledStripStatusModeConfig()->ledConfigs[index]); } // then @@ -194,7 +194,7 @@ TEST(LedStripTest, parseLedStripConfig) TEST(LedStripTest, smallestGridWithCenter) { // given - memset(&ledStripConfigMutable()->ledConfigs, 0, LED_MAX_STRIP_LENGTH); + memset(&ledStripStatusModeConfigMutable()->ledConfigs, 0, LED_MAX_STRIP_LENGTH); // and static const ledConfig_t testLedConfigs[] = { @@ -206,7 +206,7 @@ TEST(LedStripTest, smallestGridWithCenter) DEFINE_LED(0, 1, 0, LD(SOUTH) | LD(WEST), LF(FLIGHT_MODE), LO(WARNING), 0), DEFINE_LED(0, 2, 0, LD(SOUTH), LF(ARM_STATE), LO(INDICATOR), 0) }; - memcpy(&ledStripConfigMutable()->ledConfigs, &testLedConfigs, sizeof(testLedConfigs)); + memcpy(&ledStripStatusModeConfigMutable()->ledConfigs, &testLedConfigs, sizeof(testLedConfigs)); // when reevaluateLedConfig(); @@ -222,7 +222,7 @@ TEST(LedStripTest, smallestGridWithCenter) TEST(LedStripTest, smallestGrid) { // given - memset(&ledStripConfigMutable()->ledConfigs, 0, LED_MAX_STRIP_LENGTH); + memset(&ledStripStatusModeConfigMutable()->ledConfigs, 0, LED_MAX_STRIP_LENGTH); // and static const ledConfig_t testLedConfigs[] = { @@ -231,7 +231,7 @@ TEST(LedStripTest, smallestGrid) DEFINE_LED(0, 0, 0, LD(NORTH) | LD(WEST), LF(FLIGHT_MODE), LO(INDICATOR), 0), DEFINE_LED(0, 1, 0, LD(SOUTH) | LD(WEST), LF(FLIGHT_MODE), LO(INDICATOR), 0) }; - memcpy(&ledStripConfigMutable()->ledConfigs, &testLedConfigs, sizeof(testLedConfigs)); + memcpy(&ledStripStatusModeConfigMutable()->ledConfigs, &testLedConfigs, sizeof(testLedConfigs)); // when reevaluateLedConfig(); @@ -253,7 +253,7 @@ extern hsvColor_t *colors; TEST(ColorTest, parseColor) { // given - memset(ledStripConfigMutable()->colors, 0, sizeof(hsvColor_t) * LED_CONFIGURABLE_COLOR_COUNT); + memset(ledStripStatusModeConfigMutable()->colors, 0, sizeof(hsvColor_t) * LED_CONFIGURABLE_COLOR_COUNT); // and const hsvColor_t expectedColors[TEST_COLOR_COUNT] = { @@ -287,9 +287,9 @@ TEST(ColorTest, parseColor) printf("iteration: %d\n", index); #endif - EXPECT_EQ(expectedColors[index].h, ledStripConfig()->colors[index].h); - EXPECT_EQ(expectedColors[index].s, ledStripConfig()->colors[index].s); - EXPECT_EQ(expectedColors[index].v, ledStripConfig()->colors[index].v); + EXPECT_EQ(expectedColors[index].h, ledStripStatusModeConfig()->colors[index].h); + EXPECT_EQ(expectedColors[index].s, ledStripStatusModeConfig()->colors[index].s); + EXPECT_EQ(expectedColors[index].v, ledStripStatusModeConfig()->colors[index].v); } }