Skip to main content
ranran
Senior
January 7, 2020
Solved

Real-life UART with DMA using HAL ?

  • January 7, 2020
  • 9 replies
  • 4429 views

Hello,

Is it possible to use uart with dma, so that on idle we also get informed, so that we can read the rx data ?

I found no example in hal cube for using UART with DMA in such "real life" scenario, only in simple full buffer fill - which is not practical.

I use stm32h7.

Thanks,

ranran

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

No.

HAL covers only a small subset of what the STM32 hardware can do. It is good enough to get started with STM32, create a prototype fast, but its limitations become soon apparent.

As far as I can tell, the UART idle interrupt is neither checked nor handled in the HAL interrupt handler. Enabling, checking and handling it separately might or might not confuse HAL code.

You can of course set

USARTx->CR1 |= USART_CR1_IDLEIE;

in your code, and have an interrupt handler which can deal with it. Then you must either check the HAL code that it won't get confused by anything you do with the registers, or implement all of the UART handling without HAL. The latter approach has the advantage that the register interface is far better documented as HAL functions.

DMA TC and HT interrupts are handled by HAL, but they are not exactly useful for this task (maybe TC for detecting buffer rollover). You can read the DMA stream NDTR register to find out the amount of data in the buffer.

You might also want to check out the UART receiver timeout feature (RTOR register and the associated interrupt mask and flag bits) which provides a more flexible way of detecting gaps in the transmission.

9 replies

S.Ma
Principal
January 7, 2020

Application in mind examples are a minority vs peripheral in mind ones for STM32.

Dig maybe through Tilen's https://github.com/MaJerle

Use DMA in rollover buffer big enough to make sure your regular poll from main loop don't miss any incoming bytes.

Time interval checks avoid interrupt at the expense of latency.

ranran
ranranAuthor
Senior
January 7, 2020

Thanks, I am familiar with Tilen's git (very good tutorial), and I see that Tilen use LL driver in his implementation.

Do you think it is possible to catch TC, HC, and idle interrupts using HAL (instead of LL) ?

berendi
berendiBest answer
Principal
January 7, 2020

No.

HAL covers only a small subset of what the STM32 hardware can do. It is good enough to get started with STM32, create a prototype fast, but its limitations become soon apparent.

As far as I can tell, the UART idle interrupt is neither checked nor handled in the HAL interrupt handler. Enabling, checking and handling it separately might or might not confuse HAL code.

You can of course set

USARTx->CR1 |= USART_CR1_IDLEIE;

in your code, and have an interrupt handler which can deal with it. Then you must either check the HAL code that it won't get confused by anything you do with the registers, or implement all of the UART handling without HAL. The latter approach has the advantage that the register interface is far better documented as HAL functions.

DMA TC and HT interrupts are handled by HAL, but they are not exactly useful for this task (maybe TC for detecting buffer rollover). You can read the DMA stream NDTR register to find out the amount of data in the buffer.

You might also want to check out the UART receiver timeout feature (RTOR register and the associated interrupt mask and flag bits) which provides a more flexible way of detecting gaps in the transmission.

ranran
ranranAuthor
Senior
January 7, 2020

Thanks,

It is a pity that there is no "real-life" example for UART-DMA in h7cube.

Thanks!