cancel
Showing results for 
Search instead for 
Did you mean: 

USART3 offset bytes when receive for the first time after boot

Kévin
Associate III

Hello,

 

I am using a nucleoH743ZI2 and STM32CubeIDE v1.13.2 on windows10

I configured the USART 3 in order to receive some telecommands from my laptop (windows 10) using a software (HTerm v0.8.9)

USART3conf.png

USART3confDMA.png


The telecommands are written in binary, 52 bytes, but the first 8 bytes are ASCII so I can read it directly, for example the keyword "C0FFEE5\0"

I intialize my callback with DMA:

 
 

 

char UART3_rxBuffer[UART_DMAsize]={0};

HAL_UART_Receive_DMA (&huart3, &(UART3_rxBuffer[0]), (uint16_t) UART_DMAsize);

 



And in a while(true) loop and I am reading every 3 seconds what is inside my buffer which receives TC by UART:

 

 

 

 

	char configReceived[sizeof(TypeReadConfig)];
	memcpy(configReceived, &(UART3_rxBuffer[0]),sizeof(TypeReadConfig));
	printf("##++ ConfigReceived %d\r\n",sizeof(TypeReadConfig));
	for(indice=0;indice<sizeof(TypeReadConfig);indice++){
		printf("%c",configReceived[indice]);
	}
	printf("\r\n##++ End ConfigReceived\r\n");

 

 

 


I noticed that if I flash my code, and send my TC of 52 bytes,
the C0FFEE5 keyword start at index 0 of my buffer.
And if I send again, the keyword will start at index 0.

If I hit the hard reset button on the Nucleo car, it will also starts at index 0.

 

 

 

##++ ConfigReceived <\r><\n>
C0FFEE5<\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\r><\n>
##++ End ConfigReceived<\r><\n>

 

 

 


However, if I unplug my Nucleo, plug it again, and send my TC, the keyword starts at index +1,
as a result my callback is not called because the buffer was not filled completely.
In this state I cannot make it work again, I have to hard reset the Nucleo so the keyword starts at 0.

 

 

 

##++ ConfigReceived <\r><\n>
<\0>C0FFEE5<\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\0><\r><\n>
##++ End ConfigReceived<\r><\n>

 

 

 



Why is there a different behavior between flash/reset and start on power ?

How can I force the index to 0, know that the same code will behave differently according how I started the card?



1 ACCEPTED SOLUTION

Accepted Solutions
Karl Yamashita
Lead II

You can use HAL_UARTEx_ReceiveToIdle_DMA and HAL_UARTEx_RxEventCallback to help eliminating random data. After POR, if you get a random byte and it idles, you'll get an interrupt. In the callback you can check the size which will probably be 1. You can check the first byte and if it's not the start of your ASCII character, you can then disregard the data and reset your array/pointer to be ready for your 52 byte telecommand.

View solution in original post

3 REPLIES 3
Pavel A.
Evangelist III

Immediately after reset or power-up your UARTs can see a glitch, more or less random. Software must be prepared for this and catch up. (Because of this and other reasons, naïve receive routines suck. Invest more effort for reasonable results).

 

Karl Yamashita
Lead II

You can use HAL_UARTEx_ReceiveToIdle_DMA and HAL_UARTEx_RxEventCallback to help eliminating random data. After POR, if you get a random byte and it idles, you'll get an interrupt. In the callback you can check the size which will probably be 1. You can check the first byte and if it's not the start of your ASCII character, you can then disregard the data and reset your array/pointer to be ready for your 52 byte telecommand.

Kévin
Associate III

Hello,
I replaced the use of the DMA by a simple IT because easier to use.
Thank you Karl for the hint, I followed this tutorial which explains how to do:
STM32 UART #5 || Receive Data using IDLE LINE (controllerstech.com)