/******************************************************************************* * Function Name: WCO_LowPowerStart ******************************************************************************** * Summary: * Start WCO in low power mode by configuring the system in DeepSleep mode during * WCO startup time(500ms) * * Parameters: * None * * Return: * None * *******************************************************************************/ void WCO_ECO_LowPowerStart(void) { WDT_WcoEcoLpStartSetup(); /* Setup WDT counters to enable low power WCO & ECO startup */ CySysClkWcoStart(); /* Start the WCO clock */ WDT_EnableWcoCounter(); /* Enable WDT's WCO counter (counter 0) */ #if DEBUG_ENABLE DeepSleep_Write(1); #endif /* End of #if DEBUG_ENABLE */ CySysPmDeepSleep(); /* Wait for the WDT counter 0 interrupt to wake up the device. On wakeup WCO is up & running */ #if DEBUG_ENABLE DeepSleep_Write(0); #endif /* End of #if DEBUG_ENABLE */ (void)CySysClkWcoSetPowerMode(CY_SYS_CLK_WCO_LPM); /* Switch WCO to the low power mode after startup */ CySysClkSetLfclkSource(CY_SYS_CLK_LFCLK_SRC_WCO); /* LFCLK is now driven by WCO */ CySysClkIloStop(); /* WCO is running, shut down the ILO */ (void)CySysClkEcoStart(0); /* It's time to start ECO */ WDT_EnableEcoCounter(); /* Enable WDT's ECO counter (counter 1) */ #if TIMING_DEBUG_ENABLE DeepSleep_Write(1); #endif CySysPmDeepSleep(); /* Wait for the WDT counter 1 interrupt to wake up the device. On wakeup ECO is up & running */ #if TIMING_DEBUG_ENABLE DeepSleep_Write(0); #endif WDT_DisableWcoEcoCounters(); }
/******************************************************************************* * Function Name: System_ManagePower() ******************************************************************************** * * Summary: * This function puts the system in appropriate low power modes based on the * state of BLESS and application power state. * * Parameters: * none * ********************************************************************************/ inline void System_ManagePower() { /* Variable declarations */ CYBLE_BLESS_STATE_T blePower; uint8 interruptStatus ; /* Disable global interrupts to avoid any other tasks from interrupting this section of code*/ interruptStatus = CyEnterCriticalSection(); /* Get current state of BLE sub system to check if it has successfully entered deep sleep state */ blePower = CyBle_GetBleSsState(); /* System can enter DeepSleep only when BLESS and rest of the application are in DeepSleep or equivalent * power modes */ if((blePower == CYBLE_BLESS_STATE_DEEPSLEEP || blePower == CYBLE_BLESS_STATE_ECO_ON) && Application_GetPowerState() == DEEPSLEEP) { Application_SetPowerState(WAKEUP_DEEPSLEEP); #if DEBUG_ENABLE DeepSleep_Write(1); #endif /* End of #if DEBUG_ENABLE */ CySysPmDeepSleep(); #if DEBUG_ENABLE DeepSleep_Write(0); #endif /* End of #if DEBUG_ENABLE */ } else if((blePower != CYBLE_BLESS_STATE_EVENT_CLOSE)) { if(Application_GetPowerState() == DEEPSLEEP) { Application_SetPowerState(WAKEUP_DEEPSLEEP); /* change HF clock source from IMO to ECO, as IMO can be stopped to save power */ CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_ECO); /* stop IMO for reducing power consumption */ CySysClkImoStop(); /* put the CPU to sleep */ #if DEBUG_ENABLE Sleep_Write(1); #endif /* End of #if DEBUG_ENABLE */ CySysPmSleep(); #if DEBUG_ENABLE Sleep_Write(0); #endif /* End of #if DEBUG_ENABLE */ /* starts execution after waking up, start IMO */ CySysClkImoStart(); /* change HF clock source back to IMO */ CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_IMO); } else if(Application_GetPowerState() == SLEEP ) { /* If the application is using IMO for its operation, we shouldn't switch over the HFCLK source */ Application_SetPowerState(WAKEUP_SLEEP); #if DEBUG_ENABLE Sleep_Write(1); #endif /* End of #if DEBUG_ENABLE */ CySysPmSleep(); #if DEBUG_ENABLE Sleep_Write(0); #endif /* End of #if DEBUG_ENABLE */ } } /* Enable interrupts */ CyExitCriticalSection(interruptStatus ); }
/******************************************************************************* * Function Name: main ******************************************************************************** * Summary: * MyBeacon entry point. This calls the BLE and other peripheral Component * APIs for achieving the desired system behaviour * * Parameters: * void * * Return: * int * *******************************************************************************/ int main() { CyGlobalIntEnable; /* Set the divider for ECO, ECO will be used as source when IMO is switched off to save power, to drive the HFCLK */ CySysClkWriteEcoDiv(CY_SYS_CLK_ECO_DIV8); /* If USE_WCO_FOR_TIMING is set, then do the following: * 1. Shut down the ECO (to reduce power consumption while WCO is starting) * 2. Enable WDT to wakeup the system after 500ms (WCO startup time). * 3. Configure PSoC 4 BLE device in DeepSleep mode for the 500ms WCO startup time * 4. After WCO is enabled, restart the ECO so that BLESS interface can function */ #if USE_WCO_FOR_TIMING CySysClkEcoStop(); WDT_Interrupt_StartEx(WDT_Handler); CySysClkWcoStart(); CySysWdtUnlock(); /* Unlock the WDT registers for modification */ CySysWdtWriteMode(SOURCE_COUNTER, CY_SYS_WDT_MODE_INT); CySysWdtWriteClearOnMatch(SOURCE_COUNTER, COUNTER_ENABLE); CySysWdtWriteMatch(SOURCE_COUNTER, COUNT_PERIOD); CySysWdtEnable(CY_SYS_WDT_COUNTER0_MASK); CySysWdtLock(); #if TIMING_DEBUG_ENABLE DeepSleep_Write(1); #endif CySysPmDeepSleep(); /* Wait for the WDT interrupt to wake up the device */ #if TIMING_DEBUG_ENABLE DeepSleep_Write(0); #endif (void)CySysClkEcoStart(2000u); CyDelayUs(500u); (void)CySysClkWcoSetPowerMode(CY_SYS_CLK_WCO_LPM); /* Switch to the low power mode */ CySysClkSetLfclkSource(CY_SYS_CLK_LFCLK_SRC_WCO); CySysWdtUnlock(); CySysWdtDisable(CY_SYS_WDT_COUNTER0_MASK); CySysWdtLock(); #endif CyBle_Start(BLE_AppEventHandler); for(;;) { CYBLE_LP_MODE_T pwrState; CYBLE_BLESS_STATE_T blessState; uint8 intStatus = 0; CyBle_ProcessEvents(); /* BLE stack processing state machine interface */ pwrState = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP); /* Configure BLESS in Deep-Sleep mode */ intStatus = CyEnterCriticalSection(); /* No interrupts allowed while entering system low power modes */ blessState = CyBle_GetBleSsState(); if(pwrState == CYBLE_BLESS_DEEPSLEEP) /* Make sure BLESS is in Deep-Sleep before configuring system in Deep-Sleep */ { if(blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP) { #if TIMING_DEBUG_ENABLE DeepSleep_Write(1); #endif CySysPmDeepSleep(); /* System Deep-Sleep. 1.3uA mode */ #if TIMING_DEBUG_ENABLE DeepSleep_Write(0); #endif } } else if (blessState != CYBLE_BLESS_STATE_EVENT_CLOSE) { /* Change HF clock source from IMO to ECO, as IMO can be stopped to save power */ CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_ECO); /* Stop IMO for reducing power consumption */ CySysClkImoStop(); #if TIMING_DEBUG_ENABLE Sleep_Write(1); #endif /* Put the CPU to Sleep. 1.1mA mode */ CySysPmSleep(); #if TIMING_DEBUG_ENABLE Sleep_Write(0); #endif /* Starts execution after waking up, start IMO */ CySysClkImoStart(); /* Change HF clock source back to IMO */ CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_IMO); } CyExitCriticalSection(intStatus); } }