I am running my code on an STM32L476RG which generates a UART interrupt every time it receives data. I am using UART2 for this purpose and USART2_IRQHandler
is called after I send data from my terminal. But inside HAL_UART_IRQHandler
, my code gets stuck on an overrun error interrupt. What is the reason for this? I've been pulling my hair trying to figure out the source of the problem. Here is my code -
UART configuration -
void uart_config(void)
{
/* Configure the UART peripheral ######################################*/
/* Put the USART peripheral in UART Mode */
/* UART configured as follows:
- Word Length = 8 Bits
- Stop Bit = One Stop bit
- Parity = None
- BaudRate = 9600 baud
- Hardware flow control disabled (RTS and CTS signals) */
UartHandle.Instance = USARTx;//USART2
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if(HAL_UART_DeInit(&UartHandle) != HAL_OK)
{
sprintf(errvar,"This is line %d of file %s (function %s)\n", __LINE__, __FILE__, __func__);
Error_Handler(101); // See "error codes.txt"
}
if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
sprintf(errvar,"This is line %d of file %s (function %s)\n", __LINE__, __FILE__, __func__);
Error_Handler(102); // See "error codes.txt"
}
/* Put UART peripheral in reception process */
if(HAL_UART_Receive_IT(&UartHandle, &aRxBuffer, 1) != HAL_OK)
{
sprintf(errvar,"This is line %d of file %s (function %s)\n", __LINE__, __FILE__, __func__);
Error_Handler(103); // See "error codes.txt"
}
#ifdef DEBUG_MODE
sprintf(dispvar,"UART = USART%d \n BAUDRATE = %d \n Word Length = 8 bits \n Stop Bit = 1 \nParity = None \n Flow Control = None \n Mode = TxRx ", 2,UartHandle.Init.BaudRate );
serial_printf();
#endif
}
interrupt handler -
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;
/* If no error occurs */
errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
if (errorflags == RESET)
{
/* UART in mode Receiver ---------------------------------------------------*/
#if defined(USART_CR1_FIFOEN)
if (((isrflags & USART_ISR_RXNE_RXFNE) != RESET)
&& (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != RESET)
|| ((cr3its & USART_CR3_RXFTIE) != RESET)))
#else
if (((isrflags & USART_ISR_RXNE) != RESET)
&& ((cr1its & USART_CR1_RXNEIE) != RESET))
#endif
{
if (huart->RxISR != NULL)
{
huart->RxISR(huart);
}
return;
}
}
/* If some errors occur */
#if defined(USART_CR1_FIFOEN)
if ((errorflags != RESET)
&& ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != RESET)
|| ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != RESET))))
#else
if ((errorflags != RESET)
&& (((cr3its & USART_CR3_EIE) != RESET)
|| ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
#endif
{
/* UART parity error interrupt occurred -------------------------------------*/
if (((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF);
huart->ErrorCode |= HAL_UART_ERROR_PE;
}
/* UART frame error interrupt occurred --------------------------------------*/
if (((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
huart->ErrorCode |= HAL_UART_ERROR_FE;
}
/* UART noise error interrupt occurred --------------------------------------*/
if (((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
huart->ErrorCode |= HAL_UART_ERROR_NE;
}
/* UART Over-Run interrupt occurred -----------------------------------------*/
#if defined(USART_CR1_FIFOEN)
if (((isrflags & USART_ISR_ORE) != RESET)
&& (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != RESET) ||
((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != RESET)))
#else
if (((isrflags & USART_ISR_ORE) != RESET)
&& (((cr1its & USART_CR1_RXNEIE) != RESET) ||
((cr3its & USART_CR3_EIE) != RESET)))
#endif
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
/* Call UART Error Call back function if need be --------------------------*/
if (huart->ErrorCode != HAL_UART_ERROR_NONE)
{
/* UART in mode Receiver ---------------------------------------------------*/
#if defined(USART_CR1_FIFOEN)
if (((isrflags & USART_ISR_RXNE_RXFNE) != RESET)
&& (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != RESET)
|| ((cr3its & USART_CR3_RXFTIE) != RESET)))
#else
if (((isrflags & USART_ISR_RXNE) != RESET)
&& ((cr1its & USART_CR1_RXNEIE) != RESET))
#endif
{
if (huart->RxISR != NULL)
{
huart->RxISR(huart);
}
}
/* If Overrun error occurs, or if any error occurs in DMA mode reception,
consider error as blocking */
if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) ||
(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
{
/* Blocking error : transfer is aborted
Set the UART gState ready to be able to start again the process,
Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
UART_EndRxTransfer(huart);
/* Disable the UART DMA Rx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* Abort the UART DMA Rx channel */
if (huart->hdmarx != NULL)
{
/* Set the UART DMA Abort callback :
will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
/* Abort DMA RX */
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
{
/* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
huart->hdmarx->XferAbortCallback(huart->hdmarx);
}
}
else
{
/* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
else
{
/* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
else
{
/* Non Blocking error : transfer could go on.
Error is notified to user through user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered error callback*/
huart->ErrorCallback(huart);
#else
/*Call legacy weak error callback*/
HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
huart->ErrorCode = HAL_UART_ERROR_NONE;
}
}
return;
} /* End if some error occurs */
/* UART wakeup from Stop mode interrupt occurred ---------------------------*/
if (((isrflags & USART_ISR_WUF) != RESET) && ((cr3its & USART_CR3_WUFIE) != RESET))
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF);
/* UART Rx gState is not reset as a reception process might be ongoing.
If UART handle gState fields need to be reset to READY, this could be done in Wakeup callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Wakeup Callback */
huart->WakeupCallback(huart);
#else
/* Call legacy weak Wakeup Callback */
HAL_UARTEx_WakeupCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
return;
}
/* UART in mode Transmitter ------------------------------------------------*/
#if defined(USART_CR1_FIFOEN)
if (((isrflags & USART_ISR_TXE_TXFNF) != RESET)
&& (((cr1its & USART_CR1_TXEIE_TXFNFIE) != RESET)
|| ((cr3its & USART_CR3_TXFTIE) != RESET)))
#else
if (((isrflags & USART_ISR_TXE) != RESET)
&& ((cr1its & USART_CR1_TXEIE) != RESET))
#endif
{
if (huart->TxISR != NULL)
{
huart->TxISR(huart);
}
return;
}
/* UART in mode Transmitter (transmission end) -----------------------------*/
if (((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
{
UART_EndTransmit_IT(huart);
return;
}
#if defined(USART_CR1_FIFOEN)
/* UART TX Fifo Empty occurred ----------------------------------------------*/
if (((isrflags & USART_ISR_TXFE) != RESET) && ((cr1its & USART_CR1_TXFEIE) != RESET))
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Tx Fifo Empty Callback */
huart->TxFifoEmptyCallback(huart);
#else
/* Call legacy weak Tx Fifo Empty Callback */
HAL_UARTEx_TxFifoEmptyCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
return;
}
/* UART RX Fifo Full occurred ----------------------------------------------*/
if (((isrflags & USART_ISR_RXFF) != RESET) && ((cr1its & USART_CR1_RXFFIE) != RESET))
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Rx Fifo Full Callback */
huart->RxFifoFullCallback(huart);
#else
/* Call legacy weak Rx Fifo Full Callback */
HAL_UARTEx_RxFifoFullCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
return;
}
#endif
}
I solved it myself. Looks like there was some problem in HAL UART .c and .h files. I just copied them from another example program for the same board and it works fine.