feat(autoresearch): LPC845 SPI+DMA async driver validation harness (#3456) - #3503
Conversation
…3456) Phase 1 of the #3453 bench bring-up series. Adds the device-side + host-side plumbing to exercise `ARMHardwareSPIOutputDMA<>` (from #3454) on real LPC845 silicon via the AutoResearch RPC contract, following the same pattern as `--pwm-dma-cl` (#3468). Device-side (`examples/AutoResearch/AutoResearchSpiDma.h`, self-gated on `FL_IS_ARM_LPC_845 && FASTLED_LPC_SPI_DMA`) exposes three RPC handlers: - `dmaSpiTransferOnce(byte_count, byte_pattern)` — single-shot DMA transfer with CPU-poll wait; reports timing. - `dmaSpiTransferOverlap(byte_count, byte_pattern)` — kicks the stream then runs a `volatile` beacon-toggle counter until `done()`. Non-zero counter under DMA load is the affirmative async claim. - `dmaSpiMeasureSck(divider_hint)` — 512-byte burst; host computes effective SCK Hz via wall-clock (no SCT capture — that's #3015 territory). Wired into `AutoResearchLowMemory.h` with a compile-time `#error` if the user tries to combine `FASTLED_LPC_SPI_DMA` with `FASTLED_LPC_PWM_DMA` (both claim DMA0 and the LowMemory flash budget doesn't fit both). Host-side: - `--dma-spi` flag on `bash autoresearch`, LPC845-only, mutually exclusive with `--pwm-dma-cl` (both would fight over DMA0 channels). - New `_run_lpc_dma_spi_tests` phase entry in `ci/autoresearch/phases.py`. - `ci/autoresearch/test_lpc_dma_spi.py` test runner: 4 cases — transferOnce@32B, transferOnce@256B (crosses driver's DMA-vs-polled fast-path threshold at 16B), transferOverlap@512B (async proof), measureSck@512B (±25 % band vs. compile-time divider). The user compiles with `-DFASTLED_LPC_SPI_DMA=1` (add to platformio.ini or fbuild config) before running the wrapper. Silicon validation deferred to next hardware bring-up run — the harness compiles clean on host (WASM + `bash test --cpp` 344/344 green) and gates out on all non-LPC targets. Closes #3456 (harness deliverable). #3453 Phase 1 device-side plumbing done; Phase 2 (clockless SCT+DMA) was already delivered via `--pwm-dma-cl` (#3468). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR adds a Phase 1 SPI+DMA async driver validation harness for LPC845. It introduces a ChangesSPI+DMA Bench Harness
Estimated code review effort: 3 (Moderate) | ~30 minutes Sequence Diagram(s)sequenceDiagram
participant CLI as autoresearch CLI
participant Phases as phases.py
participant Bench as test_lpc_dma_spi.py
participant Device as LPC845 (AutoResearchSpiDma.h)
CLI->>Phases: --dma-spi flag
Phases->>Phases: validate mutual exclusion with --pwm-dma-cl
Phases->>Bench: uv run test_lpc_dma_spi.py --port <port>
Bench->>Device: send_rpc dmaSpiTransferOnce
Device-->>Bench: CSV result (timing)
Bench->>Device: send_rpc dmaSpiTransferOverlap
Device-->>Bench: CSV result (toggle count)
Bench->>Device: send_rpc dmaSpiMeasureSck
Device-->>Bench: CSV result (byte count, time)
Bench-->>Phases: exit code 0/1
Phases-->>CLI: return status
Possibly related issues
Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Closes #3456.
Summary
Phase 1 of the #3453 bench bring-up series. Adds the device-side + host-side plumbing to exercise
ARMHardwareSPIOutputDMA<>(from #3454) on real LPC845 silicon via the AutoResearch RPC contract, mirroring the pattern established by--pwm-dma-cl(#3468).Device-side
examples/AutoResearch/AutoResearchSpiDma.h, self-gated onFL_IS_ARM_LPC_845 && FASTLED_LPC_SPI_DMA, exposes three RPC handlers:dmaSpiTransferOnce(byte_count, byte_pattern)— single-shot DMA transfer with CPU-poll wait; reports timing.dmaSpiTransferOverlap(byte_count, byte_pattern)— kicks the stream then runs avolatilebeacon-toggle counter untildone(). Non-zero counter under DMA load is the affirmative async claim (proves the CPU was free to run application code while DMA drove SPI TX).dmaSpiMeasureSck(divider_hint)— 512-byte burst; host computes effective SCK Hz via wall-clock. No SCT input capture on SCK (that's LPC845-BRK: WS2812 loopback validation via SCT-capture RX channel #3015 Phase 3 territory).Wired into
AutoResearchLowMemory.hwith a compile-time#errorif the user tries to combineFASTLED_LPC_SPI_DMAwithFASTLED_LPC_PWM_DMA— both claim DMA0 channels and the LowMemory flash budget doesn't fit both.Host-side
--dma-spiflag onbash autoresearch, LPC845-only, mutually exclusive with--pwm-dma-cl(both would fight over DMA0 channels)._run_lpc_dma_spi_testsphase entry inci/autoresearch/phases.py.ci/autoresearch/test_lpc_dma_spi.pytest runner: 4 cases —transferOnce@32B— small transfer sanitytransferOnce@256B— crosses the driver's polled-vs-DMA fast-path threshold at 16BtransferOverlap@512B— affirmative async proof (requires non-zero beacon-toggle count)measureSck@512B— ±25% band vs. compile-time dividerCompile-time contract
The user compiles with
-DFASTLED_LPC_SPI_DMA=1(add toplatformio.inior fbuild config) before running the wrapper. Optional overrides:-DFASTLED_LPC_SPI_DMA_HARNESS_DATA_PIN=<N>(default 17)-DFASTLED_LPC_SPI_DMA_HARNESS_CLOCK_PIN=<N>(default 13)-DFASTLED_LPC_SPI_DMA_HARNESS_DIVIDER=<N>(default 6 → 4 MHz SCK on the 24 MHz LPC845 FRO)-DFASTLED_LPC_SPI_DMA_CHANNEL=4(SPI1 default per driver)Silicon status
Silicon validation deferred to the next hardware bring-up run — the harness compiles clean on host and gates out on all non-LPC targets. This PR delivers the plumbing that #3456 requested; the pass/fail bands themselves are only meaningful when run against real LPC845 hardware.
Test plan
bash compile wasm --examples AutoResearch— WASM compiles clean (gates correctly compile out on non-LPC)bash test --cpp --clean— 344/344 tests passbash lint— cleanbash autoresearch lpc845 --dma-spi— pending silicon accessRelated
--pwm-dma-clharness patternCo-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes