fix(ESP32 RMT): size RMT memory block per chip, use DMA where available (fixes BLE/WiFi ghost pixels)#923
Open
darkgrue wants to merge 1 commit into
Open
Conversation
config.mem_block_symbols = 192 in NeoEsp32RmtXMethod.h gives the RMT ping-pong half-buffer only ~96 symbols (~120us at WS2812x 800Kbps). NimBLE and WiFi event handlers run at higher interrupt priority than the RMT refill ISR and routinely preempt for longer, leaving the data line idle past the ~300us LED latch threshold and producing ghost pixels at 8-pixel intervals. On chips with DMA-capable RMT (ESP32-S3, ESP32-P4), enable flags.with_dma and request a generous DMA buffer; DMA decouples the buffer from RMT channel memory and from ISR refill timing entirely. On chips without DMA support (ESP32, S2, C3, C6, H2, C5), request the maximum mem_block_symbols a single TX channel can borrow from its group (SOC_RMT_TX_CANDIDATES_PER_GROUP * SOC_RMT_MEM_WORDS_PER_CHANNEL), giving the ISR the most slack each chip can provide. Also removes NEOPIXELBUS_RMT_INT_FLAGS, a leftover macro from the legacy IDF v3/v4 driver that is unused by this IDF v5 channel API. Fixes Makuna#921 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a BLE or WiFi connection is active on ESP32, sparse LED patterns produce ghost pixels at index N+8 for every addressed pixel N. The defect scales with strip position and is introduced during RMT transmission, not in the software color buffer.
Root cause:
config.mem_block_symbols = 192inNeoEsp32RmtXMethod.hgives the RMT ping-pong half-buffer only ~96 symbols, ~120 µs at WS2812x 800 Kbps. NimBLE and WiFi event handlers run at higher interrupt priority than the RMT refill ISR and routinely preempt for longer, leaving the data line idle past the ~300 µs LED latch threshold. The LEDs latch the partial frame, producing a false frame boundary at every 8-pixel interval.Fixes #921.
Note on PR #922
PR #922 ("fixes #921") modified
src/internal/methods/NeoEsp32RmtMethod.honmaster. That file is the legacy ESP-IDF v3/v4 RMT driver and does not contain the code described in #921 at all — the reporter built against the CORE3 branch'sNeoEsp32RmtXMethod.h(the ESP-IDF v5rmt_tx_channel_config_tdriver), which only exists on this branch. #922 doesn't address this issue; this PR does.Solution
Rather than requiring a user-set build flag, size the RMT buffer automatically per chip at compile time:
SOC_RMT_SUPPORT_DMA): setflags.with_dma = trueand request a generous 512-symbol DMA buffer. DMA decouples the buffer from RMT channel memory and from ISR refill timing entirely, so preemption no longer matters.mem_block_symbolsa single TX channel can borrow from all TX-capable channels in its group (SOC_RMT_TX_CANDIDATES_PER_GROUP * SOC_RMT_MEM_WORDS_PER_CHANNEL) — 512 on original ESP32 (8×64), 256 on S2 (4×64), 96 on C3/C6/H2/C5 (2×48). This gives the RMT ISR the most slack each chip's hardware can provide.Also removes
NEOPIXELBUS_RMT_INT_FLAGS, a leftover macro from the legacy IDF v3/v4 driver (still used inCore_2_x/NeoEsp32RmtMethod.h) that was copied into this file but is unused by the IDF v5 channel API — called out as dead/confusing code in the issue.Testing
Verified by real
pio runbuilds (not just syntax checks) against the actual ESP-IDF/Arduino headers for every distinct code path this change introduces:esp32devesp32-s2-saola-1esp32-s3-devkitc-1esp32-c3-devkitm-1esp32-c6-devkitc-1Hardware verification of the ghost-pixel fix itself (BLE connected, single pixel set) still requires physical hardware, per the original issue repro.