2020-10-15 10:20 AM
In my opinion one of the simplest ways to receive an unknown amount of data has been this post which details how to use IDLE line detection to trigger the DMA to call the HAL_UART_RxCpltCallback function. This then reads the data received via UART from the DMA's buffer. It uses a trick where disabling a Stream's Enable register which when disabled "will force transfer complete interrupt if enabled". This behavior is not mentioned in the Reference manual and the only place I have seen it so far has been the linked post.
void USART2_IRQHandler(void) {
/* Check for IDLE flag */
if (USART2->SR & USART_FLAG_IDLE) { /* We want IDLE flag only */
/* This part is important */
/* Clear IDLE flag by reading status register first */
/* And follow by reading data register */
volatile uint32_t tmp; /* Must be volatile to prevent optimizations */
tmp = USART2->SR; /* Read status register */
tmp = USART2->DR; /* Read data register */
(void)tmp; /* Prevent compiler warnings */
DMA1_Stream5->CR &= ~DMA_SxCR_EN; /* Disabling DMA will force transfer complete interrupt if enabled */
}
}
I know this behavior is true for the particular F4's and F7's I have used but is it true for the L42x? Because I am not seeing any DMA interrupt triggered by disabling "DMA_CCR_EN" on my chip.
And how does one know if this behaviour is enabled or not or where is it more clearly documented?
2020-10-15 12:20 PM
There are two different DMA designs in the STM32s: single-port in 'F1/'F0/'F3/'Lx and dual-port with FIFO in 'F2/'F4/'F7.
> This behavior is not mentioned in the Reference manual
For the dual-port DMA, it *is* documented in RMs, e.g. for 'F446:
It's described also in the related AN4031, in 4.1 Software sequence to disable DMA (although with a confusing "In both cases" in a chapter describing one case... ST's documentation is not famous for being precise.).
The single-port DMA has only a very confused description of the disabling process, e.g.
The related AN2548 does not mention channel disable.
If you don't see the interrupt upon channel abort, you have to "help" it: set some volatile variable indicating "aborted transfer" to the DMA ISR, and then force the DMA ISR using the CMSIS intrinsic NVIC_SetPendingIRQ().
JW
2020-10-16 01:42 AM
Thank you for the detailed answer and the references. I have a lot of reading to do.