Large DMA transfers (some of this is ESP32 specific, I'm not so hip to other platforms) #1480
Replies: 1 comment
-
I have deliberately avoided chained DMA descriptors to keep things simple for the user and to avoid memory managment issues. The philosophy being that there must be a justifable reason for implementing something (aka there must be a user need). This also makes implementing identical functions on other processors easier. On the ESP32 I found spurious crashes were more likely when WiFi network transfers were active when chained DMA is running even though they should not, but I a lot of bugs in the underlying ESP32 board package have been fixed now. It also appears the memory partitioning has been updated (making more memory available to user sketches) so maybe this is not such an issue anymore. The lower level SPI stuff is typically direct register access to bypass the time consuming function call + parameter error checking overhead (on the RP2040 for example performance was degraded by a factor 5 for basic SPI writes, because the low level functions also read unwanted data and uneeded control register updates) . So examining the processor data sheets and manuals plus examination of the underlying board package code reveals the basic low level instructions needed. The ESP32 is slowed down quite a lot by the low I/O clock (20MHz) and the need for semaphores for resource sharing between the 2 processors. |
Beta Was this translation helpful? Give feedback.
-
On the ESP32 at least, DMA has a maximum size per transfer, and this complicates using something pushPixelsDMA? (forgive me i forget the name) or other DMA functions because you have to know your DMA size and if you exceed it you have to break up your transfers yourself.
However, on the ESP32 at least, when you do async transfers, there is a post transfer callback you can hook. I usually use it to manipulate the DC line, but it could also be used to chain DMA calls such that if you are trying to transfer 32kB over an 8kB DMA window, it will do it in 4 transactions, being chained 3 times. That's assuming you can call pushPixelsDMA within the callback.
It's something I've been planning to do with my ESP-IDF based drivers, which already support multiple "in the air" transactions queued asynchronously. If you ever want to improve your DMA code, you might look at this file and this related file
as they might give some ideas. They handle multiple asynchronous requests by queuing and it sets the DC line in the callback so you can do a full setAddrWindow/pushPixel in "one" async operation.
You do some lower level SPI stuff that I honestly don't understand yet, mucking about with the registers directly and such. I'm curious where you found all that information. What I've found at that level has been as of yet undocumented?
Beta Was this translation helpful? Give feedback.
All reactions