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.

TL16CP754C Example Drive Source Code in C

Other Parts Discussed in Thread: TL16C754C, TL16C754B, TL16C752C

I need to write a driver for the TL16CP754C quad uart.  Does TI have any example source code (in C) for this part? 

  • We do not have full sample source code available. I am working on some basic initialization and TX / RX handling code to provide to you. I hope to have it ready this afternoon.

     

    Best Regards,

    Joe

  • Hi Joe -

    I am porting a driver written for the ST16C554 to the TL17C754.  The datasheet for the TL17C754 says it is pin compatible with the ST16C554.  When I compare the two datasheets it appears that they are software compatible as well.  Can you confirm?

    Thanks,

    Dan

  • Hello Dan,

    The ST16C554FN is pin-compatible with the TI TL16C754BFN (FN package). The devices are register compatible as well, with the exception of a couple of bits:

    TI TL16C754  MCR[2] = FIFORdy Enable. The Exar device uses this bit for Internal Loopback RI# status


    TI TL16C754 MCR[6] = TCR and TLR enable. The Exar device uses this to select between the standard mdem interface or enable IR mode.

    TI TL16C754 TCR and TLR registers. When EFR[4] = 1 and MCR[6] = 1 the TCR and TLR can be used to select the FIFO trigger levels. The Exar device calls the equivalent registers XOFF1 and XOFF2 but I don't see an equivalent to the TI TCR and TLR trigger level settings.

     

    Best Regards,

    Joe

  • The best starting point for a UART driver is the code available at Stanford: https://ccrma.stanford.edu/courses/250a-fall-2002/docs/avrlib/uart_8c-source.html

    We have some test code for bench testing but do not have a user friendly source example. There is lots of documentation for the code at the link above.

    Best Regards,

    Joe 

  • Hi Joe

    I am also using TL16C754C in my design and need the linux driver, will it be available from TI or Need to port taking reference from some other driver like the link you have provided above.

    Regards

    Vivek

  • Hello Vivek, 

    Since UART driver support is provided with all of the major OSes we have not developed any sample code. There is some good sample code available through http://www.gnu.org. (https://ccrma.stanford.edu/courses/250a-fall-2002/docs/avrlib/uart_8c-source.html).

    Best Regards,

    Joe

  • Hi Joe,

    I am able to make the initial version of driver and able to send data through the port one the chip, but not able to recieive and also not getting any interrupts on recieve, I am suspecting my basic register initialization sequence at start, it would be a great help if you have and send me the basic initialization sequence.

    Thanks and Regards,

    Vivek 

  • Hello Vivek,

    Below is the basic initialization code used in most of our bench testing. 

    Best Regards,

    Joe

     

     

    /******    TL16C754C Register Initialization Test Program    *****/

    /*                                 */

    /* Texas Instruments, Inc., 02-20-06                   */

    /* Use 754C device on the 754CPM evaluation board.                    */

    /* This program assumes a device is in socket, and address            */

    /*   decode is set to x300-ChanA, x308-ChanB, x310-ChanC, x318-ChanD  */

    /* This pgm sets up basic UART functionality with divisor = 11,       */

    /*   all interrupts enabled, fifos enabled, and flow control disabled */

    /*                  */

     

    #include <dos.h>

    #include <stdio.h>

    #include <conio.h>

    #include <stdlib.h>

    #include <string.h>

    #include <time.h>

     

    /* Comm Port 1 or A -- UART register set definition */

    #define RBR_UART1      0x300  /*Receiver Buffer Register of chA */

    #define THR_UART1      0x300  /*Transmitter Holding Register of chA */

    #define IER_UART1      0x301  /*Interrupt Enable Register of chA */

    #define IIR_UART1      0x302  /*Interrupt Identify Register of chA */

    #define FCR_UART1      0x302  /*FIFO Control Register of chA */

    #define LCR_UART1      0x303  /*Line Control Register of chA */

    #define MCR_UART1      0x304  /*Modem Control Register of chA */

    #define LSR_UART1      0x305  /*Line Status Register of chA */

    #define MSR_UART1      0x306  /*Modem Status Register of chA*/

    #define SPR_UART1      0x307  /*Scratch Pad Register of chA */

    #define DLL_UART1      0x300  /*Divisor Latch LSB of chA */

    #define DLM_UART1      0x301  /*Divisor Latch MSB of chA */

    /* End Comm Port definition */

     

    /* Comm Port 2 or B -- UART register set definition */

    #define RBR_UART2      0x308  /*Receiver Buffer Register of chB */

    #define THR_UART2      0x308  /*Transmitter Holding Register of chB */

    #define IER_UART2      0x309  /*Interrupt Enable Register of chB */

    #define IIR_UART2      0x30A  /*Interrupt Identify Register of chB */

    #define FCR_UART2      0x30A  /*FIFO Control Register of chB */

    #define LCR_UART2      0x30B  /*Line Control Register of chB */

    #define MCR_UART2      0x30C  /*Modem Control Register of chB */

    #define LSR_UART2      0x30D  /*Line Status Register of chB */

    #define MSR_UART2      0x30E  /*Modem Status Register of chB*/

    #define SPR_UART2      0x30F  /*Scratch Pad Register of chB */

    #define DLL_UART2      0x308  /*Divisor Latch LSB of chB */

    #define DLM_UART2      0x309  /*Divisor Latch MSB of chB */

    /* End Comm Port definition */

     

    /* Comm Port 3 or C -- UART register set definition */

    #define RBR_UART3      0x310  /*Receiver Buffer Register of chA */

    #define THR_UART3      0x310  /*Transmitter Holding Register of chA */

    #define IER_UART3      0x311  /*Interrupt Enable Register of chA */

    #define IIR_UART3      0x312  /*Interrupt Identify Register of chA */

    #define FCR_UART3      0x312  /*FIFO Control Register of chA */

    #define LCR_UART3      0x313  /*Line Control Register of chA */

    #define MCR_UART3      0x314  /*Modem Control Register of chA */

    #define LSR_UART3      0x315  /*Line Status Register of chA */

    #define MSR_UART3      0x316  /*Modem Status Register of chA*/

    #define SPR_UART3      0x317  /*Scratch Pad Register of chA */

    #define DLL_UART3      0x310  /*Divisor Latch LSB of chA */

    #define DLM_UART3      0x311  /*Divisor Latch MSB of chA */

    /* End Comm Port definition */

     

    /* Comm Port 4 or D -- UART register set definition */

    #define RBR_UART4      0x318  /*Receiver Buffer Register of chB */

    #define THR_UART4      0x318  /*Transmitter Holding Register of chB */

    #define IER_UART4      0x319  /*Interrupt Enable Register of chB */

    #define IIR_UART4      0x31A  /*Interrupt Identify Register of chB */

    #define FCR_UART4      0x31A  /*FIFO Control Register of chB */

    #define LCR_UART4      0x31B  /*Line Control Register of chB */

    #define MCR_UART4      0x31C  /*Modem Control Register of chB */

    #define LSR_UART4      0x31D  /*Line Status Register of chB */

    #define MSR_UART4      0x31E  /*Modem Status Register of chB*/

    #define SPR_UART4      0x31F  /*Scratch Pad Register of chB */

    #define DLL_UART4      0x318  /*Divisor Latch LSB of chB */

    #define DLM_UART4      0x319  /*Divisor Latch MSB of chB */

    /* End Comm Port definition */

     

    // useful status defines for interrupt checking

    #define recv_lin_stat    0xC6   /* FIFO enabled, receiver line status error*/

    #define recv_data_avail  0xC4   /* Trigger lever reached */

    #define char_time_out    0xCC   /* Character time_out */

    #define xmt_thr_empty    0xC2   /* Transmitter Holding Register Empty */

     

     

    main(

     

    // setup ports (same ol' stuff)

    /* Port 1 - Channel A */

    outportb(LCR_UART1, 0x80);     /* Enable divisor access */

    outportb(DLL_UART1, 0x0b;      /* set divisor           */

    outportb(DLM_UART1, 0x00);

    outportb(LCR_UART1, 0x03);     /* Set 8,N,1 data        */

    outportb(FCR_UART1, 0xC7);     /* Enable and clear FIFOs, Rcv thresh=60  */     

    outportb(IER_UART1, 0x0F);     /* Enable all interrupts */

    outportb(MCR_UART1, 0x00);     /* Disable flow control   */

    /* Port 2 - Channel B */

    outportb(LCR_UART2, 0x80);     /* Enable divisor access */

    outportb(DLL_UART2, 0x0b);     /* set divisor           */

    outportb(DLM_UART2, 0x00);

    outportb(LCR_UART2, 0x03);     /* Set 8,N,1 data */

    outportb(FCR_UART2, 0xC7);     /* Enable and clear FIFOs, Rcv thresh=60  */ 

    outportb(IER_UART2, 0x0F);     /* Enable all ints */

    outportb(MCR_UART2, 0x00);     /* Disable flow control   */

     

    /* Port 3 - Channel C */

    outportb(LCR_UART3, 0x80);     /* Enable divisor access */

    outportb(DLL_UART3, 0x0b;      /* set divisor           */

    outportb(DLM_UART3, 0x00);

    outportb(LCR_UART3, 0x03);     /* Set 8,N,1 data        */

    outportb(FCR_UART3, 0xC7);     /* Enable and clear FIFOs, Rcv thresh=60  */     

    outportb(IER_UART3, 0x0F);     /* Enable all interrupts */

    outportb(MCR_UART3, 0x00);     /* Disable flow control   */

    /* Port 4 - Channel D */

    outportb(LCR_UART4, 0x80);     /* Enable divisor access */

    outportb(DLL_UART4, 0x0b);     /* set divisor           */

    outportb(DLM_UART4, 0x00);

    outportb(LCR_UART4, 0x03);     /* Set 8,N,1 data */

    outportb(FCR_UART4, 0xC7);     /* Enable and clear FIFOs, Rcv thresh=60  */ 

    outportb(IER_UART4, 0x0F);     /* Enable all ints */

    outportb(MCR_UART4, 0x00);     /* Disable flow control   */

     

    void display_port_status()

    {

         printf("UART1 Register Set value:\n");

         printf("IER = %x", inportb(IER_UART1) );

         printf("    LCR = %x", inportb(LCR_UART1) );

         printf("    MCR = %x", inportb(MCR_UART1) );

         printf("    LSR = %x", inportb(LSR_UART1) );

         printf("    MSR = %x", inportb(MSR_UART1) );

         printf("    IIR = %x\n", inportb(IIR_UART1) );

     

    }  /* end of display_port_status */

     

    }

    /* end of main */

     

     

     

     

     

     

  • I used your mentioned values to initialize the UART:
    LCR 0x80 - Enable divisor access
    DLL 0x0c - set divisor to 12
    DLH 0x00
    LCR 0x03 - 8Bit, no Parity, 1 Stop
    FCR 0xc7 - Enable and clear FIFO, Rcv thresh=60  
    IER 0x0f - Enable all interrupts
    MCR 0x00 - Disable flow control

    when I read form LSR after initializing the UART I get 0x60 ("TSR and THR empty, THR empty"), which seems fine

    Then I'm writing a Byte into THR and read the LSR again - now I get 0x40 ("TSR and THR empty, THR not empty") which seems quite contradictory as the THR can't be empty and filled at the same time.

    And as Software and Hardware-Flowcontrol is disabled I'm expecting the UART to send the Byte on the Tx-Pin but it stays on High-Level all the time

  • Hello Andre,

    I have reproduced this issue on the bench using your initialization code.

    Are you using the 754CPN (80-pin) or the 754CPM (64-pin) device?

    This might be related to the errata for the TL16C752B and the TL16C754B devices.

    TX works fine in FIFO mode on the bench but I don't see the TX line wiggle when transmitting a character in non-FIFO mode. I will continue bench testing and find a resolution.

    Best Regards,

    Joe

  • Hello Andre,

    The key is to read the value of the LCR BEFORE writing 0x80 to the LCR. Store that value in a temp variable. On my system the value is 0x1D.  If you write that value back to the LCR after setting up the way you did the device will work as expected. There is some pseudo code on page 44 of the datasheet that describes the steps.

    In your case you would do the following:

    Read LCR value, store in temp variable
    Write LCR 0x80 - Enable divisor access
    Write DLL 0x0c - set divisor to 12
    Write DLH 0x00
    Write LCR 0x03 - clear LCR[7], set 8Bit, no Parity, 1 Stop
    Write FCR 0xc7 - Enable and clear FIFO, Rcv thresh=60  
    Write IER 0x0f - Enable all interrupts
    Write MCR 0x00 - Disable flow control
    Write value of temp to LCR

    Once I did this on the bench my transmitter worked. Without writing back that value I was seeing the same thing you are seeing.
    Please give this a try and let me know if it works.

     

    Best Regards,

    Joe

  • Hello Joe,

    I'm using the TL16CP754CI (64-Pin).

    I tried your suggestion to store the initial LCR value and write it back after initializing the device but it didn't change anything for me:

    Initialize the device, Read LSR -> 0x60, Write a Byte to THR, Read LSR again -> 0x40 and no action on the TX-Pin.

     

    I noticed the pseudocode on page 44 already, but wouldn't I overwrite the Settings for 8Bit, No Parity, 1 Stop if I re-write the stored value into LCR?

     

     

    Best Regards,

    Andre

  • Hello Andre,

    When I read the LCR register the default value from my system (Intel based PC -AT) the default value is 0x1d so when I write the value back after clearing and enabling FIFOs the word length is still 8N1.

    When I run compiled code with the following steps (see below) I see the 0x55 pattern on the TX pin every time. When I use DOS debug mode and step through one step at a time I sometimes see the same thing you reported on your board:

    outportb(LCR_UART1, 0x80);        /* Enable divisor access
    outportb(DLL_UART1, 0x0c);        /* Set baud divisor of 12
    outportb(DLM_UART1, 0x00);
    outportb(LCR_UART1, 0x03);        /* Set character 8N1
    outportb(FCR_UART1, 0xc7):        /* Enable FIFOs, Clear FIFOs, set rcv thresh = 60
    outportb(IER_UART1, 0x0f);        /*Enable all interrupts

    outportb(MCR_UART1, 0x00);       /* Disable flow control

     

    I'm experiementing to find out why the executable (compiled code) works but the step-by-step setup will fail. Here are my power up default register values with a base address of 300:

    300 -> 00
    301 -> 00
    302 -> 01
    303 -> 1d       /* data character 8N1
    304 -> 00
    305 -> 60
    306 -> e0
    307 -> 10      /* scratch pad register

     

    Best Regards,

    Joe

  • Hello Joe,

    my power-up values in the registers are the same as yours, except the one in the scratch register, which is changing on every power-up but it keeps the value on reset.

    And I still think writing a 0x1d into LCR would enable the "6bit, odd partiy, 2 stop" mode?

    Best Regards,

    Andre

  • dear sir,

     

    we are using the TL16C754B in our application, can please provide us the application code for us.

    by the way we can the code to our application.

     

    regards,

    srikanth.

  • Hello Srikanth,

    Because the applications for UART or so varied we do not have specific source code. Attached is some general initialization code for setting up a UART to begin transmitting and receiving. We do not have a software team that can provide support.or detailed source code.

     

    Thank you.

    Best Regards,

    Joe

     

  • Srikanth,

    There is some general dual UART source code available from Stanford University at: https://ccrma.stanford.edu/courses/250a-fall-2003/docs/avrlib-new/uart2_8h.html

    Best Regards,

    Joe

     

  • Hey Joe,

    I am a noob in device drivers. I was going through the Register Initialization Test Program. I would like to know what/how do you compile these programs and run it. I am using a proprietary board which is having Windows XP Embedded OS. I would like to know how this is done exactly. I came across this post when i was trying to write a sample program to see if i could access the device i/o address by writing and reading some data into it.

    Anticipating positive early reply.

    Thanks

    Sudhir

  • Hello Sudhir,

    Our platform is an old MS-DOS ISA bus platform running on a Intel Pentium processor. We use Borland Turbo C for compiling our executable.

    In MS-DOS we can use Debug and read and write directly to the UART device registers and put an oscilloscope on the RX and TX pins to see the lines toggle as data is transmitted and received.

    Any C compiler should work.

    Check out the attached document. There should be some links in the file that will be helpful.

     

    Best Regards,

    Joe

    Stanford UART Driver Example.zip
  • Hi Friends,

    I am also facing the same problem. I am Using tl16c752c dual uart . Initialization i followed the same but the LCR value when i read for the first time it is 0x60 .

    I am getting LSR value as 40 . I am trying to write value to THR (0xaa) but the pin is always staying high. Please give me some guidance in this regard.

    My register values are as follows

    DLL ->0x9

    DLH -> 0x0

    LCR -> 0x3

    FCR -> 0xC7

    IER -> 0xF

    MCR -> 0

    LSR -> 0x40

    thanks in advance

    Saritha

  • Joe Fockler said:

    Because the applications for UART or so varied we do not have specific source code. Attached is some general initialization code for setting up a UART to begin transmitting and receiving. We do not have a software team that can provide support.or detailed source code.

    Hello Joe,

     

    Is it possible to share schematic for 754CPM evaluation board for which the test program was made

     

    best regards,

    Oleksiy

  • Hello Oleksiy,

    Sure. Please see attached schematics.

    Best Regards,

    Joe

    TL16CP754CPM_Rev2.pdf