cancel
Showing results for 
Search instead for 
Did you mean: 

UART receive buffers data instead of sending it to the code

msingh08
Associate II

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

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
msingh08
Associate II

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 

View solution in original post

5 REPLIES 5
Andrew Neil
Evangelist III

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

AndrewNeil_0-1716981292495.png

 

Karl Yamashita
Lead III

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

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

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. 

 

 

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?

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
msingh08
Associate II

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