/******************************************************************************* * Function Name: EnterLowPowerMode ******************************************************************************** * * Summary: * This configures the BLESS and system in low power mode whenever possible. * * Parameters: * None * * Return: * None * *******************************************************************************/ void EnterLowPowerMode(void) { CYBLE_BLESS_STATE_T blessState; uint8 intrStatus; /* Configure BLESS in Deep-Sleep mode */ CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP); /* Prevent interrupts while entering system low power modes */ intrStatus = CyEnterCriticalSection(); /* Get the current state of BLESS block */ blessState = CyBle_GetBleSsState(); /* If BLESS is in Deep-Sleep mode or the XTAL oscillator is turning on, * then PSoC 4 BLE can enter Deep-Sleep mode (1.3uA current consumption) */ if(blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP) { CySysPmDeepSleep(); } else if(blessState != CYBLE_BLESS_STATE_EVENT_CLOSE) { /* If BLESS is active, then configure PSoC 4 BLE system in * Sleep mode (~1.6mA current consumption) */ CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_ECO); CySysClkImoStop(); CySysPmSleep(); CySysClkImoStart(); CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_IMO); } else { /* Keep trying to enter either Sleep or Deep-Sleep mode */ } CyExitCriticalSection(intrStatus); }
void LowPower(void) { CYBLE_LP_MODE_T pwrState; CYBLE_BLESS_STATE_T blessState; uint8 intStatus = 0; 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) { CySysPmDeepSleep(); /* System Deep-Sleep. 1.3uA mode */ } } 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(); /* Put the CPU to Sleep. 1.1mA mode */ CySysPmSleep(); /* Starts execution after waking up, start IMO */ CySysClkImoStart(); /* Change HF clock source back to IMO */ CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_IMO); } CyExitCriticalSection(intStatus); }
/******************************************************************************* * 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); } }
int main() { /* Variable declarations */ CYBLE_LP_MODE_T lpMode; CYBLE_BLESS_STATE_T blessState; uint8 InterruptsStatus; /* Start communication component */ UART_Start(); /* Enable global interrupts */ CyGlobalIntEnable; /* Internal low power oscillator is stopped as it is not used in this project */ CySysClkIloStop(); /* 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); CyBle_Start(StackEventHandler); /*Infinite Loop*/ for(;;) { if((UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID) == 0) { if(CyBle_GetState() != CYBLE_STATE_INITIALIZING) { /* Put BLE sub system in DeepSleep mode when it is idle */ lpMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP); /* Disable global interrupts to avoid any other tasks from interrupting this section of code*/ InterruptsStatus = CyEnterCriticalSection(); /* Get current state of BLE sub system to check if it has successfully entered deep sleep state */ blessState = CyBle_GetBleSsState(); /* If BLE sub system has entered deep sleep, put chip into deep sleep for reducing power consumption */ if(lpMode == CYBLE_BLESS_DEEPSLEEP) { if(blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP) { /* Put the chip into the deep sleep state as there are no pending tasks and BLE has also ** successfully entered BLE DEEP SLEEP mode */ CySysPmDeepSleep(); } } /* BLE sub system has not entered deep sleep, wait for completion of radio operations */ 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(); /* put the CPU to sleep */ CySysPmSleep(); /* starts execution after waking up, start IMO */ CySysClkImoStart(); /* change HF clock source back to IMO */ CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_IMO); } /*Enable interrupts */ CyExitCriticalSection(InterruptsStatus); }/*end of if(CyBle_GetState() != CYBLE_STATE_INITIALIZING)*/ CyBle_ProcessEvents(); } } }