Skip to content

feat(radio): support faster RGB led timings on compatible hardware#7144

Merged
pfeerick merged 4 commits into
mainfrom
3djc/rgb-leds
Jun 23, 2026
Merged

feat(radio): support faster RGB led timings on compatible hardware#7144
pfeerick merged 4 commits into
mainfrom
3djc/rgb-leds

Conversation

@3djc

@3djc 3djc commented Mar 2, 2026

Copy link
Copy Markdown
Collaborator

Several manufacturers are using RGB leds that, while supporting 'standard' ws2812 timings, are designed for faster timings. This introduces support for those faster native timings.

Summary by CodeRabbit

  • Refactor
    • Migrated addressable RGB LED support from the previous WS2812 implementation to the standardized RGBLEDs driver across STM32 boards and the simulator.
    • Updated LED buffering, update/DMA handling, and initialization flow to use the RGBLEDs interface for consistent behavior across targets.
  • Chores
    • Adjusted target build settings to use RGBLEDs-specific LED limits and timing options (including 900ns where enabled).

Comment thread radio/src/targets/pa01/CMakeLists.txt Outdated
Comment thread radio/src/targets/common/arm/stm32/stm32_ws2812.cpp Outdated
@pfeerick pfeerick changed the title Introduce support for faster RGB leds feat(rgb): support faster timings on compatible hardware Mar 11, 2026
@pfeerick pfeerick changed the title feat(rgb): support faster timings on compatible hardware feat(firmware): support faster RGB led timings on compatible hardware Mar 11, 2026
@pfeerick pfeerick added the firmware General radio firmware issue, not colorlcd or B&W specific label Mar 11, 2026
@pfeerick pfeerick added this to the 3.0 milestone Mar 11, 2026
@raphaelcoeffic

Copy link
Copy Markdown
Member

Looks OK to me, but is it really required to rename everything? Most drivers I've seen still use that terminology (ws2812), since this is the part that started it all.

@3djc

3djc commented Mar 14, 2026

Copy link
Copy Markdown
Collaborator Author

I was not planning to, but pfeerick had me rename:D

@pfeerick pfeerick changed the title feat(firmware): support faster RGB led timings on compatible hardware feat(radio): support faster RGB led timings on compatible hardware Mar 20, 2026
@pfeerick pfeerick self-requested a review May 8, 2026 03:41
@pfeerick

Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dd898f10-a079-45bf-a835-5cf4cc7e0c59

📥 Commits

Reviewing files that changed from the base of the PR and between 5435133 and 4970695.

📒 Files selected for processing (3)
  • radio/src/boards/generic_stm32/rgb_leds.cpp
  • radio/src/boards/rm-h750/bsp_io.cpp
  • radio/src/edgetx.cpp
✅ Files skipped from review due to trivial changes (1)
  • radio/src/boards/rm-h750/bsp_io.cpp
🚧 Files skipped from review as they are similar to previous changes (2)
  • radio/src/edgetx.cpp
  • radio/src/boards/generic_stm32/rgb_leds.cpp

📝 Walkthrough

Walkthrough

This PR migrates the STM32 RGB LED driver from the ws2812-specific API to a generalized rgbleds API. The core driver is rewritten with new timing/DMA constants and initialization logic. All board implementations, build configurations, and the simulator are updated to use the new API naming (macros, functions, and driver sources).

Changes

RGBLEDS Driver Migration

Layer / File(s) Summary
API Contract Definition
radio/src/targets/common/arm/stm32/stm32_rgbleds.h
Macros renamed WS2812_RGB/WS2812_GRBRGBLEDS_RGB/RGBLEDS_GRB, WS2812_BYTES_PER_LEDRGBLEDS_BYTES_PER_LED, WS2812_TRAILING_RESETRGBLEDS_TRAILING_RESET. Functions renamed ws2812_*rgbleds_* for init, update, DMA ISR, busy-check, and buffer accessors.
Core Driver Implementation
radio/src/targets/common/arm/stm32/stm32_rgbleds.cpp
Timing/DMA macros updated to RGBLEDS_* constants. Debug facility refactored with RGBLEDS_DBG_*. DMA buffer sized with RGBLEDS_DMA_*. Initialization (rgbleds_init) computes color offsets and configures timer/DMA. Buffer accessors (rgbleds_set_color_in_buf, rgbleds_get_color_in_buf, rgbleds_get_state_in_buf) use computed offsets. Control APIs (rgbleds_is_busy, rgbleds_update) manage DMA/timer state with debug GPIO signaling.
Board Integration
radio/src/boards/generic_stm32/rgb_leds.cpp, radio/src/boards/rm-h750/bsp_io.cpp, radio/src/edgetx.cpp, radio/src/targets/pa01/board.cpp, radio/src/targets/st16/board.cpp
Headers switched to stm32_rgbleds.h. Buffer sizing changed to RGBLEDS_BYTES_PER_LED. Flush logic updated to use rgbleds_is_busy() and rgbleds_update(). Hardware init calls rgbleds_init() with RGBLEDS_GRB. LED API helpers (rgbSetLedColor, rgbGetLedColor, etc.) updated to use rgbleds_*_in_buf functions. DMA interrupt handler calls rgbleds_dma_isr().
Build Configuration
radio/src/targets/*/CMakeLists.txt
Source files switched from stm32_ws2812.cpp to stm32_rgbleds.cpp in horus, pa01, pl18, st16, t15pro, taranis, tx16smk3. Compile definitions changed WS2812_MAX_LEDSRGBLEDS_MAX_LEDS in pa01, st16, tx15, tx16smk3. RGB_LEDS_900NS timing define added in pa01, t15pro, taranis (gx12), tx15, tx16smk3 when FUNCTION_SWITCHES_WITH_RGB enabled. Taranis CMake option description updated from WS2812 to RGBLEDS.
Simulator Implementation
radio/src/targets/simu/led_driver.cpp
Buffer sizing macros changed from WS2812_BYTES_PER_LED/WS2812_MAX_LEDS to RGBLEDS_BYTES_PER_LED/RGBLEDS_MAX_LEDS. Helper functions rgbSetLedColor and rgbGetLedColor updated to use RGBLEDS_BYTES_PER_LED for indexing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

enhancement ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: introducing support for faster RGB LED timings on compatible hardware.
Description check ✅ Passed The description explains the purpose (faster RGB LED timings) but lacks detail on scope, implementation approach, or testing. It partially addresses the template but is minimal.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 3djc/rgb-leds

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@radio/src/boards/generic_stm32/rgb_leds.cpp`:
- Around line 81-85: The seqlock window is left open: snapshotting _commit_seq
once then memcpy(_back_colors) can copy mid-write; change to a read-verify loop
using _commit_seq as the seqlock: repeatedly read seq = _commit_seq, skip if
odd, memcpy(_back_colors -> _led_colors), then verify that _commit_seq hasn’t
changed (seq == _commit_seq) before setting _consumed_seq = seq; only update
_consumed_seq after the successful verify so you never consume a torn frame.
Ensure you reference and update the same _commit_seq and _consumed_seq variables
and memcpy _back_colors into _led_colors inside that loop.

In `@radio/src/targets/common/arm/stm32/stm32_rgbleds.cpp`:
- Around line 245-250: rgbleds_get_color_in_buf assumes GRB order and always
reads pixel[1], pixel[0], pixel[2]; change it to use the configured channel
offsets (_r_offset, _g_offset, _b_offset) when indexing the per-LED pixel buffer
so it mirrors rgbleds_set_color_in_buf behavior: compute const uint8_t* pixel =
&buf[led * RGBLEDS_BYTES_PER_LED] then read pixel[_r_offset], pixel[_g_offset],
pixel[_b_offset] (combining into the same 24-bit order the function returns) and
keep the early bounds check on led against _led_strip_len.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cb9f969c-8f8a-4de2-a562-241c6e7c7484

📥 Commits

Reviewing files that changed from the base of the PR and between a2aeab9 and 7d9198a.

📒 Files selected for processing (16)
  • radio/src/boards/generic_stm32/rgb_leds.cpp
  • radio/src/boards/rm-h750/bsp_io.cpp
  • radio/src/edgetx.cpp
  • radio/src/targets/common/arm/stm32/stm32_rgbleds.cpp
  • radio/src/targets/common/arm/stm32/stm32_rgbleds.h
  • radio/src/targets/horus/CMakeLists.txt
  • radio/src/targets/pa01/CMakeLists.txt
  • radio/src/targets/pa01/board.cpp
  • radio/src/targets/pl18/CMakeLists.txt
  • radio/src/targets/simu/led_driver.cpp
  • radio/src/targets/st16/CMakeLists.txt
  • radio/src/targets/st16/board.cpp
  • radio/src/targets/t15pro/CMakeLists.txt
  • radio/src/targets/taranis/CMakeLists.txt
  • radio/src/targets/tx15/CMakeLists.txt
  • radio/src/targets/tx16smk3/CMakeLists.txt

Comment thread radio/src/boards/generic_stm32/rgb_leds.cpp
Comment thread radio/src/targets/common/arm/stm32/stm32_rgbleds.cpp
@pfeerick

Copy link
Copy Markdown
Member

@3djc Did you ever test this on the GX12 or T15Pro? Out of T15Pro, TX16SMK3 and GX12, this seems to make the GX12 customisable switches flicker and carry on when they should be static, and the T15Pro gimbal rings and customisable switch leds go crazy... TX16SMK3 is the only one behaving properly. On 2.12.2 the T15Pro and GX12 are both fine.

@3djc

3djc commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator Author

Yes, they worked fine at the time. Likey tested the 2.12 version, but it should not matter. Will retry

@3djc

3djc commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator Author

Not too sure what I was under the day I tested, should have taken a note, because that must have been good stuff !!

Sorry for that, tested tx16smk3, tx15, t15pro and gx12 ok

@3djc

3djc commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator Author

t22 added and checked

@pfeerick

Copy link
Copy Markdown
Member

Not too sure what I was under the day I tested, should have taken a note, because that must have been good stuff !!

Sorry for that, tested tx16smk3, tx15, t15pro and gx12 ok

Aw... I wanna know also! 🤣 Thanks JC :)

@pfeerick pfeerick merged commit 0f5bc9b into main Jun 23, 2026
40 checks passed
@pfeerick pfeerick deleted the 3djc/rgb-leds branch June 23, 2026 02:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

firmware General radio firmware issue, not colorlcd or B&W specific hardware support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants