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.

c28xxx SCI bug

Hallo.

SCI of TMS320x28xxx has a bug.

This program sends data to TXBUF untill FIFO will will become full. Then it checks TXEMPTY flag. The logic say that we can't see "1" in TXEMPTY but there is a small interval of time when data left SCITXBUF and TXSHF but new data doesn't come from FIFO yet so we can see "1" in TXEMPTY.

The best thing you can do is to check TXEMPTY twice. Will it help us in any situation?

Try this code to reproduce this bug:

 

  • volatile int TXEMPTY_Counter;
    volatile int notTXEMPTY_Counter;

    volatile int ReSyncCounter=0;
    volatile int TestError;
    volatile int TxFifoLevel=0x10;

    void SCIbug(void){
    volatile int i;

       EALLOW;
    // Disable watchdog module
       SysCtrlRegs.WDCR= 0x0068;
    // Initalize PLL
       SysCtrlRegs.PLLCR.bit.DIV = 0xA;
       // Wait for PLL to lock
       for(i= 0; i< 5000; i++){}

    // HISPCP/LOSPCP prescale register settings
       SysCtrlRegs.HISPCP.all = 0x0001;
       SysCtrlRegs.LOSPCP.all = 0x0002;
    // Peripheral clock enables set for the selected peripherals.
       SysCtrlRegs.PCLKCR.bit.SCIENCLKB=1;
       EDIS;


        // Initalize SCI
        ScibRegs.SCICTL1.bit.SWRESET=0;
        ScibRegs.SCICTL1.bit.SWRESET=1;
        ScibRegs.SCICTL1.bit.SLEEP=1;
            ScibRegs.SCICTL1.bit.RXERRINTENA=1;
        ScibRegs.SCICTL1.bit.RXENA=1;
        ScibRegs.SCICTL1.bit.TXENA=1;

        ScibRegs.SCICTL2.bit.TXINTENA=0;
        ScibRegs.SCICTL2.bit.RXBKINTENA=1;


        ScibRegs.SCICCR.bit.STOPBITS=1;
        ScibRegs.SCICCR.bit.PARITY=0;
        ScibRegs.SCICCR.bit.PARITYENA=0;
        ScibRegs.SCICCR.bit.ADDRIDLE_MODE=0;
        ScibRegs.SCICCR.bit.SCICHAR=7;

        ScibRegs.SCIFFRX.bit.RXFFIL=4;
        ScibRegs.SCIFFRX.bit.RXFFIENA=1;
        ScibRegs.SCIFFTX.bit.TXFFIENA=0;
        ScibRegs.SCIFFTX.bit.SCIFFENA=1;
            ScibRegs.SCIFFRX.bit.RXFIFORESET=0;
            ScibRegs.SCIFFRX.bit.RXFIFORESET=1;
        ScibRegs.SCIFFCT.bit.FFTXDLY=0;

        ScibRegs.SCIHBAUD=0;
        ScibRegs.SCILBAUD=2;

        ScibRegs.SCICCR.bit.LOOPBKENA=1;

  •       TXEMPTY_Counter=0;
            notTXEMPTY_Counter=0;

            ScibRegs.SCICTL1.bit.TXWAKE=1;

            while(1){

                    if (ScibRegs.SCIFFTX.bit.TXFFST==0)
                            TestError++;

                    while (ScibRegs.SCIFFTX.bit.TXFFST<TxFifoLevel)
                    ScibRegs.SCITXBUF=12;

                    if (ScibRegs.SCICTL2.bit.TXEMPTY==1)
                            TXEMPTY_Counter++;
                    else
                            notTXEMPTY_Counter++;


                    i=ReSyncCounter;
                    while (i)
                      i--;


                    ReSyncCounter++;
                    ReSyncCounter=ReSyncCounter&0xFF;
            }

    }

  • Will we have some comments from TI about this bug?

    Is double reading of the TXEMPTY flag will help us in all situations or not and may be there are some another problems around?

  • Anuchin,

    It is not a bug.

    When FIFO is enabled, use TXFFST to know the status of TX FIFO.  When FIFO is not enabled, use TXEMPTY or TXRDY to know the status of SCITXBUF/SCITXSHF.

    Thanks and regards,

    Vamsi

     

  • I do not need to know the status of FIFO. I need to know when the last bit came out of output scitx-pin to switch RS485 driver direction to recieve reply data.

    How can I know?

    Thank you,

    Alecksey

  • Hi Alecksey

    if you have half duplex line, can't you then use RXFIFO status? Or do you disable receiver (or receiver circuitry) at that time, and you don't actually read back what you've sent?

    Mitja

  • I came across this problem myself recently when designing a Modbus - RS485 driver.  I was annoyed that there wasnt a TXCOMPLETE flag (maybe TI can change this) but I designed a way around it.  First off, Mitja's looks like the best way to go if your RX is on permenantly (which it can be unless power consumption is an issue).  However I forgot about this and came up with another solution:

    When the TXFIFOEMPTY (TXFIFOLEVEL = 0) interrupt occurs, the data has been just shifted into the output buffer for transmission.  This means it is approximately 1 byte time to 2 byte times at the worst case away from completion.  Therefore, when the last byte of my message was sent, I simply started a timer which went off (interrupted) after 1.2 byte times (12 bits at whatever baud rate).  It was at this point I cleared TX_ENABLE.  This solution works great in a state machine or OS where events are handled nicely (as the timer is simply another event).  Also, if you are implementing a high level protocol such as Modbus, you may already have code that can do timeouts.

    Hopefully this is of some help,

     

    Tim