diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c index 4d08be8718..6fea48543d 100644 --- a/src/main/cli/settings.c +++ b/src/main/cli/settings.c @@ -1248,6 +1248,7 @@ const clivalue_t valueTable[] = { { "ledstrip_beacon_period_ms", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 50, 10000 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_beacon_period_ms) }, { "ledstrip_beacon_percent", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 100 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_beacon_percent) }, { "ledstrip_beacon_armed_only", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_beacon_armed_only) }, + { "ledstrip_brightness", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 5, 100 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_brightness) }, #endif // PG_SDCARD_CONFIG diff --git a/src/main/drivers/light_ws2811strip.c b/src/main/drivers/light_ws2811strip.c index 43db606fce..1d53ff5858 100644 --- a/src/main/drivers/light_ws2811strip.c +++ b/src/main/drivers/light_ws2811strip.c @@ -140,7 +140,7 @@ void ws2811LedStripEnable(void) const hsvColor_t hsv_black = { 0, 0, 0 }; setStripColor(&hsv_black); // RGB or GRB ordering doesn't matter for black - ws2811UpdateStrip(LED_RGB); + ws2811UpdateStrip(LED_RGB, 100); ws2811Initialised = true; } @@ -177,7 +177,7 @@ STATIC_UNIT_TESTED void updateLEDDMABuffer(ledStripFormatRGB_e ledFormat, rgbCol * This method is non-blocking unless an existing LED update is in progress. * it does not wait until all the LEDs have been updated, that happens in the background. */ -void ws2811UpdateStrip(ledStripFormatRGB_e ledFormat) +void ws2811UpdateStrip(ledStripFormatRGB_e ledFormat, uint8_t brightness) { // don't wait - risk of infinite block, just get an update next time round if (!ws2811Initialised || ws2811LedDataTransferInProgress) { @@ -192,7 +192,11 @@ void ws2811UpdateStrip(ledStripFormatRGB_e ledFormat) const unsigned ledUpdateCount = needsFullRefresh ? WS2811_DATA_BUFFER_SIZE : usedLedCount; const hsvColor_t hsvBlack = { 0, 0, 0 }; while (ledIndex < ledUpdateCount) { - rgbColor24bpp_t *rgb24 = hsvToRgb24(ledIndex < usedLedCount ? &ledColorBuffer[ledIndex] : &hsvBlack); + hsvColor_t scaledLed = ledIndex < usedLedCount ? ledColorBuffer[ledIndex] : hsvBlack; + // Scale the LED brightness + scaledLed.v = scaledLed.v * brightness / 100; + + rgbColor24bpp_t *rgb24 = hsvToRgb24(&scaledLed); updateLEDDMABuffer(ledFormat, rgb24, ledIndex++); } diff --git a/src/main/drivers/light_ws2811strip.h b/src/main/drivers/light_ws2811strip.h index cca0476719..0d9f945b1a 100644 --- a/src/main/drivers/light_ws2811strip.h +++ b/src/main/drivers/light_ws2811strip.h @@ -73,7 +73,7 @@ void ws2811LedStripEnable(void); bool ws2811LedStripHardwareInit(ioTag_t ioTag); void ws2811LedStripDMAEnable(void); -void ws2811UpdateStrip(ledStripFormatRGB_e ledFormat); +void ws2811UpdateStrip(ledStripFormatRGB_e ledFormat, uint8_t brightness); void setLedHsv(uint16_t index, const hsvColor_t *color); void getLedHsv(uint16_t index, hsvColor_t *color); diff --git a/src/main/io/ledstrip.c b/src/main/io/ledstrip.c index 06730f646a..5472912538 100644 --- a/src/main/io/ledstrip.c +++ b/src/main/io/ledstrip.c @@ -115,7 +115,7 @@ 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); +PG_REGISTER_WITH_RESET_FN(ledStripConfig_t, ledStripConfig, PG_LED_STRIP_CONFIG, 2); void pgResetFn_ledStripConfig(ledStripConfig_t *ledStripConfig) { @@ -131,6 +131,7 @@ void pgResetFn_ledStripConfig(ledStripConfig_t *ledStripConfig) ledStripConfig->ledstrip_beacon_percent = 50; // 50% duty cycle ledStripConfig->ledstrip_beacon_armed_only = false; // blink always ledStripConfig->ledstrip_visual_beeper_color = VISUAL_BEEPER_COLOR; + ledStripConfig->ledstrip_brightness = 100; #ifndef UNIT_TEST ledStripConfig->ioTag = timerioTagGetByUsage(TIM_USE_LED, 0); #endif @@ -1077,7 +1078,7 @@ static void applyStatusProfile(timeUs_t now) { bool updateNow = timActive & (1 << timId); (*layerTable[timId])(updateNow, timer); } - ws2811UpdateStrip((ledStripFormatRGB_e) ledStripConfig()->ledstrip_grb_rgb); + ws2811UpdateStrip((ledStripFormatRGB_e) ledStripConfig()->ledstrip_grb_rgb, ledStripConfig()->ledstrip_brightness); } bool parseColor(int index, const char *colorConfig) @@ -1166,7 +1167,7 @@ void ledStripDisable(void) previousProfileColorIndex = COLOR_UNDEFINED; setStripColor(&HSV(BLACK)); - ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb); + ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb, ledStripConfig()->ledstrip_brightness); } void ledStripInit(void) @@ -1240,7 +1241,7 @@ static void applySimpleProfile(timeUs_t currentTimeUs) if ((colorIndex != previousProfileColorIndex) || (currentTimeUs >= colorUpdateTimeUs)) { setStripColor(&hsv[colorIndex]); - ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb); + ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb, ledStripConfig()->ledstrip_brightness); previousProfileColorIndex = colorIndex; colorUpdateTimeUs = currentTimeUs + PROFILE_COLOR_UPDATE_INTERVAL_US; } diff --git a/src/main/io/ledstrip.h b/src/main/io/ledstrip.h index b3d36aecb3..e84b198dda 100644 --- a/src/main/io/ledstrip.h +++ b/src/main/io/ledstrip.h @@ -182,6 +182,7 @@ typedef struct ledStripConfig_s { uint8_t ledstrip_beacon_percent; uint8_t ledstrip_beacon_armed_only; colorId_e ledstrip_visual_beeper_color; + uint8_t ledstrip_brightness; } ledStripConfig_t; PG_DECLARE(ledStripConfig_t, ledStripConfig); diff --git a/src/test/unit/ledstrip_unittest.cc b/src/test/unit/ledstrip_unittest.cc index a5e8226127..ce9b77f57b 100644 --- a/src/test/unit/ledstrip_unittest.cc +++ b/src/test/unit/ledstrip_unittest.cc @@ -311,7 +311,7 @@ void ws2811LedStripInit(ioTag_t ioTag) { UNUSED(ioTag); } -void ws2811UpdateStrip(ledStripFormatRGB_e) {} +void ws2811UpdateStrip(ledStripFormatRGB_e, uint8_t) {} void setLedValue(uint16_t index, const uint8_t value) { UNUSED(index);