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);
}