Quick and Dirty BX35 low-power sleep and wakeup

Started by Drew October 9, 2003
I am designing a device that needs to go into a low-power sleep mode when a
certain pin goes low and wake up when it transitions back to high.

I have reviewed the "BX24 Low Power" examples from PHA or Netmedia and they
seem to be more complicated than I need them to be. I literally need to put the
unit to sleep upon seeing Low on a pin and when it goes high, have the chip
resume where it left off. Do I really need to set up an WaitForInterrupt task to
do this? Why can't I just set up the chip to wake on interrupt and put it to
sleep? When it wakes (without an interrupt task) won't it just continue with the
next instruction after the CPUSleep() command?

The reason I wanted to avoid setting up another task is I can't spare any more
RAM for another task stack (even just a couple bytes). Program storage I have
plenty of (only 11k of 32k used so far).

Here is the code I was thinking of:

Public Const SleepPin as Byte = 17 ' INT1 Port d3 of BX35

Public Sub Main()
Call PutPin(INT1pin, bxInputPullup) ' Configure INT1 as input-pullup.
' Also configure INT0 as input-pullup
Register.DDRD = Register.DDRD And bx1111_1011
Register.PORTD = Register.PORTD Or bx0000_0100

Do 'main program loop is here

If (GetPin(SleepPin)=0) Then 'pin is Low, so go to sleep
'Clear INT1 enable (bit 7) in GIMSK to temporarily disable INT1 per Atmel
Register.GIMSK = Register.GIMSK And bx0111_1111

' Clear SM0 (bit 4).
Register.MCUCR = Register.MCUCR And bx1110_1111

' Set SE (Sleep Enable, bit 6), set SM1 (bit 5) for
' power down mode, set ISC11(bit 3) and ISC10(bit 2)
' trigger INT1 on Low-to-High pin transition
Register.MCUCR = Register.MCUCR Or bx0110_1100

'Set INT1 enable (bit 7) in GIMSK to re-enable INT1
Register.GIMSK = Register.GIMSK Or bx1000_0000

' add command here to flush serial port buffer and
'shut down external devices
Delay(0.25) ' give time to complete flushing serial

Call CPUsleep() 'program halts here until SleepPin goes High (True)

' Clear INT1 flag (bit 7) in GIFR when we wake up
Register.GIFR = Register.GIFR And bx0111_1111

' Clear SE and SM1 clear sleep enable until next time
Register.MCUCR = Register.MCUCR And bx1001_1111

' add command here to power up external devices
End If

.... ' rest of main program loop goes here

Loop

Also, could I also just put a Call ResetProcessor() after the Call CPUSleep() to
restart everything "clean" (I'm not worried about losing variables in between)?