/******************************************************************************* * 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(); }
CY_CFG_SECTION static void ClockSetup(void) { /* Set Flash Cycles based on max possible frequency in case a glitch occurs during ClockSetup(). */ CY_SET_REG32((void CYXDATA *)(CYREG_CPUSS_FLASH_CTL), (0x0012u)); /* Start the WCO */ CySysClkWcoStart(); CyDelayCycles(12000000u); /* WCO may take up to 500ms to start */ (void)CySysClkWcoSetPowerMode(CY_SYS_CLK_WCO_LPM); /* Switch to the low power mode */ /* Setup and trim IMO based on desired frequency. */ CySysClkWriteImoFreq(48u); /* CYDEV_CLK_ILO_CONFIG Starting address: CYDEV_CLK_ILO_CONFIG */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_ILO_CONFIG), 0x80000006u); /* CYDEV_WDT_CONFIG Starting address: CYDEV_WDT_CONFIG */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_WDT_CONFIG), 0x40000000u); /* Enable fast start mode for XO */ CY_SET_REG32((void*)CYREG_BLE_BLERD_BB_XO, CY_GET_REG32((void*)CYREG_BLE_BLERD_BB_XO) | (uint32)0x02u); CY_SET_XTND_REG32((void CYFAR *)(CYREG_BLE_BLERD_BB_XO_CAPTRIM), 0x00003E2Du); /*Set XTAL(ECO) divider*/ CY_SET_XTND_REG32((void CYFAR *)(CYREG_BLE_BLESS_XTAL_CLK_DIV_CONFIG), 0x00000000u); /* Disable Crystal Stable Interrupt before enabling ECO */ CY_SET_REG32((void*)CYREG_BLE_BLESS_LL_DSM_CTRL, CY_GET_REG32((void*)CYREG_BLE_BLESS_LL_DSM_CTRL) & (~(uint32)0x08u)); /* Start the ECO and do not check status since it is not needed for HFCLK */ (void)CySysClkEcoStart(2000u); CyDelayUs(1500u); /* Wait to stabalize */ /* Setup phase aligned clocks */ CY_SET_REG32((void *)CYREG_PERI_DIV_16_CTL1, 0x00BB7F00u); CY_SET_REG32((void *)CYREG_PERI_DIV_CMD, 0x8000FF41u); CY_SET_REG32((void *)CYREG_PERI_DIV_16_CTL0, 0x0001A000u); CY_SET_REG32((void *)CYREG_PERI_DIV_CMD, 0x8000FF40u); /* CYDEV_CLK_IMO_CONFIG Starting address: CYDEV_CLK_IMO_CONFIG */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_IMO_CONFIG), 0x80000000u); /* CYDEV_CLK_SELECT Starting address: CYDEV_CLK_SELECT */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_SELECT), 0x00040000u); /* CYDEV_PERI_PCLK_CTL7 Starting address: CYDEV_PERI_PCLK_CTL7 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL7), 0x00000041u); /* CYDEV_PERI_PCLK_CTL2 Starting address: CYDEV_PERI_PCLK_CTL2 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL2), 0x00000040u); (void)CyIntSetVector(8u, &CySysWdtIsr); CyIntEnable(8u); CY_SET_XTND_REG32((void CYFAR *)(CYREG_WDT_MATCH), 0x00000020u); CY_SET_XTND_REG32((void CYFAR *)(CYREG_WDT_CONFIG), 0x40000005u); CY_SET_XTND_REG32((void CYFAR *)(CYREG_WDT_CONTROL), 0x00000008u); while ((CY_GET_XTND_REG32((void CYFAR *)(CYREG_WDT_CONTROL)) & 0x00000008u) != 0u) { } CY_SET_XTND_REG32((void CYFAR *)(CYREG_WDT_CONTROL), 0x00000001u); }
CY_CFG_SECTION static void ClockSetup(void) { /* Set Flash Cycles based on max possible frequency in case a glitch occurs during ClockSetup(). */ CY_SET_REG32((void CYXDATA *)(CYREG_CPUSS_FLASH_CTL), (0x0012u)); /* Start the WCO */ CySysClkWcoStart(); (void)CySysClkWcoSetPowerMode(CY_SYS_CLK_WCO_LPM); /* Switch to the low power mode */ /* Setup and trim IMO based on desired frequency. */ CySysClkWriteImoFreq(24u); /* CYDEV_CLK_ILO_CONFIG Starting address: CYDEV_CLK_ILO_CONFIG */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_ILO_CONFIG), 0x80000006u); /* Enable fast start mode for XO */ CY_SET_REG32((void*)CYREG_BLE_BLERD_BB_XO, CY_GET_REG32((void*)CYREG_BLE_BLERD_BB_XO) | (uint32)0x02u); CY_SET_XTND_REG32((void CYFAR *)(CYREG_BLE_BLERD_BB_XO_CAPTRIM), 0x00003E2Du); /* Disable Crystal Stable Interrupt before enabling ECO */ CY_SET_REG32((void*)CYREG_BLE_BLESS_LL_DSM_CTRL, CY_GET_REG32((void*)CYREG_BLE_BLESS_LL_DSM_CTRL) & (~(uint32)0x08u)); /* Start the ECO and do not check status since it is not needed for HFCLK */ (void)CySysClkEcoStart(2000u); CyDelayUs(1500u); /* Wait to stabalize */ /* Setup phase aligned clocks */ CY_SET_REG32((void *)CYREG_PERI_DIV_16_CTL2, 0x0001DF00u); CY_SET_REG32((void *)CYREG_PERI_DIV_CMD, 0x8000FF42u); CY_SET_REG32((void *)CYREG_PERI_DIV_16_CTL0, 0x00000E00u); CY_SET_REG32((void *)CYREG_PERI_DIV_CMD, 0x8000FF40u); CY_SET_REG32((void *)CYREG_PERI_DIV_16_CTL1, 0x00001000u); CY_SET_REG32((void *)CYREG_PERI_DIV_CMD, 0x8000FF41u); /* CYDEV_CLK_IMO_CONFIG Starting address: CYDEV_CLK_IMO_CONFIG */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_IMO_CONFIG), 0x80000000u); /* CYDEV_PERI_PCLK_CTL11 Starting address: CYDEV_PERI_PCLK_CTL11 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL11), 0x00000042u); /* CYDEV_PERI_PCLK_CTL8 Starting address: CYDEV_PERI_PCLK_CTL8 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL8), 0x00000042u); /* CYDEV_PERI_PCLK_CTL7 Starting address: CYDEV_PERI_PCLK_CTL7 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL7), 0x00000042u); /* CYDEV_PERI_PCLK_CTL2 Starting address: CYDEV_PERI_PCLK_CTL2 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL2), 0x00000040u); /* CYDEV_PERI_PCLK_CTL1 Starting address: CYDEV_PERI_PCLK_CTL1 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL1), 0x00000041u); (void)CyIntSetVector(8u, &CySysWdtIsr); CyIntEnable(8u); CY_SET_XTND_REG32((void CYFAR *)(CYREG_WDT_CONFIG), 0x00000000u); /* Set Flash Cycles based on newly configured 24.00MHz HFCLK. */ CY_SET_REG32((void CYXDATA *)(CYREG_CPUSS_FLASH_CTL), (0x0011u)); }
CY_CFG_SECTION static void ClockSetup(void) { /* Set Flash Cycles based on max possible frequency in case a glitch occurs during ClockSetup(). */ CY_SET_REG32((void CYXDATA *)(CYREG_CPUSS_FLASH_CTL), (0x0012u)); /* Trim IMO BG based on desired frequency. */ SetIMOBGTrims(12u); /* Going less than or equal to 24MHz, so update the clock speed then adjust trim value. */ CY_SET_REG32((void CYXDATA *)(CYREG_CLK_IMO_TRIM2), (12u)); CyDelayCycles(5u); CY_SET_REG32((void CYXDATA *)(CYREG_CLK_IMO_TRIM1), (CY_GET_REG8((void *)CYREG_SFLASH_IMO_TRIM09))); CyDelayUs(5u); /* Start the WCO */ CySysClkWcoStart(); CyDelay(500u); /* WCO may take up to 500ms to start */ (void)CySysClkWcoSetPowerMode(CY_SYS_CLK_WCO_LPM); /* Switch to the low power mode */ /* CYDEV_WDT_CONFIG Starting address: CYDEV_WDT_CONFIG */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_WDT_CONFIG), 0x40000000u); CY_SET_XTND_REG32((void CYFAR *)(CYREG_BLE_BLERD_BB_XO_CAPTRIM), 0x00002D6Au); /* Disable Crystal Stable Interrupt before enabling ECO */ CY_SET_REG32((void*)CYREG_BLE_BLESS_LL_DSM_CTRL, CY_GET_REG32((void*)CYREG_BLE_BLESS_LL_DSM_CTRL) & (~(uint32)0x08u)); /* Start the ECO and do not check status since it is not needed for HFCLK */ (void)CySysClkEcoStart(2000u); CyDelayUs(1500u); /* Wait to stabalize */ /* Setup phase aligned clocks */ CY_SET_REG32((void *)CYREG_PERI_DIV_16_CTL02, 0x00000B00u); CY_SET_REG32((void *)CYREG_PERI_DIV_CMD, 0x8000FF42u); CY_SET_REG32((void *)CYREG_PERI_DIV_16_CTL00, 0x0000FE00u); CY_SET_REG32((void *)CYREG_PERI_DIV_CMD, 0x8000FF40u); CY_SET_REG32((void *)CYREG_PERI_DIV_16_CTL01, 0x0000FE00u); CY_SET_REG32((void *)CYREG_PERI_DIV_CMD, 0x8000FF41u); /* CYDEV_CLK_IMO_CONFIG Starting address: CYDEV_CLK_IMO_CONFIG */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_IMO_CONFIG), 0x80000000u); /* CYDEV_PERI_PCLK_CTL11 Starting address: CYDEV_PERI_PCLK_CTL11 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL11), 0x00000042u); /* CYDEV_PERI_PCLK_CTL05 Starting address: CYDEV_PERI_PCLK_CTL05 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL05), 0x00000040u); /* CYDEV_PERI_PCLK_CTL04 Starting address: CYDEV_PERI_PCLK_CTL04 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL04), 0x00000041u); /* Set Flash Cycles based on newly configured 12.00MHz HFCLK. */ CY_SET_REG32((void CYXDATA *)(CYREG_CPUSS_FLASH_CTL), (0x0000u)); }
CY_CFG_SECTION static void ClockSetup(void) { /* Set Flash Cycles based on max possible frequency in case a glitch occurs during ClockSetup(). */ CY_SET_REG32((void CYXDATA *)(CYREG_CPUSS_FLASH_CTL), (0x0012u)); /* Start the WCO */ CySysClkWcoStart(); CyDelayCycles(12000000u); /* WCO may take up to 500ms to start */ (void)CySysClkWcoSetPowerMode(CY_SYS_CLK_WCO_LPM); /* Switch to the low power mode */ /* Setup and trim IMO based on desired frequency. */ CySysClkWriteImoFreq(12u); /* CYDEV_CLK_ILO_CONFIG Starting address: CYDEV_CLK_ILO_CONFIG */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_ILO_CONFIG), 0x80000006u); /* CYDEV_WDT_CONFIG Starting address: CYDEV_WDT_CONFIG */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_WDT_CONFIG), 0x40000000u); /* Enable fast start mode for XO */ CY_SET_REG32((void*)CYREG_BLE_BLERD_BB_XO, CY_GET_REG32((void*)CYREG_BLE_BLERD_BB_XO) | (uint32)0x02u); CY_SET_XTND_REG32((void CYFAR *)(CYREG_BLE_BLERD_BB_XO_CAPTRIM), 0x00002D6Au); /* Disable Crystal Stable Interrupt before enabling ECO */ CY_SET_REG32((void*)CYREG_BLE_BLESS_LL_DSM_CTRL, CY_GET_REG32((void*)CYREG_BLE_BLESS_LL_DSM_CTRL) & (~(uint32)0x08u)); /* Start the ECO and do not check status since it is not needed for HFCLK */ (void)CySysClkEcoStart(2000u); CyDelayUs(1500u); /* Wait to stabalize */ /* Setup phase aligned clocks */ CY_SET_REG32((void *)CYREG_PERI_DIV_16_CTL0, 0x00000300u); CY_SET_REG32((void *)CYREG_PERI_DIV_CMD, 0x8000FF40u); /* CYDEV_CLK_IMO_CONFIG Starting address: CYDEV_CLK_IMO_CONFIG */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_IMO_CONFIG), 0xA6000000u); /* CYDEV_CLK_SELECT Starting address: CYDEV_CLK_SELECT */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_SELECT), 0x00000000u); /* CYDEV_PERI_PCLK_CTL6 Starting address: CYDEV_PERI_PCLK_CTL6 */ CY_SET_XTND_REG32((void CYFAR *)(CYREG_PERI_PCLK_CTL6), 0x00000040u); CY_SET_XTND_REG32((void CYFAR *)(CYREG_WDT_CONFIG), 0x40000000u); /* Set Flash Cycles based on newly configured 12.00MHz HFCLK. */ CY_SET_REG32((void CYXDATA *)(CYREG_CPUSS_FLASH_CTL), (0x0000u)); }
/******************************************************************************* * 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); } }