Skip to main content
Visitor II
March 9, 2021
Solved

How to check the UART Serial Buffer If They Are Available using HAL Library

  • March 9, 2021
  • 2 replies
  • 16519 views

I am using STM32F429 in my project which connects to an ATmega2560 thru UART. In arduino, there is a function Serial.Available() to check if the serial buffer is empty or not.

Is there a function in STM32 that is similar to Serial.Available() in Arduino?

BTW, I am using HAL libraries in STM32CubeIDE and HAL_UART_Receive(huart, pData, Size, Timeout) to read the contents of UART buffer.

Please help. Thanks!

PS. I've read the documentation in HAL library but I'm not sure if there is one. I've looked into HAL_UART_GetState but Im not sure.

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

    There is no simple equivalent to Serial.Available() in HAL. But, when you call HAL_UART_Receive with timeout 0 and buffer size 1, it will return with HAL_TIMEOUT if there was no char available or HAL_OK if there was a char which is returned in the pData buffer. At register level, you can probe for available chars using __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) == receive register not empty.

    The reason is, that there is no receive buffer managment implemented in HAL. You just read from the hardware registers. This also means that you must quite often check for available chars, otherwise you will miss some. This topic is regularily discussed here :) Remedies include using interrupts or cyclic DMA for receive, effectively implementing a receive buffer mangement. Tilen Majerle has nice blog posts and code for that: https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

    hth

    KnarfB

    2 replies

    KnarfBAnswer
    Super User
    March 9, 2021

    There is no simple equivalent to Serial.Available() in HAL. But, when you call HAL_UART_Receive with timeout 0 and buffer size 1, it will return with HAL_TIMEOUT if there was no char available or HAL_OK if there was a char which is returned in the pData buffer. At register level, you can probe for available chars using __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) == receive register not empty.

    The reason is, that there is no receive buffer managment implemented in HAL. You just read from the hardware registers. This also means that you must quite often check for available chars, otherwise you will miss some. This topic is regularily discussed here :) Remedies include using interrupts or cyclic DMA for receive, effectively implementing a receive buffer mangement. Tilen Majerle has nice blog posts and code for that: https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

    hth

    KnarfB

    CDolo.1Author
    Visitor II
    March 10, 2021

    Thank you for this. At register level, I use this right? --

    	while(1) {
    		if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_RXNE) == SET) {													
    			HAL_UART_Receive(&huart3, (int16_t *) &CAM_reso_W, 2, 1000);
     }
     }									

    Is that correct?

    Super User
    March 10, 2021

    Looks reasonable.

    But, it also depends on how reliable your communication timing is. When 2 chars are sent in a row, HAL_UART_Receive will happily return HAL_OK (which you should check) and the buffer contains the result. If only one char is sent within 1000 ms, HAL_UART_Receive will return HAL_TIMEOUT and there is no return value indicating how many chars were read. Okay here must be at least 1 because the register was not empty and less than 2, so you can deduce the result. But: not if you had choosen a larger buffer.

    As said in my first reply, you really have to check often, because there is no buffer keeping chars for you inbetween calls to HAL_UART_Receive.

    hth

    KnarfB

    Super User
    March 10, 2021

    If HAL_UART_Receive returns HAL_TIMEOUT, huart->RxXferCount is the number of remaining characters not received.

    So you can know how many characters are received.

    -- pa