cancel
Showing results for 
Search instead for 
Did you mean: 

Long DMA transfer with strict timing requirement

Christian Zingl
Associate II

Dear ST community,

on a STM32H7A3ZIT6 MCU running at 280 MHz, I need to transfer blocks consisting of up to 2^19 (524288) half-words (16 bits) to a 16 bit parallel interface DAC connected via Port F and the DAC clock connected to PE9. Sample rate should be at least 20 MHz, but up to 50 MHz may be desired.

Any arbitrary block size between 2 and 524288 needs to be supported. It is crucial for my application that the operation is seamlessly circular, which means that after the last transfer happened, the process needs to be immediately restarted from the initial source address.

The transfer is characterized as following:

  • DMA 1 Stream 0
  • DMA request is TIM1_CH1
  • Memory To Peripheral
  • Source is the 1 Mbyte RAM starting at 0x24000000; Source address is automatically increased by 2 bytes each transfer (half-word operation)
  • Destination is GPIOF->ODR; Destination address is not increased

Timer 1 is configured for PWM operation which generates a clock for the DAC and simultaneously provides the DMA request.

Of course, this works effortlessly for block sizes of up to 65534 as this is the maximum block size the DMA supports. Going beyond this requires additional effort.

One idea is to use the dual-memory-address mode which alternates between two initial source addresses. This allows me to modify the source address which is currently not in use, enabling infinitely large block transfers at high speed with low CPU usage. Unfortunately, at some point, I also need to modify the transfer length as I cannot divide the arbitrary block length into evenly sized chunks.

Is there a solution to this problem or do I need to accept the fact that it is not possible to seamlessly transfer blocks of arbitrary length using the DMA?

Thank you and kind regards

7 REPLIES 7
TDK
Guru

You could pad the array with 0s or whatever an "idle" signal is.

If you feel a post has answered your question, please click "Accept as Solution".

Thank you for your reply! This is not possible as there is no idle signal. The data needs to appear at Port F as it is in memory.

Ah, I missed that part of the explanation.
There's no way to dynamically change transfer length without an interruption in the process as far as I know.
One option would be to duplicate the start of the buffer such that the last DMA operation which would normally not have enough data can complete. You would then set the next start address to skip those bytes at the start of the buffer. It seems like that could work with minimal headache.
If you feel a post has answered your question, please click "Accept as Solution".

Thank you very much also for the suggestion to duplicate the data! This could indeed work if there was enough memory available. In my case, I'm potentially already using all of the 1 Mbyte RAM area (the large RAM is the reason I picked the STM32H7A3ZIT6). But maybe I can decrease the amount of usable memory to use this workaround. Thank you!

I personally would start experimenting with PSSI to provide buffer between DMA and the output.

JW

Uwe Bonnes
Principal III

PSSI?

PSSI!

0693W00000BdCFUQA3.pngJW