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.

LCDK OMAP-L138 UART0\UART1 Problems

Other Parts Discussed in Thread: OMAP-L138

Hello all,

I saw this problem happen for people in this forum but I couldn't find a satisfactory answer.

I tried configuring the UART0 and UART1 on the ARM9 so I can use it with other modules.
UART2 is working perfectly through the USB connector but the other 2 UARTs connected to the expansion connector pins (J15: UART1 -  17,19 \ UART0 - 31,29) doesn't seem to work.

The registers state:
PINMUX3 = 0x00220000
PINMUX4 = 0x22220000

As they should be according to the pinmux utility.

I don't have any other peripheral connected.

Here is my code (only echoing between the UARTs):

int main(void)
{
unsigned int intFlags = 0;
unsigned int config = 0;
/* Enabling the PSC for UART2.*/
PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_UART0, PSC_POWERDOMAIN_ALWAYS_ON,
PSC_MDCTL_NEXT_ENABLE);
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART1, PSC_POWERDOMAIN_ALWAYS_ON,
PSC_MDCTL_NEXT_ENABLE);
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART2, PSC_POWERDOMAIN_ALWAYS_ON,
PSC_MDCTL_NEXT_ENABLE);
/* Setup PINMUX */
UARTPinMuxSetup(0, FALSE);
UARTPinMuxSetup(1, FALSE);
UARTPinMuxSetup(2, FALSE);

/* Enabling the transmitter and receiver*/
UARTEnable(SOC_UART_0_REGS);
UARTEnable(SOC_UART_1_REGS);
UARTEnable(SOC_UART_2_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,
460800, config,
UART_OVER_SAMP_RATE);
UARTConfigSetExpClk(SOC_UART_1_REGS, SOC_UART_1_MODULE_FREQ,
460800, config,
UART_OVER_SAMP_RATE);
UARTConfigSetExpClk(SOC_UART_2_REGS, SOC_UART_2_MODULE_FREQ,
460800, config,
UART_OVER_SAMP_RATE);
/* Enabling the FIFO and flushing the Tx and Rx FIFOs.*/
UARTFIFOEnable(SOC_UART_0_REGS);
UARTFIFOEnable(SOC_UART_1_REGS);
UARTFIFOEnable(SOC_UART_2_REGS);
/* Setting the UART Receiver Trigger Level*/
UARTFIFOLevelSet(SOC_UART_0_REGS, UART_RX_TRIG_LEVEL_1);
UARTFIFOLevelSet(SOC_UART_1_REGS, UART_RX_TRIG_LEVEL_1);
UARTFIFOLevelSet(SOC_UART_2_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_RXDATA_CTI);
/* Enable the Interrupts in UART.*/
UARTIntEnable(SOC_UART_0_REGS, intFlags);
UARTIntEnable(SOC_UART_1_REGS, intFlags);
UARTIntEnable(SOC_UART_2_REGS, intFlags);
while(1);
}
static void UARTIsr()
{
unsigned char rxData = 0;
unsigned int int_id = 0;
/* This determines the cause of UART2 interrupt.*/
int_id = UARTIntStatus(SOC_UART_0_REGS);
/* Clears the system interupt status of UART2 in AINTC. */
IntSystemStatusClear(SYS_INT_UARTINT0);

/* Check if the cause is receiver data condition.*/
if(UART_INTID_RX_DATA == int_id)
{
rxData = UARTCharGetNonBlocking(SOC_UART_0_REGS);
UARTCharPutNonBlocking(SOC_UART_2_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;
}
static void UART1Isr()
{
unsigned char rxData = 0;
unsigned int int_id = 0;
/* This determines the cause of UART2 interrupt.*/
int_id = UARTIntStatus(SOC_UART_1_REGS);
/* Clears the system interupt status of UART2 in AINTC. */
IntSystemStatusClear(SYS_INT_UARTINT1);
/* Check if the cause is receiver data condition.*/
if(UART_INTID_RX_DATA == int_id)
{
rxData = UARTCharGetNonBlocking(SOC_UART_1_REGS);
UARTCharPutNonBlocking(SOC_UART_2_REGS, rxData);
}
/* Check if the cause is receiver line error condition.*/
if(UART_INTID_RX_LINE_STAT == int_id)
{
while(UARTRxErrorGet(SOC_UART_1_REGS))
{
/* Read a byte from the RBR if RBR has data.*/
UARTCharGetNonBlocking(SOC_UART_1_REGS);
}
}
return;
}
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);
/* Check if the cause is receiver data condition.*/
if(UART_INTID_RX_DATA == int_id)
{
rxData = UARTCharGetNonBlocking(SOC_UART_2_REGS);
UARTCharPutNonBlocking(SOC_UART_2_REGS, rxData);
UARTCharPutNonBlocking(SOC_UART_1_REGS, rxData);
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_2_REGS))
{
/* Read a byte from the RBR if RBR has data.*/
UARTCharGetNonBlocking(SOC_UART_2_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)
{
/* 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();
}
/*
** \brief This function confiugres the AINTC to receive UART interrupts.
*/
static void ConfigureIntUART(void)
{
/* Registers the UARTIsr in the Interrupt Vector Table of AINTC. */
IntRegister(SYS_INT_UARTINT0, UARTIsr);
IntRegister(SYS_INT_UARTINT1, UART1Isr);
IntRegister(SYS_INT_UARTINT2, UART2Isr);
/* Map the channel number 2 of AINTC to UART2 system interrupt. */
IntChannelSet(SYS_INT_UARTINT0, 2);
IntChannelSet(SYS_INT_UARTINT1, 4);
IntChannelSet(SYS_INT_UARTINT2, 3);
IntSystemEnable(SYS_INT_UARTINT0);
IntSystemEnable(SYS_INT_UARTINT1);
IntSystemEnable(SYS_INT_UARTINT2);
}

 I believe that the connections are correct.

Anyone knows how to solve this problem?

Thanks,

Yoel

  • Hey,

    I dug some more and I can see that the only difference between the UART registers is at the "Modem Status Register (MSR)".

    The values are:

    UART2 (the working one) = 0x00

    UART1                              = 0x11

    UART2                              = 0x10

    Cant figure our what it means but if any of you can, please help.

    Thanks,

    Yoel

  • Did you check to see if the other UARTs are enabled in the power and sleep controller registers?

    UART0 is in PSC 0, LPSC number 9

    UART1 is in PSC 1, LPSC number 12

    UART2 is in PSC 1, LPSC number 13

    Update: I just noticed after I posted this you have enabled them in your code.  You can check the status registers to make sure, but I'm guessing they are o.k.

  • Hey Aaron,

    I double checked and all of the UARTs are enabled.

    Yoel

  • How did you hook this up, which pins did you connect?  Are you using any flow control or control lines or just connecting tx to rx in each direction between UART0 and UART1?

  • UARTs connected to the expansion connector pins (J15: UART1 -  17,19 \ UART0 - 31,29), Each uart connected to another device.

    This is a method I use on my Concerto board without problems.

    No flow control is used, I expect the uC to pass the information between the uarts so the other devices can talk.

  • It looks to me like the LCDK has 3.3V I/O on the UARTs, they are all on power group A, and the voltage for DVDD3318-A is 3.3V on the schematic.  Is that compatible with the other board?  The ftdi chip can handle from 1.8V to 5V so it wouldn't have a problem.

    If your not sure of the voltage I would try a loopback between ports UART0 and UART1 first.

    It looks like autoflow is off by default, so it shouldn't be a problem.  I found a function to clear it in starterware under drivers/uart.c 

    /**
    * \brief This function is intended to clear the Autoflow control
    * enable(AFE) bit and the Request To Send(RTS) bit in the
    * Modem Control Register(MCR).
    *
    * \param baseAdd Memory address of the UART instance being used.
    * \param ctrlFlags This is a bitwise OR of AFE bit and the RTS bit in MCR
    *
    * \return None.
    *
    */

    void UARTModemControlClear(unsigned int baseAdd, unsigned int ctrlFlags)
    {
    HWREG(baseAdd + UART_MCR) &= ~(ctrlFlags & (UART_AUTOFLOW | UART_RTS));
    }

  • The voltage is OK.

    I tried using the function above but the outcome was the same.

    No interrupts except for UART2...

    Did anyone ever managed to activate one of the other UARTs on the LCDK?

  • Yoel,

    I would advise a simpler test to start with.

    Take the UART interrupt example from the OMAP-L13x starterware (http://processors.wiki.ti.com/index.php/StarterWare).
    Assuming that PSC and pinmux are already changed you can look at:
    - modify it for internal loopback (see OMAP-L13x TRM SPRUH77A section 32.2.5.5) so that you can validate the UART0 or UART1 completely alone.
    - Interrupt might not work as the UART0/1 interrupt event to CPU might be different events compared to UART2 (see TRM section 12.2). You could start with CPU polling first.

    Once you have internal loopback working then you can look at external loopback (ie same UART with cable to enable external loopback).
    Then you can look at using 2 UART as you wanted.

    Hope it helps.
    Anthony

  • Anthony,

    Internal loopbak works fine. 

    I tried connecting the UARTs in external loopback (each of the UARTs I connected the RX with the TX pin seperately) but again, no signal (I even tried it in polling mode without interrupts).

    Maybe there is a problem with the GPIO configuration?
    Is there something I'm missing?

    Here is the new code:

    int main(void)
    {
    unsigned int intFlags = 0;
    unsigned int config = 0;
    /* Enabling the PSC for UART2.*/
    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_UART0, PSC_POWERDOMAIN_ALWAYS_ON,
    PSC_MDCTL_NEXT_ENABLE);
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART1, PSC_POWERDOMAIN_ALWAYS_ON,
    PSC_MDCTL_NEXT_ENABLE);
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART2, PSC_POWERDOMAIN_ALWAYS_ON,
    PSC_MDCTL_NEXT_ENABLE);
    /* Setup PINMUX */
    UARTPinMuxSetup(0, FALSE);
    UARTPinMuxSetup(1, FALSE);
    UARTPinMuxSetup(2, FALSE);
    /* Enabling the transmitter and receiver*/
    UARTEnable(SOC_UART_0_REGS);
    UARTEnable(SOC_UART_1_REGS);
    UARTEnable(SOC_UART_2_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);
    UARTConfigSetExpClk(SOC_UART_1_REGS, SOC_UART_1_MODULE_FREQ,
    BAUD_115200, config,
    UART_OVER_SAMP_RATE_16);
    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_0_REGS);
    UARTFIFOEnable(SOC_UART_1_REGS);
    UARTFIFOEnable(SOC_UART_2_REGS);
    /* Setting the UART Receiver Trigger Level*/
    UARTFIFOLevelSet(SOC_UART_0_REGS, UART_RX_TRIG_LEVEL_1);
    UARTFIFOLevelSet(SOC_UART_1_REGS, UART_RX_TRIG_LEVEL_1);
    UARTFIFOLevelSet(SOC_UART_2_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_RXDATA_CTI);
    /* Enable the Interrupts in UART.*/
    UARTIntEnable(SOC_UART_0_REGS, intFlags);
    UARTIntEnable(SOC_UART_1_REGS, intFlags);
    UARTIntEnable(SOC_UART_2_REGS, intFlags);
    int i;
    /* Programming the LOOPBACKEN bit in MCR. */
    //HWREG(SOC_UART_0_REGS + UART_MCR) |= (1 << 4);
    //HWREG(SOC_UART_1_REGS + UART_MCR) |= (1 << 4);
    while(1)
    {
    UARTCharPutNonBlocking(SOC_UART_0_REGS, '0');
    UARTCharPutNonBlocking(SOC_UART_1_REGS, '1');
    for(i=0;i<1000;i++);
    char rxData;
    while(UARTCharsAvail(SOC_UART_0_REGS))
    {
    /* Read a byte from the RBR if RBR has data.*/
    rxData = UARTCharGetNonBlocking(SOC_UART_0_REGS);
    UARTCharPutNonBlocking(SOC_UART_2_REGS, rxData);
    }
    while(UARTCharsAvail(SOC_UART_1_REGS))
    {
    /* Read a byte from the RBR if RBR has data.*/
    rxData = UARTCharGetNonBlocking(SOC_UART_1_REGS);
    UARTCharPutNonBlocking(SOC_UART_2_REGS, rxData);
    }
    }
    }

    Thanks,

    Yoel

  • With external loopback you mean for example UART1 TX to UART1 RCV, UART2 TX to UART2 RCV?

    Do you see something at all on the TX pin? have you tried to toggle the pins using the pins as GPIO just o be sure that there is no problem with the routing of the signals?

  • 1. Yes

    2. I can't toggle UART1 pins (17,19) - GP1[0], GP1[1], they are constantly low, other pins like (16,20) GP8[10], GP8[12] do toggle.

    This is the code I used:

    /* The Local PSC number for GPIO is 3. GPIO belongs to PSC1 module.*/
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON,
    PSC_MDCTL_NEXT_ENABLE);
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(4)) |= 0x88000000;
    GPIODirModeSet(SOC_GPIO_0_REGS, 17, GPIO_DIR_OUTPUT);
    GPIODirModeSet(SOC_GPIO_0_REGS, 18, GPIO_DIR_OUTPUT);
    GPIOPinWrite(SOC_GPIO_0_REGS, 17, GPIO_PIN_HIGH);
    GPIOPinWrite(SOC_GPIO_0_REGS, 18, GPIO_PIN_HIGH);

    Is there a lock on the UART pins?

  • For GPIO tried to check with the below post. May be you are not accessing the according register:
    See http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/p/99391/348348.aspx#348348

    Also on ealier silicon version some register needed to be used to lock/unlock some region but I don't think it is the case on silicon rev 2.x:
    http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/p/87319/304129.aspx#304129

    Also check the PCB routing on the board to be sure there is nothing between the OMAP-L138 pins and where you are measuring the signal.

  • 1.I'm using the StarterWare drivers to access the GPIO, I'm assuming it has been debugged and with all the other GPIO's it works well.
    It runs the following function and handles the Banks:

     void GPIODirModeSet(unsigned int baseAdd, unsigned int pinNumber, 

     unsigned int pinDir)
    {
    unsigned int regNumber = 0;
    unsigned int pinOffset = 0;
    /*
    ** Each register contains settings for each pin of two banks. The 32 bits
    ** represent 16 pins each from the banks. Thus the register number must be
    ** calculated based on 32 pins boundary.
    */
    regNumber = (pinNumber - 1)/32;

    /*
    ** In every register the least significant bits starts with a GPIO number on
    ** a boundary of 32. Thus the pin offset must be calculated based on 32
    ** pins boundary. Ex: 'pinNumber' of 1 corresponds to bit 0 in
    ** 'register_name01'.
    */
    pinOffset = (pinNumber - 1) % 32;
    if(GPIO_DIR_OUTPUT == pinDir)
    {
    HWREG(baseAdd + GPIO_DIR(regNumber)) &= ~(1 << pinOffset);
    }
    else
    {
    HWREG(baseAdd + GPIO_DIR(regNumber)) |= (1 << pinOffset);
    }
    }

    2. How do I know which silicon rev do I have? On the board it says: "L138/C6748 Development Kit Rev ___" and a sticker "A5".

    3. I don't have the tools nor the ability to check the PCB routing, I Do software the most advanced tool I have here is a scope, which, by the way, shows nothing as well.

    4. Has anyone tried working with UART0 and UART1 with the LCDK and can tell me that it works?

  • 1) as far as I know the starterware was validated on the EVM, I am not sure on the LCDK.

    3) Sorry I meant checking the schematics:
    http://processors.wiki.ti.com/index.php/L138/C6748_Development_Kit_%28LCDK%29#Online_Resources

    If you look at page 12 of the schematics you can see that there are other devices connected on the UART1_TXD and UART1_RXD.I guess it is why you do not see the pin toggling. You will probably need to unsolder some resistors to isolate the pins from the other device.

    2) For silicon rev you can look at the device marking and double the rev in the silicon errata:
    http://www.ti.com/product/omap-l138
    Also the below GEL file can provide useful info for the debug:
    http://processors.wiki.ti.com/index.php/OMAP-L1x_Debug_Gel_Files

    Also there are lot of ressources, tips, advises that can help on the twiki:
    http://processors.wiki.ti.com/index.php/Device:OMAP-L138:Device_Evaluation
    http://processors.wiki.ti.com/index.php/Category:OMAPL1
    http://processors.wiki.ti.com/index.php/OMAP-L138_Hardware_Design_Guide


  • Dear Anthony,

    I give up.

    How can it be that the most basic communication form exists in the digital world is so complicated to activate in a supposed to be "The low-cost LCDK will also speed and ease your hardware development of real-time DSP applications" takes me 3 weeks to do what I have done in 2 days with other devices?

    I still don't know if anyone ever worked with those uarts on this board and I'm tired of waiting for someone to popup and give me the solution.

    Thanks for the help, I know you mean well.

    Yoel

  • Yoel,

    One point to keep in mind is that there is a lot of pin multiplexed on the OMAP/L13x devices. It is not so easy to enable all the options on a given board in order to make all interface available.

    I think for UART1 you need to remove some resistors to use the pins as UART instead of SPI. Default is to use the pin as SPI to interface to the finger print sensor. See the bottom of page 12 of the schematics:
    processors.wiki.ti.com/images/a/a2/Omap-l138_c6748_lc_dev_kit_ver_a5.zip

    See R205, R206, R208 and R209.

    It is key to double check the schematics to ensure what is effectively connected on the given pins.

  • As I understand from the schematics, the only resistors that may interrupt UART1 are R206 & R209, and by checking the board, I see that there isn't any resistor in those places.

    Do you think that removing R205 and R208 will help to activate the UART?

    Is this the case for R218 & R219 for UART0 (even tough I couldn't find them...)?

  • Then for UART1 you will have to remove R205 and had a wire on R206 to make a connection. Probably same thing for UART0.

  • Anthony,

    At last, UART1 works !

    Now I need to find if UART0 is available or not.

    Thank you very much for the help.

    Yoel

  • Summary:

    To enable UART1:

    Remove R205, R208
    Short R206, R209

    To enable UART0:

    Remove R172, R173, R277
    Short R218, R219

    This will probable disable the ethernet module and the SPI for the fingerprints module so beware. 

  • Yoel,

    Thanks for the feedback :)

    A.

  • Dear Motola,

    How you made it work?

    With regards
    AS