Skip to main content
Graduate
January 9, 2025
Solved

An odd difference between homologous functions in hal_uart vs hal_usart.

  • January 9, 2025
  • 2 replies
  • 987 views

Hi, any idea about why stm32xx_hal_uart functions write to USART control registers by ATOMIC_CLEAR_BIT()/ATOMIC_SET_BIT(), while homologous stm32xx_hal_usart functions write to the same registers by CLEAR_BIT()/SET_BIT()?

In example:
UART_DMATransmitCplt() -> ATOMIC_CLEAR_BIT(huart ->Instance->CR3, USART_CR3_DMAT);
USART_DMATransmitCplt() -> CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);

Since both UART/USART are referred to by the same USART_TypeDef structure, I'd be expected to use them in the same way. So, is that due to some undocumented difference in the silicon between UART/USART?

    This topic has been closed for replies.
    Best answer by Pavel A.

    'By convention' (or 'historic reasons') the HAL based code uses stm32xx_hal_uart module for both USART and UART IPs, for the most common async mode. So it looks that the stm32xx_hal_usart module is neglected. Do you think you have a genuine need for the "uart" module?

     

    2 replies

    Super User
    January 9, 2025

    UART is asynchronous in the sense that RX and TX can be happening at the same time, independently of each other. If using DMA, the TX interrupt could pre-empt the RX interrupt if you have them set up that way. USART is not, they happen synchronously with a single clock signal. So the interrupts should not overlap each other and there is no need to make "atomic" accesses.

    USART is close to SPI in terms of architecture.

    Super User
    January 9, 2025

    @TDK wrote:

    USART is close to SPI in terms of architecture.


    but only when used in the sync mode, surely?

    when used in async mode, a USART is just a UART, surely?

    Super User
    January 9, 2025

    The USART functions are only used in USART mode.

    If you use the USART1 peripheral in UART mode, you are using UART functions (e.g. HAL_UART_*).

    Pavel A.Answer
    Super User
    January 9, 2025

    'By convention' (or 'historic reasons') the HAL based code uses stm32xx_hal_uart module for both USART and UART IPs, for the most common async mode. So it looks that the stm32xx_hal_usart module is neglected. Do you think you have a genuine need for the "uart" module?

     

    elKarroAuthor
    Graduate
    January 9, 2025

    I think I haven't a genuine need for both, since I always write my own drivers :)
    I only read HAL code to try to fill the lack of documentation and this time a neglected module adds even more chaos.

    USART has a S (sync) more than UART, the peripheral struct itself is named USART_TypeDef, but stm32xx_hal_uart module is maintained while stm32xx_hal_usart is neglected?
    For 'historic reasons' I see nations where they write the year in letters... the unification should be applied to the stm32xx_hal_usart module, don't you think?

    "With Cube and a Nucleo, the deli worker too can build a speed controller for his slicer!"
    Come on ST, less marketing and more engineering.

    Super User
    January 9, 2025

    I think I haven't a genuine need for both, since I always write my own drivers :)

    This is the best :)

     

     the unification should be applied to the stm32xx_hal_usart module, don't you think?

    I guess they wanted to unify USARTs and UARTs (perhaps LPUARTs too) at the HAL level, all covered by stm32xx_hal_uart module. stm32xx_hal_usart should then be dropped.  The differences should remain in the low level (LL) modules as they are closest to the register-level. The world is not ideal, may this be our worst problem.