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.

CCS/OMAP-L138: UART1 Connection - No Reading on Oscilloscope or Arduino Nano

Part Number: OMAP-L138
Other Parts Discussed in Thread: OMAPL138

Tool/software: Code Composer Studio

I am trying to interface an arduino nano with the OMAP-L138/C6748 via a connection through the J15 pinout and have a few questions. (Note: this is my first time dealing with any sort of embedded system design and I'm very new).

  1. I am using UART1, should I be using UART0 instead?
  2. When I probe the UART1 TX line with an oscilloscope (gnd is connected as well), I get a constant 0V signal. I based my code off of the uartEcho.c example provided in the startware package for the omap-l138, but modified it to use UART1 instead of UART2 and have provided it below (I am not receiving any errors when I compile in CCS). Could anybody provide any advice as to how I may fix my code?
    /**
     * \file  uartEcho.c
     *
     * \brief This is a sample application file which invokes some APIs
     *        from the UART device abstraction library to perform configuration,
     *        transmission and reception operations.
     */
    
    #include "hw_psc_OMAPL138.h"
    #include "soc_OMAPL138.h"
    #include "interrupt.h"
    #include "lcdkOMAPL138.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 UART2.*/
    //    PSCModuleControl(SOC_PSC_2_REGS, HW_PSC_UART2, PSC_POWERDOMAIN_ALWAYS_ON,
    //		     PSC_MDCTL_NEXT_ENABLE);
        PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART1, PSC_POWERDOMAIN_ALWAYS_ON,
        		     PSC_MDCTL_NEXT_ENABLE);
    
        /* Setup PINMUX */
        /**
         * \param   instanceNum       The instance number of the UART instance to be
         *                            used.
         * \param   modemCtrlChoice   User specifies whether he wants to use modem
         *                            control pins namely UARTn_RTS(Request To Send)
         *                            and UARTn_ CTS(Clear To Send).\n
         *                            This is:
         *                            TRUE - when modem control lines need to be
         *                                   selected.
         *                            FALSE - when modem control lines need not be
         *                                    selected.
         */
    //    UARTPinMuxSetup(2, FALSE);
        UARTPinMuxSetup(1, FALSE);
        
        /* Enabling the transmitter and receiver*/
    //    UARTEnable(SOC_UART_2_REGS);
        UARTEnable(SOC_UART_1_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);
    #define BAUD_9600 9600
        UARTConfigSetExpClk(SOC_UART_1_REGS, SOC_UART_1_MODULE_FREQ,
                            BAUD_9600, config,
                            UART_OVER_SAMP_RATE_16); //may have to change this
    
        /* Enabling the FIFO and flushing the Tx and Rx FIFOs.*/
    //    UARTFIFOEnable(SOC_UART_2_REGS);
        UARTFIFOEnable(SOC_UART_1_REGS);
    
        /* Setting the UART Receiver Trigger Level*/
    //    UARTFIFOLevelSet(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_1);
        UARTFIFOLevelSet(SOC_UART_1_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_2_REGS, intFlags);
        UARTIntEnable(SOC_UART_1_REGS, intFlags);
    
    //    while(1);
        unsigned char a = 97;
        while(1) {
        	UARTCharPutNonBlocking(SOC_UART_1_REGS, a);
        }
    //     I also used just a while(1); here as well and it made no difference
    }
    
    /*
    ** \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 UART2 interrupt.*/
    //    int_id = UARTIntStatus(SOC_UART_2_REGS);
        int_id = UARTIntStatus(SOC_UART_1_REGS);
    
    #ifdef _TMS320C6X
        // Clear UART2 system interrupt in DSPINTC
    //    IntEventClear(SYS_INT_UART2_INT);
        IntEventClear(SYS_INT_UART1_INT);
    #else
        /* Clears the system interupt status of UART2 in AINTC. */
    //    IntSystemStatusClear(SYS_INT_UARTINT2);
        IntSystemStatusClear(SYS_INT_UARTINT1);
    #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_2_REGS, txArray[count]);
            	UARTCharPutNonBlocking(SOC_UART_1_REGS, txArray[count]);
                length--;
                count++;
            }
            if(0 == length)
            {
                /* Disable the Transmitter interrupt in UART.*/
    //            UARTIntDisable(SOC_UART_2_REGS, UART_INT_TX_EMPTY);
            	UARTIntDisable(SOC_UART_1_REGS, UART_INT_TX_EMPTY);
            }
         }
    
        /* Check if the cause is receiver data condition.*/
        if(UART_INTID_RX_DATA == int_id)
        {
    //        rxData = UARTCharGetNonBlocking(SOC_UART_2_REGS);
        	rxData = UARTCharGetNonBlocking(SOC_UART_1_REGS);
    //        UARTCharPutNonBlocking(SOC_UART_2_REGS, rxData);
        	UARTCharPutNonBlocking(SOC_UART_1_REGS, rxData);
        }
    
    
        /* Check if the cause is receiver line error condition.*/
        if(UART_INTID_RX_LINE_STAT == int_id)
        {
    //        while(UARTRxErrorGet(SOC_UART_2_REGS))
        	while(UARTRxErrorGet(SOC_UART_1_REGS))
            {
                /* Read a byte from the RBR if RBR has data.*/
    //            UARTCharGetNonBlocking(SOC_UART_2_REGS);
        		UARTCharGetNonBlocking(SOC_UART_1_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_UART2_INT);
    	IntEnable(C674X_MASK_INT4);
    #else
        /* Registers the UARTIsr in the Interrupt Vector Table of AINTC. */
    //    IntRegister(SYS_INT_UARTINT2, UARTIsr);
        IntRegister(SYS_INT_UARTINT1, UARTIsr);
    
        /* Map the channel number 2 of AINTC to UART2 system interrupt. */
    //    IntChannelSet(SYS_INT_UARTINT2, 2);
        IntChannelSet(SYS_INT_UARTINT1, 2  );
    
    
    //    IntSystemEnable(SYS_INT_UARTINT2);
        IntSystemEnable(SYS_INT_UARTINT1);
    #endif
    }

  • Hi,

    Can you share which Processor SDK RTOS version are you using?

    Best Regards,
    Yordan
  • I am currently using code from the starterware package. I realize that it is no longer supported but I would very much appreciate it if you would be able to look over my code.
  • Check if either of these posts from help you

    e2e.ti.com/.../640437

    e2e.ti.com/.../639623

    Make sure the pinmux registers are set correctly too.

    Regards
    Mukul
  • Also, as a note we have unsoldered the necessary resistors to isolate the pins from other devices connected to the UART1_TXD and UART1_RXD. I believe we removed the R205, R208, and shorted R206 and R209
  • Hi Mukul,
    I'm looking into the threads you suggested. We have already made the necessary hardware modifications and I am currently looking through the second thread. I am currently using a pinmux function from one of the startware files and this section of the code is getting called (it's accessing the pinmux4 register which I have verified to be the register that controls the functionality of the correct pins on the omap-l138 (GP1[0] and GP1]1]):

    /*
    ** Clearing the pins in context and retaining the other pin values
    ** of PINMUX4 register.
    */
    svPinMuxTxdRxd = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) & \
    ~(SYSCFG_PINMUX4_PINMUX4_31_28 | \
    SYSCFG_PINMUX4_PINMUX4_27_24));

    /* Actual pin multiplexing for UART1_TXD and UART1_RXD. */
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) = \
    (PINMUX4_UART1_TXD_ENABLE | \
    PINMUX4_UART1_RXD_ENABLE | \
    svPinMuxTxdRxd);
  • Also, in the code I provided it contains both definitions for use of the TMS320C6X or a seperate MCU (presumably the OMAP-L138). Since I'm using the OMAP-L138/C6748 LCKD I'm not sure which sections I should remove. I have been instructed by my professor to include the following directories:

    "C:\ti\OMAPL138_StarterWare_1_10_04_01\include"
    "C:\ti\OMAPL138_StarterWare_1_10_04_01\include\hw"
    "C:\ti\OMAPL138_StarterWare_1_10_04_01\include\c674x\omapl138"

    instead of the arm5 directories. Should I stick with this or include the header files within the arm5 directory of the starterware instead?
  • I do not see any other major issues with your code.
    I would recommend first getting familiar with UART2 starterware / stuff that works out of box - compilation/includes etc.

    Are you running this from DSP side or ARM side? Does your LCDK have an OMAPL138 - ARM+DSP (look at case marking) or C6748 (DSP only)

    There are several posts on E2E that confirm that customers have been able to do this on the LCDK, so hopefully you are missing something minor.
  • It has an OMAPL138-ARM+DSP
  • Also, certain sections of the code have the format:

    #ifdef _TMS320C6X
         //stuff using C6748 libraries/macros/interrupts
    #else
         //stuff using arm5 libraries/macros/interrupts
    #endif

    The code for the arm5 is currently undefined as I was instructed by my professor to include the folder C:\ti\OMAPL138_StarterWare_1_10_04_01\include\c674x\omapl138 which contains definitions for things such as the interrupt.h file for the c6748. Should I instead be using the arm5 versions of this?

  • You should be able to run it from the ARM or the DSP side.
    Again, did you try the UART2 - if so, did you rebuid/retry from ARM side or DSP side- once you have a stable working instance, you should be able to replicate that on another instance.