/**************************************************************************** * * NAME: Device_vMain * * DESCRIPTION: * Main device loop * * RETURNS: * void * ****************************************************************************/ PUBLIC void Device_vMain(void) { /* Debug */ DBG_vPrintf(DEBUG_DEVICE_FUNC, "\nDevice_vMain()"); /* Make sure sleep flag is clear */ bSleep = FALSE; /* Main loop */ while(FALSE == bSleep || u32Awake > 0) { /* Main processing for network config changing mode ? */ if (MibNwkConfigPatch_bMain()) { #if MK_BLD_MIB_NWK_PROFILE /* Ensure the configured profile is applied */ MibNwkProfile_vApply(); #endif } /* Restart watchdog */ vAHI_WatchdogRestart(); /* Deal with device tick timer events ? */ Device_vTick(); /* Doze */ vAHI_CpuDoze(); } }
/**************************************************************************** * * NAME: Device_vSleep * * DESCRIPTION: * Go to sleep * * RETURNS: * void * ****************************************************************************/ PUBLIC void Device_vSleep(void) { /* Debug */ DBG_vPrintf(DEBUG_DEVICE_FUNC, "\nDevice_vSleep()"); /* Debug */ //DBG_vPrintf(DEBUG_DEVICE_FUNC, "\nPDM_vSave()"); /* Save all records to PDM */ //PDM_vSave(); /* Get node to do pre-sleep preparation */ Node_vSleep(); /* Pass fake second calls into mibs (these save PDM data) */ #if MK_BLD_MIB_DIO_CONFIG MibDioConfig_vSecond(); #endif #if MK_BLD_MIB_DIO_CONTROL MibDioControl_vSecond(); #endif #if MK_BLD_MIB_HAT_LIGHTS MibHatLights_vSecond(); #endif #if MK_BLD_MIB_HAT_PVN MibHatPvN_vSecond(); #endif /* Debug */ DBG_vPrintf(DEBUG_DEVICE_FUNC, "\nv6LP_Sleep(TRUE, %d) ", DEVICE_ED_SLEEP); /* Request stack to put us to sleep */ v6LP_Sleep(TRUE, DEVICE_ED_SLEEP); /* Sleep loop */ while(1) { /* Deal with device tick timer events ? */ Device_vTick(); /* Doze */ vAHI_CpuDoze(); } }
static void main_loop(void) { int r; clock_time_t time_to_etimer; rtimer_clock_t ticks_to_rtimer; while(1) { do { /* Reset watchdog. */ watchdog_periodic(); r = process_run(); } while(r > 0); /* * Idle processing. */ watchdog_stop(); #if DCOSYNCH_CONF_ENABLED /* Calibrate the DCO every DCOSYNCH_PERIOD * if we have more than 500uSec until next rtimer * PS: Calibration disables interrupts and blocks for 200uSec. * */ if(clock_seconds() - last_dco_calibration_time > DCOSYNCH_PERIOD) { if(rtimer_arch_time_to_rtimer() > RTIMER_SECOND / 2000) { /* PRINTF("ContikiMain: Calibrating the DCO\n"); */ eAHI_AttemptCalibration(); /* Patch to allow CpuDoze after calibration */ vREG_PhyWrite(REG_PHY_IS, REG_PHY_INT_VCO_CAL_MASK); last_dco_calibration_time = clock_seconds(); } } #endif /* DCOSYNCH_CONF_ENABLED */ /* flush standard output before sleeping */ uart_driver_flush(E_AHI_UART_0, TRUE, FALSE); /* calculate the time to the next etimer and rtimer */ time_to_etimer = clock_arch_time_to_etimer(); ticks_to_rtimer = rtimer_arch_time_to_rtimer(); #if JN516X_SLEEP_ENABLED /* we can sleep only up to the next rtimer/etimer */ rtimer_clock_t max_sleep_time = ticks_to_rtimer; if(max_sleep_time >= JN516X_MIN_SLEEP_TIME) { /* also take into account etimers */ uint64_t ticks_to_etimer = ((uint64_t)time_to_etimer * RTIMER_SECOND) / CLOCK_SECOND; max_sleep_time = MIN(ticks_to_etimer, ticks_to_rtimer); } if(max_sleep_time >= JN516X_MIN_SLEEP_TIME) { max_sleep_time -= JN516X_SLEEP_GUARD_TIME; /* bound the sleep time to 1 second */ max_sleep_time = MIN(max_sleep_time, JN516X_MAX_SLEEP_TIME); #if !RTIMER_USE_32KHZ /* convert to 32.768 kHz oscillator ticks */ max_sleep_time = (uint64_t)max_sleep_time * JN516X_XOSC_SECOND / RTIMER_SECOND; #endif vAHI_WakeTimerEnable(WAKEUP_TIMER, TRUE); /* sync with the tick timer */ WAIT_FOR_EDGE(sleep_start); sleep_start_ticks = u32AHI_TickTimerRead(); vAHI_WakeTimerStartLarge(WAKEUP_TIMER, max_sleep_time); ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_EXTRA_LPM); vAHI_Sleep(E_AHI_SLEEP_OSCON_RAMON); } else { #else { #endif /* JN516X_SLEEP_ENABLED */ clock_arch_schedule_interrupt(time_to_etimer, ticks_to_rtimer); ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); vAHI_CpuDoze(); watchdog_start(); ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); } } } /*---------------------------------------------------------------------------*/ void AppColdStart(void) { /* After reset or sleep with memory off */ main(); } /*---------------------------------------------------------------------------*/ void AppWarmStart(void) { /* Wakeup after sleep with memory on. * Need to initialize devices but not the application state. * Note: the actual time this function is called is * ~8 ticks (32kHz timer) later than the scheduled sleep end time. */ uint32_t sleep_ticks; uint64_t sleep_end; rtimer_clock_t sleep_ticks_rtimer; clock_arch_calibrate(); leds_init(); uart0_init(UART_BAUD_RATE); /* Must come before first PRINTF */ NETSTACK_RADIO.init(); watchdog_init(); watchdog_stop(); WAIT_FOR_EDGE(sleep_end); sleep_ticks = (uint32_t)(sleep_start - sleep_end) + 1; #if RTIMER_USE_32KHZ sleep_ticks_rtimer = sleep_ticks; #else { static uint32_t remainder; uint64_t t = (uint64_t)sleep_ticks * RTIMER_SECOND + remainder; sleep_ticks_rtimer = (uint32_t)(t / JN516X_XOSC_SECOND); remainder = t - sleep_ticks_rtimer * JN516X_XOSC_SECOND; } #endif /* reinitialize rtimers */ rtimer_arch_reinit(sleep_start_ticks, sleep_ticks_rtimer); ENERGEST_SWITCH(ENERGEST_TYPE_EXTRA_LPM, ENERGEST_TYPE_CPU); watchdog_start(); /* reinitialize clock */ clock_arch_init(1); /* schedule etimer interrupt */ clock_arch_schedule_interrupt(clock_arch_time_to_etimer(), rtimer_arch_time_to_rtimer()); #if DCOSYNCH_CONF_ENABLED /* The radio is recalibrated on wakeup */ last_dco_calibration_time = clock_seconds(); #endif main_loop(); }