Skip to content

feat(channels): add LPC DefaultBus<> specializations (#3450 B4)#3451

Merged
zackees merged 1 commit into
masterfrom
feat/3450-channels-default-bus-lpc
Jun 30, 2026
Merged

feat(channels): add LPC DefaultBus<> specializations (#3450 B4)#3451
zackees merged 1 commit into
masterfrom
feat/3450-channels-default-bus-lpc

Conversation

@zackees

@zackees zackees commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

Adds LPC DefaultBus<> specializations in src/fl/channels/bus.h. Resolves blocker B4 from the #3450 meta — the in-fastled3 piece of the LPC compile + autoresearch + channels-API restoration.

  • DefaultBus<ClocklessChipset>Bus::BIT_BANG for the whole LPC family (FL_IS_ARM_LPC). LPC8xx / LPC11Uxx / LPC15xx have no parallel-IO clockless peripheral; clockless output already routes through the shared M0 cycle-counted C++ driver (FASTLED_M0_USE_C_IMPLEMENTATION in src/platforms/arm/lpc/led_sysdefs_arm_lpc.h), which is exactly what Bus::BIT_BANG names. Plugging the trait is a no-op at the hardware level — it just stops the channels-API selector from hitting the unspecialized primary template.
  • DefaultBus<SpiChipsetConfig>Bus::SPI for LPC845 / LPC804 only. Those chips ship the hardware SPI driver in src/platforms/arm/lpc/spi_arm_lpc.h (UM11029 SPI peripheral block, SPI0 @ 0x40058000, SPI1 @ 0x4005C000 on LPC845). LPC11xx / LPC15xx have separate SPI register layouts (meta: LPC dev roadmap — Stages 3 + 4 (port completion, family expansion) #2845 Stage 4) and intentionally fall through to the unspecialized primary — a link error there is the right signal that no SPI driver is wired.

Scope of #3450 covered

This is B4. The other three blockers from the meta are cross-repo and tracked separately:

  • B1 — fbuild matcher rejected hyphenated nxp-lpc GitHub URL form: fix(core): match nxp-lpc (hyphenated GitHub form) in platform parser fbuild#900 (open).
  • B2framework-arduino-lpc8xx tarball checksum mismatch from the 2026-06-28 org transfer: needs an upstream re-record alongside the next fbuild release.
  • B3 — Editable pip install -e ~/dev/fbuild on Windows fails because rust-toolchain.toml's host-unspecified 1.94.1 pin selects windows-gnu and rust-lld can't find -lcfgmgr32: fbuild-side fix.

#3450 stays open until B1–B3 and the #3300 hardware bring-up also flip.

Test plan

  • bash lint — clean (Python, C++ via fastled-lint, JS, meson, root-pio lockdown, size thresholds — all green)
  • bash test --cpp — 340/340 passed in 77.9s
  • LPC hardware compile (bash compile lpc845brk --examples Blink) — gated on B1/B2 landing per the meta; cannot validate end-to-end on this machine until fbuild 2.3.15 ships

Closes #3450 (B4 acceptance box only — meta stays open for the remaining blockers).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Improved automatic bus selection on supported LPC platforms.
    • Clockless chipsets now use bit-banged communication by default on LPC targets.
    • SPI chipsets now default to SPI on LPC 845 and LPC 804 devices.
  • Bug Fixes

    • Reduced the need for manual bus configuration on these platform variants.

`src/fl/channels/bus.h` declared `DefaultBus<>` specializations for
STUB/WASM, ESP32 (RMT / FLEX_IO), and Teensy 4.x (FLEX_IO). LPC had
none, so a channels-API consumer that resolved through
`DefaultBus<ClocklessChipset>::value` on an LPC build hit an
unspecialized primary template — silent missing default, not a clean
selection.

Add the LPC routing:

- `DefaultBus<ClocklessChipset>` -> `Bus::BIT_BANG` for the whole
  LPC family. There is no parallel-IO clockless peripheral on LPC8xx
  / LPC11Uxx / LPC15xx; clockless output goes through the shared M0
  cycle-counted C++ driver gated by `FASTLED_M0_USE_C_IMPLEMENTATION`
  in `led_sysdefs_arm_lpc.h`, which is exactly what `Bus::BIT_BANG`
  names. The existing LPC `ClocklessController` template already
  routes through that same engine, so this is a no-op at the
  hardware level — it just plugs the missing trait.

- `DefaultBus<SpiChipsetConfig>` -> `Bus::SPI` for LPC845 / LPC804
  only. Those parts ship the hardware SPI driver in
  `src/platforms/arm/lpc/spi_arm_lpc.h` (UM11029 SPI peripheral block,
  base 0x40058000 / 0x4005C000). LPC11xx / LPC15xx have separate SPI
  register layouts (#2845 Stage 4) and intentionally fall through to
  the unspecialized primary — a link error there is the right signal
  that no SPI driver is wired yet.

This is B4 from the #3450 meta. B1 (fbuild matcher PR
FastLED/fbuild#900), B2 (`framework-arduino-lpc8xx` tarball checksum
mismatch from the 2026-06-28 org transfer), and B3 (editable-install
rust-toolchain pin on Windows) all live in fbuild / upstream and are
tracked separately on the meta. B4 is the only in-fastled3 blocker.

Tests: `bash test --cpp` — 340/340 passed. Compile validation on real
LPC hardware is gated on the fbuild fixes landing (per the meta).

Closes #3450 B4 (one of four acceptance boxes; meta stays open until
B1-B3 + #3300 hardware path also flip).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9e9d31d1-a935-4ca9-ad85-a33f2e5c4be1

📥 Commits

Reviewing files that changed from the base of the PR and between ec3f33c and 246e5c1.

📒 Files selected for processing (1)
  • src/fl/channels/bus.h

📝 Walkthrough

Walkthrough

Adds platform-specific DefaultBus template specializations for ARM LPC targets in src/fl/channels/bus.h. ClocklessChipset defaults to Bus::BIT_BANG under FL_IS_ARM_LPC, and SpiChipsetConfig defaults to Bus::SPI for LPC845/LPC804 variants only. No other logic changed.

Changes

LPC DefaultBus Specialization

Layer / File(s) Summary
DefaultBus specializations for LPC
src/fl/channels/bus.h
Adds DefaultBus<ClocklessChipset> mapped to Bus::BIT_BANG for FL_IS_ARM_LPC, and DefaultBus<SpiChipsetConfig> mapped to Bus::SPI for FL_IS_ARM_LPC_845/FL_IS_ARM_LPC_804.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Possibly related PRs

  • FastLED/FastLED#2429: Both PRs modify the same DefaultBus template specializations in src/fl/channels/bus.h for ClocklessChipset and SpiChipsetConfig.

Poem

A rabbit hops on LPC ground,
Bits banged out without a sound. 🐇
SPI wires for 845 and 804,
Default bus routes shut the door
On compile gaps we'd seen before.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately describes the new LPC DefaultBus specializations.
Linked Issues check ✅ Passed The changes implement B4 by routing LPC clockless to BIT_BANG and LPC845/LPC804 SPI to Bus::SPI.
Out of Scope Changes check ✅ Passed The patch is limited to the LPC DefaultBus specializations described in the issue.
✨ 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 feat/3450-channels-default-bus-lpc

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.

@zackees
zackees merged commit 1874d0f into master Jun 30, 2026
10 of 12 checks passed
@zackees
zackees deleted the feat/3450-channels-default-bus-lpc branch June 30, 2026 20:32
@fastled-project-sync fastled-project-sync Bot moved this to Triage in FastLED Tracker Jun 30, 2026
@fastled-project-sync fastled-project-sync Bot moved this from Triage to Done in FastLED Tracker Jun 30, 2026
zackees added a commit that referenced this pull request Jun 30, 2026
)

Wires LPC845 into the runtime channels-API dispatch path. The legacy
template clockless engine in `clockless_arm_lpc_pwm_dma.h` was
unreachable from `BusTraits<Bus::X>::instancePtr()` → `ChannelManager`
because no `IChannelDriver` subclass wrapped it. This change lifts the
peripheral onto the channels API, matching the structural pattern
established by `ChannelEngineObjectFLED` on Teensy 4.

New driver tree:

    src/platforms/arm/lpc/drivers/sct_dma/
      channel_engine_lpc_sct_dma.h        — IChannelDriver subclass
      channel_engine_lpc_sct_dma.cpp.hpp  — impl (scaffold + state machine)
      bus_traits.h                        — BusTraits<Bus::BIT_BANG>
      _build.cpp.hpp                      — unity build entry

Plus the platform dispatch wiring:

    src/platforms/arm/lpc/channel_drivers_lpc.impl.hpp  — new fragment
    src/platforms/arm/lpc/_build.cpp.hpp                — pull in sct_dma/
    src/platforms/channel_drivers.impl.cpp.hpp          — add FL_IS_ARM_LPC arm

Routing decisions:

- Registers under `Bus::BIT_BANG` to match `DefaultBus<ClocklessChipset>
  = Bus::BIT_BANG` that landed for LPC in PR #3451. The portable Bus
  enum has no `SCT_DMA` slot; the channels-API convention is that the
  peripheral is the dispatch boundary, not the protocol mode, so reusing
  `BIT_BANG` for the LPC parallel-IO clockless peripheral is consistent
  with `Bus::FLEX_IO` covering Teensy FlexPWM AND ESP32 LCD_CAM/I2S/PARLIO.
- `Capabilities(true, false)` — clockless only. LPC's SCT does not drive
  SPI; the LPC845 SPI block is a separate peripheral with its own DMA
  engine in `spi_arm_lpc_dma.h` (PR #3454). This is the documented
  "different-peripheral-same-protocol" exception to the parallel-IO
  unification rule in `src/fl/channels/README.md`.
- `canHandle()` filters to clockless WS2812-range chipsets (total bit
  period 1000-2500 ns) — same convention as ObjectFLED.

**Scaffold status.** The channels-API surface (canHandle / enqueue /
show / poll / capabilities / name) is in. The actual SCT match-register
programming + 3-channel DMA chunk-stream lift from
`clockless_arm_lpc_pwm_dma.h` is intentionally a documented `TODO(3459)`
block in `show()`/`poll()`. The state machine transitions through
`READY → BUSY → DRAINING → READY` so the manager doesn't stall, but
`show()` does not actually program the SCT in v1. This mirrors the
scaffold convention used for `rx_sct_capture.h::begin()` (#3015) and
`spi_arm_lpc_dma.h` (PR #3454) — channels-API plumbing first, peripheral
body next.

The structural lift required for the follow-up is itemised in the
`TODO(3459)` comment: convert `LpcSctTicks<NS>` from compile-time
template helper to runtime helper, hoist
`configureSct/configureDma/startDmaChunk/waitDmaChunk` out of the
templated `ClocklessController`, and iterate enqueued channels through
the lifted helper (single-strip v1 just takes the first; multi-strip
parallel is #2879).

Host-compile clean: `bash test --cpp` 340/340 passed. The new files
self-gate on `FL_IS_ARM_LPC_845`, so default builds on every other
platform are unaffected. Untested on silicon — same blockers as #3454
on the bench-validation side (#3300 echo bring-up still open). fbuild
matcher (#3450 B1) IS resolved in fbuild 2.3.15 which just landed in
master, so the LPC compile path itself can be exercised once #3450 B2
(framework-arduino-lpc8xx tarball checksum) clears.

Implements #3459 scaffold. Issue stays open until the `TODO(3459)`
show()/poll() body lands and at least one on-device frame transmits
through the channels-API path.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[META] LPC8xx compile + autoresearch + channels API end-to-end restoration — all blockers

1 participant