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.

C6748 UART interrupt has no response using the example of uart int C6748_StarterWare\examples\lcdkC6748\uart

Other Parts Discussed in Thread: OMAPL138

Hello,

I have a C6748 test board and I'm using a modified uartEcho program from C6748_StarterWare_1_20_04_01.

1.I modified the example of  C6748_StarterWare\examples\lcdkC6748\uart, I only delete(mask) the code of " length--; count++; "in UARTIsr().

2.I sent seven characters "abcdefg" to uart using pc every second;

3.The uart can not transmit and receive after the board run a few minutes, 

Any suggestions or reasons?

The code is shown below.

#include "hw_psc_C6748.h"

#include "soc_C6748.h"

#include "interrupt.h"

#include "lcdkC6748.h"

#include "hw_types.h"

#include "uart.h"

#include "psc.h"

/****************************************************************************/

/*                      LOCAL FUNCTION PROTOTYPES                           */

/****************************************************************************/

static void ConfigureIntUART(void);

static void SetupInt(void);

static void UARTIsr(void);

/****************************************************************************/

/*                      GLOBAL VARIABLES                                    */

/****************************************************************************/

char txArray[] = "StarterWare UART echo application\n\r";

/****************************************************************************/

/*                      LOCAL FUNCTION DEFINITIONS                          */

/****************************************************************************/

int main(void)

{

    unsigned int intFlags = 0;

    unsigned int config = 0;

    /* Enabling the PSC for UART0.*/

    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_UART0, PSC_POWERDOMAIN_ALWAYS_ON,

    PSC_MDCTL_NEXT_ENABLE);

    /* Setup PINMUX */

    UARTPinMuxSetup(0, FALSE);

    

    /* Enabling the transmitter and receiver*/

    UARTEnable(SOC_UART_0_REGS);

    /* 1 stopbit, 8-bit character, no parity */

    config = UART_WORDL_8BITS;

    /* Configuring the UART parameters*/

    UARTConfigSetExpClk(SOC_UART_0_REGS, SOC_UART_0_MODULE_FREQ,

                        BAUD_115200, config,

                        UART_OVER_SAMP_RATE_16);

    /* Enabling the FIFO and flushing the Tx and Rx FIFOs.*/

    UARTFIFOEnable(SOC_UART_0_REGS);

    /* Setting the UART Receiver Trigger Level*/

    UARTFIFOLevelSet(SOC_UART_0_REGS, UART_RX_TRIG_LEVEL_1);

    

    /*

    ** Enable AINTC to handle interrupts. Also enable IRQ interrupt in ARM 

    ** processor.

    */

    SetupInt();

    /* Configure AINTC to receive and handle UART interrupts. */

    ConfigureIntUART();

    /* 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_0_REGS, intFlags);

    while(1);

}

/*

** \brief   Interrupt Service Routine(ISR) to be executed on UART interrupts.

**          Depending on the source of interrupt, this 

**          1> writes to the serial communication console, or 

**          2> reads from the serial communication console, or 

**          3> reads the byte in RBR if receiver line error has occured.

*/

static void UARTIsr()

{

    static unsigned int length = sizeof(txArray);

    static unsigned int count = 0;

    unsigned char rxData = 0;

    unsigned int int_id = 0;

    /* This determines the cause of UART0 interrupt.*/

    int_id = UARTIntStatus(SOC_UART_0_REGS);

#ifdef _TMS320C6X

    // Clear UART0 system interrupt in DSPINTC

    IntEventClear(SYS_INT_UART0_INT);

#else

    /* Clears the system interupt status of UART0 in AINTC. */

    IntSystemStatusClear(SYS_INT_UARTINT0);

#endif

  

    /* Checked if the cause is transmitter empty condition.*/

    if(UART_INTID_TX_EMPTY == int_id)

    {

        if(0 < length)

        {

            /* Write a byte into the THR if THR is free. */

            UARTCharPutNonBlocking(SOC_UART_0_REGS, txArray[count]);

//            length--;

//            count++;

        }

        if(0 == length)

        {

            /* Disable the Transmitter interrupt in UART.*/

            UARTIntDisable(SOC_UART_0_REGS, UART_INT_TX_EMPTY);

        }

     }

    /* Check if the cause is receiver data condition.*/

    if(UART_INTID_RX_DATA == int_id)

    {

        rxData = UARTCharGetNonBlocking(SOC_UART_0_REGS);

//        UARTCharPutNonBlocking(SOC_UART_0_REGS, rxData);

    }

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

    if(UART_INTID_RX_LINE_STAT == int_id)

    {

        while(UARTRxErrorGet(SOC_UART_0_REGS))

        {

            /* Read a byte from the RBR if RBR has data.*/

            UARTCharGetNonBlocking(SOC_UART_0_REGS);

        }

    }

    return;

}

/*

** \brief   This function invokes necessary functions to configure the ARM

**          processor and ARM Interrupt Controller(AINTC) to receive and

**          handle interrupts.

*/

static void SetupInt(void)

{

#ifdef _TMS320C6X

// Initialize the DSP INTC

    IntDSPINTCInit();

// Enable DSP interrupts globally

    IntGlobalEnable();

#else

    /* Initialize the ARM Interrupt Controller(AINTC). */

    IntAINTCInit();

    /* Enable IRQ in CPSR.*/     

    IntMasterIRQEnable();

    /* Enable the interrupts in GER of AINTC.*/

    IntGlobalEnable();

    /* Enable the interrupts in HIER of AINTC.*/

    IntIRQEnable();

#endif

}

/*

** \brief  This function confiugres the AINTC to receive UART interrupts.

*/ 

static void ConfigureIntUART(void)

{

#ifdef _TMS320C6X

    IntRegister(C674X_MASK_INT4, UARTIsr);

    IntEventMap(C674X_MASK_INT4, SYS_INT_UART0_INT);

    IntEnable(C674X_MASK_INT4);

#else

    /* Registers the UARTIsr in the Interrupt Vector Table of AINTC. */

    IntRegister(SYS_INT_UARTINT0, UARTIsr);

    /* Map the channel number 2 of AINTC to UART0 system interrupt. */

    IntChannelSet(SYS_INT_UARTINT0, 2);

    IntSystemEnable(SYS_INT_UARTINT0);

#endif

}

  • Hi jlkmaster,

    1.I modified the example of C6748_StarterWare\examples\lcdkC6748\uart, I only delete(mask) the code of " length--; count++; "in UARTIsr().

    2.I sent seven characters "abcdefg" to uart using pc every second;

    3.The uart can not transmit and receive after the board run a few minutes,

    Why did you delete the lines ?
    Have you tried to understand the code ?

    Please make sure that "UARTIsr" UART ISR function is called when you send data from PC to UART.
  • HI,

    I have already provided the steps to run this UART example on the target board. The steps given there for OMAPL138 LCDK is applicable for C6748 LCDK too.

    Please follow it and let me know how it goes for you.

  • Hi Shankari,
    I have already verify the original UART example is OK. But I want uart to output the information every seconds, not once. So I modified the UART example to test the function, it is only a test example.
    Regards,
    jlkmaster
  • If you are sending characters to UART from PC then you would get the data in "rxData" array, you should use this array for further stuff.
    Can you please print the "rxData" array ?
    That "length" and "count" changes won't affect for your current setup.

    Actually you are sending the data from PC to UART so you would "int_id" for receive.
    if(UART_INTID_RX_DATA == int_id)

    Please try to understand the code and change it as per your requirement.
    This example is just UART loopback.
  • Your interrupt code appears to
    - transmit a 'S' character repeatedly.
    - receive a character and discard it.
    - on overflow, parity, framing or break then read out all data in the FIFO.

    In another forum thread, you say that disabling ELSI solves your problem. That removes overflow, parity, framing or break interrupts. Implies that your interrupt code is busy handling one of those errors.

    Could you elaborate on "The uart can not transmit and receive after the board run a few minutes,". Is the PC side still sending? What is happening on the target? You should dump the UART status registers after the problem occurs.

    You say that your PC app sends "abcdefg" every second. Does your PC app read the serial port. It may be possible that input buffer is getting full of 'S' characters (because you are not reading them out?). The behavior of the Windows Serial Port driver is not well documented in that case. Perhaps the driver is sending back a "break" to flag that it it full. Normally flow control characters or signals would be used. If you are using a USB to serial adaptor cable, maye the adaptor is sending back a "break".
  • In reply to Norman Wrong:

    Thank you!

    Is the PC side still sending? What is happening on the target? You should dump the UART status registers after the problem occurs.

    The PC is still sending, the target has no interrupt.PC app  read the serial port when PC app sends character. what means you should dump the UART status registers after the problem occurs?what can I do?

  • In reply to Titusrathinaraj Stalin:

    I want to test the situation that I transmit and receive simultaneously. 

    I set up a timer (~1 second)  to reset the "length" variable , "count" variable and re-enable the UART_TX interrupt.  The program will start, and send out "StarterWare UART echo application", and  send out "StarterWare UART echo application" every second.

    I will send a command to uart after 30 seconds the program started, and repeat it. The uart has no interrupt after 300 times, and LSR register have a OE indicator,IER register is 0x7. The situation is miss when I disable the ELSI interrupt. I don't know why.

    Any suggestions or reasons?

    the code :

    #include "soc_C6748.h"
    
    #include "interrupt.h"
    
    #include "lcdkC6748.h"
    
    #include "hw_types.h"
    
    #include "uart.h"
    
    #include "psc.h"
    
    /****************************************************************************/
    
    /*                      LOCAL FUNCTION PROTOTYPES                           */
    
    /****************************************************************************/
    
    static void ConfigureIntUART(void);
    
    static void SetupInt(void);
    
    static void UARTIsr(void);
    
    /****************************************************************************/
    
    /*                      GLOBAL VARIABLES                                    */
    
    /****************************************************************************/
    
    char txArray[] = "StarterWare UART echo application\n\r";
    static unsigned int length = sizeof(txArray);
    static unsigned int count = 0;
    
    /****************************************************************************/
    
    /*                      LOCAL FUNCTION DEFINITIONS                          */
    
    /****************************************************************************/
    
    int main(void)
    
    {
    
        unsigned int intFlags = 0;
    
        unsigned int config = 0;
    
        /* Enabling the PSC for UART0.*/
    
        PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_UART0, PSC_POWERDOMAIN_ALWAYS_ON,
    
        PSC_MDCTL_NEXT_ENABLE);
    
        /* Setup PINMUX */
    
        UARTPinMuxSetup(0, FALSE);
    
        
    
        /* Enabling the transmitter and receiver*/
    
        UARTEnable(SOC_UART_0_REGS);
    
        /* 1 stopbit, 8-bit character, no parity */
    
        config = UART_WORDL_8BITS;
    
        /* Configuring the UART parameters*/
    
        UARTConfigSetExpClk(SOC_UART_0_REGS, SOC_UART_0_MODULE_FREQ,
    
                            BAUD_115200, config,
    
                            UART_OVER_SAMP_RATE_16);
    
        /* Enabling the FIFO and flushing the Tx and Rx FIFOs.*/
    
        UARTFIFOEnable(SOC_UART_0_REGS);
    
        /* Setting the UART Receiver Trigger Level*/
    
        UARTFIFOLevelSet(SOC_UART_0_REGS, UART_RX_TRIG_LEVEL_1);
    
        
    
        /*
    
        ** Enable AINTC to handle interrupts. Also enable IRQ interrupt in ARM 
    
        ** processor.
    
        */
    
        SetupInt();
    
        /* Configure AINTC to receive and handle UART interrupts. */
    
        ConfigureIntUART();
    
        /* 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_0_REGS, intFlags);
    
        while(1);
    
    }
    
    /*
    
    ** \brief   Interrupt Service Routine(ISR) to be executed on UART interrupts.
    
    **          Depending on the source of interrupt, this 
    
    **          1> writes to the serial communication console, or 
    
    **          2> reads from the serial communication console, or 
    
    **          3> reads the byte in RBR if receiver line error has occured.
    
    */
    
    static void UARTIsr()
    
    {
        unsigned char rxData = 0;
    
        unsigned int int_id = 0;
    
        /* This determines the cause of UART0 interrupt.*/
    
        int_id = UARTIntStatus(SOC_UART_0_REGS);
    
    #ifdef _TMS320C6X
    
        // Clear UART0 system interrupt in DSPINTC
    
        IntEventClear(SYS_INT_UART0_INT);
    
    #else
    
        /* Clears the system interupt status of UART0 in AINTC. */
    
        IntSystemStatusClear(SYS_INT_UARTINT0);
    
    #endif
    
      
    
        /* Checked if the cause is transmitter empty condition.*/
    
        if(UART_INTID_TX_EMPTY == int_id)
    
        {
    
            if(0 < length)
    
            {
    
                /* Write a byte into the THR if THR is free. */
    
                UARTCharPutNonBlocking(SOC_UART_0_REGS, txArray[count]);
    
                length--;
    
                count++;
    
            }
    
            if(0 == length)
    
            {
    
                /* Disable the Transmitter interrupt in UART.*/
    
                UARTIntDisable(SOC_UART_0_REGS, UART_INT_TX_EMPTY);
    
            }
    
         }
    
        /* Check if the cause is receiver data condition.*/
    
        if(UART_INTID_RX_DATA == int_id)
    
        {
    
            rxData = UARTCharGetNonBlocking(SOC_UART_0_REGS);
    
    //        UARTCharPutNonBlocking(SOC_UART_0_REGS, rxData);
    
        }
    
        /* Check if the cause is receiver line error condition.*/
    
        if(UART_INTID_RX_LINE_STAT == int_id)
    
        {
    
            while(UARTRxErrorGet(SOC_UART_0_REGS))
    
            {
    
                /* Read a byte from the RBR if RBR has data.*/
    
                UARTCharGetNonBlocking(SOC_UART_0_REGS);
    
            }
    
        }
    
        return;
    
    }
    
    /*
    
    ** \brief   This function invokes necessary functions to configure the ARM
    
    **          processor and ARM Interrupt Controller(AINTC) to receive and
    
    **          handle interrupts.
    
    */
    
    static void SetupInt(void)
    
    {
    
    #ifdef _TMS320C6X
    
    // Initialize the DSP INTC
    
        IntDSPINTCInit();
    
    // Enable DSP interrupts globally
    
        IntGlobalEnable();
    
    #else
    
        /* Initialize the ARM Interrupt Controller(AINTC). */
    
        IntAINTCInit();
    
        /* Enable IRQ in CPSR.*/     
    
        IntMasterIRQEnable();
    
        /* Enable the interrupts in GER of AINTC.*/
    
        IntGlobalEnable();
    
        /* Enable the interrupts in HIER of AINTC.*/
    
        IntIRQEnable();
    
    #endif
    
    }
    
    /*
    
    ** \brief  This function confiugres the AINTC to receive UART interrupts.
    
    */ 
    
    static void ConfigureIntUART(void)
    
    {
    
    #ifdef _TMS320C6X
    
        IntRegister(C674X_MASK_INT4, UARTIsr);
    
        IntEventMap(C674X_MASK_INT4, SYS_INT_UART0_INT);
    
        IntEnable(C674X_MASK_INT4);
    
    #else
    
        /* Registers the UARTIsr in the Interrupt Vector Table of AINTC. */
    
        IntRegister(SYS_INT_UARTINT0, UARTIsr);
    
        /* Map the channel number 2 of AINTC to UART0 system interrupt. */
    
        IntChannelSet(SYS_INT_UARTINT0, 2);
    
        IntSystemEnable(SYS_INT_UARTINT0);
    
    #endif
    
    }
    

    Regards,
    jlkmaster

  • When do you get a OE? Is it long after the test has failed? Could you put a breakpoint just after the line status check and get the value of the LSR register?

    if(UART_INTID_RX_LINE_STAT == int_id)
    {
    while(UARTRxErrorGet(SOC_UART_0_REGS)) // Put breakpoint here. Check LSR.

    Note that re-abling TX interrupts sometimes does not always work with 16550 UARTs. You might need to write the first character to the THR to prime the transmitter.
  • hello,
    we note: the value of IIR register is:

    1h-Transmitter holding register empty(priority 3)

    2h-Receiver data available(priority 2)

    3h-Receiver line status(priority 1, highest)

    6h-character timeout indication(priority 2);

    If transmit interrupt, receiver interrupt and Receiver line status interrupt is a ISR function, the value of IIR register is 3h when transmit interrupt and receive interrupt come in simultaneously, there is a conflict between 3h(transmit interrupt and receive interrupt simultaneously) and 3h-Receiver line status; what will happen at this time and how to deal with it?
    Thank you!
  • Interrupt sources in the IIR are queued according to their priority. You read the IIR repeatedly to get all the interrupts. If two interrupts occur simultaneously, the higher priority will be in the IIR. After servicing the higher priority interrupt, another interrupt should occour for the lower priority one.

    Typically, the ISR would repeatedly read the IIR and handle interrupts until there are no more pending interrupts (see IPEND). This is more efficicent as there can be a lot of overhead in handling an interrupt. The StarterWare driver is a very simple demo and takes the less efficient approach. StarterWare code does not define a way to access IPEND nor does it seem to use it. The 16550 UART is a very common driver. There is a lot of bare-metal driver code to use as an example. For example, u-boot and linux come to mind.