cancel
Showing results for 
Search instead for 
Did you mean: 

Not able to use HAL_UARTEx_ReceiveToIdle_IT & HAL_UART_Receive simultaneously

YMaha
Associate

Hello,

I am trying to use USART peripheral of my STM32F303VCT6 based board. 

I want to receive the data on serial line and size of the data is not fixed or known beforehand. Once the particular string of data is received, I compare it with predefined strings stored in various arrays & based on the match, which of the if/else codes in while loop should be implemented, is decided.

In the If/else code, I also want to receive the data from same USART but this data is not to be used for the comparison above & length of this data is known. Once If/else code is executed, program should again wait for new string for comparison.

For this, I have used HAL_UARTEx_ReceiveToIdle_IT & HAL_UART_Receive  as given in the code snippet below,

 

Callback Function is -

 

 

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	FS1State=memcmp((uint8_t *) globalRxBuff,FS1,sizeof(FS1));			
	FS2State=memcmp((uint8_t *) globalRxBuff,FS2,sizeof(FS2));			
	FS3State=memcmp((uint8_t *) globalRxBuff,FS3,sizeof(FS3));			
	FS4State=memcmp((uint8_t *) globalRxBuff,FS4,sizeof(FS4));	
        if(FS1State==0)
	{
	page=1;
	}
	else if(FS2State==0)
	{
	page=2;
	}
	else if(FS3State==0)
	{
	page=3;
	}
	else if(FS4State==0)
	{
	page=4;
	}	
        memset((uint8_t *) globalRxBuff,0x00,27);
	HAL_UARTEx_ReceiveToIdle_IT(&huart2, (uint8_t*)globalRxBuff, 100);
}

	

 

 

While loop -

 

while(1)
{
if(page==1)
{
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);  //Disabling the RXNE Interrupt
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);  // Disabling the Idle Line Interrupt
huart2.RxState= HAL_UART_STATE_READY;
HAL_UART_Transmit(&huart2,txBuff,10,HAL_MAX_DELAY);
HAL_UART_Receive(&huart2, page1RxBuff, 6, HAL_MAX_DELAY);
SET_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);
SET_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);
}
else if(page==2)
{
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);  //Disabling the RXNE Interrupt
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);  // Disabling the Idle Line Interrupt
huart2.RxState= HAL_UART_STATE_READY;
HAL_UART_Transmit(&huart2,txBuff,10,HAL_MAX_DELAY);
HAL_UART_Receive(&huart2, page2RxBuff, 6, HAL_MAX_DELAY);
SET_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);
SET_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);
}
else if(page==3)
{
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);  //Disabling the RXNE Interrupt
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);  // Disabling the Idle Line Interrupt
huart2.RxState= HAL_UART_STATE_READY;
HAL_UART_Transmit(&huart2,txBuff,10,HAL_MAX_DELAY);
HAL_UART_Receive(&huart2, page3RxBuff, 6, HAL_MAX_DELAY);
SET_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);
SET_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);
}
else if(page==4)
{
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);  //Disabling the RXNE Interrupt
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);  // Disabling the Idle Line Interrupt
huart2.RxState= HAL_UART_STATE_READY;
HAL_UART_Transmit(&huart2,txBuff,10,HAL_MAX_DELAY);
HAL_UART_Receive(&huart2, page4RxBuff, 6, HAL_MAX_DELAY);
SET_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);
SET_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);
}
HAL_UART_Receive_IT(&huart2, (uint8_t*)globalRxBuff, 100);
}

 

 

This code above sometimes work and sometimes it does not trigger the callback function.

At the time when it is not working, it is stuck in HAL_UART_IRQHandler function & when I go through the code step by step in debug mode, at some point it gets back into the while loop & starts working again.

Has anyone else experienced such issue?

Is there any problem in the code above?

Desperately in need of help!

Thanks in Advance..

1 REPLY 1
Pavel A.
Evangelist III

This is a Very Frequently Asked Question.

Short answer: HAL_UARTEx_ReceiveToIdle_IT is not convenient to use as-is in most real life cases. Either use other functions, especially circular DMA - HAL_UARTEx_ReceiveToIdle_DMA  - or roll your own.