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.

TMS320F280049C: SCI RX Frame Error when receiving continuous stream of data with no gap/delays in between

Part Number: TMS320F280049C


The following code for receiving SCI frames throws SCI RX FRAME errors when receiving continuous stream of data.

The continuous stream of data being received has 1 STOP bit, and NO parity.

//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include "board.h"

uint32_t sciInterruptStatus = 0;
uint16_t rawReceivedData[6] = {0};
uint16_t rawReceivedDataIndex = 0;
uint16_t dataRecCount = 0;

//
// Debug variables
//
uint16_t debug_numberOfRXInts = 0;
uint16_t debug_numberOfErrorInts = 0;

//
// Main
//
void main(void)
{
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Setup GPIO by disabling pin locks and enabling pullups
    //
    Device_initGPIO();

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Board Initialization
    //
    Board_init();

    //
    // Enables CPU interrupts
    //
    Interrupt_enableMaster();

    for(;;)
    {

    }
}

interrupt void INT_mySCI0_RX_ISR()
{
    sciInterruptStatus = SCI_getInterruptStatus(mySCI0_BASE);
    if (sciInterruptStatus & SCI_INT_FE)
    {
        debug_numberOfErrorInts++;
        SCI_resetChannels(mySCI0_BASE);
        SCI_performSoftwareReset(mySCI0_BASE);
    }
    else if (sciInterruptStatus & SCI_INT_RXFF)
    {
        debug_numberOfRXInts++;

        rawReceivedData[0] = SCI_readCharBlockingFIFO(mySCI0_BASE);
        rawReceivedData[1] = SCI_readCharBlockingFIFO(mySCI0_BASE);
        rawReceivedData[2] = SCI_readCharBlockingFIFO(mySCI0_BASE);
        rawReceivedData[3] = SCI_readCharBlockingFIFO(mySCI0_BASE);
        rawReceivedData[4] = SCI_readCharBlockingFIFO(mySCI0_BASE);
        rawReceivedData[5] = SCI_readCharBlockingFIFO(mySCI0_BASE);

    }
    SCI_clearInterruptStatus(mySCI0_BASE, SCI_INT_RXFF | SCI_INT_FE | SCI_INT_RXERR);
    Interrupt_clearACKGroup(INT_mySCI0_RX_INTERRUPT_ACK_GROUP);
}


interrupt void INT_mySCI0_TX_ISR()
{
    //
    // This is only used if you wish to send the data using the ISR
    // We don't have this enabled by default.
    //
    SCI_clearInterruptStatus(mySCI0_BASE, SCI_INT_TXFF);
    Interrupt_clearACKGroup(INT_mySCI0_TX_INTERRUPT_ACK_GROUP);
}

What is the solution?

  • One solution is to either change the transmitter module to send 2 stop bit to allow the ISR to receive the data correctly, or use the following code to read the data without needing the ISR.

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    
    uint32_t sciInterruptStatus = 0;
    uint16_t rawReceivedData[6] = {0};
    uint16_t rawReceivedDataIndex = 0;
    uint16_t dataRecCount = 0;
    
    //
    // Debug variables
    //
    uint16_t debug_numberOfRXInts = 0;
    uint16_t debug_numberOfErrorInts = 0;
    
    //
    // Main
    //
    void main(void)
    {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Setup GPIO by disabling pin locks and enabling pullups
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Board Initialization
        //
        Board_init();
    
        //
        // Enables CPU interrupts
        //
        Interrupt_enableMaster();
    
        for(;;)
        {
            rawReceivedData[rawReceivedDataIndex++] = SCI_readCharBlockingFIFO(mySCI0_BASE);
            rawReceivedData[rawReceivedDataIndex++] = SCI_readCharBlockingFIFO(mySCI0_BASE);
            rawReceivedData[rawReceivedDataIndex++] = SCI_readCharBlockingFIFO(mySCI0_BASE);
            rawReceivedData[rawReceivedDataIndex++] = SCI_readCharBlockingFIFO(mySCI0_BASE);
            rawReceivedData[rawReceivedDataIndex++] = SCI_readCharBlockingFIFO(mySCI0_BASE);
            rawReceivedData[rawReceivedDataIndex++] = SCI_readCharBlockingFIFO(mySCI0_BASE);
            rawReceivedDataIndex = 0;
        }
    }
    
    interrupt void INT_mySCI0_RX_ISR()
    {
        sciInterruptStatus = SCI_getInterruptStatus(mySCI0_BASE);
        if (sciInterruptStatus & SCI_INT_FE)
        {
            debug_numberOfErrorInts++;
            SCI_resetChannels(mySCI0_BASE);
            SCI_performSoftwareReset(mySCI0_BASE);
        }
        else if (sciInterruptStatus & SCI_INT_RXFF)
        {
            debug_numberOfRXInts++;
            //
            // Reading the values in the main loop instead.
            //
    
        }
        SCI_clearInterruptStatus(mySCI0_BASE, SCI_INT_RXFF | SCI_INT_FE | SCI_INT_RXERR);
        Interrupt_clearACKGroup(INT_mySCI0_RX_INTERRUPT_ACK_GROUP);
    }
    
    
    interrupt void INT_mySCI0_TX_ISR()
    {
        //
        // This is only used if you wish to send the data using the ISR
        // We don't have this enabled by default.
        //
        SCI_clearInterruptStatus(mySCI0_BASE, SCI_INT_TXFF);
        Interrupt_clearACKGroup(INT_mySCI0_TX_INTERRUPT_ACK_GROUP);
    }