2
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ have you searched for example code? \$\endgroup\$
    – jsotola
    Commented Mar 9, 2021 at 16:04
  • 1
    \$\begingroup\$ @jsotola Yes, I have. I can't find one similar to Serial.Available(), that's why I ask here. \$\endgroup\$ Commented Mar 9, 2021 at 16:14

2 Answers 2

4
\$\begingroup\$

AFAIK there is no similar function in HAL. The common way to do it is:

// index of first unread byte in the RX buffer
static uint32_t rxpos = 0;
// find end of data position in the RX buffer
uint32_t pos = rxsize - puart->hdmarx->Instance->CNDTR;
// pass accumulated bytes to listener
if (pos != rxpos) {
    if (pos > rxpos) {
        // Process data directly by subtracting indexes
            processData(rxbuffer + rxpos, pos - rxpos);
        } else {
        // First process data to the end of the buffer
            processData(rxbuffer + rxpos, rxsize - rxpos);
        // Continue with beginning of the buffer
            processData(rxbuffer, pos);
        }
}
// update starting index
rxpos = (pos == rxsize)? 0 : pos;

You can call the above code from HAL_UART_RxHalfCpltCallback, HAL_UART_RxCpltCallback and, if you have code for processing either IDLE or RTO events, from corresponding handlers as well.

Note that current HAL implementation treats RTO as an error, eliminating the possibility to handle it properly. You'd have to bypass that if you want to get circular DMA transfers handled without added latency.

UPDATE

To answer your question in comments, please note that checking for available bytes in a buffer and using blocking HAL_UART_Receive call are two different approaches. You did not specify baud rate or whether or not you have variable message length. These two really define correct method of doing things in STM32.

But in general, you either need low latency communication, or you don't care how long it takes and your code has nothing to do meanwhile.

In the former case you have to use either interrupt or circular DMA versions of Receive function. With DMA you can check for available data length as described above.

In the latter you can do a loop calling blocking Receive which will either give you expected data or will time out. At low speeds you may even be better handling incoming data byte by byte in UART interrupt handler.

The methods available to you are quite different from Arduino approach. I would suggest to follow the examples available for HAL instead of trying to fit HAL functions into Arduino perspective.

\$\endgroup\$
2
  • \$\begingroup\$ I don't really understand this right now, I'm a beginner in STM32. But thank you very much, will look into this once I understand HAL library. BTW, can I use while loop to just constantly check if UART buffer is empty or not? then use HAL_UART_Receive and if else statements inside the loop? Will that work? \$\endgroup\$ Commented Mar 9, 2021 at 16:28
  • \$\begingroup\$ @ChandlerTimm I've updated the answer. It is probably not what you hoped for. \$\endgroup\$
    – Maple
    Commented Mar 9, 2021 at 16:56
3
\$\begingroup\$

Arduino environment does a lot of stuff behind the scenes to implement it. It sets up data reception to happen with interrupts that stores the received data into a buffer, which keeps state how many bytes there is in the buffer.

Obviously, no MCU library will not provide you with the exact same interface, for multiple reasons. One of the reasons is that you can just as easily implement the same concept yourself on any MCU, with or without any HAL. If you don't need a buffer or interrupts, you can simply use the HAL to see if has received a byte or not, and if it has then read the data. Or if you want similar what Arduino does, the concept is exactly the same - set up receive interrupts, store data into buffer, keep count how many bytes there are in the buffer.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.