void main( void ) { calScheduler=0; // Initialize calibration scheduler // Initialize microcontroller (Digital and analog I/O, timers, clock, etc) HAL_INIT(); // Initialize board-specific hardware functionality such as sensors, // power management, LEDs, etc. BSP_INIT(); // Load all configuration registers of radio and put radio into idle mode RADIO_INIT(); // Set power level for transmit operation RADIO_SET_TX_PWR(0xFF); // Radio goes to sleep here to save power during remaining initialization RADIO_SLEEP(); // Initialize the ADC for sensor measurements HAL_ADC_INIT(); // Select the proper input channel for sampling an analog sensor HAL_ADC_CHANNEL_SELECT(BSP_INCH_TEMP); //HAL_ADC_CHANNEL_SELECT(BSP_INCH_PHOTO); while(1) { // Calibrate radio VCO every fourth frame (starting with first frame) if(!calScheduler) { // Calibrate the radio frequency synth. // Automatically wakes the radio if it's asleep. RADIO_CALIBRATE(); calScheduler=3; } else { calScheduler--; } // Sample the sensors HAL_ADC_CHANNEL_SELECT(BSP_INCH_TEMP); tempValue = HAL_ADC_SAMPLE(); // Turn ON photosensor BSP_PHOTO_ENABLE(); HAL_PRECISE_DELAY(1); // Wait a while to let node charge HAL_ADC_CHANNEL_SELECT(BSP_INCH_PHOTO); photoValue = HAL_ADC_SAMPLE(); BSP_PHOTO_DISABLE(); // Load up the message buffer msgBuf[0] = SENSOR_ID_TEMP; msgBuf[1] = _swap_bytes(tempValue) & 0x03u; // 2 MSbs msgBuf[2] = tempValue & 0xFFu; // 8 LSbs msgBuf[3] = SENSOR_ID_PHOTO; msgBuf[4] = _swap_bytes(photoValue) & 0x03u; // 2 MSbs msgBuf[5] = photoValue & 0xFFu; // 8 LSbs // Transmit a message to the receiver. This function will also send // the network ID and sensor ID automatically. // This function may return before the transmission is complete. // Automatically wakes the radio if it's asleep. RADIO_TX(msgBuf); // Add delay to make sure all data is transmitted. What is the minimum delay? HAL_PRECISE_DELAY(100); // DEBUG: No need to sleep if we're going down... RADIO_SLEEP(); // DEBUG: Blackout/recharge BSP_LDO_HOLD_POUT &= ~BSP_LDO_HOLD_BIT; HAL_LONG_DELAY(12000); BSP_LDO_HOLD_POUT |= BSP_LDO_HOLD_BIT; } }
void nodeSleep(u16 tenthSeconds) { // ************** Power down the other board peripherals Leds_off(); // ************** Power down the radio // wait for radio to be done u8 state = BUSY_TX_ARET; while (state == BUSY_TX_ARET || state == BUSY_RX_AACK) state = radioGetTrxState(); // Now put radio to sleep radioEnterSleepMode(); // TODO: figure out what needs to be put to sleep to minimize current consumption // ************** Power down the on-chip modules // PRR = 0xbf; ??? // Disable ADC // ADCSRA &= ~(1 << ADEN); // Turn off comparator // ACSR |= (1 << // turn off ports etc // Turn off BOD // This should only be done once -- No need to do it over again /* AVR_ENTER_CRITICAL_REGION(); #define BODS 6 #define BODSE 5 MCUCR |= (1 << BODSE) | (1<< BODS); MCUCR &= ~(1 << BODSE); AVR_LEAVE_CRITICAL_REGION(); */ // ************** Set the timer to wake up // Set TIMER2 Asyncronous Mode. ASSR |= (1 << AS2); // Set TIMER2 Prescaler to 1024. TCCR2B |= ((1 << CS22)|(1 << CS21)|(1 << CS20)); // Wait for TCNT2 write to finish. while(ASSR & (1 << TCR2BUB)) ; // Sleep as many times as needed to sleep for the full time while (tenthSeconds) { // This is to get the node manually out of sleeping mode -- // Might take up to 7.5Sec to detect button press // if (BUTTON_PRESSED() ) { Led1_on(); macConfig.sleeping = false; while (BUTTON_PRESSED()) ; Led1_off(); break; // exit the Sleeping loop } // Set TIMER2 output compare register from user. if (tenthSeconds > 75) { // Just decrement by the max timeout OCR2A = 240; // 7.5 seconds, max timeout tenthSeconds -= 75; } else { // Can measure the remaining time in one timer cycle tenthSeconds = tenthSeconds * 16 / 5; if (!tenthSeconds) tenthSeconds++; OCR2A = tenthSeconds; tenthSeconds = 0; } // Wait for OCR2 write to finish. while(ASSR & (1 << OCR2AUB)) ; // Reset TIMER2 timer counter value. TCNT2 = 0; // Wait for TCNT2 write to finish before entering sleep. while(ASSR & (1 << TCN2UB)) ; // Clear interrupt flag TIFR2 |= (1 << OCF2A); // Enable TIMER2 output compare interrupt. TIMSK2 |= (1 << OCIE2A); // ************** Go to sleep AVR_ENTER_CRITICAL_REGION(); set_sleep_mode( SLEEP_MODE_PWR_SAVE); sleep_enable(); sei(); sleep_cpu(); // sleeping right here sleep_disable(); AVR_LEAVE_CRITICAL_REGION(); wdt_disable(); } // ************** Awake now, wake up everything // PRR = 0x03; ?? if (SERIAL) serial_init(NULL); debugMsgStr("\r\nNode slept"); if ( macConfig.associated) HAL_ADC_INIT(); // Bring SPI port back up (must re-init after sleep) radio_spi_init(); // Wake up radio. radioLeaveSleepMode(); // Set RF212 to 250KB mode. // TODO: do I need to call this?? //radioSetup900(); radioSetTrxState(PLL_ON); }