diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c index 59f72f0acd..431d51540f 100644 --- a/src/main/cli/settings.c +++ b/src/main/cli/settings.c @@ -437,7 +437,7 @@ static const char * const lookupTableLEDProfile[] = { #endif #endif -const char * const lookupTableLEDRaceColors[COLOR_COUNT] = { +const char * const lookupTableLedstripColors[COLOR_COUNT] = { "BLACK", "WHITE", "RED", @@ -568,7 +568,7 @@ const lookupTableEntry_t lookupTables[] = { #endif #ifdef USE_LED_STRIP LOOKUP_TABLE_ENTRY(lookupTableLEDProfile), - LOOKUP_TABLE_ENTRY(lookupTableLEDRaceColors), + LOOKUP_TABLE_ENTRY(lookupTableLedstripColors), #endif LOOKUP_TABLE_ENTRY(lookupTableGyroFilterDebug), @@ -1079,9 +1079,14 @@ const clivalue_t valueTable[] = { // PG_LED_STRIP_CONFIG #ifdef USE_LED_STRIP { "ledstrip_visual_beeper", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_visual_beeper) }, + { "ledstrip_visual_beeper_color",VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_LEDSTRIP_COLOR }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_visual_beeper_color) }, { "ledstrip_grb_rgb", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_RGB_GRB }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_grb_rgb) }, { "ledstrip_profile", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_LED_PROFILE }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_profile) }, - { "ledstrip_race_color", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_LED_RACE_COLOR }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledRaceColor) }, + { "ledstrip_race_color", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_LEDSTRIP_COLOR }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_race_color) }, + { "ledstrip_beacon_color", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_LEDSTRIP_COLOR }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_beacon_color) }, + { "ledstrip_beacon_period_ms", VAR_UINT16 | MASTER_VALUE, .config.minmax = { 50, 10000 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_beacon_period_ms) }, + { "ledstrip_beacon_percent", VAR_UINT8 | MASTER_VALUE, .config.minmax = { 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) }, #endif // PG_SDCARD_CONFIG diff --git a/src/main/cli/settings.h b/src/main/cli/settings.h index cec73d1756..a1024a41fa 100644 --- a/src/main/cli/settings.h +++ b/src/main/cli/settings.h @@ -133,7 +133,7 @@ typedef enum { #endif #ifdef USE_LED_STRIP TABLE_LED_PROFILE, - TABLE_LED_RACE_COLOR, + TABLE_LEDSTRIP_COLOR, #endif TABLE_GYRO_FILTER_DEBUG, LOOKUP_TABLE_COUNT @@ -224,4 +224,4 @@ extern const char * const lookupTableMagHardware[]; extern const char * const lookupTableRangefinderHardware[]; -extern const char * const lookupTableLEDRaceColors[]; +extern const char * const lookupTableLedstripColors[]; diff --git a/src/main/cms/cms_menu_ledstrip.c b/src/main/cms/cms_menu_ledstrip.c index 88b3bf1cd7..ed3fba012a 100644 --- a/src/main/cms/cms_menu_ledstrip.c +++ b/src/main/cms/cms_menu_ledstrip.c @@ -48,8 +48,15 @@ #ifdef USE_LED_STRIP static uint8_t cmsx_FeatureLedstrip; -static uint8_t cmsx_LedProfile; -static uint8_t cmsx_RaceColor; +static uint8_t cmsx_ledProfile; +static uint8_t cmsx_ledRaceColor; +static uint8_t cmsx_ledBeaconColor; +static uint16_t cmsx_ledBeaconPeriod; +static uint8_t cmsx_ledBeaconOnPercent; +static uint8_t cmsx_ledBeaconArmedOnly; +static uint8_t cmsx_ledVisualBeeper; +static uint8_t cmsx_ledVisualBeeperColor; + const char * const ledProfileNames[LED_PROFILE_COUNT] = { "RACE", "BEACON", @@ -61,8 +68,14 @@ const char * const ledProfileNames[LED_PROFILE_COUNT] = { static long cmsx_Ledstrip_OnEnter(void) { cmsx_FeatureLedstrip = featureIsEnabled(FEATURE_LED_STRIP) ? 1 : 0; - cmsx_LedProfile = getLedProfile(); - cmsx_RaceColor = getLedRaceColor(); + cmsx_ledProfile = getLedProfile(); + cmsx_ledRaceColor = ledStripConfig()->ledstrip_race_color; + cmsx_ledBeaconColor = ledStripConfig()->ledstrip_beacon_color; + cmsx_ledBeaconPeriod = ledStripConfig()->ledstrip_beacon_period_ms; + cmsx_ledBeaconOnPercent = ledStripConfig()->ledstrip_beacon_percent; + cmsx_ledBeaconArmedOnly = ledStripConfig()->ledstrip_beacon_armed_only; + cmsx_ledVisualBeeper = ledStripConfig()->ledstrip_visual_beeper; + cmsx_ledVisualBeeperColor = ledStripConfig()->ledstrip_visual_beeper_color; return 0; } @@ -78,18 +91,30 @@ static long cmsx_Ledstrip_OnExit(const OSD_Entry *self) featureDisable(FEATURE_LED_STRIP); } - setLedProfile(cmsx_LedProfile); - setLedRaceColor(cmsx_RaceColor); + setLedProfile(cmsx_ledProfile); + ledStripConfigMutable()->ledstrip_race_color = cmsx_ledRaceColor; + ledStripConfigMutable()->ledstrip_beacon_color = cmsx_ledBeaconColor; + ledStripConfigMutable()->ledstrip_beacon_period_ms = cmsx_ledBeaconPeriod; + ledStripConfigMutable()->ledstrip_beacon_percent = cmsx_ledBeaconOnPercent; + ledStripConfigMutable()->ledstrip_beacon_armed_only = cmsx_ledBeaconArmedOnly; + ledStripConfigMutable()->ledstrip_visual_beeper = cmsx_ledVisualBeeper; + ledStripConfigMutable()->ledstrip_visual_beeper_color = cmsx_ledVisualBeeperColor; return 0; } static OSD_Entry cmsx_menuLedstripEntries[] = { - { "-- LED STRIP --", OME_Label, NULL, NULL, 0 }, - { "ENABLED", OME_Bool, NULL, &cmsx_FeatureLedstrip, 0 }, - { "PROFILE", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_LedProfile, LED_PROFILE_COUNT-1, ledProfileNames }, 0 }, - { "RACE COLOR", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_RaceColor, COLOR_COUNT-1, lookupTableLEDRaceColors }, 0 }, + { "-- LED STRIP --", OME_Label, NULL, NULL, 0 }, + { "ENABLED", OME_Bool, NULL, &cmsx_FeatureLedstrip, 0 }, + { "PROFILE", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_ledProfile, LED_PROFILE_COUNT - 1, ledProfileNames }, 0 }, + { "RACE COLOR", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_ledRaceColor, COLOR_COUNT - 1, lookupTableLedstripColors }, 0 }, + { "BEACON COLOR", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_ledBeaconColor, COLOR_COUNT -1, lookupTableLedstripColors }, 0 }, + { "BEACON PERIOD", OME_UINT16,NULL, &(OSD_UINT16_t){ &cmsx_ledBeaconPeriod, 50, 10000, 10 }, 0 }, + { "BEACON ON %", OME_UINT8, NULL, &(OSD_UINT8_t){ &cmsx_ledBeaconOnPercent, 0, 100, 1 }, 0 }, + { "BEACON ARMED ONLY",OME_Bool, NULL, &cmsx_ledBeaconArmedOnly, 0 }, + { "VISUAL BEEPER", OME_Bool, NULL, &cmsx_ledVisualBeeper, 0 }, + { "VISUAL COLOR", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_ledVisualBeeperColor, COLOR_COUNT - 1, lookupTableLedstripColors }, 0 }, { "BACK", OME_Back, NULL, NULL, 0 }, { NULL, OME_END, NULL, NULL, 0 } }; diff --git a/src/main/io/ledstrip.c b/src/main/io/ledstrip.c index 784f3de950..c19b455cef 100644 --- a/src/main/io/ledstrip.c +++ b/src/main/io/ledstrip.c @@ -80,15 +80,15 @@ 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 previousBeaconColorIndex = COLOR_BLACK; -static uint8_t previousRaceColorIndex = COLOR_BLACK; -static timeUs_t raceColorUpdateTimeUs = 0; +static uint8_t previousProfileColorIndex = COLOR_UNDEFINED; void ledStripDisable(void); @@ -96,11 +96,12 @@ void ledStripDisable(void); #define MAX_TIMER_DELAY (5 * 1000 * 1000) -#define BEACON_FLASH_PERIOD_MS 1000 // 1000ms -#define BEACON_FLASH_ON_TIME 100 // 100ms -#define RACE_COLOR_UPDATE_INTERVAL_US 1e6 // normally updates when color changes but this is a 1 second forced update +#define PROFILE_COLOR_UPDATE_INTERVAL_US 1e6 // normally updates when color changes but this is a 1 second forced update -#define VISUAL_BEEPER_COLOR COLOR_ORANGE +#define VISUAL_BEEPER_COLOR COLOR_WHITE + +#define BEACON_FAILSAFE_PERIOD_US 250 // 2Hz +#define BEACON_FAILSAFE_ON_PERCENT 50 // 50% duty cycle #if LED_MAX_STRIP_LENGTH > WS2811_LED_STRIP_LENGTH # error "Led strip length must match driver" @@ -174,7 +175,12 @@ void pgResetFn_ledStripConfig(ledStripConfig_t *ledStripConfig) #else ledStripConfig->ledstrip_profile = LED_PROFILE_RACE; #endif - ledStripConfig->ledRaceColor = COLOR_ORANGE; + 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 @@ -582,7 +588,7 @@ static void applyLedWarningLayer(bool updateNow, timeUs_t *timer) } } else { if (isBeeperOn()) { - warningColor = &hsv[VISUAL_BEEPER_COLOR]; + warningColor = &hsv[ledStripConfig()->ledstrip_visual_beeper_color]; } } @@ -1081,34 +1087,64 @@ static void applyStatusProfile(timeUs_t now) { static uint8_t selectVisualBeeperColor(uint8_t colorIndex) { if (ledStripConfig()->ledstrip_visual_beeper && isBeeperOn()) { - return VISUAL_BEEPER_COLOR; + return ledStripConfig()->ledstrip_visual_beeper_color; } else { return colorIndex; } } -static void applyBeaconProfile(void) -{ - const bool beaconState = millis() % (BEACON_FLASH_PERIOD_MS) < BEACON_FLASH_ON_TIME; - uint8_t colorIndex = (beaconState) ? COLOR_WHITE : COLOR_BLACK; - colorIndex = selectVisualBeeperColor(colorIndex); +static void applySimpleProfile(timeUs_t currentTimeUs) +{ + static timeUs_t colorUpdateTimeUs = 0; + uint8_t colorIndex = COLOR_BLACK; + bool blinkLed = false; + bool visualBeeperOverride = true; + unsigned flashPeriod; + unsigned onPercent; - if (colorIndex != previousBeaconColorIndex) { - previousBeaconColorIndex = colorIndex; + if (IS_RC_MODE_ACTIVE(BOXBEEPERON) || failsafeIsActive()) { + // RX_SET or failsafe - force the beacon on and override the profile settings + blinkLed = true; + visualBeeperOverride = false; // prevent the visual beeper from interfering + flashPeriod = BEACON_FAILSAFE_PERIOD_US; + onPercent = BEACON_FAILSAFE_ON_PERCENT; + colorIndex = ledStripConfig()->ledstrip_visual_beeper_color; + } else { + switch (ledStripConfig()->ledstrip_profile) { + case LED_PROFILE_RACE: + colorIndex = ledStripConfig()->ledstrip_race_color; + break; + + case LED_PROFILE_BEACON: { + if (!ledStripConfig()->ledstrip_beacon_armed_only || ARMING_FLAG(ARMED)) { + flashPeriod = ledStripConfig()->ledstrip_beacon_period_ms; + onPercent = ledStripConfig()->ledstrip_beacon_percent; + colorIndex = ledStripConfig()->ledstrip_beacon_color; + blinkLed = true; + } + break; + } + + default: + break; + } + } + + if (blinkLed) { + const unsigned onPeriod = flashPeriod * onPercent / 100; + const bool beaconState = (millis() % flashPeriod) < onPeriod; + colorIndex = (beaconState) ? colorIndex : COLOR_BLACK; + } + + if (visualBeeperOverride) { + colorIndex = selectVisualBeeperColor(colorIndex); + } + + if ((colorIndex != previousProfileColorIndex) || (currentTimeUs >= colorUpdateTimeUs)) { setStripColor(&hsv[colorIndex]); ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb); - } -} - -static void applyRaceProfile(timeUs_t currentTimeUs) -{ - uint8_t colorIndex = selectVisualBeeperColor(ledStripConfig()->ledRaceColor); - // refresh the color if it changes or at least every 1 second - if ((colorIndex != previousRaceColorIndex) || (currentTimeUs >= raceColorUpdateTimeUs)) { - setStripColor(&hsv[colorIndex]); - ws2811UpdateStrip((ledStripFormatRGB_e) ledStripConfig()->ledstrip_grb_rgb); - previousRaceColorIndex = colorIndex; - raceColorUpdateTimeUs = currentTimeUs + RACE_COLOR_UPDATE_INTERVAL_US; + previousProfileColorIndex = colorIndex; + colorUpdateTimeUs = currentTimeUs + PROFILE_COLOR_UPDATE_INTERVAL_US; } } @@ -1127,7 +1163,7 @@ void ledStripUpdate(timeUs_t currentTimeUs) } else if (!IS_RC_MODE_ACTIVE(BOXLEDLOW)) { ledStripEnabled = true; } - + if (ledStripEnabled) { switch (ledStripConfig()->ledstrip_profile) { #ifdef USE_LED_STRIP_STATUS_MODE @@ -1136,14 +1172,12 @@ void ledStripUpdate(timeUs_t currentTimeUs) break; } #endif - case LED_PROFILE_RACE: { - applyRaceProfile(currentTimeUs); - break; - } + case LED_PROFILE_RACE: case LED_PROFILE_BEACON: { - applyBeaconProfile(); + applySimpleProfile(currentTimeUs); break; } + default: break; } @@ -1244,8 +1278,7 @@ void ledStripEnable(void) void ledStripDisable(void) { ledStripEnabled = false; - previousRaceColorIndex = COLOR_BLACK; - previousBeaconColorIndex = COLOR_BLACK; + previousProfileColorIndex = COLOR_UNDEFINED; setStripColor(&HSV(BLACK)); if (ledStripInitialised) { ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb); @@ -1264,16 +1297,4 @@ void setLedProfile(uint8_t profile) ledStripConfigMutable()->ledstrip_profile = profile; } } - -uint8_t getLedRaceColor(void) -{ - return ledStripConfig()->ledRaceColor; -} - -void setLedRaceColor(uint8_t color) -{ - if (color <= COLOR_DEEP_PINK) { - ledStripConfigMutable()->ledRaceColor = color; - } -} #endif diff --git a/src/main/io/ledstrip.h b/src/main/io/ledstrip.h index 49ebba14ab..0acdc496d4 100644 --- a/src/main/io/ledstrip.h +++ b/src/main/io/ledstrip.h @@ -176,13 +176,17 @@ typedef struct ledStripConfig_s { hsvColor_t colors[LED_CONFIGURABLE_COLOR_COUNT]; modeColorIndexes_t modeColors[LED_MODE_COUNT]; specialColorIndexes_t specialColors; - uint8_t ledstrip_visual_beeper; // suppress LEDLOW mode if beeper is on + uint8_t ledstrip_visual_beeper; uint8_t ledstrip_aux_channel; ioTag_t ioTag; ledStripFormatRGB_e ledstrip_grb_rgb; ledProfile_e ledstrip_profile; - colorId_e ledRaceColor; - + colorId_e ledstrip_race_color; + colorId_e ledstrip_beacon_color; + uint16_t ledstrip_beacon_period_ms; + uint8_t ledstrip_beacon_percent; + uint8_t ledstrip_beacon_armed_only; + colorId_e ledstrip_visual_beeper_color; } ledStripConfig_t; PG_DECLARE(ledStripConfig_t, ledStripConfig); @@ -230,5 +234,3 @@ void updateRequiredOverlay(void); uint8_t getLedProfile(void); void setLedProfile(uint8_t profile); -uint8_t getLedRaceColor(void); -void setLedRaceColor(uint8_t color);