This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

uart overrun handling

Other Parts Discussed in Thread: OMAP-L138, AM1808, TMS320F2812, OMAPL138

We are using logic pd omap-l138 ZOOM experimental kit. with starterware version AM1808_StarterWare_1_00_02_02 on CCSv5x.

We are facing an unique problem with UART. Once the UART overruns we do not get any interrupt. How to handle this issue ?

Thank you.

static void ConfigureAINTCIntUART2(void)
{
    /* Registers the UARTIsr in the Interrupt Vector Table of AINTC. */
    IntRegister(SYS_INT_UARTINT2, UART2Isr);
    /* Map the channel number 2 of AINTC to UART2 system interrupt. */
    IntChannelSet(SYS_INT_UARTINT2, 3);
    IntSystemEnable(SYS_INT_UARTINT2);
}

void vInitUART_2()
{
   unsigned int intFlags = 0;
   unsigned int config = 0;

   /* Enabling the PSC for UART2.*/
   PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART2, PSC_POWERDOMAIN_ALWAYS_ON,
        PSC_MDCTL_NEXT_ENABLE);
   /* Setup PINMUX */
   UARTPinMuxSetup(2, FALSE);
   /* Enabling the transmitter and receiver*/
   UARTEnable(SOC_UART_2_REGS);
   /* 1 stopbit, 8-bit character, no parity */
   config = UART_WORDL_8BITS;
   /* Configuring the UART parameters*/
   UARTConfigSetExpClk(SOC_UART_2_REGS, SOC_UART_2_MODULE_FREQ,
                  BAUD_115200, config,
                  UART_OVER_SAMP_RATE_16);
   /* Enabling the FIFO and flushing the Tx and Rx FIFOs.*/
   UARTFIFOEnable(SOC_UART_2_REGS);
   /* Setting the UART Receiver Trigger Level*/
   UARTFIFOLevelSet(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_1);
   SetupAINTCInt();
   /* Configure AINTC to receive and handle UART interrupts. */
   ConfigureAINTCIntUART2();
   /* Preparing the 'intFlags' variable to be passed as an argument.*/
   intFlags |= (UART_INT_LINE_STAT  |  \
            UART_INT_TX_EMPTY |     \
            UART_INT_RXDATA_CTI);
   /* Enable the Interrupts in UART.*/
   UARTIntEnable(SOC_UART_2_REGS, intFlags);
}

static void UART2Isr()
{
    unsigned char rxData = 0;
    unsigned int int_id = 0;

    /* This determines the cause of UART2 interrupt.*/
    int_id = UARTIntStatus(SOC_UART_2_REGS);
    /* Clears the system interupt status of UART2 in AINTC. */
    IntSystemStatusClear(SYS_INT_UARTINT2);
    /* Checked if the cause is transmitter empty condition.*/
    if(UART_INTID_TX_EMPTY == int_id)
    {
       //Tx Code
    }
    /* Check if the cause is receiver data condition.*/
    if(UART_INTID_RX_DATA == int_id)
    {
      //Rx Code
    }
    /* Check if the cause is receiver line error condition.*/
    if(UART_INTID_RX_LINE_STAT == int_id)
    {
        while(UARTRxErrorGet(SOC_UART_2_REGS))
        {
            /* Read a byte from the RBR if RBR has data.*/
            UARTCharGetNonBlocking(SOC_UART_2_REGS);
        }
    }
}

 

 

  • Dear SW Team,

    Can you please help here? We need some clues on the behavior. Not sure if per byte inerrupt is a good idea. Can you please review and advise?

    Posting more details on this:

    Following configuration was used:

    1. Starterware 1.00.02.02
    2. Windows based CCSv5.1
    3. Code Sourcery GCC for arm-none-eabi - v2009q1 arm-none-eabi tool chain
    4. Target: AM1808 Zoom eXp board.

    However we would like to highlight some workarounds we sought and require your expert view on them:

     

    1. We have used two UARTs (namely UART1 and UART2). The application communication protocol being Modbus RTU, we need interrupt every 1 byte. For this we had setup FIFO (16 bytes) with trigger set to 1. However when we ran both of them in IRQ along with other interrupt sources, we faced OVERRUN issues. We know that Starterware cannot preempt IRQ for IRQ and FIQ for FIQ. So we have moved receive interrupts of both UARTs to FIQ. It’s working fine till now… but do you foresee any issues.
    2. Secondly, OVERRUN flag doesn’t give an interrupt, and after having an OVERRUN event, UART communication is stalled permanently.  This is observed in DEBUG mode, we haven’t tested this on RELEASE. Same has been seen by “pausing” the application and re-running it. Is there any way by which we can clear OVERRUN flag. Existing code with error check doesn’t work.

     

    Potentially, OVERRUN is a risk when we go on field.  Please help us to get through on the above two issues. 

    Thanks

    Feroz

  • More inputs from customer:


    Yes we have set the trigger to OE for ISR. Please see the code below. Same reflects in above e2e post.

     

    intFlags |= (UART_INT_LINE_STAT  |  UART_INT_RXDATA_CTI);
    /* Enable the Interrupts in UART.*/
    UARTIntEnable(SOC_UART_2_REGS, intFlags);


    The Starterware code example can be used to simulate this problem. While receiving continuous bytes coming from the serial port (without handshaking), you may pause and see that the OE flag getting set and the ISR is not serviced at all, if you put break point in ISR. However it may not give you overrun without pausing as there is not other interrupt source.

     

    The overrun occurs on other interrupts during runtime (without pausing). This is because the unavailability of nesting of interrupts. There are only two levels of interrupts when it comes to nesting – FIQ and IRQ.

     

    Another important observation in due course of time is that transmit doesn’t get affected, even when the OE flag is set.

     

    From my perspective, disabling OE (even if it provides) may not be a good idea. It is important for an application to know this. Based on all other MCUs I have worked with (and including your DSC – TMS320F2812), Overrun gets interrupt attention and cleared after the UART interrupt register is read (and/or the receive buffer is read).

     

    P.S. Other important attributes you may require to know are:

    1. Processor running at 300MHz.
    2. Peripherals set to 133MHz
    3. Baud Rate of UART is 38400
    4. FIFO set
    5. Rx Trigger at Level 1
    Thanks!
    Best Regards,
    Feroz


  • Hello Feroz/Jitendra,

    I studied your query. I also tested the UART interrupt application of AM1808.

    The details are given below.

    Test Setup Configurations

    The test configurations that I used are given below:

    Release Package:  AM1808 STARTERWARE 01.00.02.02

    Baud Rate: 38400/115200 baud

    UART Input Clock Frequency: 150MHz

    Serial Console application: Tera Term

    Receiver FIFO Trigger Level: 1

    Description

    The UART interrupt application prints a string relevant to the application. Then it expects the user to enter characters. The entered characters are echoed immediately after they are entered. In essence, the application uses a receive trigger level of 1. Thus an interrupt is generated after every byte is received.

    To test a faster input of characters, I sent a text file from Tera Term. This text file was 74 KiloBytes in size. The characters were echoed properly. To also test if a Receiver Line Status Interrupt was raised, I put a breakpoint in the respective branch in the UART ISR. The breakpoint was not hit implying that during the reception of the file, no errors were generated.

    As I have mentioned above, I tested with two baud rates – 38400 baud and 115200 baud with an oversampling rate of 16.

    In your recent post, you have mentioned that the “Peripheral Frequency is 133MHz”. By telling “Peripheral Frequency” did you mean the input frequency to the UART module? Or did you confuse it with the frequency of mDDR which is 132Mhz?. If you meant this to be UART’s input frequency, could you try with an UART input frequency of 150MHz?

    You could try your application with the parameters that I tested with. If you still encounter Overrun errors, do revert with your observations.

     

    Thanks and Regards.

    Gurudutt.

  • Hi Gurudutt,

    Thanks for your reply.

    The configuration is as follows and the UART input frequency is 150MHz: 

    UARTConfigSetExpClk(SOC_UART_2_REGS, SOC_UART_2_MODULE_FREQ, BAUD_115200, config, UART_OVER_SAMP_RATE_16);

    Note that the overrun is not because of continuous stream of data or a particular baud, it is primarily because of CPU processing other interrupt that may take a longer time and cannot nest-in UART ISR. I appreciate your test, but please note that overrun during run-time will not occur due to singly run UART receive example or application. When atleast two UARTs (all with same Rx Trigger = 1) and yet more interrupt sources run together - and all under IRQs, overrun would occur. It is best simulated by pausing the application in between stream of continous data... I suggest you pause the application and then send data from Teraterm, you would find that overrun flag is set and receive stalled. Also FREE bit is crucial for this simulated result which is being zero by default. Alternatively, you can also integrate Webserver example and two UARTs together with Ethernet connected to Internet (i.e. receive good amount of external world traffic and hence result in continuous receive interrupts)

    I cannot share my application with you as it is confidential to the organization but a TI employee can surely come down to have a look at one of our integration test, the result of which is all other tasks (related to non-UART peripherals) continue to run except for the UARTs. 

    Regards,

    Yogendra

  • Hello Yogendra,

    I performed the experiments as you suggested. I am able to get the Overrun Interrupt and am able to service it. Allow me to explain what I did.

    Configuration Setup

    1>    AM1808_StarterWare_1_00_02_02 release package

    2>    Board used – OMAPL138 board

    Steps that I followed during the experiments

    1>    Built the UART interrupt application using GCC.

    2>    Loaded the executable file (.out) on the board using CCS.

    3>    Gave a Run to check if the application printed the appropriate message. It did. Then typed some characters to check if they were echoed. It happened.

    4>    Now I suspended (paused) the execution. The control suspended in the while (1) loop in the main function.

    5>    Now I sent a file containing 56 bytes of data through Tera Term. Though the file was sent, no contents were visible on the Tera Term window. This was expected.

    6>    Now in CCS I put a breakpoint in the error section of the UART ISR.

    7>    Then I gave a Run. The control hit the breakpoint.

    8>    Now I opened the Memory Browser Window in CCS and viewed the UART register space.

    9>    The Line Status Register (LSR) showed that Overrun Error Bit was set. I stepped the control into the function UARTRxErrorGet(). After execution of the single   instruction in this API, the Overrun Error (OE) bit was cleared to zero. That is, as soon as the LSR was read, the OE bit was reset to zero. Since the Overrun error was recognized, the Overrun error had to be handled in that error section of the ISR itself by reading all the bytes in the FIFO. Instead of doing this, the ISR read a single byte only.

    Realizing this I modified the error section of the ISR to read all the bytes present in the receive FIFO. I have pasted the modified error section of the ISR code below.

     

    static void UARTIsr()

    {

       unsigned int rxErrorType = 0;

       …………………………………………………………

       …………………………………………………………

     

        /* Check if the cause is receiver line error condition.*/

        if(UART_INTID_RX_LINE_STAT == int_id)

        {

            /* Collect the status of error bits. */

            rxErrorType = UARTRxErrorGet(SOC_UART_2_REGS);

     

            /* Checking if the error is an Overrun error. */

            if(rxErrorType & UART_OVERRUN_ERROR)

            {

                UARTPuts("Overrun Error Occured.\r\n", -1);

                while(UARTCharsAvail(SOC_UART_2_REGS))

                {

                    rxData = UARTCharGet(SOC_UART_2_REGS);

                    UARTCharPut(SOC_UART_2_REGS, rxData);

                }

            }

         }

         return;

    }

     

    We have to realize that the receive FIFO size is 16 bytes. Thus although I had sent 56 bytes, only the first 16 bytes were received by the receive FIFO and the remaining bytes were lost.

    Was not the Overrun Interrupt generated previously with the release package code?

    The Overrun interrupt was generated. However, proper handling of the Overrun Error was not performed. We read the LSR register which cleared the OE bit. We had to immediately read the entire FIFO but it was not done. Thus the OE condition was lost and the FIFO was not read.

    We would never get an opportunity to read the entire FIFO again.

    With this being the case, it seemed that the Overrun Interrupt was not generated even though the OE bit was set.

     

    I suggest that you use the error section code mentioned above in your ISR and get back to us with the results.

    Please revert if you have any comments.

     

    Thanks and Regards.

    Gurudutt.

  • Sorry for replying late as we have moved to other features holding the issue to come back later on.

    Our application doesn't reach to breakpoint you have hit, by that we mean that we never go to that ISR code section after getting affected by overrun event.

    As an aside note, we have found a latest version of Starterware 2.0.0.7 released on 3rd Aug 2012 for AM335x (http://processors.wiki.ti.com/index.php/StarterWare_02.00.00.07_Release_Notes) has introduced IRQ pre-emption which is "a big welcome" for our application  However a latest version for our processor Starter-ware 1.0.3.3 is still not upgraded to this feature. Can your team port the stuff to AM18xx version of Starter-ware i.e. introduce IRQ pre-emption as done in 2.0.0.7?