libaray DMA channel selection

duff

Well-known member
I was wondering if there shouldn't be a way to hand out DMA channels to librarys implemented into the core? When writting a library using DMA it makes it hard to choose what DMA channel we should use not to confict with other libraries. Looks like the Audio library already kind of does this, at least it makes it easier to change the channels. Since more and more libraries are using DMA this would be really useful!
 
its a good starting point but I think it needs to be part of the core so people actually use it. Also the problem with a library to do this is how the IDE is setup to link in libraries. I just can't include it in my library without also including it into the sketch and I hate that convention.

So how does your library handle libraries that don't use your DMA allocation but just hard code the channels? Would it detect that?
 
No, that would not be detectable before anything goes wrong. If a library tries to configure a DMA channel that is already in use, the DMA controller will probably set the corresponding channel error flag.
 
Makes me wonder if it's conceivable to write a little parsing program to do a report on a library's codebase. Might make it easier to port libraries to comply. Something like below.

DMA: yes/no <filename>.c: 120
SPI: yes/no <filename>.c: 133
Timer: yes/no <filename>.c: 16
Interrupt: yes/no <filename>.c: 22
 
No, that would not be detectable before anything goes wrong. If a library tries to configure a DMA channel that is already in use, the DMA controller will probably set the corresponding channel error flag.

Another issue to deal with is the DMA register conflicts also. I already had this problem with the OctoWS2181 library's DMA conflicting with my SerialEvent library. I just set my library with a higher DMA channel but if any other library uses those channels then the user has to edit one of the libraries. Looks like the Audio library had this problem too so Paul added a fix (dma_chan.h) but the user still would have to edit the library if any libraries share the same DMA channels. Maybe its me but the idea of any library that expects me too keep track of this low level code kinda sucks.

Maybe some hybrid of the Audio (dma_chan.h) and isr template code would work, but again I think having it part of the core would be the best place for it?
 
Last edited:
The idea of the library in the code is simple. It's impossible to prevent the use of DMA by other libraries that don't request it, but at least for the ones that would introduce those changes it's possible.

There are at least two ways for a library to select different DMA channels, one is the "static" one, like Paul does in the Audio library. It uses macros to select the correct channel. The channel number has to be in the code at compilation time, so the user has to actually change it.

An other way is in the ADC library (RingBufferDMA.h/cpp). You can get the correct channel registers by adding the offset depending on the requested DMA channel number. The problem is that you can't do this for the isr (or can you?). The solution is to move the vector table to the RAM and introduce your function in the correct "slot" for the channel. For that we need the vector table code in the core library (and even better some mechanism like the one I propose in the DMAControl to assign channels to libraries).

The code is not complicated, but any change to the core library has to be well tested I guess. So Paul, maybe can we get the vector table thing for the next update and think about the DMA in the near future?
 
An other way is in the ADC library (RingBufferDMA.h/cpp). You can get the correct channel registers by adding the offset depending on the requested DMA channel number.
hmm... not sure if i like having to make new place holders for already existing DMA registers? Maybe it's not a big deal but shouldn't they be declared static in the library anyway?
 
So Paul, maybe can we get the vector table thing for the next update and think about the DMA in the near future?

Yes, I want to do this for 1.20 or 1.21. I'm still undecided on the finer details, but yes, I agree the vector table needs to be in RAM.

The DMA allocator does need to be a core library function, much like how IntervalTimer was brought into the core library quite some time ago.
 
What I mean is:

Code:
volatile uint16_t* DMA_TCD_CSR = &DMA_TCD0_CSR + 0x8*DMA_channel;

Then you set DMA_TCD_CSR to whatever you want, independently of the channel.
 
Back
Top