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.

SCI receive frames with errors issue

Part Number: TMS320F280049C

Hello,

I am working on application that reads data coming from another device via SCI. That device is sending lot of "garbage" frames (different baud rates) and I need to ignore all invalid frames and process only frames, which are valid (the same baud rate as listener, no framing/parity errors). But here is a issue:

I am using FIFO receive interrupt, one interrupt for each byte. There I check if received byte is valid by SCI_getRxStatus(..). If there is error (parity error) , function SCI_getRxStatus(..) returns the same error for all bytes received after first invalid byte (it is not reset). Specification says: "The PE bit is reset by an active SW RESET or a system reset." so I am calling SCI_performSoftwareReset(..); in every interrupt if error is set (I know I can call SCI_clearInterruptStatus(SCI_INT_PE) what resets SCI itself, but the result is the same).

But this is strange to me. Why would I reset whole SCI, in each interrupt, just to get correct status on next received byte? Plus it does not even work properly. When I send byte stream 0x01 0x02 0x03 from putty (with wrong parity - intentionally), third sent byte (0x03) is decoded as 0xE0 and status (SCI_getRxStatus) is zero (no errors).  So I guess this is not correct solution.

What am I doing wrong?

Thanks in advance

My code bellow is based on official demo exmple sci_ex3_interrupts_fifo.c

#include "driverlib.h"
#include "device.h"

__interrupt void sciaRxISR(void);

void main(void)
{
    // Configure PLL, disable WD, enable peripheral clocks.
    Device_init();

    // Disable pin locks and enable internal pullups.
    Device_initGPIO();

    // GPIO28 is the SCI Rx pin.
    GPIO_setMasterCore(DEVICE_GPIO_PIN_SCIRXDA, GPIO_CORE_CPU1);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_SCIRXDA);
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCIRXDA, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SCIRXDA, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCIRXDA, GPIO_QUAL_ASYNC);

    // Disable global interrupts.
    DINT;

    // Initialize interrupt controller and vector table.
    Interrupt_initModule();
    Interrupt_initVectorTable();
    IER = 0x0000;
    IFR = 0x0000;

    // Map the ISR to the wake interrupt.
    Interrupt_register(INT_SCIA_RX, sciaRxISR);

    // Initialize SCIA and its FIFO.
    SCI_performSoftwareReset(SCIA_BASE);

    SCI_setConfig(SCIA_BASE, 25000000, 38400, (SCI_CONFIG_WLEN_8 |
                                             SCI_CONFIG_STOP_ONE |
                                             SCI_CONFIG_PAR_EVEN));
    SCI_resetChannels(SCIA_BASE);
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
    SCI_enableFIFO(SCIA_BASE);
    SCI_enableModule(SCIA_BASE);
    SCI_performSoftwareReset(SCIA_BASE);

    // Set the transmit FIFO level to 0 and the receive FIFO level to 2.
    // Enable the TXFF and RXFF interrupts.
    SCI_setFIFOInterruptLevel(SCIA_BASE, SCI_FIFO_TX15, SCI_FIFO_RX1);
    SCI_enableInterrupt(SCIA_BASE, SCI_INT_TXFF | SCI_INT_RXFF);

    // Clear the SCI interrupts before enabling them.
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXFF | SCI_INT_RXFF | SCI_INT_TXRDY);

    // Enable the interrupts in the PIE: Group 9 interrupts 1 & 2.
    Interrupt_enable(INT_SCIA_RX);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

    EINT;

    for(;;)
    {
    }
}


char receivedChars[10] = {5,5,5,5,5,5,5,5,5,5};
char receivedErrors[10] = {5,5,5,5,5,5,5,5,5,5};
int index = 0;

__interrupt void
sciaRxISR(void)
{
    uint16_t receivedChar1;
    uint16_t status;

    receivedChar1 = SCI_readCharBlockingFIFO(SCIA_BASE);
    status = SCI_getRxStatus(SCIA_BASE);

    if (index < 10) {
        receivedChars[index] = receivedChar1;
        receivedErrors[index] = status;
        index++;
    }

    if (status != 0) {
        SCI_performSoftwareReset(SCIA_BASE);
    }
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_RXFF);

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

}