5
\$\begingroup\$

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.

\$\endgroup\$
8
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ I see, that makes a lot of sense -- I wasn't aware of this feature. Thanks! \$\endgroup\$ – Ace Mango Jan 30 '17 at 20:26
3
\$\begingroup\$

It appears that the STM32 DMA supports Double-Buffering operation (I'm no STM32 pro so I cannot tell you what the related API calls are). This is what you're actually looking for. This is how you handle it:

  1. You configure size and memory location for two buffers. Usually those two are equally sized
  2. You start the DMA transfer
  3. Once the first buffer has filled up, the DMA controller will automatically start storing at the second buffer with no missed data
  4. At the same time (when the DMA switches the buffer) you will receive an interrupt, stating that the buffer was full, now is the time to act on the data on buffer 1 while buffer 2 is getting filled up
  5. Once buffer 2 has filled up, the DMA controller will start overwriting data at the first buffer location, no need to delete any data or whatsoever. Again, you will receive an interrupt and can now work on the data stored in buffer 2.
  6. Repeat from the beginning

Basically the idea is, that the DMA fills one buffer while you work on the other, the switch between the two of them is handled by the DMA controller itself and you won't lose any data due to the time required to switch between buffers if you did it in software.

The data that is transferred in one go is - as you said - typically programmed into one of the DMA registers, BufferSize sounds like the way to go (although I cannot confirm this for the STM32 as I don't know that platform so well).

\$\endgroup\$
  • \$\begingroup\$ The double buffer is a clean solution. I'm using an STM32F0, though, which doesn't support this feature. \$\endgroup\$ – Ace Mango Jan 30 '17 at 20:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.