cancel
Showing results for 
Search instead for 
Did you mean: 

UART Rx Interrupt triggered, but state is READY, when it should be BUSY, causing Rx Data to not be returned.

PLane.1
Associate II

STM32H743

Using USART3 in Asynchronous mode with interrupt. The hope is to use this with FreeRTOS+CLI

I am able to Tx as expected. Rx will trigger the interrupt, but the RX State is READY when it should be BUSY. This causes the value to not be saved, and the Rx complete callback is not called.

Seen below is where the stepping through leads to. RxState = 32, which is HAL_UART_STATE_READY.

This results in the character not getting transferred and the callback not getting called.

Any idea what could be going on here and where to look next?

void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
 
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */
 
  /* USER CODE END USART3_IRQn 1 */
}
 
 
/**
  * @brief RX interrrupt handler for 7 or 8 bits data word length .
  * @param huart UART handle.
  * @retval None
  */
static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
{
  uint16_t uhMask = huart->Mask;
  uint16_t  uhdata;
 
  /* Check that a Rx process is ongoing */
  if (huart->RxState == HAL_UART_STATE_BUSY_RX)
  {
    uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
    *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
    huart->pRxBuffPtr++;
    huart->RxXferCount--;
 
    if (huart->RxXferCount == 0U)
    {
      /* Disable the UART Parity Error Interrupt and RXNE interrupts */
      CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
 
      /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
      CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
 
      /* Rx process is completed, restore huart->RxState to Ready */
      huart->RxState = HAL_UART_STATE_READY;
 
      /* Clear RxISR function pointer */
      huart->RxISR = NULL;
 
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
      /*Call registered Rx complete callback*/
      huart->RxCpltCallback(huart);
#else
      /*Call legacy weak Rx complete callback*/
      HAL_UART_RxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
    }
  }
  else
  {
    /* Clear RXNE interrupt flag */
    __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
  }
}

1 REPLY 1
TDK
Guru

HAL_UART_IRQHandler will call UART_RxISR_8BIT prior to setting the state to READY. You can examine the code yourself.

Has to be another reason for this behavior. Are you accessing the peripheral from multiple threads? You could set a hardware watchpoint on the state variable and see where it's getting changed.

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