Skip to content

fix(rmt): correct TX open-drain handling and idle level#120

Merged
floitsch merged 1 commit into
patch-head-5.4.2from
floitsch/patch-head-5.4.2.fix-rmt
Jun 21, 2026
Merged

fix(rmt): correct TX open-drain handling and idle level#120
floitsch merged 1 commit into
patch-head-5.4.2from
floitsch/patch-head-5.4.2.fix-rmt

Conversation

@floitsch

Copy link
Copy Markdown
Member

Two related fixes in rmt_new_tx_channel() / rmt_tx_destroy() for the Toit RMT hardware tests on ESP32 and ESP32S3:

  1. Open-drain (pad_driver) was enabled for io_od_mode channels but never cleared, and gpio_output_disable() on channel deletion does not clear it. A pin previously used by an open-drain channel therefore stayed open-drain, so a later push-pull channel on the same pin could only drive the line low; with no pull-up this silently broke transmission and a dependent receiver hung forever. The configured drive mode is now established explicitly on create (od_enable/od_disable) and restored to push-pull on destroy.

  2. The initial idle level was keyed on io_loop_back -- which Toit sets on every channel -- instead of io_od_mode, so every push-pull output idled high. Transmitting with a done-level of 0 then switched the idle level just before tx_start, which the ESP32 receiver recorded as a spurious leading glitch. Key the high idle level on io_od_mode (the workaround's stated intent); push-pull channels now idle low and no longer glitch.

Together these fix the ESP32S3 rmt-test hang and the ESP32 rmt-test leading-glitch failures.

Two related fixes in rmt_new_tx_channel() / rmt_tx_destroy() for the Toit RMT
hardware tests on ESP32 and ESP32S3:

1. Open-drain (pad_driver) was enabled for io_od_mode channels but never cleared,
   and gpio_output_disable() on channel deletion does not clear it. A pin
   previously used by an open-drain channel therefore stayed open-drain, so a
   later push-pull channel on the same pin could only drive the line low; with no
   pull-up this silently broke transmission and a dependent receiver hung forever.
   The configured drive mode is now established explicitly on create
   (od_enable/od_disable) and restored to push-pull on destroy.

2. The initial idle level was keyed on io_loop_back -- which Toit sets on every
   channel -- instead of io_od_mode, so every push-pull output idled high.
   Transmitting with a done-level of 0 then switched the idle level just before
   tx_start, which the ESP32 receiver recorded as a spurious leading glitch. Key
   the high idle level on io_od_mode (the workaround's stated intent); push-pull
   channels now idle low and no longer glitch.

Together these fix the ESP32S3 rmt-test hang and the ESP32 rmt-test leading-glitch
failures.
@floitsch

Copy link
Copy Markdown
Member Author

TBR.

@floitsch floitsch merged commit ded0ae5 into patch-head-5.4.2 Jun 21, 2026
2 checks passed
@floitsch floitsch deleted the floitsch/patch-head-5.4.2.fix-rmt branch June 21, 2026 12:13
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