Skip to main content
CLeo.1
Senior II
January 10, 2022
Solved

How do you know the data transferred from Memory into peripheral has been fully sent VIA DMA into the real world.

  • January 10, 2022
  • 2 replies
  • 2449 views

I've always been curious to know if there was a method to find out the data transferred via the DMA into the peripheral has been sent out probably.

For example a Timer

All it does is

  1. Create an array with varying CCR1 values (Duty Cycles)
  2. Once done, enable the DMA to start transferring the CCR1 values from the array into the peripheral
  3. Then from here I monitor the DMA Transfer Complete flag, however this just tells you the DMA is done, but how do I know the peripheral is done sending out the data into the real world? if that makes any sense

Code:

Create the Array

uint32_t RGB = GREEN << 16 | RED << 8 | BLUE;
 
	wait();
 
	LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_4, ((offset * 24) + 50));
	for (uint32_t LED = 0; LED < offset; LED++) {
 
		if ((offset - 1) == LED) {
 
			for (int bit = 23 + ((int)LED * 24); bit >= 0 + ((int)LED * 24); bit--) {
 
				if ((RGB) & (1 << ((23 + (LED * 24)) - bit))) {
 
					WS28128B_BUFF[bit] = 0xC0;
				} else {
					WS28128B_BUFF[bit] = 0x60;
				}
			}
 
		} else {
 
			for (int bit = 23 + ((int)LED * 24); bit >= 0 + ((int)LED * 24); bit--) {
 
				WS28128B_BUFF[bit] = 0x60;
			}
		}
	}
 
	for (uint32_t RESET_LINE = (offset * 24); RESET_LINE < ((offset * 24) + 50); RESET_LINE++) {
		 WS28128B_BUFF[RESET_LINE] = 0x00;
	}

Enable DMA and Peripheral

LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_4);
	LL_TIM_EnableCounter(TIM15);
	WS2812B::block = true;

Once DMA Transfer Flag complete flag is done disable

extern "C" void DMA1_Stream4_IRQHandler() {
 
	LL_DMA_ClearFlag_TC4(DMA1);
	LL_TIM_DisableCounter(TIM15);
	WS2812B::block = false;
}

Can I trust the DMA flag, when its set for the data to be sent out to the real world or do I need to now rely on a flag within the TIMER peripheral to do that?

This topic has been closed for replies.
Best answer by TDK

The DMA TC flag indicates the data has been transferred to the peripheral, but not that the peripheral is "done" with it. You would need to wait another timer update cycle for this to happen and there's no super clean way of doing it.

An alternative is to add an additional dummy byte at the end of the buffer that doesn't affect the stream (i.e. CCR value for 0% duty cycle) and interrupt during that byte (at the TC flag). Double check on a scope, you may need two dummy bytes.

2 replies

TDK
TDKBest answer
January 11, 2022

The DMA TC flag indicates the data has been transferred to the peripheral, but not that the peripheral is "done" with it. You would need to wait another timer update cycle for this to happen and there's no super clean way of doing it.

An alternative is to add an additional dummy byte at the end of the buffer that doesn't affect the stream (i.e. CCR value for 0% duty cycle) and interrupt during that byte (at the TC flag). Double check on a scope, you may need two dummy bytes.

"If you feel a post has answered your question, please click ""Accept as Solution""."
CLeo.1
CLeo.1Author
Senior II
January 11, 2022

Is there no more of a definitive way to know if the peripheral is "done"? For example for let say UART, cant really send empty bytes into it like you can with the TIMER.

TDK
January 11, 2022
Usually there is a way, but it's peripheral specific. UART has the BUSY or IDLE flag to do so.
"If you feel a post has answered your question, please click ""Accept as Solution""."
CLeo.1
CLeo.1Author
Senior II
January 11, 2022

Ah I see fair enough, or I guess the "TC" Flag in the UART. Thank you for the explanation