How do you know the data transferred from Memory into peripheral has been fully sent VIA DMA into the real world.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-01-10 3:36 PM
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
- Create an array with varying CCR1 values (Duty Cycles)
- Once done, enable the DMA to start transferring the CCR1 values from the array into the peripheral
- 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?
Solved! Go to Solution.
- Labels:
-
DMA
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-01-10 4:38 PM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-01-10 4:38 PM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-01-10 5:08 PM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-01-10 5:46 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-01-10 5:59 PM
Ah I see fair enough, or I guess the "TC" Flag in the UART. Thank you for the explanation
