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.

TMS320F28377D: Problem of SCI polling mode

Part Number: TMS320F28377D
Other Parts Discussed in Thread: C2000WARE

Dear team:

One of my customers had a problem using SCI polling receive mode:

Uint16 scid_read(void)
{
Uint16 rtn=0;

while(ScidRegs.SCIFFRX.bit.RXFFST == 0);
rtn = ScidRegs.SCIRXBUF.all;

// while(ScidRegs.SCIFFRX.bit.RXFFST != 0)
// {
// rtn = ScidRegs.SCIRXBUF.all;
// }
return rtn;
}

If you use the above method, the chip can receive data. But the program will stop there.

If the following method is used, the chip cannot receive data. However, the data in the SCIRXBUF register can be seen to be changing during the simulation, indicating that it has been received. However, the condition of while(RXFFST != 0) cannot be passed.

void UART_GpioInit(void)
{
GPIO_SetupPinMux(77, GPIO_MUX_CPU1, 6);
GPIO_SetupPinOptions(77, GPIO_INPUT, GPIO_PUSHPULL);
GPIO_SetupPinMux(76, GPIO_MUX_CPU1, 6);
GPIO_SetupPinOptions(76, GPIO_OUTPUT, GPIO_ASYNC);
}

void scid_init(Uint32 baud)
{
//
// Note: Clocks were turned on to the SCIA peripheral
// in the InitSysCtrl() function
//
Uint16 brr;
Uint16 brrh,brrl;

ScidRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScidRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
ScidRegs.SCICTL2.all = 0x0000;
ScidRegs.SCICTL2.bit.TXINTENA = 0;
ScidRegs.SCICTL2.bit.RXBKINTENA = 0;
brr=(Uint16)(50000000/(baud*8)-1);//低速时钟50MHz
brrh = brr>>8;
brrl = brr & 0xff;
ScidRegs.SCIHBAUD.all = 0x0002;//9600
ScidRegs.SCILBAUD.all = 0x008B;
ScidRegs.SCICCR.bit.LOOPBKENA = 0; // Enable loop back
ScidRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset
}

void scid_fifo_init()
{
ScidRegs.SCIFFTX.all = 0xE040;//初始化发送缓冲寄存器
ScidRegs.SCIFFRX.all = 0x2040;//接收缓冲寄存器0个levle
ScidRegs.SCIFFCT.all = 0x0;
}

while(1)
{
read_data = scid_read();
}

Best Regards

  • Hello,

    Thanks for your question! To confirm, is the customer using "(RXFFST != 0)"? This is commented out in the first code snippet.

    If you are using "while(RXFFST != 0)", the issue is that this will stay here until the buffer is empty. However, the buffer will never be emptied because the while loop cannot be passed. The solution to this would be to change this to "while(RXFFST == 0)", which will wait until the buffer is not empty. Then the rest of the read function can execute. See the following C2000Ware SCI function that shows an example of using a blocking char read (used in sci_ex3_echoback.c from C2000Ware_version#\driverlib\f2837xd\examples\cpu1\sci):

    //*****************************************************************************
    //
    //! Waits for a character from the specified port when the FIFO enhancement
    //! is enabled.
    //!
    //! \param base is the base address of the SCI port.
    //!
    //! Gets a character from the receive FIFO for the specified port.  If there
    //! are no characters available, this function waits until a character is
    //! received before returning. Returns immediately in case of Error.
    //!
    //! \return Returns the character read from the specified port as \e uint16_t
    //!         or 0x0 in case of Error. The application must use
    //!         SCI_getRxStatus() API to check if some error occurred before
    //!         consuming the data
    //
    //*****************************************************************************
    static inline uint16_t
    SCI_readCharBlockingFIFO(uint32_t base)
    {
        //
        // Check the arguments.
        //
        ASSERT(SCI_isBaseValid(base));
    
        //
        // Wait until a character is available in the receive FIFO.
        //
        while(SCI_getRxFIFOStatus(base) == SCI_FIFO_RX0)
        {
            //
            //If there is any error return
            //
            if((SCI_getRxStatus(base) & SCI_RXSTATUS_ERROR) != 0U)
            {
                return 0U;
            }
        }
    
        //
        // Return the character from the receive buffer.
        //
        return(uint16_t)(HWREGH(base + SCI_O_RXBUF) & SCI_RXBUF_SAR_M);
    }

    Let me know if this answers your question!

    Regards,

    Vince