B0 interrupt enable "turning off" while in sleep

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
User avatar
RadioT
Registered User
Registered User
Posts: 157
Joined: Tue Nov 27, 2007 12:50 pm
Location: Winnipeg, Canada

B0 interrupt enable "turning off" while in sleep

Post by RadioT » Wed Mar 12, 2008 3:33 am

Hello,

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  
73's,
de Tom

Post Reply