Skip to main content
Associate II
June 24, 2025
Question

STM32U585x UART Poll receive is happening only for first byte :

  • June 24, 2025
  • 7 replies
  • 823 views

Dear Community

I have a problem with the UART1 on the STM32U585x board. I try to read some bytes in polling mode using HAL_UART_Receive();

And i set the size parameter to any number greater than 1 and i only receive 1 byte, even though i am sending more data from the other side.
This is really bizarre, i have used this function countless times in other projects with other controllers, and this is the first time this happens.
When i use the HAL_UART_Receive_IT(); It reads the whole message that can be 4,8 or 10 bytes.

I have an idea of what i am doing and i used the UART peripheral of the STM boards a lot and everything i tried didn't solved this.
Can someone please help me to figure out how to solve this? or is this some kind of a problem with the specific boards?

Thanks, 

#define RX_BUFFER_SIZE 100
char rx_buffer[RX_BUFFER_SIZE] = "Hello_World\"r\n";
 
HAL_UART_Transmit(&huart1, (uint8_t*)rx_buffer, strlen(rx_buffer), HAL_MAX_DELAY);
rx_buffer[RX_BUFFER_SIZE] = 0;
char ch;
uint16_t index = 0;
 
// Receive 1 byte at a time until newline
if (HAL_UART_Receive(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY) == HAL_OK)
{
// Store character
if (index < RX_BUFFER_SIZE - 1)
{
rx_buffer[index++] = ch;
 
// If newline received, end string and echo back
if (ch == '\n')
{
rx_buffer[index] = '\0'; // Null-terminate string
 
// Echo the received string back
HAL_UART_Transmit(&huart1, (uint8_t*)rx_buffer, strlen(rx_buffer), HAL_MAX_DELAY);
 
// Reset index for next message
index = 0;
}
}
else
{
// Buffer overflow, reset
index = 0;
}
}

  

7 replies

KnarfB
Super User
June 24, 2025

Add the relevant code snippets by using "insert code sample" blocks.

hth

KnarfB

ram_janaAuthor
Associate II
June 24, 2025

Added code in main thread by removing from here.

Andrew Neil
Super User
June 24, 2025

@KnarfB wrote:

 by using "insert code sample" blocks.


@ram_jana See How to insert source code for how to do that.

You can edit your post by clicking the little arrow at top-right:

AndrewNeil_0-1750761674924.png

 

You'll need to paste the code again from your editor because it's now lost all its indentation.

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.
TDK
Super User
June 24, 2025

You need to be ready to receive before the character is sent. There is no buffer for characters waiting to be read out. Using blocking receive isn't going to work here. Use DMA or IT.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Karl Yamashita
Principal
June 24, 2025

You need a do/while loop to receive more than 1 byte. As of now with your code, after 1 byte is received or times out, it'll just continue through the rest of the code after the if statement.

Also, if you are doing loopback sending hello world and trying to receive, it won't work when polling for receive because the transmit would have been done before you're ready for receiving. But if you are receiving from another device, then you can poll. But you still need a while loop to receive more than 1 byte.

But as @TDK mentions, a better approach is to use DMA or IT

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
Tesla DeLorean
Guru
June 24, 2025

>>This is really bizarre, i have used this function countless times in other projects with other controllers, and this is the first time this happens.

Not really, the HAL_UART_Transmit() blocks and completes entirely before you even start to receive the data. The data is sent, you're just not ready

The IT/DMA versions allow for concurrent reception, to catch the data as it is sent.

 

This isn't the issue, but you shouldn't write beyond the scope of the buffer

rx_buffer[RX_BUFFER_SIZE] = 0;

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Associate II
June 24, 2025

ensure the interrupt is enabled in the cube IOC file and in the it.c file and use this line to re-enable the interrupt for receiving the next byte (use this line at the end of the UART receive function)

 

HAL_UART_Receive_IT(&huart1, &rx_buffer, 1);

 



If this helps, Hit Accept as solution , so that we know what really works.

ram_janaAuthor
Associate II
June 25, 2025

Hi,

I’m currently porting the ESP32-based Iridium 9603N modem code to the STM32U585x SoC.
As per the reference implementation, I’m using the polling method for UART communication.

However, I’m not observing any data reception in polling mode.

After doing the porting from ESP32 to STM32 it is working for polling transmission, somewhere it is not receiving as expected, In order to confirm the receive in poll mode, I have added small test whether it receive more characters or not (above shared code) But it is receiving only first character.

Can I use the polling method to receive responses from the Iridium 9603N modem, as per its design? Will polling supports to receive response from modem as per this design ?


Any suggestions or recommendations would be appreciated.

Andrew Neil
Super User
June 25, 2025

@ram_jana wrote:

Can I use the polling method to receive responses from the Iridium 9603N modem, as per its design? Will polling supports to receive response from modem as per this design ?


As @TDK and @Tesla DeLorean have explained, the trouble with polling is that the receiver has to be ready and waiting before the transmitter starts sending.

That can be very difficult to achieve with a 3rd-party device over which you have little control.

With a modem, you'd have to ensure that it can never send anything unsolicited.

ie, it never sends anything except in response to a command/request.

If you can do that, you know that the only time it will send is in response to a command/request - so you can be ready.

But it means that your receiver will need to block while it waits for the response to start, and then wait for it to complete.

Which can make the rest of your application hard to manage.

This is why using interrupt-driven reception is generally preferred.

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.