diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index d38b54e9fa9..ab74303b7cd 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -72,6 +72,29 @@ if(PCB STREQUAL X7 AND PCBREV STREQUAL LR3PRO) else() option(POWER_LED_BLUE "Override Power LED to be normally Blue" OFF) endif() +option(POWER_LED_GREEN "Override Power LED to be normally Green" OFF) +option(POWER_LED_CYAN "Override Power LED to be normally Cyan" OFF) +option(POWER_LED_YELLOW "Override Power LED to be normally Yellow" OFF) +option(POWER_LED_MAGENTA "Override Power LED to be normally Magenta" OFF) +option(POWER_LED_WHITE "Override Power LED to be normally White" OFF) + +set(POWER_LED_OPTIONS + POWER_LED_BLUE + POWER_LED_GREEN + POWER_LED_CYAN + POWER_LED_YELLOW + POWER_LED_MAGENTA + POWER_LED_WHITE +) +set(POWER_LED_OPTION_COUNT 0) +foreach(POWER_LED_OPTION ${POWER_LED_OPTIONS}) + if(${POWER_LED_OPTION}) + math(EXPR POWER_LED_OPTION_COUNT "${POWER_LED_OPTION_COUNT} + 1") + endif() +endforeach() +if(POWER_LED_OPTION_COUNT GREATER 1) + message(FATAL_ERROR "Only one POWER_LED_* color option can be enabled") +endif() # since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags. set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).") @@ -549,9 +572,11 @@ if(USBJ_EX) ) endif() -if(POWER_LED_BLUE) - add_definitions(-DPOWER_LED_BLUE) -endif() +foreach(POWER_LED_OPTION ${POWER_LED_OPTIONS}) + if(${POWER_LED_OPTION}) + add_definitions(-D${POWER_LED_OPTION}) + endif() +endforeach() foreach(FILE ${TARGET_SRC}) set(SRC targets/${TARGET_DIR}/${FILE} ${SRC}) diff --git a/radio/src/boards/generic_stm32/led_driver.cpp b/radio/src/boards/generic_stm32/led_driver.cpp index d2596efe4ba..986556ec69a 100644 --- a/radio/src/boards/generic_stm32/led_driver.cpp +++ b/radio/src/boards/generic_stm32/led_driver.cpp @@ -115,31 +115,57 @@ __weak void ledOff() #endif } -__weak void ledRed() +static void ledRgb(bool red, bool green, bool blue) { ledOff(); #if defined(LED_RED_GPIO) - GPIO_LED_GPIO_ON(LED_RED_GPIO); + if (red) GPIO_LED_GPIO_ON(LED_RED_GPIO); #endif #if defined(LED_RED2_GPIO) - GPIO_LED_GPIO_ON(LED_RED2_GPIO); + if (red) GPIO_LED_GPIO_ON(LED_RED2_GPIO); +#endif +#if defined(LED_GREEN_GPIO) + if (green) GPIO_LED_GPIO_ON(LED_GREEN_GPIO); #endif +#if defined(LED_BLUE_GPIO) + if (blue) GPIO_LED_GPIO_ON(LED_BLUE_GPIO); +#endif + +} + +__weak void ledRed() +{ + ledRgb(true, false, false); } __weak void ledGreen() { - ledOff(); -#if defined(LED_GREEN_GPIO) - GPIO_LED_GPIO_ON(LED_GREEN_GPIO); -#endif + ledRgb(false, true, false); } __weak void ledBlue() { - ledOff(); -#if defined(LED_BLUE_GPIO) - GPIO_LED_GPIO_ON(LED_BLUE_GPIO); -#endif + ledRgb(false, false, true); +} + +__weak void ledYellow() +{ + ledRgb(true, true, false); +} + +__weak void ledMagenta() +{ + ledRgb(true, false, true); +} + +__weak void ledCyan() +{ + ledRgb(false, true, true); +} + +__weak void ledWhite() +{ + ledRgb(true, true, true); } #if defined(FUNCTION_SWITCHES_RGB_LEDS) diff --git a/radio/src/boards/jumper-h750/board.cpp b/radio/src/boards/jumper-h750/board.cpp index fe955f4f669..cb1ba3ddd2b 100644 --- a/radio/src/boards/jumper-h750/board.cpp +++ b/radio/src/boards/jumper-h750/board.cpp @@ -18,7 +18,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - + #include "stm32_adc.h" #include "stm32_gpio.h" #include "stm32_i2c_driver.h" @@ -198,7 +198,7 @@ void boardOff() // RTC->BKP0R = SHUTDOWN_REQUEST; pwrOff(); - // We reach here only in forced power situations, such as hw-debugging with external power + // We reach here only in forced power situations, such as hw-debugging with external power // Enter STM32 stop mode / deep-sleep // Code snippet from ST Nucleo PWR_EnterStopMode example #define PDMode 0x00000000U @@ -212,7 +212,7 @@ void boardOff() /* Set SLEEPDEEP bit of Cortex System Control Register */ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); - + // To avoid HardFault at return address, end in an endless loop while (1) { diff --git a/radio/src/boards/jumper-h750/board.h b/radio/src/boards/jumper-h750/board.h index 354d4bbd9b6..34f05e31713 100644 --- a/radio/src/boards/jumper-h750/board.h +++ b/radio/src/boards/jumper-h750/board.h @@ -165,6 +165,10 @@ void ledOff(); void ledRed(); void ledBlue(); void ledGreen(); +void ledYellow(); +void ledMagenta(); +void ledCyan(); +void ledWhite(); // LCD driver void lcdSetInitalFrameBuffer(void* fbAddress); diff --git a/radio/src/boards/rm-h750/board.cpp b/radio/src/boards/rm-h750/board.cpp index c5f0e11ee75..5f7b16caba2 100644 --- a/radio/src/boards/rm-h750/board.cpp +++ b/radio/src/boards/rm-h750/board.cpp @@ -18,7 +18,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - + #include "stm32_adc.h" #include "stm32_gpio.h" #include "stm32_i2c_driver.h" @@ -167,6 +167,7 @@ void boardInit() timersInit(); usbChargerInit(); + #if !defined(POWER_LED_BLUE) ledBlue(); #else @@ -227,7 +228,7 @@ void boardOff() pwrOff(); - // We reach here only in forced power situations, such as hw-debugging with external power + // We reach here only in forced power situations, such as hw-debugging with external power // Enter STM32 stop mode / deep-sleep // Code snippet from ST Nucleo PWR_EnterStopMode example #define PDMode 0x00000000U @@ -241,7 +242,7 @@ void boardOff() /* Set SLEEPDEEP bit of Cortex System Control Register */ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); - + // To avoid HardFault at return address, end in an endless loop while (1) { diff --git a/radio/src/boards/rm-h750/board.h b/radio/src/boards/rm-h750/board.h index 46f4ef02f46..5db1e7bf0d4 100644 --- a/radio/src/boards/rm-h750/board.h +++ b/radio/src/boards/rm-h750/board.h @@ -163,6 +163,10 @@ void ledOff(); void ledRed(); void ledBlue(); void ledGreen(); +void ledYellow(); +void ledMagenta(); +void ledCyan(); +void ledWhite(); // LCD driver void lcdSetInitalFrameBuffer(void* fbAddress); diff --git a/radio/src/edgetx.h b/radio/src/edgetx.h index 80eb1fb0321..ab010de7009 100644 --- a/radio/src/edgetx.h +++ b/radio/src/edgetx.h @@ -570,15 +570,60 @@ constexpr uint8_t OPENTX_START_NO_CHECKS = 0x04; #if STATUS_LEDS #define LED_ERROR_BEGIN() ledRed() - // Green "ready to use" if available, unless overridden by user or mfg preference -#if !defined(POWER_LED_BLUE) && (defined(LED_GREEN_GPIO) || defined(LED_STRIP_GPIO)) - #define LED_ERROR_END() ledGreen() - #define LED_BIND() ledBlue() + + // Check discrete GPIO capability. STATUS_LED_STRIP means a board's + // led_driver.cpp drives the status LED through an RGB strip and can + // produce any color, so it satisfies every check below. + #define LED_HAS_RED (defined(LED_RED_GPIO) || defined(LED_RED2_GPIO) || defined(STATUS_LED_STRIP)) + #define LED_HAS_GREEN (defined(LED_GREEN_GPIO) || defined(STATUS_LED_STRIP)) + #define LED_HAS_BLUE (defined(LED_BLUE_GPIO) || defined(STATUS_LED_STRIP)) + + #define LED_HAS_YELLOW (LED_HAS_RED && LED_HAS_GREEN) + #define LED_HAS_MAGENTA (LED_HAS_RED && LED_HAS_BLUE) + #define LED_HAS_CYAN (LED_HAS_GREEN && LED_HAS_BLUE) + #define LED_HAS_WHITE (LED_HAS_RED && LED_HAS_GREEN && LED_HAS_BLUE) + +#if defined(POWER_LED_WHITE) && !LED_HAS_WHITE + #error "POWER_LED_WHITE requires red, green and blue status LED GPIOs (or a strip-driven status LED)" +#elif defined(POWER_LED_MAGENTA) && !LED_HAS_MAGENTA + #error "POWER_LED_MAGENTA requires red and blue status LED GPIOs (or a strip-driven status LED)" +#elif defined(POWER_LED_YELLOW) && !LED_HAS_YELLOW + #error "POWER_LED_YELLOW requires red and green status LED GPIOs (or a strip-driven status LED)" +#elif defined(POWER_LED_CYAN) && !LED_HAS_CYAN + #error "POWER_LED_CYAN requires green and blue status LED GPIOs (or a strip-driven status LED)" +#elif defined(POWER_LED_GREEN) && !LED_HAS_GREEN + #error "POWER_LED_GREEN requires a green status LED GPIO (or a strip-driven status LED)" +#endif + +#if defined(POWER_LED_WHITE) && LED_HAS_WHITE + #define LED_ERROR_END() ledWhite() + #define LED_BIND() ledBlue() +#elif defined(POWER_LED_MAGENTA) && LED_HAS_MAGENTA + #define LED_ERROR_END() ledMagenta() + #define LED_BIND() ledBlue() +#elif defined(POWER_LED_YELLOW) && LED_HAS_YELLOW + #define LED_ERROR_END() ledYellow() + #define LED_BIND() ledBlue() +#elif defined(POWER_LED_CYAN) && LED_HAS_CYAN + #define LED_ERROR_END() ledCyan() + #define LED_BIND() ledBlue() +#elif defined(POWER_LED_GREEN) && LED_HAS_GREEN + #define LED_ERROR_END() ledGreen() + #define LED_BIND() ledBlue() #else -// Either green is not an option, or blue is preferred "ready to use" color - #define LED_ERROR_END() ledBlue() + // No POWER_LED_* override set - default to green if available, else blue. + #if !defined(POWER_LED_BLUE) && LED_HAS_GREEN + #define LED_ERROR_END() ledGreen() + #define LED_BIND() ledBlue() + #else + #define LED_ERROR_END() ledBlue() + #endif #endif #else +#if defined(POWER_LED_BLUE) || defined(POWER_LED_GREEN) || defined(POWER_LED_CYAN) || \ + defined(POWER_LED_YELLOW) || defined(POWER_LED_MAGENTA) || defined(POWER_LED_WHITE) + #error "POWER_LED_* requires a board with a status LED (STATUS_LEDS)" +#endif #define LED_ERROR_BEGIN() #define LED_ERROR_END() #endif diff --git a/radio/src/options.h b/radio/src/options.h index 1c01e8abd26..6ffd1c1b3f7 100644 --- a/radio/src/options.h +++ b/radio/src/options.h @@ -105,6 +105,21 @@ static const char * const options[] = { #endif #if defined(POWER_LED_BLUE) "power_led_blue", +#endif +#if defined(POWER_LED_GREEN) + "power_led_green", +#endif +#if defined(POWER_LED_CYAN) + "power_led_cyan", +#endif +#if defined(POWER_LED_YELLOW) + "power_led_yellow", +#endif +#if defined(POWER_LED_MAGENTA) + "power_led_magenta", +#endif +#if defined(POWER_LED_WHITE) + "power_led_white", #endif nullptr //sentinel }; diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 0a5bbb22e60..c3f77eaefc0 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -190,9 +190,11 @@ void ledInit(); void ledOff(); void ledRed(); void ledBlue(); -#if defined(LED_GREEN_GPIO) - void ledGreen(); -#endif +void ledGreen(); +void ledYellow(); +void ledMagenta(); +void ledCyan(); +void ledWhite(); // LCD driver diff --git a/radio/src/targets/pa01/CMakeLists.txt b/radio/src/targets/pa01/CMakeLists.txt index 888410fd6c2..e78a717445f 100644 --- a/radio/src/targets/pa01/CMakeLists.txt +++ b/radio/src/targets/pa01/CMakeLists.txt @@ -39,6 +39,7 @@ set(SIZE_TARGET_MEM_DEFINE "MEM_SIZE_SDRAM1=8192") set(FIRMWARE_STRIP_BOOTLOADER YES) add_definitions(-DPCBPA01 -DPCBHORUS -DPCBFLYSKY) +add_definitions(-DSTATUS_LED_STRIP) add_definitions(-DBATTERY_CHARGE) add_definitions(-DSTM32_SUPPORT_32BIT_TIMERS) add_definitions(-DFIRMWARE_QSPI) diff --git a/radio/src/targets/pa01/board.cpp b/radio/src/targets/pa01/board.cpp index 95ea26d215c..9d107c6f0e1 100644 --- a/radio/src/targets/pa01/board.cpp +++ b/radio/src/targets/pa01/board.cpp @@ -18,7 +18,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - + #include "stm32_adc.h" #include "stm32_gpio.h" #include "stm32_i2c_driver.h" @@ -149,7 +149,7 @@ bool pwrPressedDebounced() debouncedState = state; else lastState = state; - + return debouncedState; } @@ -182,7 +182,7 @@ void boardInit() adcInit(&_adc_driver); getADC(); - + flysky_gimbal_init(); usbInit(); rgbChargeInit(); // RTOS was not running, timer_create will prevent the ADC from reading. @@ -204,7 +204,7 @@ void boardInit() // Init debounce pwrPressedDebounced(); pwrPressedDebounced(); - + // Handle charging state if charger is active if (isChargerActive()) { static uint32_t adc_sample_time = 0; // Hardware ADC sample tick @@ -247,7 +247,7 @@ void boardInit() } } } - + // Second stage: Detect secondary long-press sequence while (1) { @@ -378,7 +378,7 @@ void boardInit() } } } -#endif +#endif #endif rgbLedInit(); rgbLedClearAll(); @@ -386,6 +386,12 @@ void boardInit() switchInit(); audioInit(); +#if !defined(POWER_LED_BLUE) + ledBlue(); +#else + ledGreen(); +#endif + #if defined(RTCLOCK) rtcInit(); // RTC must be initialized before rambackupRestore() is called #endif @@ -423,7 +429,7 @@ void boardOff() // RTC->BKP0R = SHUTDOWN_REQUEST; pwrOff(); - // We reach here only in forced power situations, such as hw-debugging with external power + // We reach here only in forced power situations, such as hw-debugging with external power // Enter STM32 stop mode / deep-sleep // Code snippet from ST Nucleo PWR_EnterStopMode example #define PDMode 0x00000000U @@ -437,7 +443,7 @@ void boardOff() /* Set SLEEPDEEP bit of Cortex System Control Register */ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); - + // To avoid HardFault at return address, end in an endless loop while (1) { @@ -456,7 +462,7 @@ int usbPlugged() debouncedState = state; else lastState = state; - + return debouncedState; } */ diff --git a/radio/src/targets/pa01/board.h b/radio/src/targets/pa01/board.h index 42a2b5bc765..dc31242e405 100644 --- a/radio/src/targets/pa01/board.h +++ b/radio/src/targets/pa01/board.h @@ -161,6 +161,10 @@ void ledOff(); void ledRed(); void ledBlue(); void ledGreen(); +void ledYellow(); +void ledMagenta(); +void ledCyan(); +void ledWhite(); // LCD driver void lcdSetInitalFrameBuffer(void* fbAddress); diff --git a/radio/src/targets/pa01/led_driver.cpp b/radio/src/targets/pa01/led_driver.cpp index 449d6e437ae..519d7009af4 100644 --- a/radio/src/targets/pa01/led_driver.cpp +++ b/radio/src/targets/pa01/led_driver.cpp @@ -69,3 +69,31 @@ void ledBlue() rgbSetLedColor(9, 0, 0, 20); rgbLedColorApply(); } + +void ledYellow() +{ + rgbSetLedColor(8, 20, 20, 0); + rgbSetLedColor(9, 20, 20, 0); + rgbLedColorApply(); +} + +void ledMagenta() +{ + rgbSetLedColor(8, 20, 0, 20); + rgbSetLedColor(9, 20, 0, 20); + rgbLedColorApply(); +} + +void ledCyan() +{ + rgbSetLedColor(8, 0, 20, 20); + rgbSetLedColor(9, 0, 20, 20); + rgbLedColorApply(); +} + +void ledWhite() +{ + rgbSetLedColor(8, 20, 20, 20); + rgbSetLedColor(9, 20, 20, 20); + rgbLedColorApply(); +} diff --git a/radio/src/targets/pl18/CMakeLists.txt b/radio/src/targets/pl18/CMakeLists.txt index 137c1620106..bc762503875 100644 --- a/radio/src/targets/pl18/CMakeLists.txt +++ b/radio/src/targets/pl18/CMakeLists.txt @@ -40,6 +40,7 @@ set(PCB_RF_BAUD 921600 CACHE STRING "INTERNAL_MODULE_BAUDRATE: ${RF_BAUD_RATE}") set_property(CACHE PCB_RF_BAUD PROPERTY STRINGS ${RF_BAUD_RATE}) add_definitions(-DPCBPL18 -DPCBFLYSKY) +add_definitions(-DSTATUS_LED_STRIP) add_definitions(-DBATTERY_CHARGE) add_definitions(-DSTM32_SUPPORT_32BIT_TIMERS) @@ -224,7 +225,7 @@ add_library(board OBJECT EXCLUDE_FROM_ALL targets/common/arm/stm32/trainer_driver.cpp targets/common/arm/stm32/spi_flash.cpp targets/common/arm/stm32/diskio_spi_flash.cpp - drivers/frftl.cpp + drivers/frftl.cpp ) set(FIRMWARE_SRC ${FIRMWARE_SRC} $) diff --git a/radio/src/targets/pl18/board.h b/radio/src/targets/pl18/board.h index 3c45038f3f8..48f897d6d25 100644 --- a/radio/src/targets/pl18/board.h +++ b/radio/src/targets/pl18/board.h @@ -184,6 +184,10 @@ void ledOff(); void ledRed(); void ledBlue(); void ledGreen(); +void ledYellow(); +void ledMagenta(); +void ledCyan(); +void ledWhite(); // LCD driver void lcdSetInitalFrameBuffer(void* fbAddress); diff --git a/radio/src/targets/pl18/led_driver.cpp b/radio/src/targets/pl18/led_driver.cpp index 8b909202fd0..1da21c252ed 100644 --- a/radio/src/targets/pl18/led_driver.cpp +++ b/radio/src/targets/pl18/led_driver.cpp @@ -58,3 +58,35 @@ void ledBlue() } rgbLedColorApply(); } + +void ledYellow() +{ + for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) { + rgbSetLedColor(i, 50, 50, 0); + } + rgbLedColorApply(); +} + +void ledMagenta() +{ + for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) { + rgbSetLedColor(i, 50, 0, 50); + } + rgbLedColorApply(); +} + +void ledCyan() +{ + for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) { + rgbSetLedColor(i, 0, 50, 50); + } + rgbLedColorApply(); +} + +void ledWhite() +{ + for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) { + rgbSetLedColor(i, 50, 50, 50); + } + rgbLedColorApply(); +} diff --git a/radio/src/targets/st16/board.h b/radio/src/targets/st16/board.h index cc95deef494..7035dca3864 100644 --- a/radio/src/targets/st16/board.h +++ b/radio/src/targets/st16/board.h @@ -144,6 +144,10 @@ void ledOff(); void ledRed(); void ledBlue(); void ledGreen(); +void ledYellow(); +void ledMagenta(); +void ledCyan(); +void ledWhite(); // LCD driver void lcdSetInitalFrameBuffer(void* fbAddress); diff --git a/radio/src/targets/stm32h7s78-dk/board.h b/radio/src/targets/stm32h7s78-dk/board.h index 215bd21393d..0d6b7bf0f0e 100644 --- a/radio/src/targets/stm32h7s78-dk/board.h +++ b/radio/src/targets/stm32h7s78-dk/board.h @@ -128,6 +128,10 @@ void ledOff(); void ledRed(); void ledBlue(); void ledGreen(); +void ledYellow(); +void ledMagenta(); +void ledCyan(); +void ledWhite(); // LCD driver void lcdSetInitalFrameBuffer(void* fbAddress);