Skip to content

feat: configurable and dimmable status (power) LEDs - #7806

Merged
pfeerick merged 13 commits into
mainfrom
3djc/pwm-power-led
Oct 7, 2026
Merged

pfeerick merged 13 commits into
mainfrom
3djc/pwm-power-led

Conversation

@3djc

@3djc 3djc commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator

Allow adjustment of power LED brightness, using similar controls as speaker volume, so that user using it for sims in darker rooms are not incommoded by power LED brightness. On TX16SMK3, the ambient light sensor can be used to drive the power LED brightness.

A few things to know:

  • H7 only, optimized to reduce IRQ load
  • ST16 and PA01 excluded as they have a different hardware setup
  • LED cannot be turned off, there is a minimum brightness
  • LED color continues to obey current functions (and this is compatible with existing compile flag)

Somewhat addresses and closes #7796
Closes #7454 by making this runtime configurable

@3djc 3djc added enhancement ✨ New feature or request firmware (fw) General radio firmware issue, not colorlcd or B&W specific labels Sep 18, 2026
@philmoz

philmoz commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

Will the average person associate the phrase 'Status LED' with the power button LED?

@pfeerick pfeerick changed the title feat(h7): dimmable status LED feat(h7): dimmable status (power) LED Sep 18, 2026
@3djc

3djc commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator Author

But it is more than a power led, it actually tells the status (booting, error, running), so I think we should name it for what it does. I won't fight over this tho

@Taxom

Taxom commented Sep 19, 2026

Copy link
Copy Markdown

One thought for future extensibility: would it make sense to structure the low-level PWM driver so it can eventually support independent per-channel duty levels, even if this PR only exposes a single overall brightness?

At the moment _led_gpio[2] + one shared _led_level works perfectly for dimming the current status color, but adding an RGB color override later would require changing the PWM engine itself.

Something like three internal channel levels (R/G/B), with the current API simply setting the active status channel(s) to the same brightness, could keep the behavior of this PR unchanged while making a future RGB override a much smaller addition.

I’m not suggesting adding RGB controls to this PR — just wondering if it is worth keeping the low-level implementation extensible while the driver is being introduced.

@3djc

3djc commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator Author

RGB would only work in a small subset of radio, where the led are close enough so that the color merges

@pfeerick pfeerick changed the title feat(h7): dimmable status (power) LED feat(h7): dimmable status (power) LEDs Sep 19, 2026
@Taxom

Taxom commented Sep 19, 2026

Copy link
Copy Markdown

This is what it looks like on the tx16s mk3.
изображение
изображение

@3djc 3djc added the rn: feature Feature to be highlighted in release notes label Sep 20, 2026
@3djc

3djc commented Sep 20, 2026 •

Copy link
Copy Markdown
Collaborator Author

I do not plan to do rgb because of MCU impact of it. A single led is about 0,5% CPU used, 3 would be 1,5 for lets be honest, a bling feature, I would rather keep MCU for useful stuff (btw, it is coded so that at full brightness, there is no impact at all (no interrupt generated))

I have however made a massive change:

  • at boot, the button is white (all 3 leds are on)
  • there is now a UI to choose which led is on for those 3 status: error, ready, transmitting
Capture d’écran 2026-09-20 à 11 11 22

Removed the now useless compile option for H7 codeline (but @pfeerick there will be likely impact on buddy for example)

@3djc 3djc changed the title feat(h7): dimmable status (power) LEDs feat(h7): configurable and dimmable status (power) LEDs Sep 20, 2026
@pfeerick

pfeerick commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

What about doing just the LED colour also for F4 (skip the brightness)? Then we can ditch the defines entirely :)

@3djc

3djc commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator Author

What about doing just the LED colour also for F4 (skip the brightness)? Then we can ditch the defines entirely :)

Should be able too, incomming

@pfeerick pfeerick added this to the 3.0 milestone Sep 25, 2026
@Taxom

Taxom commented Sep 25, 2026

Copy link
Copy Markdown

I was looking at the current PWM ISR and noticed that it runs at 8 kHz (250 Hz × 32 levels), and _led_pins_off() is currently called on every tick after _led_level, rather than only at the falling edge.
Would it make sense to at least use _led_tick == _led_level there?
Longer term, since all active status LED channels currently share the same duty cycle, could the timer be scheduled only for the ON and OFF edges instead of every PWM subdivision? That would reduce the interrupt rate from 8 kHz to about 500 Hz while keeping the same 250 Hz / 32-level brightness resolution.
It might also make independent RGB duties practical later: even with three different OFF edges it would still be at most about 1 kHz of timer events.

@pagrey

pagrey commented Sep 25, 2026

Copy link
Copy Markdown

This is a great addition, thanks for including the older radios and tying the status led to the module output!

I have a feeling allot of people will like the white power button when the radio boots and ask how they can choose that for normal operation. Would it be possible to add ledBoot to the color selections? It does appear white on the Zorro and Boxer but that might not be the best label if it appears different on other radios.

I appreciate all the work that went into this.

@3djc

3djc commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator Author

No, because you cannot do that before much later in the boot when SDcard gets mounted and you can read radio settings, so not an option for the boot color

@pagrey

pagrey commented Sep 25, 2026

Copy link
Copy Markdown

It was not my intention to change the boot color but to add white (the color show while booting) to the selection options for ready, error and transmitting. Since people will see the boot color every time they boot with this firmware they might want to select that color for normal operation. I hope that makes more sense.

@3djc

3djc commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator Author

Understood. I have already received comments that it is not white but light blue on mk3, and the perceived color will also be different on each radio model, something I have no intention to manage.

3djc and others added 9 commits October 7, 2026 00:19
Allow adjustment of power led brightness
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
All status LEDs light from boardInit until the radio reports itself ready,
which also shows at a glance that each LED works.

The colour of each phase - error, ready, transmitting - is then a setting,
defaulting to red, blue and green. Transmitting means a module is initialised
and sending frames. The stored 0 keeps meaning "the default for this phase",
so settings written before this behave as they did.
The Chinese, Taiwanese and Japanese status LED strings need 7 glyphs the
fonts did not carry: 就 绪 / 就 緒 / 緑 赤 青.
Storage is unchanged; Companion's spin box moves on the same 10% grid.
…ED_BLUE

The error / ready / transmitting colour choice now exists on every radio
whose status LED can show at least two colours: discrete GPIOs, or the RGB
strip on the PL18 family and PA01 (new status_led_rgb_strip hw_defs key).
Colours a radio lacks are hidden, and fall back to one it has. 128x64 radios
get the rows in radio setup; Companion derives the rows from the hw_defs JSON
instead of a board list.

With the colour a setting, the POWER_LED_BLUE build option goes. The boot
sites it drove on horus, taranis and pl18 now run the lamp test, and radios
with a single colour light it on error only, as before.

Radios without status LEDs are untouched.
T15-H7 landed on main after this branch was cut; its status_leds
hw_def enables STATUS_LED_SETTINGS, so RadioData gains the per-phase
colour fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The schema validation CI from #7872 rejects the status_led_rgb_strip
and status_led_pwm_timer* keys this branch adds to the leds block.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pfeerick and others added 2 commits October 7, 2026 00:47
Same status LED pins as the T15 Pro, with TIM7 free, so enable
STATUS_LED_PWM the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pfeerick
pfeerick force-pushed the 3djc/pwm-power-led branch from 8cafb85 to db2c3e1 Compare October 7, 2026 00:51
pfeerick and others added 2 commits October 7, 2026 00:57
The Slovak translation landed on main (#6830) after this branch was
cut, so it lacked the new TR_STATUS_LED* strings and broke the
simulator translation build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
T20 is a 512KB STM32F407xE radio like the others that got
-DUSE_FW_LTO=y in #7562, but was missed, leaving it under 1KB of
free flash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pfeerick pfeerick changed the title feat(h7): configurable and dimmable status (power) LEDs feat: configurable and dimmable status (power) LEDs Oct 7, 2026
@pfeerick

pfeerick commented Oct 7, 2026

Copy link
Copy Markdown
Member

LTGM on TX16SMK3, TX16S and T14... a very, very nice new feature! :)

@pfeerick
pfeerick merged commit 637cc48 into main Oct 7, 2026
58 checks passed
@pfeerick
pfeerick deleted the 3djc/pwm-power-led branch October 7, 2026 03:44
pfeerick added a commit that referenced this pull request Oct 7, 2026
Opt V15 into the configurable/dimmable status LEDs from #7806, like V12:

- -DSTATUS_LED_PWM, with TIM2 (free, APB1, own IRQ) as the software PWM
  timer in v15.json. TIM7 can't be used as on V12, it is the DShot
  tester's frame timer.
- Drop V15's own led_driver.cpp. It was a copy of the generic driver
  from before #7806 whose strong symbols override the generic weak ones,
  so PWM would never be used. Without PWM the generic driver behaves the
  same (same pins, CFS strip start is 0).
- boardInit() uses ledBoot() instead of setting the blue LED directly.
- Regenerate yaml_datastructs_v15.cpp for statusLedDim/statusLedSrc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pfeerick added a commit that referenced this pull request Oct 7, 2026
Opt V15 into the configurable/dimmable status LEDs from #7806, like V12:

- -DSTATUS_LED_PWM, with TIM2 (free, APB1, own IRQ) as the software PWM
  timer in v15.json. TIM7 can't be used as on V12, it is the DShot
  tester's frame timer.
- Drop V15's own led_driver.cpp. It was a copy of the generic driver
  from before #7806 whose strong symbols override the generic weak ones,
  so PWM would never be used. Without PWM the generic driver behaves the
  same (same pins, CFS strip start is 0).
- boardInit() uses ledBoot() instead of setting the blue LED directly.
- Regenerate yaml_datastructs_v15.cpp for statusLedDim/statusLedSrc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement ✨ New feature or request firmware (fw) General radio firmware issue, not colorlcd or B&W specific rn: feature Feature to be highlighted in release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TX16S MK3: power/status LED brightness and RGB control via software PWM

5 participants