2021-06-15 02:02 PM
I am using DMA to acquire eight ADC channels, and would like to get the DMA to de-interleave a capture of 768x8 channels so that in memory:
channel 1 data is at address A, A+0, A+1, ... A+767
channel 2 data is at address A+768, A+768 + 1, A+ 768 + 2, ... A+768 + 767
channel 3 data is at address A+2*768, A+2*768 + 1, A+2*678 + 2, ... A+2*768 + 767
and so on. In other words, the data from each ADC channel is in a contiguous section of memory. I've been able to do that with other DMA controllers, but it looks like you can't with the STM32L4 DMA engines? I'm just not getting how that could be set up from the manual. Has anyone done something like this?
2021-06-15 02:22 PM
DMA transfers readings as they are made, in order, which means they will be interleaved.
You'll have to rearrange them manually after they are complete using the half complete and/or transfer complete interrupts.
2021-10-11 07:21 PM
When you configure the DMA to transfer sample from the ADC to Memory, you are using a peripheral -> memory DMA mode. This will result in the interleaved data you describe: Channel 1 Sample 1, Channel 2 Sample 1, ..... Channel n Sample1, Channel 1 Sample 2, Channel 2 Sample 2, ..... Channel n Sample 2 etc
The process of de-interleaving the data is simple, but requires a second DMA operation and a second set of buffers. To do this setup the DMA for memory -> memory mode.
The source address is the address of the channel you want to extract from the interleaved data that was DMAed from the ADC, e.g. address of Channel 1 Sample 1 to extract Channel 1 data
The stride (address increment) must be set to equal the distance in memory of subsequent samples of the same channel. For 8 channels and 16-bit data this would be 16 bytes.
To de-interleave all 8 channels you'd have to repeat this operation 8 times with different start addresses. You may be able to chain these operations or just setup 8 DMA channels to do them in parallel, I'm not sure, you'd have to read up on the STM32 manuals for this level of detail.
Lastly, I suppose ask yourself if you really need to de-interleave the data. If the code that consumes your ADC data is going to walk the data anyway, then why not just walk the interleaved data by incrementing your read address by 16 each time.
One more thought which may or may not be relevant, you can setup the ADC DMA ISR to trigger on both half completion and DMA complete which allows you to process the first half of your data, whilst the second is being collected, and then process the second half whilst the first is being refilled. So you have a nice ping-ping / double buffer system which is very easy to implement.
2021-10-11 08:33 PM
No playcard shuffling as this would require many address pointer hw dma registers....