* @date October 26, 2005
*/
-module McuSleepC {
+module McuSleepC @safe() {
provides {
interface McuSleep;
interface McuPowerState;
}
implementation {
/* There is no dirty bit management because the sleep mode depends on
- the amount of time remaining in timer0. */
+ the amount of time remaining in timer0. Note also that the
+ sleep cost depends typically depends on waiting for ASSR to clear. */
/* Note that the power values are maintained in an order
* based on their active components, NOT on their values.
(1 << SM1)}; /* power down */
mcu_power_t getPowerState() {
- uint8_t diff;
// Note: we go to sleep even if timer 1, 2, or 3's overflow interrupt
// is enabled - this allows using these timers as TinyOS "Alarm"s
// while still having power management.
return ATM128_POWER_IDLE;
}
// SPI (Radio stack on mica/micaZ
- else if (bit_is_set(SPCR, SPIE)) {
+ else if (bit_is_set(SPCR, SPE)) {
return ATM128_POWER_IDLE;
}
- // UARTs are active
- else if (UCSR0B & (1 << TXCIE | 1 << RXCIE)) { // UART
+ // A UART is active
+ else if ((UCSR0B | UCSR1B) & (1 << TXCIE | 1 << RXCIE)) { // UART
return ATM128_POWER_IDLE;
}
- else if (UCSR1B & (1 << TXCIE | 1 << RXCIE)) { // UART
+ // I2C (Two-wire) is active
+ else if (bit_is_set(TWCR, TWEN)){
return ATM128_POWER_IDLE;
}
// ADC is enabled
else if (bit_is_set(ADCSR, ADEN)) {
return ATM128_POWER_ADC_NR;
}
- // How soon for the timer to go off?
- else if (TIMSK & (1 << OCIE0 | 1 << TOIE0)) {
- // force waiting for timer0 update (overflow glitches otherwise)
- TCCR0 = TCCR0;
- while (ASSR & (1 << TCN0UB | 1 << OCR0UB | 1 << TCR0UB))
- ;
- diff = OCR0 - TCNT0;
- if (diff < 16 || TCNT0 > 240)
- return ATM128_POWER_EXT_STANDBY;
- return ATM128_POWER_SAVE;
- }
else {
return ATM128_POWER_DOWN;
}
(MCUCR & 0xe3) | 1 << SE | read_uint8_t(&atm128PowerBits[powerState]);
sei();
- asm volatile ("sleep");
+ // All of memory may change at this point...
+ asm volatile ("sleep" : : : "memory");
cli();
}