Showing results for 
Search instead for 
Did you mean: 

STM32G4: USART FIFO Error Flags

Associate III

I'm using the USART on my STM32G474 in FIFO mode with LL-libraries.

The datasheet says:

" However the RXFIFO default width is 12 bits. This is due to the fact that the receiver does not only store the data in the FIFO, but also the error flags associated to each character (Parity error, Noise error and Framing error flags)."

I want to read these error flags, but it is not clear if I have to read the flag register first and then the data register or the other way round.


I don't know how is it in the 'G4 UART, but in traditional UARTs with Rx FIFO (16550 and family) the exposed data/status registers showed the data/status bits from the top of the FIFO, i.e. the status bits were always related to the particular datum, as they were received.

The description in RM0440 is sloppy indeed to put it politely, but I'd say, read status, and if RXNE (quite idiotically double-named as RXFNE) is set, that status is probably valid for the data you are going to read from RXD, so perhaps clear the status bits before you read RXD.

You may want to experiment with generating deliberately wrong data from a second UART.


Associate II

Did you ever figure this out?  I have literally the same problem on the STM32G4 series.  I implemented my code to check the ISR bits after receiving each byte, but the PE bit always remains 0 even when I intentionally inject errors.

Bob S

> check the ISR bits after receiving each byte

This is ambiguous.  Do you (a) send a byte to the STM32, then STM32 reads the status bits then the data byte (as mentioned above), or do you (b) send a byte to the STM32, then STM32 reads data byte then status bits?

Obvious question, do you have the STM32 UART configured with a parity bit?  Try sending enough data to overflow the STM32's FIFO and see if you ever see the OV (or is it OR? I don't recall off hand) bit set.

Associate II

Thanks for the reply.  Yes, I have even parity enabled for sure.  I checked bits on an oscilloscope and confirmed USART1_CR1 has the PCE bit enabled.  You can see my code below where I'm reading the ISR register before the RDR.  The ADCU1PEError, ADCU1FEError, and ADCU1NEError variables remain 0's no matter how many errors I inject.

Following is a snippet of the code we’re using to receive 8bit data with parity enabled:
uint32_t ADCU1PEError;

uint32_t ADCU1FEError;

uint32_t ADCU1NEError;
uint32_t Rx1stSentADCMicroPacket1Err[6];

uint8_t Rx1stSentADCMicroPacket1Data[6];

                for (register uint8_t i=0; i < 6; i++)


                     Rx1stSentADCMicroPacket1Err[i] = READ_REG(USART1->ISR);           // & kUSART_ERROR_MASK;

                     Rx1stSentADCMicroPacket1Data[i] = LL_USART_ReceiveData8(USART1);


                     if ((Rx1stSentADCMicroPacket1Err[i] & USART_ISR_PE) != 0) ADCU1PEError++;

                     if ((Rx1stSentADCMicroPacket1Err[i] & USART_ISR_FE) != 0) ADCU1FEError++;

                     if ((Rx1stSentADCMicroPacket1Err[i] & USART_ISR_NE) != 0) ADCU1NEError++;


The error bits in the ISR register surely work, so there's likely another explanation here. Interrupts enabled? Perhaps the flags get cleared elsewhere. You don't appear to be waiting for RXNE, perhaps the lines are just idle or misconfigured or otherwise not connected how you think. Or you are "receiving" before data is even there.

If those variables are not used anywhere else, they can be optimized out. Probably aren't but could be.

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