esp-rs / esp-hal

no_std Hardware Abstraction Layers for ESP32 microcontrollers
https://docs.esp-rs.org/esp-hal/
Apache License 2.0
717 stars 194 forks source link

Circular DMA does not handle wrap around correctly #2021

Open Dominaezzz opened 1 month ago

Dominaezzz commented 1 month ago

Someone brought this up in the matrix room but circular DMA transfers don't handle wrap around properly. Just thought I'd create an issue so other people know about it as well.

In the RX case, wrap around happens when the user doesn't read fast enough and the DMA runs out of space to write data to, causing the DMA to go through all the descriptors and coming back to the start (over and over again, since we don't enable check_owner). In the TX case, it happens when the user doesn't write fast enough, and the DMA runs out of data to transmit. In practice, the DMA just resends old data over and over again, since we don't enable check_owner.

Once this happens, the user has to drop and restart the transfer, but the current code doesn't do this. Each peripheral will have its quirks.

This is the code that needs updating on the RX side. https://github.com/esp-rs/esp-hal/blob/61bb24016651425e1535e71860973fb0097605eb/esp-hal/src/dma/mod.rs#L1046-L1065

There are a couple of ways to fix this, using the check_owner bit, using the IN_DSCR_EMPTY interrupt, or better bookkeeping. I'm not sure which way is right, and it's likely the answer will depend on the peripheral (and use case) in question.

Dominaezzz commented 1 month ago

cc @Noxime