cancel
Showing results for 
Search instead for 
Did you mean: 

UART IRQ_Handler will not Flush RDR Register when Receiver is not Enabled(no call to HAL_UART_Receive_IT() )

RemoF
Associate

Hi

I had a Problem with the HAL UART driver.

On my Custom Board with STM32H7 the TX and RX Pin are connected together, so i have a local echo and read back everything i transmitt.

My Problem now is that it will generate a Receive interrupt but don't flush the RDR Register.

What i don't understand is that every time a Receive ist complete, the RXISR Function sets the Pointer to itself in the UART_Handle to NULL. (Line26) So it will not be called by the IRQ_Handler when another Frame will be received when the Receiver is not busy.

But with the Lines 7 and 37 to 41 it will check if the receiver is busy (waiting for incoming Data) and when not, it will Flush the RDR Register. But it will never do that because the Pointer is set to NULL and the Function is not called when receiver is not busy.

I think this is a Bug and Line 26 should be deleted.

What i also not understand is why the selection of the RXISR Function is made in the HAL_UART_Receive_IT() and not in the HAL_UART_Init Function.

The Pointer to the RXISR Function should be set in the HAL_UART_Init() and should not be deleted until i change it.

For me this is a change in the Configuration where i have to reinitialize the UART.

Or do i misunderstand something?

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);
  }
}
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
  uint32_t isrflags   = READ_REG(huart->Instance->ISR);
  uint32_t cr1its     = READ_REG(huart->Instance->CR1);
  uint32_t cr3its     = READ_REG(huart->Instance->CR3);
 
  uint32_t errorflags;
  uint32_t errorcode;
 
  /* If no error occurs */
  errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF));
  if (errorflags == 0U)
  {
    /* UART in mode Receiver ---------------------------------------------------*/
    if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)
        && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)
            || ((cr3its & USART_CR3_RXFTIE) != 0U)))
    {
      if (huart->RxISR != NULL)
      {
        huart->RxISR(huart);
      }
      return;
    }
  }

Thanks

0 REPLIES 0