AHH!! A careful third look at the data sheet turns up this nugget: If Timer/Counter0 is used to wake the device up from Power-save or Extended Standby mode, precautions must be taken if the user wants to re-enter one of these modes: (and I do) The interrupt logic needs one TOSC1 cycle to be reset. If the time between wake-up and re-entering sleep mode is less than one TOSC1 cycle, the interrupt will not occur, and the device will fail to wake up. (That's what's happening to me!) If the user is in doubt whether the time before re-entering Power-save or Extended Standby mode is sufficient, the following algorithm can be used to ensure that one TOSC1 cycle has elapsed: 1. Write a value to TCCR0, TCNT0, or OCR0. 2. Wait until the corresponding Update Busy flag in ASSR returns to zero. 3. Enter Power-save or Extended Standby mode. So, the sleeping loop looks like this now, and it works! :) (code above here shuts down the T2 int, and enables the T0 int, as well as converting T0 from a PWM timer to a regular timer) Snooz_Loop: ;Set up the sleep mode in TEMP,MCUCR ; ori TEMP,$3C ;00111100 ;0XXXXXXX External SRAM enable ;X0XXXXXX Wait state select bit ;XX1XXXXX Sleep enable ;XXX1XXXX SM1 ;XXXX1XXX SM0 ;XXXXX1XX SM2 Extended Standby mode ;XXXXXX0X Int vector select ;XXXXXXX0 Int vector change enable out MCUCR,TEMP ; sleep ; out OCR0,TEMP ;I don't care what gets written, but I need the write to ;pace my re-entry to sleep. I write this as early as possible ;so as to minimize wasted time waiting for the update to take. in TEMP,MCUCR ; andi TEMP,$DF ;11011111 ;0XXXXXXX External SRAM enable ;X0XXXXXX Wait state select bit ;XX0XXXXX Sleep enable ;XXX1XXXX SM1 ;XXXX1XXX SM0 ;XXXXX1XX SM2 Extended Standby mode ;XXXXXX0X Int vector select ;XXXXXXX0 Int vector change enable out MCUCR,TEMP ; ;Wake up here on pressed button ints, or T0 overflow ;Test for pressed buttons clr TEMP2 ; sbic PIND,3 ; ldi TEMP2,0x08 ;Sets a 1 in this position if the button is NOT pressed in TEMP,PINE ; BBBBXXXX andi TEMP,0xF0 ;Mask out buttons 11110000 (If no buttons pushed) or TEMP,TEMP2 ;Add in the lone stranger 00001000 ori TEMP,0x07 ;Fill in zeroes 11111111 inc TEMP ; 00000000 and TEMP,TEMP ;Check for zero brne Wake_Up ;If no buttons, resume sleeping T0_Snooz_Update: in TEMP,ASSR ;0000XXXX Reserved andi TEMP,$07 ;XXXXX111 T0 async mode enable ;00000--- Busy flags, 1 if register updating brne T0_Snooz_Update ; rjmp Snooz_Loop ; Wake_Up: (down here, we re-activate the T2 int, and put T0 back to being a PWM timer)
Message
Re: [AVR-Chat] Sleep and timer T0
2005-06-17 by Dave VanHorn
Attachments
- No local attachments were found for this message.