1.8.2 Unexpected Interrupt Flag Generation May Occur in Asynchronous External Input Mode

When Timer1 or Timer3 is operated in Asynchronous External Input mode, unexpected interrupt flag generation may occur if an external clock edge arrives too soon following a firmware write to the TMRxH:TMRxL registers. An unexpected interrupt flag event may also occur when enabling the module or switching from Synchronous to Asynchronous mode.

Work around

This issue only applies when operating the timer in Asynchronous mode. Whenever possible, operate the timer module in Synchronous mode to avoid spurious timer interrupts.

If Asynchronous mode must be used in the application, potential strategies to mitigate the issue may include any of the following:
  • Design the firmware so it does not rely on the TMRxIF flag or keep the respective interrupt disabled. The timer still counts normally and does not reset to 0x0000 when the spurious interrupt flag event is generated.
  • Design the firmware so that it does not write to the TMRxH:TMRxL registers or does not periodically disable/enable the timer, or switch modes. Reading from the timer does not trigger the spurious interrupt flag events.
  • If the firmware must use the timer interrupts and must write to the timer (or disable/enable, or mode switch the timer), implement code to suppress the spurious interrupt event, should it occur. This can be achieved by following the process shown in the example below:

Asynchronous Timer Mode Work Around to Avoid Spurious Interrupts

// Timer1 update procedure in Asynchronous mode
// The code below uses Timer1 as example

T1CONbits.TMR1ON = 0;  // Stop timer from incrementing
PIE1bits.TMR1IE = 0;   // Temporarily disable Timer1 interrupt vectoring
TMR1H = 0x00;          // Update timer value
TMR1L = 0x00;
T1CONbits.TMR1ON = 1;  // Turn on timer

/* Now wait at least two full T1CKI periods + 2TCY before re-enabling Timer1
interrupts. Depending upon clock edge timing relative to TMR1H/TMR1L 
firmware write operation,a spurious TMR1IF flag event may sometimes assert.
If this happens, to suppress the actual interrupt vectoring, the TMR1IE bit 
should be kept clear until after the "window of opportunity"(for spurious
interrupt event has passed). After the window is passed, no further 
spurious interrupts occur, at least until the next timer write
(or mode switch/enable event).*/

while(TMR1L < 0x02);  // Wait for 2 timer increments more than the updated
                      // timer value (indicating more than 2 full T1CKI
                      // clock periods elapsed)
NOP();                // Wait two more instruction cycles
NOP();
PIR1bits.TMR1IF = 0;  // Clear TMR1IF in case it was spuriously set
PIE1bits.TMR1IE = 1;  // Re-enable interrupt vectoring for Timer1

Affected Silicon Revisions

A2A3A4A6A7
XXXXX