Skip to main content
Visitor II
May 29, 2024
Solved

UART receive buffers data instead of sending it to the code

  • May 29, 2024
  • 3 replies
  • 1682 views

Hi all, 

I'm trying to receive UART data from an xbee module, I've noticed the xbee is sending out the data correctly (using a logic analyzer) however the STM32L431KCU6 is not receiving this data properly and instead seems like the data is being buffered somewhere? I have a timer counting the time from a start byte and if no further bytes are received for 10ms the timer ISR will terminate this frame reception. The fist message I send generates a timer interrupt however I only see the first byte of the data, when I send the second message I am able to see the full frame of the first message. Then when I send a 3rd message then I'm able to see the second message. with time this message difference increases and can reach 4/5 messages difference. I'm unsure what's going on and where is this data being buffered? 

 

Appreciate any help. 

 

 

 

 

 

static void MX_USART1_UART_Init(void)
{

 /* USER CODE BEGIN USART1_Init 0 */

 /* USER CODE END USART1_Init 0 */

 /* USER CODE BEGIN USART1_Init 1 */

 /* USER CODE END USART1_Init 1 */
 huart1.Instance = USART1;
 huart1.Init.BaudRate = 9600;
 huart1.Init.WordLength = UART_WORDLENGTH_8B;
 huart1.Init.StopBits = UART_STOPBITS_1;
 huart1.Init.Parity = UART_PARITY_NONE;
 huart1.Init.Mode = UART_MODE_TX_RX;
 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART1_Init 2 */

 /* USER CODE END USART1_Init 2 */

}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart == &huart1)
	{
		TIM15_reset_count();
		Hyb_process_received_byte(Rx_byte);
		Uart_Receive_raw(&huart1,0,1);
		TIM15_reset_count();
	}

}

void Hyb_process_received_byte (uint8_t byte)
{

	#ifdef indicator
		resetTimerIsr(TIMER_INTRA_MESSAGE);
	#endif

	if(byte == Frame_start)
	{
		if(Rx.data[3] != 0)		//the 3rd byte is the data length which cannot be 0 in any frame
		{
			Finish_frame_reception(); 
		}

		Init_Rx_byte_proces(); //resets the Rx structure
		Rx.data[Rx.incoming_bytes_index] = Frame_start;
		Rx.incoming_bytes_index++;

		TIM15_start();		//This is used to ensure if no further bytes are coming in, the received message can be processed without waiting for another start byte
	}

	else
	{
		static bool escape_next_byte = false;

		if(escape_next_byte)
		{
			byte = byte ^ 0x20;
			Rx.data[Rx.incoming_bytes_index] = byte;
			Rx.incoming_bytes_index++;
			escape_next_byte = false;
		}

		else if(byte == Escape)
			escape_next_byte = true;


		else
		{
			Rx.data[Rx.incoming_bytes_index] = byte;
			Rx.incoming_bytes_index++;
		}
	}
}

 

 

 

Kind Regards

Manpreet Singh

 

 

 

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

    Hi karl, 

     

    I've solved the issue by shortening the ISR, I'm now filling a buffer until 1ms is elapsed since the last received byte and then performing all checks in while1. Thanks for your help anyways 

    3 replies

    Super User
    May 29, 2024

    Please use this button to properly post source code - not screenshots:

    AndrewNeil_0-1716981292495.png

     

    Graduate II
    May 29, 2024

    You're not showing enough code. Have no idea what you're doing in almost all your function calls.

    msingh08Author
    Visitor II
    May 30, 2024

    Hi Karl, thanks for you reply. I've added the receive ISR which stores the received byte into an array. when the Timer15 ISR is executed or another Start_byte is received the finish_frame_reception function coppies the data into an array used my the while1 loop. The issue I am experiencing is with Rx.data not being filled with the correct data. 

     

     

    Graduate II
    May 30, 2024

    In your code if byte is your Frame_start

    if(byte == Frame_start)
    	{
    		if(Rx.data[3] != 0)		//the 3rd byte is the data length which cannot be 0 in any frame
    		{
    			Finish_frame_reception(); 
    		}

     But how are you going to test for index 3 which is your 4th byte, not 3rd byte, if the data is just starting to stream in and the 4th byte hasn't even arrived yet? Again you're not showing your code. What does Finish_frame_reception() do?

    msingh08AuthorAnswer
    Visitor II
    June 3, 2024

    Hi karl, 

     

    I've solved the issue by shortening the ISR, I'm now filling a buffer until 1ms is elapsed since the last received byte and then performing all checks in while1. Thanks for your help anyways