Other Parts Discussed in Thread: C2000WARE
HI,
I am using the SCI-A peripheral of the micro-controller to interface with a THVD1450DGK. I have observed that after the peripheral encounters an Overflow Error(OE) about 10-15 times it stops generating interrupts.
Checking the peripheral registers show that all the RXRDY and OE flags in the SCIRXST registers are set and the RXBKINTENA and RXERRINTENA bits are set as well. The interrupts are also enabled at the PIE level.
Following is the code for my RX interrupt. Help will be appreciated.
__interrupt void sciaRX_isr(void)
{
// Check if interrupt was entered because of an error. In that case put SCI module into a reset state.
if (SciaRegs.SCIRXST.bit.RXERROR == 1)
{
//check which error happened.
if (SciaRegs.SCIRXST.bit.OE)
sciOEErrorCountThvd++;
if (SciaRegs.SCIRXST.bit.PE)
sciPEErrorCountThvd++;
if (SciaRegs.SCIRXST.bit.FE)
sciFEErrorCountThvd++;
if (SciaRegs.SCIRXST.bit.BRKDT)
sciBRKDTErrorCountThvd++;
//SW_RESET SCI
SciaRegs.SCICTL1.bit.SWRESET = 0;
SciaRegs.SCICTL1.bit.SWRESET = 1;
sciErrorCountThvd++;
enter_mute();
}
/*enter this if the errors have not caused the interrupt*/
else if (SciaRegs.SCIRXST.bit.RXRDY) //rx caused the interrupt
{
if (SciaRegs.SCIRXST.bit.RXWAKE == 1) // Address byte has been received. RXWAKE is set when address bit is detected in the word.
{
rxIndexThvd = 0;
}
rxPackThvd[rxIndexThvd] = SciaRegs.SCIRXBUF.bit.SAR;
switch (rxIndexThvd)
{
case 0: //Looking for address byte.
{
if (rxPackThvd[0] == SENSOR_ID) // If address byte matches sensor_id
{
rxIndexThvd++; //increase rxIndexthvd to accept next character.
SciaRegs.SCICTL1.bit.SLEEP = 0; //bring the uart peripheral out of sleep as it is being addressed!
break;
}
else
{
rxIndexThvd = 0; //reset rxindexThvd
enter_mute(); //if the address byte received doesn't match the one set by software stay in sleep
}
break;
}
case 1:
{
//index 1 will be the instruction type.
//insert code here to evaluate rxPackLenThvd based on isntruction type.
//if rxPackLenThvd is fixed leave this if statement empty.
rxIndexThvd++;
break;
}
default:
{
if (rxIndexThvd == (rxPackLenThvd - 1)) //last byte in packet has been received.
{
if (calculate_crc(rxPackThvd, rxPackLenThvd)
== ((rxPackThvd[rxPackLenThvd - 2] | (rxPackThvd[rxPackLenThvd - 1] << 8)))) //crc check over here
{
rxPackCount++;
// Return type code Start
/*
* */
// Return Type Code End
if (txPackLenThvd > 0) // means that data has to be sent back to the uC
{
GpioDataRegs.GPBSET.bit.GPIO33 = 1; //NRE
GpioDataRegs.GPASET.bit.GPIO16 = 1; //DE
thvd_copy_shdbuff(); // functions copies shadow buffer into main transmit buffer.
SciaRegs.SCICTL1.bit.RXENA = 0;
SciaRegs.SCICTL1.bit.RXERRINTENA = 0;
SciaRegs.SCICTL2.bit.RXBKINTENA = 0; // disable RX interrupts and RX
SciaRegs.SCICTL1.bit.TXENA = 1;// enable TX and TXINT
SciaRegs.SCICTL2.bit.TXINTENA = 1;
SciaRegs.SCITXBUF.bit.TXDT = txPackThvd[0]; //put the first packet of data to be sent
txIndexThvd = 1; //set txIndexThvd to 1 as first byte has already been loaded.
}
else //if there is nothing to transmit then enter mute again.
{
enter_mute();
}
break;
}
else //crc failed
{
crcErrorCountThvd++;
enter_mute();
break;
}
}
rxIndexThvd++;
}
}
}
//acknowledge Group interrupt
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}enter_mute() function
void enter_mute(void)
{
GpioDataRegs.GPBCLEAR.bit.GPIO33 = 1; // clear NRE
GpioDataRegs.GPACLEAR.bit.GPIO16 = 1; // clear DE
SciaRegs.SCICTL1.bit.SWRESET = 0; // reset
SciaRegs.SCICTL1.bit.RXENA = 1; //enable rx
SciaRegs.SCICTL1.bit.RXERRINTENA = 1; //enable rx error interrupt
SciaRegs.SCICTL2.bit.RXBKINTENA = 1; //enable rxrdy/ break detect interrupt
SciaRegs.SCICTL1.bit.TXENA = 0; // Disable transmistter
SciaRegs.SCICTL1.bit.SWRESET = 1; //bring out from reset
SciaRegs.SCICTL1.bit.SLEEP = 1; //set the UART module in sleep mode till the module receives a stream of data is addressing it
}calculate_crc() function
uint16_t calculate_crc(volatile uint16_t *packet, uint16_t packLen)
{
uint16_t index = 0;
uint16_t crc = 0;
for (int h = 0; h < packLen - 2; h++)
{
index = ((crc >> 8) ^ ((int16_t) packet[h])) & 0xFF;
crc = (crc << 8) ^ crc_table[index];
}
return crc;
}