Skip to main content
Associate II
May 29, 2025
Solved

STM32L431KCUX UART cannot receive more than 49 bytes

  • May 29, 2025
  • 15 replies
  • 1154 views

Recently I have encountered a strange issue I cannot really explain...

I have a firmware that manages serial UART communication with a callback that has a state machine with 3 states.

In the first state, UART is set to perpetually expect 1 byte of data until a specific value is received. If the value is received, another byte is set to be read via UART_Receive_IT and SM proceeds to the next state.

In the second state, the received byte is considered message length and UART_Receive_IT is set to read the expected amount of bytes.

The third state is supposed to happen when the expected amount of bytes is received and all parsing is done... however, it is never triggered when the serial data is longer than 49 bytes.

I am sending data with RealTerm. Short messages work just fine, but then I need to send 147 bytes. In the debug, I can see from the state of huart2 handler that RxXferCount starts at 147 and decrements until 98. Then, UART_RxISR_8BIT is never called again, the state remains unchanged until firmware's timeout triggers and aborts the reception.

 I tried to look at some other things. RTS and CTS pins are low at the time when timeout happens. The timeout was initially 0.02s, I raised it to 1s with no effect. Overrun flag is low as well. My buffer is larger than the message I am expecting. I tried to use UART_Receive_IT in batches of 32 bytes, but then the first batch is received correctly and the second batch freezes in the similar way as soon as the total amount of received bytes reaches 49. I am not supposed to reset something between UART_Receive_IT calls, correct?

Why UART might just stop receiving data? What else can I do to try debug this?

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

Hello everyone, thank you for the participation.

After a couple of tests I found out that Realterm v2.0.0.7 does not send more than 49 bytes in one go for some reason. I used a makeshift python script to send the data and it worked. Good grief, threw me for quite a loop.

15 replies

Senior III
May 29, 2025

A common STM32 bug: uncached memory or alignment issues if you use DMA with a non-DMA-safe buffer.

Check that your Rx buffer is:

__attribute__((aligned(4))) // Especially on Cortex-M7 or with DCache
uint8_t rx_buf[256];

Also, if using DMA, ensure buffer is in RAM region not cached, e.g., .dma_buffer section or DTCM.

MO94Author
Associate II
May 29, 2025

Hello, I am not using DMA, only IT. 

I tried to add

__attribute__((aligned(4)))

 before the declaration of my buffer but it did not resolve the issue.

urbito
Senior II
May 29, 2025

Hello,

 

I have a similar issue in the past, in my case was regarding the "send" through UART. In my case when i wanted to send more bytes through UART, i had to increase the timeout for function: 

HAL_UART_Transmit(&huart1, sendbuf, sizeof(sendbuf), 100);

When i wanted this function with a timeout of like, 10ms, it was sending few bytes, then i did increase the timeout and worked.

In the receiver what i do is a custom rutine to get byte by byte in each interrupt.

I do a similar "protocol" as you mentioned. Try to check in your stm32 device that you are trating the values as uint8_t and not as string, for example.

 

MO94Author
Associate II
May 29, 2025

Hello, my firmware does not use UART in polling mode and the problem is only with the reception. I transmit data using a serial terminal from my PC, RealTerm. 

Andrew Neil
Super User
May 29, 2025

@MO94 wrote:

I transmit data using a serial terminal from my PC, RealTerm. 


How, exactly, do you do that?

Are you typing characters manually, one-by-one, or getting RealTerm to send them all together as a block?

If the latter, perhaps you are too slow in your receive handling, and you are getting UART overrun ... ?

If the former, you should be able to follow it in the debugger, and see what changes at 98 ...

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Tesla DeLorean
Guru
May 29, 2025

Count the number of times your IRQHandler is called vs that of.the callback routine.

Read the UARTs ISR register directly, any other bits flagging?

Check overrun, framing and noise errors.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
TDK
May 29, 2025

If ORE=0, data probably didn't make it to the peripheral. Put a logic analyzer on the line to find the truth.

"If you feel a post has answered your question, please click ""Accept as Solution""."
MO94AuthorBest answer
Associate II
May 29, 2025

Hello everyone, thank you for the participation.

After a couple of tests I found out that Realterm v2.0.0.7 does not send more than 49 bytes in one go for some reason. I used a makeshift python script to send the data and it worked. Good grief, threw me for quite a loop.