This sequency is working very well for me, running on STM32L4: The buffer to store the received data (guc_RXBuffer) and buffer index (gui16_RXWritePointer) are global variables, treated in the main loop, outside the interrupt routine. Each error can be monitored using the global error counters, optional.
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
uint32_t ui32_ISR_Reg;
ui32_ISR_Reg = USART2->ISR; // get the Interrupt and status register content
if(ui32_ISR_Reg & 0x0F) { // One or more Error flags are active (Overrun, Noise, Framing, Parity)
USART2->RQR = USART_RQR_RXFRQ; // Clear the RXNE flag and discard the received data without reading it
if(ui32_ISR_Reg & USART_ISR_ORE) { // Overrun
USART2->ICR = USART_ICR_ORECF; // Clear the Overrun error flag
// gui16_LoRa_ORE++;
}
if(ui32_ISR_Reg & USART_ISR_NE) { // Noise
USART2->ICR = USART_ICR_NCF; // Clear the Noise error flag
// gui16_LoRa_NE++;
}
if(ui32_ISR_Reg & USART_ISR_FE) { // Framing
USART2->ICR = USART_ICR_FECF; // Clear the Framing error flag
// gui16_LoRa_FE++;
}
if(ui32_ISR_Reg & USART_ISR_PE) { // Parity
USART2->ICR = USART_ICR_PECF; // Clear the Parity error flag
// gui16_LoRa_PE++;
}
return;
}
if((USART2->CR1 & USART_CR1_RXNEIE) && (ui32_ISR_Reg & USART_ISR_RXNE)) { // RXNE flag will be cleared by reading of DR register
guc_RXBuffer[gui16_RXWritePointer] = (unsigned char)(USART2->RDR & 0xFFU); // reading DR register
}
return; // avoid calling the HAL_UART_IRQHandler bellow
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}