Electronic – STM32 DMA: continuous peripheral to memory (array) transfer

dmastm32

I am trying to use a DMA in circular mode to transfer data from an ADC to an array that will hold the data. I need to concurrently use the incoming data (in this case, I am using AT commands to send the data over Wi-Fi with the esp8266 module)

I am wondering what the software flow would look like.

Here are some questions:

  • How will the DMAC know when to wrap around when it reaches the end of the array? — i.e. how can I ensure that the DMA won't transfer data past the last array index? (Is this size limit defined by the DMA_BufferSize?)

  • Because I want to concurrently use the collected data, I am thinking of using 3 arrays to store the data. I would read & erase the data out of one array whilst the others are being filled by the DMA, and it would cycle around. Is it smart and/or possible to change the DMA destination constantly like this?

Thank you.

Best Answer

How will the DMAC know when to wrap around when it reaches the end of the array? -- i.e. how can I ensure that the DMA won't transfer data past the last array index? (Is this size limit defined by the DMA_BufferSize?)

Yes, it will either stop at the limit you set, or if you enable circular mode, it will start over and overwrite data at the start of the array. It will never go past the limit.

I would read & erase the data out of one array whilst the others are being filled by the DMA, and it would cycle around. Is it smart and/or possible to change the DMA destination constantly like this?

On the STM32, you can allocate one big array, and use the two halves as double buffer. There is a half-transfer interrupt (when enabled) which tells you that the first half is filled and ready for processing, and the second half is being modified. Then you'll get a transfer complete interrupt when the second half is ready and (in circular mode) it goes on updating the first half again.

So, there is no need to change the DMA destination (you can't do it anyway while DMA is running), but you'll always be able to tell which half is ready by examining the DMA status bits.

On higher-end controllers (STM32F4, STM32F7), there are actually two memory addresses for each DMA channel, the buffers halves do not need to be contiguous, and you can even change the address of the inactive buffer on the fly.