arduino / ArduinoCore-API

Hardware independent layer of the Arduino cores defining the official API
https://www.arduino.cc/reference/en/
GNU Lesser General Public License v2.1
216 stars 120 forks source link

Should provide DMA library #93

Open matthijskooijman opened 5 years ago

matthijskooijman commented 5 years ago

The SAMD core supports DMA, but this cannot be easily used from a library or sketch currently. In particular, multiple users of the DMA module need some coordination about what channels are in use, where the descriptor memory is located (I think), when to reset the DMA controller, etc.

Currently, I think there is the Adafruit_ZeroDMA library that does this, but the I2S library also has a DMA coordinator embedded (so these two will not play together nicely).

A single official library contained in the core (or perhaps an API contained in the core itself) would be good here. This could be a fully featured DMA library, but it might also be useful to have a minimal DMA coordinator library (that e.g. only handles resetting/initializing the controller, allocating channels and descriptors and maybe more, leaving all the channel-specific configuration that can coexist to third party or other libraries).

fontanon commented 5 years ago

I believe this is related https://github.com/adafruit/ArduinoCore-samd/issues/159

ladyada commented 5 years ago

we use our zerodma handler library a lot for displays, audio, i2s, etc. it works pretty well so far, and supports m0 and m4.

fontanon commented 5 years ago

Just to let you know about a functional workaround here: https://github.com/adafruit/Adafruit_ZeroDMA/issues/12

matthijskooijman commented 5 years ago

That workaround is useful to use I2S, but essentially just replaces the Arduino I2S library with the adafruit one which uses Adafruit_ZeroDMA. This does not generally fix this problem by providing a single official DMA library that can be used by all other libraries.

I suspect that the Adafruit_ZeroDMA library might be a good starting point, since it already has some usage. If not using that one verbatim, an official Arduino DMA library should probably try to be compatible with the Adafruit one as much as possible.

ladyada commented 5 years ago

yes making an official DMA library like Wire and SPI would be really helpful. @PaulStoffregen was also interested in making something

sslupsky commented 5 years ago

This is a good idea. One matter to consider is the DMA library uses the event system. I recommend some thought go into an event system API concurrently with this. Moreover, compatibility with the low power library should be considered as well.

PaulStoffregen commented 5 years ago

Teensy has a DMA abstraction and management of which channels are allocated in its core library. Here's the main header file.

https://github.com/PaulStoffregen/cores/blob/master/teensy3/DMAChannel.h

Teensy's approach tries to create Arduino style functions to specify what the DMA transfer does in a hardware-independent way. The functionality is similar to Adafruit's library, but the API style is quite different. Adafruit's library depends pretty heavily on a number of Atmel's defines in utility/dma.h. Those Atmel constants might not be the best long-term for an API meant to work across all platforms.

Teensy's DMAChannel also creates a data type called DMASettings, which is a container for a DMA transfer settings without allocating hardware. Both DMAChannel and DMASettings derive from the same base class, so they mostly share the same functions. C++ operators are used to allow nice syntax to assign one from the other. The DMASettings instances also allow support for more advanced features like DMA scatter-gather, which admittedly is only available on more powerful hardware. But as we're still seeing microcontrollers advance in capability, I believe that's a pretty valuable feature to be at least made possible by a generic API.

matthijskooijman commented 5 years ago

@sandeepmistry has transferred this issue from the SAMD repo to the API repo, but I am not quite sure if this is an API that can be generalized across architectures. I do not have much experience with DMA hardware, but I suspect that different architectures use significantly different DMA features and terminology, so any user of such a DMA library must already be target-specific.

Having said that: If we can find a generic API that is meaningful and can be implemented on all (DMA-supporting) architectures (possibly augmented by target-specific additions where needed), that would of course be great.