cancel
Showing results for 
Search instead for 
Did you mean: 

Can't get HAL_UART_Receive_IT() to receive more than 256 bytes using standard stm32 hal functions.

Brian Khuu
Associate III

I am sure I'm overlooking something simple, but I'm trying to figure how to to send 256 bytes or more using the standard uart HAL functions.

Source At This Current Point: https://github.com/mofosyne/stm32h7xx-uart/tree/41645cf33e00eb2de8438d5a04264d78cf9bb767

Dev Board Used: NUCLEO-H743ZI2

File of interest:

* /Src/uart_test.c

The main test function is a uart_ISR_test() which will continuously request a certain amount of data from `./stm32_impulse_test.py`. Ergo you can use the below commands...

```

# Load and run test on micro

make swd

# Turn on swo viewer

./swo_parser.py

# Send test data to device

./stm32_impulse_test.py /dev/tty.usbmodem14403

```

So what I found is that when I modify both the python script and the firmware rx buffer size. I can receive any data below 256 bytes. But have problem getting 256 or more bytes.

## For hal uart rx buffer size of 256-12

```

I: ************************* Rx *********************************

E: Rx Received (HAL_OK)

I: Got 244 valid bytes

I: Rx :

  0 | 01 02 03 04 05 06 07 08 09 01 02 03 04 05 06 07

  16 | 08 09 01 02 03 04 05 06 07 08 09 01 02 03 04 05

  32 | 06 07 08 09 01 02 03 04 05 06 07 08 09 01 02 03

  48 | 04 05 06 07 08 09 01 02 03 04 05 06 07 08 09 01

  64 | 02 03 04 05 06 07 08 09 01 02 03 04 05 06 07 08

  80 | 09 01 02 03 04 05 06 07 08 09 01 02 03 04 05 06

  96 | 07 08 09 01 02 03 04 05 06 07 08 09 01 02 03 04

 112 | 05 06 07 08 09 01 02 03 04 05 06 07 08 09 01 02

 128 | 03 04 05 06 07 08 09 01 02 03 04 05 06 07 08 09

 144 | 01 02 03 04 05 06 07 08 09 01 02 03 04 05 06 07

 160 | 08 09 01 02 03 04 05 06 07 08 09 01 02 03 04 05

 176 | 06 07 08 09 01 02 03 04 05 06 07 08 09 01 02 03

 192 | 04 05 06 07 08 09 01 02 03 04 05 06 07 08 09 01

 208 | 02 03 04 05 06 07 08 09 01 02 03 04 05 06 07 08

 224 | 09 01 02 03 04 05 06 07 08 09 01 02 03 04 05 06

 240 | 07 08 09 01

```

## For hal uart rx buffer size of 256+12

```

I: ************************* Rx *********************************

E: Rx Timeout (HAL_OK)

E: Got only 12 valid bytes out of 268

I: Rx :

  0 | 01 02 03 04 05 06 07 08 09 01 02 03 01 02 03 04

  16 | 05 06 07 08 09 01 02 03 00 00 00 00 00 00 00 00

  32 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  48 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  64 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  80 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  96 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 112 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 128 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 144 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 160 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 176 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 192 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 208 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 224 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 240 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 256 | 00 00 00 00 00 00 00 00 00 00 00 00

```

## For hal uart rx buffer size of 256

```

I: ************************* Rx *********************************

E: Rx Timeout (HAL_OK)

E: Got only 0 valid bytes out of 256

I: Rx :

 0 | All 00 (256 Bytes)

```

---------------------------

Btw this is what my reg initially looks like for (256-12) buffer size...

I: Uart Test Start

I:  0:        ghwuart_ptr->Instance->CR1 = 0000000D : USART Control register 1

I:  0:        ghwuart_ptr->Instance->CR2 = 00000000 : USART Control register 2

I:  0:        ghwuart_ptr->Instance->CR3 = 00001000 : USART Control register 3

I:  0:        ghwuart_ptr->Instance->BRR = 00000364 : USART Baud rate register

I:  0:       ghwuart_ptr->Instance->GTPR = 00000000 : USART Guard time and prescaler register

I:  0:       ghwuart_ptr->Instance->RTOR = 00000000 : USART Receiver Time Out register

I:  0:        ghwuart_ptr->Instance->RQR = 00000000 : USART Request register

I:  0:        ghwuart_ptr->Instance->ISR = 006000D0 : USART Interrupt and status register

I:  0:       ghwuart_ptr->Instance->PRESC = 00000000 : USART clock Prescaler register

I: (0) USART_CR1_UE bit set : USART Enable

I: (0) USART_CR1_RE bit set : Receiver Enable

I: (0) USART_CR1_TE bit set : Transmitter Enable

I: (0) USART_CR3_OVRDIS bit set : Overrun Disable

Then

I:  1:        ghwuart_ptr->Instance->ISR = (006000D0 --> 006010D0) : USART Interrupt and status register

I: (1) USART_ISR_EOBF bit set : End Of Block Flag

-------

For 256 bytes rx...

```

I: Uart Test Start

I:  0:        ghwuart_ptr->Instance->CR1 = 0000000D : USART Control register 1

I:  0:        ghwuart_ptr->Instance->CR2 = 00000000 : USART Control register 2

I:  0:        ghwuart_ptr->Instance->CR3 = 00001000 : USART Control register 3

I:  0:        ghwuart_ptr->Instance->BRR = 00000364 : USART Baud rate register

I:  0:       ghwuart_ptr->Instance->GTPR = 00000000 : USART Guard time and prescaler register

I:  0:       ghwuart_ptr->Instance->RTOR = 00000000 : USART Receiver Time Out register

I:  0:        ghwuart_ptr->Instance->RQR = 00000000 : USART Request register

I:  0:        ghwuart_ptr->Instance->ISR = 006000D0 : USART Interrupt and status register

I:  0:       ghwuart_ptr->Instance->PRESC = 00000000 : USART clock Prescaler register

I: (0) USART_CR1_UE bit set : USART Enable

I: (0) USART_CR1_RE bit set : Receiver Enable

I: (0) USART_CR1_TE bit set : Transmitter Enable

I: (0) USART_CR3_OVRDIS bit set : Overrun Disable

I: ************************* Rx *********************************

E: Rx Timeout (HAL_OK)

E: Got only 0 valid bytes out of 256

I: Rx :

 0 | All 00 (256 Bytes)

... next rx cycle

I:  1:        ghwuart_ptr->Instance->CR1 = (0000000D --> 0000012D) : USART Control register 1

I:  1:        ghwuart_ptr->Instance->CR3 = (00001000 --> 00001001) : USART Control register 3

I: ************************* Rx *********************************

E: Rx Timeout (HAL_OK)

E: Got only 0 valid bytes out of 256

I: Rx :

 0 | All 00 (256 Bytes)

```

--------------------

I am also curious how everyone approaches uart rx. Do they only just use HAL_UART_Receive_IT() but just throw it into a software FIFO pipe?

If I am recommended to just skip the HAL and just rewrite it myself that is alright as well. Just needs some pointers

6 REPLIES 6
Brian Khuu
Associate III

FYI the inline uart reg dump is done by. The current source at the this point doesn't place it anywhere. But for the description above, I placed it before `HAL_UART_Abort(ghwuart_ptr)`

  uart_debug_print();

  uart_debug_error();

Also I got these messages via the SWO interface.

Brian Khuu
Associate III

Hmmm... I'm actually using the VCP of the onboard STLINK of NUCLEO-H743ZI2... is there a limitation to it?

Though I'm pretty sure you should be able to load the stm32 via VCP serial. Haven't tested it yet.

For context, was trying to use STM32 HAL uart in blocking mode for an exercise in replicating the STM32 bootloader protocol (For testing basic bootloader code), when I hit this problem of not being able to read 256 bytes sized payloads. Hence I was trying to use ISR and when that didn't work, I'm contacting this community.

So I want to be able to ensure I have a reliable way to communicate first.

turboscrew
Senior III

How did you try to send more than 256 bytes?

I think the output and 100 ms delay at the end might take too much time?

The rest of the data might be sent without anybody listening?

Brian Khuu
Associate III

> How did you try to send more than 256 bytes? I didn't find a trace in the code. All I saw was 256 byte buffer and receiving "sizeof(buffer)".

nBytes in the python script (~/git/stm32h7xx-uart/stm32_impulse_test.py) determine the size of the transmitted payload. Looks like I should have cleaned it up a bit more. I admit that it's not very clear... so I've rewritten it again at this point shown below:

https://github.com/mofosyne/stm32h7xx-uart/tree/e5e92e0c418a01732224d8aeb03164648d22d469

This time, the firmware will send a request to the python `stm32_impulse_test` for a certain amount of bytes and it will output 244, 256 and 268 bytes respectively.

Also I've removed the delay. But the problem still remains. You can see my latest test report below, that you can replicate via above link.

# stm32h7 uart test #

## Testing 244 Bytes

 * Tx '244' : Done (HAL_OK)

 * Rx : Done (HAL_OK)

 * Success : Got all 244 bytes

 * Rx :

```

  0 | 01 02 03 04 05 06 07 08 09 01 02 03 04 05 06 07

  16 | 08 09 01 02 03 04 05 06 07 08 09 01 02 03 04 05

  32 | 06 07 08 09 01 02 03 04 05 06 07 08 09 01 02 03

  48 | 04 05 06 07 08 09 01 02 03 04 05 06 07 08 09 01

  64 | 02 03 04 05 06 07 08 09 01 02 03 04 05 06 07 08

  80 | 09 01 02 03 04 05 06 07 08 09 01 02 03 04 05 06

  96 | 07 08 09 01 02 03 04 05 06 07 08 09 01 02 03 04

 112 | 05 06 07 08 09 01 02 03 04 05 06 07 08 09 01 02

 128 | 03 04 05 06 07 08 09 01 02 03 04 05 06 07 08 09

 144 | 01 02 03 04 05 06 07 08 09 01 02 03 04 05 06 07

 160 | 08 09 01 02 03 04 05 06 07 08 09 01 02 03 04 05

 176 | 06 07 08 09 01 02 03 04 05 06 07 08 09 01 02 03

 192 | 04 05 06 07 08 09 01 02 03 04 05 06 07 08 09 01

 208 | 02 03 04 05 06 07 08 09 01 02 03 04 05 06 07 08

 224 | 09 01 02 03 04 05 06 07 08 09 01 02 03 04 05 06

 240 | 07 08 09 01

```

## Testing 256 Bytes

 * Tx '256' : Done (HAL_OK)

 * Rx : Timeout (HAL_OK)

 * Failed : Got only 0 valid bytes out of 256

 * Rx : 0 | All 00 (256 Bytes)

## Testing 268 Bytes

 * Tx '268' : Done (HAL_OK)

 * Rx : Timeout (HAL_OK)

 * Failed : Got only 12 valid bytes out of 268

 * Rx :

```

  0 | 01 02 03 04 05 06 07 08 09 01 02 03 00 00 00 00

  16 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  32 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  48 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  64 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  80 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

  96 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 112 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 128 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 144 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 160 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 176 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 192 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 208 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 224 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 240 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 256 | 00 00 00 00 00 00 00 00 00 00 00 00

```

You were a bit too quick. I changed the comment when I realized that the receiver loops. :D

Then my attention went to the delay after reading. In 100 ms you may loose quite some bytes. Depending on your bit rate, of course.

Brian Khuu
Associate III

Problem fixed and traced to the stlink on the dev board. I found that the reason is because stlink-v3 version V3J2M1 has problem handling 256 bytes being sent out. This was fixed when updated to V3J6M2.

All code used to prove uart is working is now in:

https://github.com/mofosyne/stm32h7xx-uart