Has anyone experienced the port B0 interrupt INT0IE becoming disabled on it's own while in idle "sleep" (primary idle) mode? I find that after running in low-speed idle mode (31 kHz on internal osc) and waking every few seconds on a timer1 interrupt to flash an LED that the B0 interrupt enable will be set to 0. Maybe it's just noise from the OLED charge pump causing a glitch?? This is an intermittent event. It happens only after a number of hours of operation...I've seen it happen 3 hours after starting sleep, 30 hours, etc.
The B0 interrup is operated about every 10 minutes. It wakes up the controller, executes some serial-based code to communicate with a radio device, then goes back to sleep (idle mode, actually, since Timer0 is still running). This is on an 18F66J16. I actually found I had to set B0 to enable each time through the interrupt to make sure it did not fail. So it is solved, but what a kluge - now I can't disable the B0 interrupt while leaving the other interrupts in the ISR enabled unless I put in some extra logic. I used B0 with other PICs, this seems strange. I posted to the Microchip support site as well.
Code: Select all
Interrupt Flash(IPHigh)
Dim SaveFSR0,SaveFSR1,SavePROD As Word,
PRODRegister As PRODL.AsWord
// 1. if B0 caused the interrupt, speed up the clock and set the clock chip to enable INT to be asserted
If INT0IF = 1 Then
SaveFSR0 = FSR0
SaveFSR1 = FSR1
SavePROD = PRODL
OSCCON.1 = 1 // set this to us primary idle and primary run using the int osc
OSCCON.0 = 0
OSCTUNE.6 = 1 //turn on the PLL for 32 MHz with intosc
OSCCON.6 = 1
OSCCON.5 = 1
OSCCON.4 = 1
DelayMS(100) //delay so USART2 debug isn't gibberish
sleep_on = false
USART2.Write("finished B0 wakeup routine in ISR",$0D)
FSR0=SaveFSR0
FSR1=SaveFSR1
PRODL=SavePROD
EndIf
// 2. check to see if the external switch has been activated
If PORTB.1 = 1 Then
sleep_on = false
OSCCON.1 = 1 // set this to us primary idle and primary run using the int osc
OSCCON.0 = 0
OSCTUNE.6 = 1 //turn on the PLL for 32 MHz with intosc
OSCCON.6 = 1
OSCCON.5 = 1
OSCCON.4 = 1
EndIf
// 3. check on the LED flasher and see if sleep_on is true or not
If TMR1IF = 1 And sleep_on Then
If Power_LED = 0 Then
T1scaleH = 0
T1scaleL = 0
TMR1H = $FE // preload 8 bits to keep LED on for shorter time
TMR1L = $FF /////-already set up in initialization sequence
If sleep_on Then Power_LED = 1 EndIf // only use the LED if in sleep mode
ElseIf Power_LED = 1 Then
T1scaleH = 0
T1scaleL = 0
Power_LED = 0
AReply = 0
TMR1H = $C0 // preload 8 bits to keep LED on for shorter time -4 secs at 500 kHz, 16.8 secs 125 kHz
TMR1L = $00 // high byte is read in when low byte is written to, so they occure simultaneously
EndIf
EndIf
//clear interrupts at the end of the service routine or they could trigger again before it's done
LVDIF = 0 //clear Low Voltage interrupt
TMR1IF = 0 //clear timer1 interrupt
INT0IF = 0 //clear B0 interrupt - to be sure, to be sure...
INT0IE = 1 //enable port b 0 interrupt - this fixes the odd non-wake from sleep but it's a kluge
If sleep_on Then Sleep EndIf
End Interrupt
de Tom