URGENT: UART stops working with overrun error

Hello forum,

we are using the S7G2 on a custom board with two SCI UARTs over UART Framework and SSP 1.6.0.

One of these two UARTs has the following configuration:

The interrupt priorities are set to zero for testing to eliminate any interrupt related conflicts. 

When we run the software with this configuration the UART does not receive any data after some time.

With the debugger connected I can see that the sci_uart_eri_isr() gets called with an Overrun Error when this happens. For test I did some pin toggeling within the sci_uart_rxi_isr() and sci_uart_eri_isr(). At the beginning the sci_uart_rxi_isr() gets called with every received character. But then after some minutes or hours the sci_uart_eri_isr() gets called with every second character but the sci_uart_rxi_isr() never gets called again. 

For further testing I set the "Receive FIFO Trigger Level" from "One" to "Max". As far as I understand the Hardware Manual the Receive Interrupt should call the sci_uart_rxi_isr() after 16 characters. But as the following image shows the interrupt (green) fires after receiving 18 characters (blue) and so some characters are missing.

My question are:

  • Why does the Overrun Error occurs? A baud rate of 19200b/s should be no problem for a controller running with 240MHz ICLK. Especally when the amount of received data is that low (less than 1kB within 3 seconds).
  • Why does the Receive Interrupt never fires again after the Overrun Error occurs? I've checked the Interrupt flags with the debugger RIE and RE are set to 1.
  • Why does changing the Receive FIFO Trigger Level from One to Max does not work in general?

Because our projetc is very critical, help would be appreciated and is urgently needed.

Best regards

David

  • Hi David,

    I got some of these notes about overrun errors from the web, i hope this helps.

    Overrun error occurs when another byte of data arrives even before the previous byte has not been read from the UART's receive buffer. This is mainly due to time taken by CPU to service the UART interrupt in order to remove characters from receive buffer. If the CPU does not service the UART interrupt quick enough and does not read the received byte before the next arrives, then the buffer becomes full and an Overrun error occurs. Below are some tips to avoid overrun errors.

    1. Run the CPU at the maximum possible speed. This will speed up the execution of the UART interrupt (and any other interrupt too).

    2. Keep the UART ISR efficient and as short as possible. For example the ISR could just read from the UART's RX buffer and transfer it to a RAM buffer and set a flag. The processing of the received data could be done in the foreground. The time taken to execute the ISR should be less than the time taken to receive the next data byte.

    3. Writing a C ISR pushes and pops all the virtual registers, paging registers and A and X registers. This increases the time taken to execute an ISR. Write the UART ISR in assembly to make it more efficient.

    4. Other interrupts in the program can also create interrupt latencies which could result in overrun errors. Under such circumstances, reducing the baud rate of the UART will also prevent the overrun error.

    Herald
    RenesasRulz Forum Moderator

    https://renesasrulz.com/
    https://academy.renesas.com/
    en-us.knowledgebase.renesas.com/

  • In reply to Herald:

    Hello Herald,

    first of all thank you for your reply.

    I am using the UART functionality from SSP UART framework. So, I did not program the ISR's code. From my tests with pin toggeling within the ISR I can say, that the time it takes to handle the ISR is much shorter than the time it takes to receive the next byte.

    Even if there would be some latency, this does not explain why I can not receive a single byte after the overrun error occurs the first time.

    I also tried to give the error interrupt a lower priority than the receive interrupt. If something would block the receive ISR than it would also block the error ISR. But this change did not make any difference.

    Maybe it sounds a little bit strange, but is it possible that an ISR is not called by the NVIC although the appropriate interrupt occurs?

    Best regards
  • I have some additional information about this problem:

    A test with FIFO Receive Tigger Level One shows that, the receive ISR does not get called after some time, although there are bytes send to the S7G2. The error occurs after byte no. 17 is received after the last receive ISR call. I think 16 bytes are stored in the FIFO, but the FIFO overruns when receiving the 17th byte.

    Obviously the receive ISR is never called again after some runtime and this causes the Overrun Error to be permantly. But I really don't know what prevents the receive ISR from being called.

    green - Receive ISR start to Receive ISR end

    red - Error ISR start (the pin is held high because I set a breakpoint into the ISR)

    blue - receive data

  • In reply to dgaw86:

    We had encountered a similar issue with an S3A1 using Hal drivers. The quick fix was to recognize an overrun occurred and to close then open the Hal driver. Overruns can not be avoided 100% so they must be handled. Is this a Hal driver issue?
  • In reply to RPM:

    Hi RPM,

    thanks for your hint.

    I am using the UART Framework and when this error occurs I close and reopen the framework. But I don't know if this restart the underlying driver, too. So I will test this.

    There is something else I've figured out. I've checked the IELSR8-Register in the ICU when a bytes was received successfully and when the overrun error occurs.

               

    In this register the SCI Receive IRQ of the UART is registered. But when the error occurs the IR-Flag is not set (HW-manual says the IR-Flag is set "When an interrupt request is received from the associated peripheral module or IRQi pin"). I believe that's why the receive ISR is not called. But when I check the SCI2 registers. Then the RIE and RE Flags are set.

  • In reply to dgaw86:

    Hello David,

    How is your issue? Have you eventually solved it?

    Kind regards,
  • In reply to Sergey Sokol:

    The cause of overrun-error still takes place, what is very suspicious, but error-handling now works correct by resetting the FIFO and clearing the RDF-flag in the sci_uart_eri_isr() of the r_sci_uart.c:

    /** Determine cause of error. */
    if (HW_SCI_OverRunErrorCheck(p_sci_reg))
    {
    args.event = UART_EVENT_ERR_OVERFLOW;

    /** Reset FIFO **/
    HW_SCI_ReceiveFifoReset(p_sci_reg);

    /** Clear RDF Flag **/
    HW_SCI_RDFClear(p_sci_reg);
    }

  • In reply to dgaw86:

    Hi dgaw86-
    Thanx for letting us know your approach!

    Warren