Skip to content

fix(spi): preserve the final word of full ESP32 DMA receives - #138

Merged
floitsch merged 1 commit into
patch-head-5.4.2from
floitsch/esp32-spi-dma-rx-limit
Oct 27, 2026
Merged

floitsch merged 1 commit into
patch-head-5.4.2from
floitsch/esp32-spi-dma-rx-limit

Conversation

@floitsch

@floitsch floitsch commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Classic ESP32 SPI DMA reception can lose its final four bytes when the controller fills the configured receive capacity. A standalone ESP-IDF target driven by an nRF5340 reproduces this without Toit, including at just four bytes and across the 4092-byte DMA descriptor boundary.

Program the hardware RX limit one word beyond the requested capacity while keeping DMA descriptors and allocations at the original size. Correct the length counter against that hardware limit, then clamp the reported length to the caller's capacity. TX-only and non-DMA paths retain their existing limits; the adjustment is specific to classic ESP32 and cannot overflow the register.

Add an internal-loopback regression covering four SPI modes, capacities from 4 to 8192 bytes, short/exact/overlong transfers (including one-bit boundaries), fresh payloads, and guard bytes. The 156 cases pass on an ESP32 DevKitC. On the original driver the test fails because a 31-bit transfer is reported as 32 bits. The separate external-controller baseline reports payload failures in 80 of 112 word-aligned cases, with the final word left untouched.

This replaces the allocation-padding workaround in toitlang/toit#3320. No Toit runtime is needed to run this regression. The Toit integration also passes all 511 nRF/ESP32 paired SPI fixture requests with the allocation-padding workaround removed.

@floitsch

Copy link
Copy Markdown
Member Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

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 Oct 27, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6b1ac8d7-f722-4811-adb5-621d02970d22
Commits

Reviewing files that changed from the base of the PR and between 0a6f1d9 and e87eea5.

Files selected for processing: 2
  • components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c
  • components/hal/spi_slave_hal_iram.c

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

The SPI slave HAL adjusts the programmed RX bit limit for qualifying classic ESP32 DMA transfers and corrects the reported received length. A new ESP32 test covers receive lengths, data, and guard bytes across SPI modes and buffer capacities.

Changes

SPI slave DMA receive handling

Layer / File(s) Summary
RX limit calculation and result correction
components/hal/spi_slave_hal_iram.c
For qualifying classic ESP32 DMA transfers, the HAL adds 32 bits to the programmed RX limit. Result correction uses that limit and clamps the count to the configured bit length when needed.
Receive length and buffer validation
components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c
An ESP32 test covers four SPI modes, eight receive capacities, and wire-length offsets. It checks the reported length, complete four-byte words, and 16 bytes beyond the configured capacity.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: Minimal · up to e87ee

No actionable issue is established for the SPI DMA receive fix; it is mergeable after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed 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%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within survi… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: preserving the final word during full ESP32 DMA receives.
Description check Passed The description directly explains the ESP32 SPI DMA bug, the implementation approach, and the regression coverage.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 3 functions across 2 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@floitsch
floitsch merged commit 8a8b4a7 into patch-head-5.4.2 Oct 27, 2026
3 checks passed
@floitsch
floitsch deleted the floitsch/esp32-spi-dma-rx-limit branch October 27, 2026 22:08
floitsch added a commit to toitlang/toit that referenced this pull request Oct 27, 2026
An exactly full classic ESP32 SPI target DMA receive can lose its final
word. Update ESP-IDF to toitware/esp-idf#138,
which fixes the hardware receive limit and length accounting without
enlarging DMA buffers. The Toit allocation-padding workaround has been
removed.

Keep the hardware regression cases for exact capacities of 4088, 4092,
4096, 4100, 4104, and 8192 bytes in modes 0 and 2, using two payload
patterns. The controller holds chip select across DMA-sized chunks so it
can exercise those capacities on a classic ESP32.
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