-
Notifications
You must be signed in to change notification settings - Fork 221
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
Async RMT Tx not working with >64 PulseCodes #1779
Comments
So, I dug a bit into the let cycles = sequence.len() / 64;
for i in 0..cycles {
channel
.transmit(sequence[i * 64..(i + 1) * 64])
.await
.unwrap();
}
channel
.transmit(sequence[cycles * 64..])
.await
.unwrap(); |
Couldn't one do an async wait for the RMT channel being ready to send the next chunk? In the |
Thanks for filing this! Closely related to my current musings in esp-rs/esp-hal-community#4 |
I've been digging into this as well in #1768. It seems the 64 symbol limit was acknowledged in the original commit in #787 I can send unlimited symbols with fixed memory usage - no need for any buffers - main...tschundler:esp-hal:async-led-iterator I noticed the async implementation doesn't read any more from the input buffer / iterator. This weekend I'm trying to extend my changes to the async trait also also to the smart LEDs hal. Trying without interrupts, unless the content is less than 64 symbols, it doesn't start sending until I press the reset button. |
Trying to address the 64 symbol limit in esp-rs#1779. Having troubles, I tried disabling the interrupts so it just polls the device, but the transmission never actually starts until I reset the controller.
Spending most of today fussing with this, I can only seem to get it to work without interrupts, just forcing polling by having it call It seems at least for LED purposes there isn't enough time to refill the buffer with the overhead restarting the task after an interrupt. There should be time for ~7,000 instructions to run. By adding some panics, often it is time to refill the buffer on the first time the poll is called. (I'm building with Also I noticed when I call in a loop, sometimes the first time has an underrun, while subsequent runs are OK Perhaps the RMT buffer needs to be refilled in the interrupt and the async routine refills a buffer that is read in the interrupt? |
It's a known limitation that the async implementation won't handle sending more pulse codes than the buffer can take: Lines 1173 to 1175 in 5d6354c
Lines 1166 to 1168 in 5d6354c
Refilling the buffer is very time critical - I'm not surprised it doesn't work via wakers. It might work with just an interrupt handler refilling the buffer and waking the waker once it's completely done. Depending on the number of pulses sent and how often that is done it might be okay to use the blocking API - this will block other tasks from running until all the pulses are clocked out but depending on how time sensitive other tasks are that might be okay |
Removed the "bug" label since it's working as documented. However, it's certainly a valid feature request |
I was switching my project from manual interrupt handling to using embassy. In the process I also switched from blocking to async RMT. Before, I was sending about 150*24=3000
PulseCode
s on each transmission without issues to control an LED strip. With the async implementation, the strip wasnt getting any input apparently. I used parts of theembassy_rmt
example to reproduce this and check for which array sizes the RMT would stop working completely. At 65 PulseCodes, my example stopped working, so 64 seems to be the sweet spot.This makes some sense as the RAM blocks for each RMT channel hold up to 64 data points according to the ESP32 documentation. So, I guess, something which the Blocking implementation is doing right is going wrong on the Async side. I haven't had the time to look into the implementation further. Maybe someone has an insight on this?
Here are some snippets of the program:
The text was updated successfully, but these errors were encountered: