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.

TL16C754B not asserting RXRDY*

Greetings,

In my application I am using RXRDY* to trigger unloading of the receive FIFOs.  No interrupts on the part are enabled (or connected).  The original implementation included a 4800 baud data stream being applied to the part during reset and initialization.  *Sometimes*, upon completion of initialization, RXRDY* would only be asserted a single time and after returning to the de-asserted state would stay there regardless of the continuous data stream being applied to the chip.  On other occasions (about 50% of the time) it would respond as expected and the data stream would be received (and read by the processor) as intended.

Uninformed work-around:  Although I have not determined the details or reasons for this behavior, I have determined that if I implement both of the following (neither, by itself is sufficient) the problem behavior does not occur.

1- Force all the receive lines into the idle state during reset and initialization. 

2- Use a timeout so that if the application waits too long, at startup, for expected data (from a FIFO that sits between the interrupt routine and the application) to force reading from the receive fifos on the chip (bypassing the int routine) until they are empty.

What I have found with these work-arounds is that some of the time, 2- will have data to empty even though RXRDY* is not asserted and after emptying the FIFO RXRDY* resumes normal operation.

I have also observed that if 1- is not implemented, 2- will continue to have data to empty and the expected behavior of RXRDY* never occurs.

I would like a better work around (or correction to my init etc.),  if available, as 1- requires board rework I would like to avoid.  I would also like a better understanding of what I going on so that I can have high assurance that my eventual implementation is bullet proof in this area.

All my indications are that once RXRDY* starts running as expected (i.e. it asserts after initialization more that just once) it will continue to work as expected.

My init code is below.  For my work so far, only the GPS connection is implemented.  Thanks for any and all insights!

Steve.

/* Init of UARTS first */

//Write special "key" code into LCR (0xBF) to enable access to the EFR, Xon/Xoff, DLL
//and DLH registers. (available registers now: DLL, DLH, EFR, Xon-1, Xon-2, Xoff-1, Xoff-2)
cellUart[UART_LCR] = 0xBF;
gpsUart[UART_LCR] = 0xBF;
sonicUart[UART_LCR] = 0xBF;
valveUart[UART_LCR] = 0xBF;

//Write ^Q (0x11) into Xon-1 and ^S (0x13) into Xoff-1
cellUart[UART_Xon1] = 0x11;
gpsUart[UART_Xon1] = 0x11;
sonicUart[UART_Xon1] = 0x11;
valveUart[UART_Xon1] = 0x11;

cellUart[UART_Xoff1] = 0x13;
gpsUart[UART_Xoff1] = 0x13;
sonicUart[UART_Xoff1] = 0x13;
valveUart[UART_Xoff1] = 0x13;

//Write 0x00 into DLH and 0x18 into DLL to set baud rate to 9600 (default) except for GPS which is 4800.
cellUart[UART_DLH] = hBaudByte(cpot.cell_baud);
gpsUart[UART_DLH] = hBaudByte(cpot.gps_baud);
sonicUart[UART_DLH] = hBaudByte(cpot.sonic_baud);
valveUart[UART_DLH] = hBaudByte(cpot.valve_baud);

cellUart[UART_DLL] = lBaudByte(cpot.cell_baud);;
gpsUart[UART_DLL] = lBaudByte(cpot.gps_baud);
sonicUart[UART_DLL] = lBaudByte(cpot.sonic_baud);
valveUart[UART_DLL] = lBaudByte(cpot.valve_baud);

//Write 0x10 into the EFR to enable access to enhanced feature bits in EIR 4-7, FCR 4-5 and MCR 5-7
//(or write 0x1A to also enable "software" flow control as implemented in the controller
// but only after flow contrl trigger levels are set below in the TCR)
cellUart[UART_EFR] = 0x10;
gpsUart[UART_EFR] = 0x10;
sonicUart[UART_EFR] = 0x10;
valveUart[UART_EFR] = 0x10;

//Write0x03 into LCR to set 8bit, no parity and one stop bit AND to re-enable access to MCR
//(available registers now: RHR/THR, IER, IIR/FCR,LCR, MCR, LSR, MSR, SPR)
cellUart[UART_LCR] = 0x03;
gpsUart[UART_LCR] = 0x03;
sonicUart[UART_LCR] = 0x03;
valveUart[UART_LCR] = 0x03;

//Write 0x40 into MCR to enable access to TCR and TLR (instead of FifoRdy)
//(available registers now: RHR/THR, IER, IIR/FCR,LCR, MCR, LSR, TCR, TLR)
cellUart[UART_MCR] = 0x40;
gpsUart[UART_MCR] = 0x40;
sonicUart[UART_MCR] = 0x40;
valveUart[UART_MCR] = 0x40;

//Write 0x8F into TCR to set recieve flow control trigger levels of 60 chars (halt) and 32
//chars (resume)
cellUart[UART_TCR] = 0x8F;
gpsUart[UART_TCR] = 0x8F;
sonicUart[UART_TCR] = 0x8F;
valveUart[UART_TCR] = 0x8F;

//Write 0x88 into TLR to set DMA (i.e. interrrupt in this application) trigger levels of 32 chars
//for both Rx and Tx - Note: if these values are changed, the #defines, above, for CellComBlkSize,
// etc. need to be updated.
cellUart[UART_TLR] = 0x88;
gpsUart[UART_TLR] = 0x88;
sonicUart[UART_TLR] = 0x88;
valveUart[UART_TLR] = 0x88;

//Write 0x04 into MCR to enable access to FifoRdy (instead of TCR and TLR)
//(available registers now: RHR/THR, IER, IIR/FCR,LCR, MCR, LSR, MSR, FifoRdy)
//NOTE: IRQ outputs not used except for debug - I've left them on, writing 04
//instead of 0C will turn them off
cellUart[UART_MCR] = 0x04;
gpsUart[UART_MCR] = 0x04;
sonicUart[UART_MCR] = 0x04;
valveUart[UART_MCR] = 0x04;

//Write 0xA9 into FCR to set RX fifo trigger level to 56 chars, TX fifo trigger level to 32 chars,
//NOTE: these trigger levels are over-ridden by those defined in the TLR
//DMA Mode 1 and Enable both RX and TX fifos. And reset them (0xA9 -> 0xAF to reset).
cellUart[UART_FCR] = 0xAF;
gpsUart[UART_FCR] = 0xAF;
sonicUart[UART_FCR] = 0xAF;
valveUart[UART_FCR] = 0xAF;

  • Hi Steve,

    I am looking through the information you provided and will get back to you later today.

    Thank you.

    Best Regards,

    Joe

  • I'm looking forward to hearing from you.

    Steve.

  • Hi Steve,

    I apologize for the delay in responding.

    Are all four channels receiving data during the initialization, or just the 4800 baud GPS channel?
    Do you know if it is the GPS channel that is asserting /RXRDY the single time upon completion of initialization?

    Please try setting the baud rate before you enable the EFR and program your Xon/Xoff characters. It might be that a channel is receiving data before the baud rate is set and it is getting confused.

    From the Programmer's Guide at the back of the datasheet the following programming sequence is suggested for setting up flow control:

    Set baud rate to VALUE1,VALUE2:
       Read LCR (03), save in temp
       Set LCR (03) to 80
       Set DLL (00) to VALUE1
       Set DLM (01) to VALUE2
       Set LCR (03) to temp

    Set Xoff1,Xon1 to VALUE1,VALUE2:
       Read LCR (03), save in temp
       Set LCR (03) to BF
       Set Xoff1 (06) to VALUE1
       Set Xon1 (04) to VALUE2
       Set LCR (03) to temp

    Set Xoff2,Xon2 to VALUE1,VALUE2:
       Read LCR (03), save in temp
       Set LCR (03) to BF
       Set Xoff2 (07) to VALUE1
       Set Xon2 (05) to VALUE2
       Set LCR (03) to temp

    Set software flow control mode to VALUE:
       Read LCR (03), save in temp
       Set LCR (03) to BF
       Set EFR (02) to VALUE
       Set LCR (03) to temp

    Set flow control threshold to VALUE:
       Read LCR (03), save in temp1
       Set LCR (03) to BF
       Read EFR (02), save in temp2
       Set EFR (02) to 10 + temp2
       Set LCR (03) to 00
       Read MCR (04), save in temp3
       Set MCR (04) to 40 + temp3
       Set TCR (06) to VALUE
       Set LCR (03) to BF
       Set EFR (02) to temp2
       Set LCR (03) to temp1
       Set MCR (04) to temp3

    Set xmt and rcv FIFO thresholds to VALUE:
       Read LCR (03), save in temp1
       Set LCR (03) to BF
       Read EFR (02), save in temp2
       Set EFR (02) to 10 + temp2
       Set LCR (03) to 00
       Read MCR (04), save in temp3
       Set MCR (04) to 40 + temp3
       Set TLR (07) to VALUE
       Set LCR (03) to BF
       Set EFR (02) to temp2
       Set LCR (03) to temp1
       Set MCR (04) to temp3

    Read FIFORdy register Read:
       MCR (04), save in temp1
       Set temp2 = temp1 * EF
       Set MCR (04), save in temp2
       Read FRR (07), save in temp2
       Pass temp2 back to host
       Set MCR (04) to temp1

    Best Regards,

    Joe

  • Hi Joe,

    I appreciate the response.  The conditions that led to the behavior I reported only have the gps active during initialization.   The other channels are idle.  While I don't *know* which channel is asserting /RXRDY it is my inference from the observed behavior and assumption that it is the gps channel.  Nonetheless I recognize assumptions have their dangers...

    I will play with changing the initialization ordering per your recommendations.  Note, however, that my initialization doesn't actually enable flow control (that I recall, I will confirm when I make the time to revisit this issue) and therefore the setting up of the xon/xoff registers is currently superfluous.  It may take a couple of days before I can report back.

    Thanks for your guidance,

    Steve.

  • Hi Joe,

    First, regarding the question of which channel is asserting /RXRDY I can add the additional information that when I bypass my interrupt routine and read directly from the chip (in response to what is effectively a timeout waiting for an assertion of /RXRDY that never comes) the only channel that has anything to read from is the gps channel (as I would expect).

    I ran some tests this morning.  First, of course, I disabled my work-arounds and confirmed the undesired behavior reappeared.  Then,  I found that if I reordered my init sequence by moving the writes to the DLH and DLL (preceded, of course, by the obligatory enabling write to the LCR) to the beginning of the init sequence, as you suggested, there was no improvement to the problem behavior.  I confirmed that even with the timeout triggered read (the work-around that bypassed the int routine), the problem still occurred.

    Next, I reconfigured my init sequence into the "style" of that in the datasheet.  I've included it below.  With this change, and both of my workarounds disabled, I confirmed the problem still occurred.  

    However, when I re-enabled the timeout triggered read work-around, the problem was no longer evident (but it was a relatively small sample size of 10).  It would be nice to know if this is because I have eliminated the problem mechanism entirely or, as I fear given the "style" of the data sheet init, I have just significantly improved the statistics associated with the problem, or I was just lucky on this particular test.  

    I would greatly appreciate hearing your perspectives and insight on this question.

    Once again, thanks for your help and I look forward to hearing from you again.

    Steve.

    /* Init of UARTS first. Note: this seemly redundant and awful init sequence is to match *
    * the example in the data sheet. A prior seemingly legal cleaner one resulted in *
    * intermittent erroneous chip behavior (the gps not found problem) */

    //Write0x03 into LCR to set 8bit, no parity and one stop bit AND to re-enable access to MCR
    //(available registers now: RHR/THR, IER, IIR/FCR,LCR, MCR, LSR, MSR, SPR)
    cellUart[UART_LCR] = 0x03;
    gpsUart[UART_LCR] = 0x03;
    sonicUart[UART_LCR] = 0x03;
    valveUart[UART_LCR] = 0x03;

    //Write 0x80 into LCR (0xBF) to enable access to DLL
    //and DLH registers. (available registers now: DLL, DLH)
    tmp = gpsUart[UART_LCR];

    cellUart[UART_LCR] = 0x80;
    gpsUart[UART_LCR] = 0x80;
    sonicUart[UART_LCR] = 0x80;
    valveUart[UART_LCR] = 0x80;

    //Write 0x00 into DLH and 0x18 into DLL to set baud rate to 9600 (default) except for
    //gps which gets 4800 baud
    cellUart[UART_DLH] = hBaudByte(cpot.cell_baud);
    gpsUart[UART_DLH] = hBaudByte(cpot.gps_baud);
    sonicUart[UART_DLH] = hBaudByte(cpot.sonic_baud);
    valveUart[UART_DLH] = hBaudByte(cpot.valve_baud);

    cellUart[UART_DLL] = lBaudByte(cpot.cell_baud);;
    gpsUart[UART_DLL] = lBaudByte(cpot.gps_baud);
    sonicUart[UART_DLL] = lBaudByte(cpot.sonic_baud);
    valveUart[UART_DLL] = lBaudByte(cpot.valve_baud);

    cellUart[UART_LCR] = tmp;
    gpsUart[UART_LCR] = tmp;
    sonicUart[UART_LCR] = tmp;
    valveUart[UART_LCR] = tmp;

    //Write special "key" code into LCR (0xBF) to enable access to the EFR, Xon/Xoff, DLL
    //and DLH registers. (available registers now: DLL, DLH, EFR, Xon-1, Xon-2, Xoff-1, Xoff-2)
    tmp = gpsUart[UART_LCR];

    cellUart[UART_LCR] = 0xBF;
    gpsUart[UART_LCR] = 0xBF;
    sonicUart[UART_LCR] = 0xBF;
    valveUart[UART_LCR] = 0xBF;

    //Write ^Q (0x11) into Xon-1 and ^S (0x13) into Xoff-1
    cellUart[UART_Xon1] = 0x11;
    gpsUart[UART_Xon1] = 0x11;
    sonicUart[UART_Xon1] = 0x11;
    valveUart[UART_Xon1] = 0x11;

    cellUart[UART_Xoff1] = 0x13;
    gpsUart[UART_Xoff1] = 0x13;
    sonicUart[UART_Xoff1] = 0x13;
    valveUart[UART_Xoff1] = 0x13;

    cellUart[UART_LCR] = tmp;
    gpsUart[UART_LCR] = tmp;
    sonicUart[UART_LCR] = tmp;
    valveUart[UART_LCR] = tmp;

    //Write 0x00 into the EFR to ensure flow control is disabled
    tmp = gpsUart[UART_LCR];

    cellUart[UART_LCR] = 0xBF;
    gpsUart[UART_LCR] = 0xBF;
    sonicUart[UART_LCR] = 0xBF;
    valveUart[UART_LCR] = 0xBF;

    cellUart[UART_EFR] = 0x00;
    gpsUart[UART_EFR] = 0x00;
    sonicUart[UART_EFR] = 0x00;
    valveUart[UART_EFR] = 0x00;

    cellUart[UART_LCR] = tmp;
    gpsUart[UART_LCR] = tmp;
    sonicUart[UART_LCR] = tmp;
    valveUart[UART_LCR] = tmp;

    //Write 0x8F into TCR to set recieve flow control trigger levels of 60 chars (halt) and 32
    //chars (resume)
    tmp = gpsUart[UART_LCR];
    cellUart[UART_LCR] = 0xBF;
    gpsUart[UART_LCR] = 0xBF;
    sonicUart[UART_LCR] = 0xBF;
    valveUart[UART_LCR] = 0xBF;

    tmp2 = gpsUart[UART_EFR];
    cellUart[UART_EFR] = tmp2 | 0x10;
    gpsUart[UART_EFR] = tmp2 | 0x10;
    sonicUart[UART_EFR] = tmp2 | 0x10;
    valveUart[UART_EFR] = tmp2 | 0x10;

    cellUart[UART_LCR] = 0x00;
    gpsUart[UART_LCR] = 0x00;
    sonicUart[UART_LCR] = 0x00;
    valveUart[UART_LCR] = 0x00;

    tmp3 = gpsUart[UART_MCR];
    cellUart[UART_MCR] = tmp3 | 0x40;
    gpsUart[UART_MCR] = tmp3 | 0x40;
    sonicUart[UART_MCR] = tmp3 | 0x40;
    valveUart[UART_MCR] = tmp3 | 0x40;

    cellUart[UART_TCR] = 0x8F;
    gpsUart[UART_TCR] = 0x8F;
    sonicUart[UART_TCR] = 0x8F;
    valveUart[UART_TCR] = 0x8F;

    cellUart[UART_LCR] = 0xBF;
    gpsUart[UART_LCR] = 0xBF;
    sonicUart[UART_LCR] = 0xBF;
    valveUart[UART_LCR] = 0xBF;

    cellUart[UART_EFR] = tmp2;
    gpsUart[UART_EFR] = tmp2;
    sonicUart[UART_EFR] = tmp2;
    valveUart[UART_EFR] = tmp2;

    cellUart[UART_LCR] = tmp;
    gpsUart[UART_LCR] = tmp;
    sonicUart[UART_LCR] = tmp;
    valveUart[UART_LCR] = tmp;

    cellUart[UART_MCR] = tmp3;
    gpsUart[UART_MCR] = tmp3;
    sonicUart[UART_MCR] = tmp3;
    valveUart[UART_MCR] = tmp3;

    //Write 0x88 into TLR to set DMA (i.e. interrrupt in this application) trigger levels of 32 chars
    //for both Rx and Tx - Note: if these values are changed, the #defines, above, for CellComBlkSize,
    // etc. need to be updated.

    tmp = gpsUart[UART_LCR];
    cellUart[UART_LCR] = 0xBF;
    gpsUart[UART_LCR] = 0xBF;
    sonicUart[UART_LCR] = 0xBF;
    valveUart[UART_LCR] = 0xBF;

    tmp2 = gpsUart[UART_EFR];
    cellUart[UART_EFR] = tmp2 | 0x10;
    gpsUart[UART_EFR] = tmp2 | 0x10;
    sonicUart[UART_EFR] = tmp2 | 0x10;
    valveUart[UART_EFR] = tmp2 | 0x10;

    cellUart[UART_LCR] = 0x00;
    gpsUart[UART_LCR] = 0x00;
    sonicUart[UART_LCR] = 0x00;
    valveUart[UART_LCR] = 0x00;

    tmp3 = gpsUart[UART_MCR];
    cellUart[UART_MCR] = tmp3 | 0x40;
    gpsUart[UART_MCR] = tmp3 | 0x40;
    sonicUart[UART_MCR] = tmp3 | 0x40;
    valveUart[UART_MCR] = tmp3 | 0x40;

    cellUart[UART_TLR] = 0x88;
    gpsUart[UART_TLR] = 0x88;
    sonicUart[UART_TLR] = 0x88;
    valveUart[UART_TLR] = 0x88;


    cellUart[UART_LCR] = 0xBF;
    gpsUart[UART_LCR] = 0xBF;
    sonicUart[UART_LCR] = 0xBF;
    valveUart[UART_LCR] = 0xBF;

    cellUart[UART_EFR] = tmp2;
    gpsUart[UART_EFR] = tmp2;
    sonicUart[UART_EFR] = tmp2;
    valveUart[UART_EFR] = tmp2;

    cellUart[UART_LCR] = tmp;
    gpsUart[UART_LCR] = tmp;
    sonicUart[UART_LCR] = tmp;
    valveUart[UART_LCR] = tmp;

    cellUart[UART_MCR] = tmp3;
    gpsUart[UART_MCR] = tmp3;
    sonicUart[UART_MCR] = tmp3;
    valveUart[UART_MCR] = tmp3;

    //Write 0x04 into MCR to enable access to FifoRdy (instead of TCR and TLR)
    //(available registers now: RHR/THR, IER, IIR/FCR,LCR, MCR, LSR, MSR, FifoRdy)
    //NOTE: IRQ outputs not used except for debug - I've left them on, writing 04
    //instead of 0C will turn them off
    cellUart[UART_MCR] = 0x04;
    gpsUart[UART_MCR] = 0x04;
    sonicUart[UART_MCR] = 0x04;
    valveUart[UART_MCR] = 0x04;

  • Greetings,

    In summary, the two open issues are:

    1) I still require an un-documented (other than here) work around to obtain reliable signalling on RXRDY (the one that reads directly from the chip FIFO even when RXRDY is not asserted if the software thinks the chip is hung).  The open question is:  Is this due to an error in my implementation (in which case I would like to fix it) or is this an error in the documentation for the chip (in which case I would hope TI would fix it).

    2) By changing the init code to one that is identical in terms of register settings but is much more tortured in terms of chip interactions (but is in the style of the datasheet example) I have been able to obtain the desired functionality without the other work around (the force all channels to the idle state during reset and initialization work around).  As the requirement for the different style of initialization appears not to be documented anywhere, I am uncertain as to how much I can trust the improved behavior of the chip when it is initialized in this manner.  The open question here is:  Have I just significantly improved the statistics associated with the problem by changing the style of the initialization or have I eliminated it?  In addition to answering this question, I would hope TI would provide additional documentation on the details of the initialization requirements so that I can be clear I have performed what is necessary for the chip to do it's job reliably.

    Please reply so that I know if these issues are still being pursued or if I should expect no additional technical information on these issues as I have to decide my next course of action.

    I appreciate your assistance so far and any additional assistance you can provide.

    Best regards,

    Steve Stearns - NaCaPe Design, Boulder CO.