cancel
Showing results for 
Search instead for 
Did you mean: 

USART HAL_UART_RxCpltCallback is not called.

interactics_ST
Associate III

Hello. 

 

I am currently using USART6 by setting RX as interrupt, and TX as DMA in STM32F4.

The ST board mostly worked well, however, after some hours (maybe 10 hour), the RX interrupt wasn't called.

 

I suppose that this problem is not related to hardware or IC because it worked well after software reset, 

I captured the huart information at the moment, and posted it and my code related to RX.

interactics_ST_0-1708928863366.png

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
	if(huart->Instance == USART2){ // Nersys
		q_in = (q_in + 1) % UART_BUF_MAX; // For ring buffer
	        HAL_UART_Receive_IT(&huart2, &q_buf[q_in], 1);
	}
}

////

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}

 

I have read an article about USART and I find out that IDLEIE in USART CR1 have to be set as 1 to be interrupted.

But in my case, 

interactics_ST_1-1708929532250.png

 

How do I address this issue? Would I just add a code that force to change the bit from 0 to 1 in IRQHandler?

 

 

 

3 REPLIES 3
TDK
Guru

If you want idle interrupts, use HAL_UARTEx_ReceiveToIdle functions instead.

There's nothing wrong with the code you posted.

When the error happens, pause the program and look for reasons it may have stopped. Specifically, look at ErrorCode within the huart2 structure and the state machine in general. Possibly there was a parity or framing or other error on the line, in which case you need to reset the peripheral and/or address the issue to continue.

If you feel a post has answered your question, please click "Accept as Solution".
Karl Yamashita
Lead II

More than likely the UART interrupt was not successful due to HAL was busy. You should set a flag then check flag in main while loop and re-enable interrupt if needed.

 

HAL_StatusTypeDef hal_status;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
	if(huart->Instance == USART2){ // Nersys
		q_in = (q_in + 1) % UART_BUF_MAX; // For ring buffer
	        UART_EnableInt(); // enable again
	}
}

int main(void)
{
    // init first interrupt
    UART_EnableInt();
    
    while(1)
    {
        // other code
        
        UART_CheckStatus();
    }
}

// check HAL status and try to re-enable interrupt
void UART_CheckStatus(void)
{
    if(hal_status != HAL_OK)
    {
        UART_EnableInt();
    }
}

// enable UART rx interrupt
void UART_EnableInt(void)
{
    hal_status = HAL_UART_Receive_IT(&huart2, &q_buf[q_in], 1);
}

 

 

 

I'm sorry for my late reply.

I will try this next week, and then post the consequence about it.

 

 

Until now, I found that my status register was [01 1111 1000] which show that my MCU had Overrun error.

I post an SR information for someone who may experience the same issue like me. 

interactics_ST_2-1709274103076.png

* TXE : Tx Empty.
* TC : Transmit Complete.
* RXNE : Rx Not Empty 
* ORE : Overrun Error
* NE : Noise Error
* FE : Framing Error
* PE : Parity Error

 

I believe that your solution will be helpful to address this problem.