Why am I unable to clear UART overrun/framing error?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Why am I unable to clear UART overrun/framing error?

4,990 Views
asfarley
Contributor IV

I'm unable to clear UART framing/overrun errors following the recommended procedure:

-disable RX

-read S1

-read D

-enable RX

It looks like this person was having the same issue, not sure if it was ever resolved:

Kinetis K10 UART overrun error. 

I'm using a K22f, the UART in question is UART5. 

Two questions: 

1) Why isn't the above procedure clearing the overrun error?

2) What dictates whether the device transitions to PE_ISR(Cpu_ivINT_UART5_ERR) after encountering an error? 

My main concern is preventing my code from hanging when it hits a UART error.

Labels (1)
0 Kudos
4 Replies

3,053 Views
asfarley
Contributor IV

I'd like to bump this question. Mark - thanks for the reply. Your procedure seems to essentially the same as what I'm doing, but still the UART overruns are causing the UART to eventually stop receiving RX interrupts. 

Here's what I'm seeing:

1) UART RX is working

2) Eventual buffer overrun or framing error

3) UART5_OnError function is hit. UART5_OnError clears error flags.

4) PE_ISR(Cpu_ivINT_UART5_ERR) is hit. I've commented out PE_DEBUGHALT() and replaced with a printf call.

5) Soon after, PE_ISR(Cpu_ivINT_UART5_ERR) is hit without UART5_OnError being executed. (Why is the PE_ISR triggered twice, while UART5_OnError  is only triggered once?)

6) UART5 fails to receive any incoming bytes.

Why is this happening? I am:

a) clearing error flags in the interrupt

b) flushing buffer in the interrupt

c) flushing before before and after any large transfers

So I don't see how the UART is getting into what looks like a permanent RX buffer overrun state. Even if it temporarily overruns, it should eventually flush and start up again. 

Would appreciate some support from NXP on this one. Thanks.

0 Kudos

3,053 Views
mariusb
Contributor I

Hello, Alexander,

I believe I have found what causes the issue.

I had the same problem with Kinetis KEA64 MCU - once overrun flag occurs, interrupts stop and OR flag cannot be cleared.

I found out, that in order to clear OR flag OR interrupt itself must be enabled. Is is possibly connected together in a way that if interrupt is not enabled, then the flag is untouchable. Once I enabled overrun interrupt in C3 register (in my case), I was able to clear overrun flag and interrupts continued to work.

After my discovery, I read the datasheet again, and found out, that I was probably misinterpreting the below line provided in the datasheet:

To clear OR, read UART_S1 with OR set and then read the UART data register (UART_D).

Before the discovery I thought, that in order to clear OR it should be set in S1 (obviously), but now I started to think that author of the datasheet maybe meant that OR interrupt must be set in order to be able to clear the OR flag.

Let me know if this is the case for you.

Regards,

Marius

0 Kudos

3,053 Views
asfarley
Contributor IV

Very interesting. I will test this possibility when I get a chance. Thanks!

0 Kudos

3,052 Views
mjbcswitzerland
Specialist V

Hi Alexander

I have used this code in the uTasker project for several years on various parts in order to recover from overruns:

        if (((UART5_S1 & UART_S1_RDRF) & UART5_C2) != 0) {               // reception interrupt flag is set and the reception interrupt is enabled
            fnUART5_HANDLER((unsigned char)UART5_D);                     // receive data interrupt - read the byte
            if ((UART5_S1 & UART_S1_OR) != 0) {                          // check status here to ensure that an overrun taking place between reading the status register on entry to the interrupt and reading the data register is detected
                (void)UART5_D;                                           // read the data register in order to clear the overrun flag and allow the receiver to continue operating
            }
        }

Since there will always be a receive interrupt to handle I never found it useful to install a dedicated interrupt for this error source. Practically it was never fund necessary to disable the receiver.

Regards

Mark

0 Kudos