2022-10-17 08:01 PM
Dear ST/reader,
I’m currently implementing a uart receive interrupt function for use with the STM32H743 specifically using HAL_UART_Receive_IT(). This is straightforward when the receive length (number of bytes to receive) is just 1 in which case it either receives and notifies via the callback, or I timeout.
In another application the number of bytes to receive can vary. I don’t like the idea of using HAL_UART_Receive_IT() for each and every byte, so am considering other options for example HAL_UARTEx_ReceiveToIdle_IT().
What are the “idle�? conditions associated with HAL_UARTEx_ReceiveToIdle_IT() ? Is it a set period of time during which if no reception is detected then idle is considered to have happened ? If for example I set the length to 250, when I initially call this routine, but only 100 bytes are received then what happens and when ? And how do I determine how many bytes were actually received ?
In the same way that HAL_UART_Receive_IT() causes HAL_UART_RxCpltCallback() to be called will this same callback be called either when HAL_UARTEx_ReceiveToIdle_IT() receives its full quota of bytes or if it detects idle ? If it’s due to an idle condition then can whatever bytes were received previous to this still be read normally ? If so then this might be a good way to implement the new application; ie, I set the length to some much higher-than-expected value and rely on the idle for the receiving process to end.
Another option is to still use HAL_UART_Receive_IT(), but to use it twice – once for the first four bytes, from which I can calculate the remaining number expected, and then a second time for that remainder, but in this application this would be very difficult to do hence the interest in the other hal function.
And for HAL_UART_Receive_IT() … if less than the expected length of data was received can these bytes still be read ? This is still the preferred option for when the received length is known beforehand, but what if for some unknown/unexpected reason the transmitter sends one byte less ? Would just like to know the proper way to proceed in that case.
2022-10-23 03:31 PM
Hi,
can anyone from ST assist with these questions (or at least some of the questions), please ?
2022-10-24 01:56 PM
@Community member While waiting for more useful replies from ST, please browse this forum for threads tagged UART/USART and STM32H7. This topic is very frequent here.
STM32 U(S)ARTs have two hardware features to detect RX idle state. The second one is RTO (receive timeout). Usually when people want to receive unknown or variable amount of data, they want exactly the RTO. The most efficient way to receive from U(S)ARTs is DMA.
You can find more info on the USART operation in the RM and online training.
2022-10-25 03:12 PM
Thank-you very much Pavel.
Hopefully someone from ST may be able to provide further feedback in relation to my questions.
I did subsequently find another topic here relating to HAL_UARTEx_ReceiveToIdle_IT() – actually it was one where I believe you kindly provided an answer to another member’s question. They were also asking how to know the number of bytes received, and your suggestion was to look at RxXferCount.
My understanding is that the relevant callback function is HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size). The documentation I’ve found describes “Size�? as follows “@param Size Number of data available in application reception buffer (indicates a position in * reception buffer until which, data are available)�?. Is “Size�? the maximum number of received bytes allowed for this transfer whereas RxXferCount is the actual number received ?
I might implement a scheme where HAL_UARTEx_ReceiveToIdle_IT() is called with a larger than expected number of bytes to receive (as we don’t know beforehand this expected size) then rely on an “idle�? condition to end the process.
I’ve found this statement also “(+) Detection of inactivity period (RX line has not been active for a given period). (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state) for 1 frame time, after last received byte.�? So is the definition of “idle�? just one frame time without receiving a byte (at 115,200 baud and ten-bit data about 87us) ? Does it mean this scheme wouldn’t work when receiving from a transmitter that is not transmitting bytes immediately one after the other with no gaps ?
Any additional feedback would be appreciated, thanks.
I also see another post titled “BUG found on HAL STM32L4 HAL_UARTEx_ReceiveToIdle_IT(). This function works on STM32F0 HAL V1.11.3 but not on STM32L4 V1.17 An update is needed to solve bug when UART bytes is equaly to RxXferSize, because currently it stays on endless IT loop�? from about a year ago with no response – is this still an issue ?
2022-11-01 10:12 PM
hi, can anyone from ST help with my questions above in relation to HAL_UARTEx_ReceiveToIdle_IT, please ?
2022-11-02 02:36 PM
> Is “Size�? the maximum number of received bytes allowed for this transfer whereas RxXferCount is the actual number received ?
Yes. But note that in 9-bit data mode the buffer is array of uint16 rather than bytes (in each uint16, only 9 bits are used) and Size is number of uint16.
> I might implement a scheme where HAL_UARTEx_ReceiveToIdle_IT() is called with a larger than expected number of bytes to receive ...
This can work, unless you need continuous RX with random bursts.
(in that case, with HAL it gets more complicated).