-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
Update esp32.RMT module to the new API #16293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
6b14d89 to
1cb1e6c
Compare
9247d15 to
77ed23a
Compare
|
Thank you. I have been trying to figure this out but with little success. When working with neopixel strips I noticed that the legacy RMT IDF4 + Bitstream has some oddness (extra bytes, noise) and the legacy bitbang is erratic on startup. With C++ and ESPIDF I get good results with RMT IDF 5, but haven't been able to integrated with micropython or bitbang. If I can help with testing, let me know. Thanks again |
|
@ricksorensen testing would be great, since my use cases are limited here (433MHz key fob emulator). At least in this application, it has been working perfectly. The only known showstopper is calling RMT.disable() while transmitting, sometimes it panics with a WDT interrupt timeout, but only on ESP32, not in an ESP32-C3 board. Smeels more like an ESP-IDF issue. |
|
@elvis-epx I can get some evaluation done at the end of this week.... fingers crossed. IDF 5.2.2 is the plan (I can try others, but I have some issues with 5.2.3 and 5.3.1 that I have not resolved yet) Today (Friday 20241129 CST) I ran a few simple experiments. Boards:
I then tried simple
wiith subsequent writes giving A few experiments seem to indicate that if number of bytes sent is 1 or 2 then the timeout occurs. On the C3 RMT printed some more debug information:
I will try some other experiments at end of weekend possibly. Thanks again- Rick |
|
@ricksorensen Have pushed an additional commit 9cdb7dd that should fix at least items 2.1 and 3. We weren't waiting on TX completion for long enough and were treating the timeout as a fatal error, not running the cleanup code lines right after. |
|
@elvis-epx Thank you all, this is a great feature update. hope it can be released in the stable version soon. Does the ESP32-C3 require specific IO pins to properly use the RMT function for receiving infrared signals? |
As far as I know, any pin capable of input can do RMT. I have only one C3 (devkit-rust-1) and play with the onboard led pin (Pin 7). |
|
@ricksorensen good catch, one possible workaround is to keep the channel for the bitstream after the first use (do not delete it, so not calling rmt_del_channel() and not exercising the offending behavior). |
|
Yes that is a work around- to store and save the allocated RTM channel for
a bitstream. Can you change the pin assigned to an active RTM channel?
Maybe (extreme pseudo code:)
if no bitstream RTM, instantiate one
else assign new pin to RTM
transfer data
do not delete/disable channel/encoder/ .
Add new function to release bitstream.
…On Wed, Dec 4, 2024 at 5:50 PM Elvis Pfützenreuter ***@***.***> wrote:
@ricksorensen <https://github.com/ricksorensen> good catch, one possible
workaround is to keep the channel for the bitstream after the first use (do
not delete it, so not calling rmt_del_channel() and not exercising the
offending behavior).
—
Reply to this email directly, view it on GitHub
<#16293 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA5QPQESRXQNHGRRCVWRZKD2D6IN7AVCNFSM6AAAAABSLVHTG6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKMJYG44TCMBXGU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
Rick Sorensen
***@***.***
651-470-5511
|
|
@ricksorensen no, if the pin changes, we need to release the channel and create another one, so there is extra logic. We can try calling esp_rom_gpio_connect_out_signal() before rmt_del_channel(), if it works, it is a cheaper solution. |
|
The RTM class seems to work well-
Worth trying again, but I believe the problem is the pin reset in the
del_channel function which adds PULL_UP to the pin. Maybe if the
micropython API is to allow independent bitstream we could override the
del_channel function and remove the pin reset?
Most boards use bitbanging for bitstream I believe. The micropython
bitbang for ESP32 seems to work- but it has a timing glitch on the first
few pulses--- maybe from the RTOS? I have been fiddling with the bitbang
too but have not figured out how to get the timing on the first few bit
pulses correct.
EDIT: I just noticed that the rmt_del_channel on ESP IDF 5.3.1 does NOT reset the pin. Unfortunately I cannot get 5.3.1 to work for my builds yet (not knowledgable enough on esp tools).. I have changed the rmt_common.c function on 5.2.2 to remove the reset and will test tomorrow.
…On Wed, Dec 4, 2024 at 6:34 PM Elvis Pfützenreuter ***@***.***> wrote:
@ricksorensen <https://github.com/ricksorensen> no, if the pin changes,
we need to release the channel and create another one, so there is extra
logic. We can try calling esp_rom_gpio_connect_out_signal() before
rmt_del_channel(), if it works, it is a cheaper solution.
—
Reply to this email directly, view it on GitHub
<#16293 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA5QPQD4VAJNSHS4H4NETFL2D6NSXAVCNFSM6AAAAABSLVHTG6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKMJYHAZTSMZVGA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
Rick Sorensen
***@***.***
651-470-5511
|
|
@ricksorensen nice, so this moves the ball to ESP-IDF court. It is not the only issue stemming from ESP-IDF in this PR (see FIXMEs). Have tried changing the position of esp_rom_gpio_connect_out_signal() without success (nothing changes or the problem is worsened). Delaying channel release is also not a perfect solution because a) suppose a use case where 2 or more pins are bitstream'ed in parallel b) the pull up still happens, albeit in a delayed moment, so it would only solve the problem for the rather narrow case that only 1 pin is bitstream'ed. |
|
I have an ad hoc work around which only affects EDIT: @elvis-epx I think I figured out how to include the I have not verified the 5.3.1 config. |
|
I have keen anticipation for this as my application requires high speed temporal dithering of dozens of neopixels. A solution that does not block the main core while data is streaming is critical. Any solution that also minimizes setup and teardown associated with each stream is ideal, as there need to be hundreds of streams per second for flicker-free dithering Thank you for your efforts. |
|
@seanmpuckett Rember there are only a finite number of RMT channels- I believe 8 on ESP32 and ESP32S3 and only 2 on ESP32C3 (single mcu too) . |
6bcd481 to
4d77fa6
Compare
|
@ricksorensen pushed additonal commit with your suggested changes, confirmed they fixed the issue here as well. |
|
@ricksorensen tested with ESP-IDF 5.3.2 with the help of PR #15733. The long pulse problem reappears since gpio_reset_pin() was moved from rmt_common.c to rmt_tx.c, and calling base->destroy() directly no longer avoids it. |
projectgus
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for being patient while waiting for more review comments, @elvis-epx
I haven't tested this on a device yet, but this looks like a really good improvement in the driver. I have a couple of suggestions/comments.
|
This relates and if the case points to an ESP IDF issue: https://forum.arduino.cc/t/esp32s3-rmt-no-free-tx-channels-opening-third-channel/1310503 My prior builds all used 5.4.2 , trying to build with 5.5.1 to see if the behavior changes. ... no change sadly. |
Thanks @ricksorensen, that does sound like the same issue. If so then seems like it'd be enough for MicroPython to change the |
|
Better check with @elvis-epx about the reason for setting it to 64 |
I believe it's always been 64 in MicroPython, because this is the RAM block size on original ESP32 (and maybe S2?) Block size of 48 is a hardware change on the newer SoCs. |
The ESP-IDF documentation recommends the minimum to be 64 when DMA is not used. https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/rmt.html#rmt-resource-allocation "If DMA is not used, this field controls the size of the dedicated memory block owned by the channel, which should be at least 64." We can change the minimum/defaults to |
|
Thanks for that information @elvis-epx and @projectgus. If you look at https://docs.espressif.com/projects/esp-idf/en/stable/esp32c3/api-reference/peripherals/rmt.html#rmt-resource-allocation "If DMA is not used, this field controls the size of the dedicated memory block owned by the channel, which should be at least 48." I think @elvis-epx suggestion to use |
Just sent a commit amending this. |
|
Should this be updated in The RMT instance in machine_bitstream is short lived so may not be as important. |
Good catch, amended the commit. |
projectgus
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me, thanks for persisting with this PR @elvis-epx!
Have also confirmed no more issues allocating both TX channels on ESP32-C6.
dpgeorge
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for persisting with this PR. It looks good now!
The current `esp32.RMT` class uses a legacy API from ESP-IDF 4.x. The ESP-IDF 5.x offers a new API, which is overall better, and easier to implement the RX side in the future. This commit updates the module and the documentation, preserving the current MicroPython RMT API as much as possible. The bitstream RMT implementation was updated as well, since ESP-IDF does not allow firmware to reference legacy and new APIs at the same time (it resets right after boot with an error message, even if neither module is imported). The documentation is updated accordingly. Signed-off-by: Elvis Pfutzenreuter <[email protected]>


Summary
The current esp32.RMT module uses a legacy API from ESP-IDF 4.x. The ESP-IDF 5.x offers a new API, which is overall better, and easier to implement the RX side in the future. This PR updates the module and the documentation, preserving the current MicroPython RMT API as much as possible.
The bitstream RMT implementation was updated as well, since ESP-IDF does not allow an image to reference legacy and new APIs at the same time (it resets right after boot with an error message, even if neither module is imported).
Testing
Tested on ESP32, ESP32-S3, ESP32-C3 and ESP32-C6. (Commenters may have tested on other variants.) We have tested all aspects of the RMT API and all seem to work fine.