X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=blobdiff_plain;f=tos%2Fchips%2Fmsp430%2FMcuSleepC.nc;h=57c6d393aaefcb522c22cc0738cb56df82d14e24;hp=dd9f5e1767e8ddda4a1388942761d97b27bf5705;hb=18412f7cf0633454a1041c223a5c6cebeadc31c1;hpb=1ba974b83d19fc41bf80acd52726f36f7f1df297 diff --git a/tos/chips/msp430/McuSleepC.nc b/tos/chips/msp430/McuSleepC.nc index dd9f5e17..57c6d393 100644 --- a/tos/chips/msp430/McuSleepC.nc +++ b/tos/chips/msp430/McuSleepC.nc @@ -38,7 +38,7 @@ * */ -module McuSleepC { +module McuSleepC @safe() { provides { interface McuSleep; interface McuPowerState; @@ -52,9 +52,7 @@ implementation { mcu_power_t powerState = MSP430_POWER_ACTIVE; /* Note that the power values are maintained in an order - * based on their active components, NOT on their values. - * Look at atm128hardware.h and page 42 of the ATmeg128 - * manual (figure 17).*/ + * based on their active components, NOT on their values.*/ // NOTE: This table should be in progmem. const uint16_t msp430PowerBits[MSP430_POWER_LPM4 + 1] = { 0, // ACTIVE @@ -66,35 +64,44 @@ implementation { }; mcu_power_t getPowerState() { - mcu_power_t pState = MSP430_POWER_LPM3; + mcu_power_t pState = MSP430_POWER_LPM4; // TimerA, USART0, USART1 check if ((((TACCTL0 & CCIE) || (TACCTL1 & CCIE) || (TACCTL2 & CCIE)) && - ((TACTL & TASSEL_3) == TASSEL_2)) || - ((ME1 & (UTXE0 | URXE0)) && (U0TCTL & SSEL1)) || - ((ME2 & (UTXE1 | URXE1)) && (U1TCTL & SSEL1)) -#ifdef __msp430_have_usart0_with_i2c + ((TACTL & TASSEL_3) == TASSEL_2)) +#ifdef __MSP430_HAS_UART0__ + || ((ME1 & (UTXE0 | URXE0)) && (U0TCTL & SSEL1)) +#endif +#ifdef __MSP430_HAS_UART1__ + || ((ME2 & (UTXE1 | URXE1)) && (U1TCTL & SSEL1)) +#endif +#ifdef __MSP430_HAS_I2C__ // registers end in "nr" to prevent nesC race condition detection || ((U0CTLnr & I2CEN) && (I2CTCTLnr & SSEL1) && (I2CDCTLnr & I2CBUSY) && (U0CTLnr & SYNC) && (U0CTLnr & I2C)) #endif ) pState = MSP430_POWER_LPM1; - // ADC12 check - if (ADC12CTL1 & ADC12BUSY){ - if (!(ADC12CTL0 & MSC) && ((TACTL & TASSEL_3) == TASSEL_2)) - pState = MSP430_POWER_LPM1; - else - switch (ADC12CTL1 & ADC12SSEL_3) { - case ADC12SSEL_2: - pState = MSP430_POWER_ACTIVE; - break; - case ADC12SSEL_3: - pState = MSP430_POWER_LPM1; - break; - } + +#ifdef __MSP430_HAS_ADC12__ + // ADC12 check, pre-condition: pState != MSP430_POWER_ACTIVE + if (ADC12CTL0 & ADC12ON){ + if (ADC12CTL1 & ADC12SSEL_2){ + // sample or conversion operation with MCLK or SMCLK + if (ADC12CTL1 & ADC12SSEL_1) + pState = MSP430_POWER_LPM1; + else + pState = MSP430_POWER_ACTIVE; + } else if ((ADC12CTL1 & SHS0) && ((TACTL & TASSEL_3) == TASSEL_2)){ + // Timer A is used as sample-and-hold source and SMCLK sources Timer A + // (Timer A interrupts are always disabled when it is used by the + // ADC subsystem, that's why the Timer check above is not enough) + pState = MSP430_POWER_LPM1; + } } +#endif + return pState; } @@ -111,6 +118,8 @@ implementation { } temp = msp430PowerBits[powerState] | SR_GIE; __asm__ __volatile__( "bis %0, r2" : : "m" (temp) ); + // All of memory may change at this point... + asm volatile ("" : : : "memory"); __nesc_disable_interrupt(); }