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.
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.
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 enablecheck_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 theIN_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.