Skip to content

feat(rgb): add optional non-blocking lighting and live LED control - #27

Draft
Fefedu973 wants to merge 3 commits into
peppapighs:devfrom
Fefedu973:codex/pr-rgb
Draft

Fefedu973 wants to merge 3 commits into
peppapighs:devfrom
Fefedu973:codex/pr-rgb

Conversation

@Fefedu973

Copy link
Copy Markdown

Important

This is part 3 of 3 split from #24. It is intentionally opened as a draft and is currently stacked on #25 and #26, so GitHub shows their prerequisite commits too. The RGB implementation itself is commit b074559. I will rebase it onto dev after the prerequisites land and will not mark it ready before the resulting RGB-only diff is green.

Context

This draft addresses #6 and is opened early so the architecture can be discussed before merge, especially the maintainer's concerns about scan-loop performance, current draw, and the difference between per-key RGB and underglow.

Scope

  • Optional portable RGB core and a small non-blocking backend API.
  • Static, breathing, rainbow and rainbow-wave effects.
  • A live mode where the host controls every LED.
  • RAW HID capability negotiation plus frame/color/effect/brightness commands.
  • Persistence for compact settings; live frames are deliberately RAM-only.
  • First hardware backend: STM32F723, WS2812 on TIM2 channel 1 using DMA.
  • Explicit logical-key, physical-chain and spatial LED topology in keyboard metadata.

Performance concern

RGB is compile-time opt-in. A keyboard without an rgb metadata block does not compile the renderer/backend, allocate frame buffers, or schedule rgb_task().

The portable layer never bit-bangs LEDs. rgb_backend_submit() must copy/queue a frame and return immediately; the STM32F723 backend uses timer DMA and completes asynchronously. Animation and transfer cadence are separate from matrix scanning. Host live frames are assembled in staging memory and become visible atomically only after every 60-byte chunk arrives, so partial/late packets cannot tear the active frame.

The draft has strict host tests for effect math and topology and has been built both with RGB enabled on KBHE and disabled on an existing HE60 target. Before ready-for-review, the rebased branch will be remeasured against the final prerequisite commits.

Current-draw concern

Brightness is a board-owned setting applied in the core before submission. KBHE deliberately defaults to 50/255 rather than full output. Suspend sends a black frame and pauses animation. Live frames cannot bypass the global brightness scaling.

This draft does not claim to provide an electrical current measurement or a universal safe current limit: that limit depends on LED type, count, PCB power path and USB budget. I would like maintainer feedback on whether the schema should also require a board-specific hard maximum in addition to the conservative default before this leaves draft.

Per-key versus underglow

The renderer is not tied to the KBHE serpentine chain. Metadata separates:

  • host-visible logical LED order;
  • physical chain order (led_index_map);
  • spatial positions used by effects (led_position);
  • optional key association (key_to_led).

KBHE uses one LED per key. The separation is intended to let an underglow board describe LEDs that have positions but no key association, without creating a second renderer/backend API. This is another point where feedback is welcome while the PR is draft.

HID/API design

Hosts must first call GET_RGB_CAPABILITIES (0x7F) rather than infer RGB support from a firmware version. Basic effect and brightness commands are small fixed reports. Live per-LED control uses chunked 64-byte RAW HID reports and publishes only complete frames. No live frame is written to Flash, avoiding wear and input stalls.

Validation completed on the isolated stack

  • strict C host tests for renderer/effect behavior and topology mapping;
  • deterministic metadata/schema generation tests;
  • KBHE RGB build: 44,744 bytes Flash, 26,232 bytes RAM;
  • existing HE60 non-RGB build: 38,936 bytes Flash, 14,420 bytes RAM;
  • ELF inspection confirmed ADC and RGB DMA buffers are in DMA-accessible AXI SRAM, not STM32F723 DTCM.

Dependency/rebase plan

  1. feat(kbhe): add KBHE 75HE target and required STM32F723 backend #25 lands (STM32F723 + KBHE only).
  2. feat(gamepad): add a selectable standards-based HID gamepad mode #26 lands (independent HID gamepad).
  3. Rebase this branch onto the new dev, resolve metadata migrations once, rerun host and both target builds, then replace the measurements above and mark ready.

Until then, please treat this as an architecture/RFC draft rather than a merge candidate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant