# PIC32 stops getting interrupts

I have a PIC32MX, and I'm using the UART interface to communicate with an external device. When I first start up the PIC, I am properly able to get interrupts on UART1 whenever I receive a byte of data. However, after a short period of time(<1 minute) I will stop getting UART interrupts. Here's the basic sekeleton of code that I'm using to test this:

void DelayUs(unsigned int delay) {
unsigned int int_status;
while (delay--) {
int_status = INTDisableInterrupts();
OpenCoreTimer(SYS_FREQ / 2000000);
INTRestoreInterrupts(int_status);
mCTClearIntFlag();
while (!mCTGetIntFlag());
}
mCTClearIntFlag();
}

extern "C"{
void __ISR(_UART_1_VECTOR, ipl2) IntUart1Handler(void) {
// Is this an RX interrupt?
if (INTGetFlag(INT_U1RX)) {
uint8_t data = (UARTGetData(UART1)).data8bit;
// Clear the RX interrupt Flag
INTClearFlag(INT_U1RX);
}

// We don't care about TX interrupt
if (INTGetFlag(INT_U1TX)) {
INTClearFlag(INT_U1TX);
}
}
}

main(){
UARTConfigure(UART1, UART_ENABLE_PINS_TX_RX_ONLY );
UARTSetFifoMode(UART1, UART_INTERRUPT_ON_TX_NOT_FULL |UART_INTERRUPT_ON_RX_NOT_EMPTY);
UARTSetLineControl(UART1, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
UARTSetDataRate(UART1, GetPeripheralClock(), 16660);
UARTEnable(UART1, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));

// Configure UART RX Interrupt
INTEnable(INT_SOURCE_UART_RX( UART1 ), INT_ENABLED);
INTSetVectorPriority(INT_VECTOR_UART( UART1 ), INT_PRIORITY_LEVEL_2);
INTSetVectorSubPriority(INT_VECTOR_UART( UART1 ), INT_SUB_PRIORITY_LEVEL_0);

//set up the output and input pins for UART1
TRISBbits.TRISB7 = 0;  //RB7 = TX
TRISBbits.TRISB6 = 1; //RB6 = RX
RPB7Rbits.RPB7R = 1; //RPB7 = U1TX
U1RXRbits.U1RXR = 1; //RPB6 = U1RX

// we can turn on interrupts now
INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);
INTEnableInterrupts();

while (1) {
// Do work here...

DelayUs(100); //wait .1mS until next ping
//This is in reality ~200 uS
}
}


I'm testing to see if I'm still getting interrupts by setting a breakpoint in the ISR using MPLABX and an ICD3. I can trigger incoming data into the PIC. When everything is working fine, I can set/remove the breakpoint in the ISR, but after a certain point the ISR does not get triggered anymore.

I think that what could be happening is that I'm getting a TX interrupt when I am delaying my main loop as part of the DelayUs function. Could that happen? Is there anything else that could cause the interrupt to stop firing?

Quick thought. When you are disabling the interrupts in your DelayUs, you may be filling the FIFO on the RX buffer. After that point, the interrupt may not be triggered because the buffer is full. Look into the receive buffer overflow interrupt.

• It looks like this was the problem. Since I was only ever reading one character from the RX buffer, it looks like characters can come in too fast/while I'm in an ISR. Reading the characters in a loop seems to have solved it. Feb 22 '14 at 21:50

You are missing the frame error handler in the ISR. Should be something like this -

Inside Initialize function

mU2EIntEnable(1);


Inside ISR

    if (mU1EGetIntFlag()) {
resetrx();//clear rx buffer here, read rxreg x 4
U1STAbits.OERR = 0;
mU1EClearIntFlag();
return;
}


Also, be sure you use the Xclr and Xset atomic write routines for clearing any interrupt flag. Example: mU1EClearIntFlag() type lib definitions are atomic.

I just found out that the flag can be corrupted between when it flags and when the interrupt fires on the 460f series, if you aren't using atomic bit clear instructions.

Example: Xbits.U1TXIF = 0 is not atomic on the pic32 series.