/***************************************************************************** * Function Name: _Watchdog_Init() ****************************************************************************** * Summary: * Initialize the watchdog. * * Parameters: * None. * * Return: * None. * * Note: * *****************************************************************************/ void _Watchdog_Init(void) { // Unlock the WDT registers for modification. CySysWdtUnlock(); // Write Mode for Counters as Interrupt on Match. CySysWdtWriteMode(CY_SYS_WDT_COUNTER0, CY_SYS_WDT_MODE_INT); CySysWdtWriteMode(CY_SYS_WDT_COUNTER1, CY_SYS_WDT_MODE_INT); // Set Clear on Match for Counters. CySysWdtWriteClearOnMatch(CY_SYS_WDT_COUNTER0, TRUE); CySysWdtWriteClearOnMatch(CY_SYS_WDT_COUNTER1, TRUE); // Set Watchdog interrupt to lower priority. CyIntSetPriority(WATCHDOG_INT_VEC_NUM, WATCHDOG_INT_VEC_PRIORITY); // Enable Watchdog Interrupt using Interrupt number. CyIntEnable(WATCHDOG_INT_VEC_NUM); // Write the match value in Counters. CySysWdtWriteMatch(CY_SYS_WDT_COUNTER0, WATCHDOG_COUNTER0_PERIOD); CySysWdtWriteMatch(CY_SYS_WDT_COUNTER1, WATCHDOG_COUNTER1_PERIOD); // Enable Counters. CySysWdtEnable(CY_SYS_WDT_COUNTER0_MASK); CySysWdtEnable(CY_SYS_WDT_COUNTER1_MASK); // Lock Watchdog to prevent further changes. CySysWdtLock(); // Set the Watchdog Interrupt vector to the address of Interrupt routine // _Watchdog_Handler. CyIntSetVector(WATCHDOG_INT_VEC_NUM, &_Watchdog_Handler); }
/******************************************************************************* * Function Name: WDT_Stop ******************************************************************************** * * Summary: * This API stops the WDT timer. * *******************************************************************************/ void WDT_Stop(void) { /* Unlock the WDT registers for modification */ CySysWdtUnlock(); /* Disable the specified WDT counter */ CySysWdtDisable(WDT_COUNTER_MASK); /* Locks out configuration changes to the Watchdog timer registers */ CySysWdtLock(); }
void WDT_Start(void) { /* Unlock the WDT registers for modification */ CySysWdtUnlock(); /* Setup ISR */ WDT_Interrupt_StartEx(&Timer_Interrupt); /* Write the mode to generate interrupt on match */ CySysWdtWriteMode(WDT_COUNTER, CY_SYS_WDT_MODE_INT); /* Configure the WDT counter clear on a match setting */ CySysWdtWriteClearOnMatch(WDT_COUNTER, WDT_COUNTER_ENABLE); /* Configure the WDT counter match comparison value */ CySysWdtWriteMatch(WDT_COUNTER, WDT_1SEC); /* Reset WDT counter */ CySysWdtResetCounters(WDT_COUNTER); /* Enable the specified WDT counter */ CySysWdtEnable(WDT_COUNTER_MASK); /* Lock out configuration changes to the Watchdog timer registers */ CySysWdtLock(); }
/******************************************************************************* * 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); } }
/***************************************************************************** * Function Name: _Watchdog_Handler() ****************************************************************************** * Summary: * Watchdog interrupt routine. * * Parameters: * None. * * Return: * None. * * Note: * *****************************************************************************/ void _Watchdog_Handler(void) { // If the Interrupt source is Counter 0 match, then process. if(CySysWdtGetInterruptSource() & CY_SYS_WDT_COUNTER0_INT) { // Clear Watchdog Interrupt from Counter 0. CySysWdtClearInterrupt(CY_SYS_WDT_COUNTER0_INT); /********************************************************************/ /********************************************************************/ // Unlock the WDT registers for modification. CySysWdtUnlock(); // Disable Counter 0 to allow modifications. CySysWdtDisable(CY_SYS_WDT_COUNTER0_MASK); // Reset Counter 0 and give ~3 LFCLK cycles to take effect. CySysWdtResetCounters(CY_SYS_WDT_COUNTER0_RESET); CyDelayUs(WATCHDOG_REG_UPDATE_WAIT_TIME); // Write the Counter 0 match value for 20 millisecond and give // ~3 LFCLK cycles to take effect. CySysWdtWriteMatch(CY_SYS_WDT_COUNTER0, WATCHDOG_COUNTER0_PERIOD); CyDelayUs(WATCHDOG_REG_UPDATE_WAIT_TIME); // Enable Watchdog Counter 0. CySysWdtEnable(CY_SYS_WDT_COUNTER0_MASK); // Lock Watchdog to prevent any further change. CySysWdtLock(); } // If the Interrupt source is Counter 1 match, then process. else if(CySysWdtGetInterruptSource() & CY_SYS_WDT_COUNTER1_INT) { // Clear Watchdog Interrupt from Counter 0. CySysWdtClearInterrupt(CY_SYS_WDT_COUNTER1_INT); /********************************************************************/ // Stores the previous state of the BLE module. static uint8 previousState = 0xFF; // If in advertising mode, flash the LED. if(CyBle_GetState() == CYBLE_STATE_ADVERTISING) { previousState = CYBLE_STATE_ADVERTISING; if(_LED_Green_On) _LED_TurnOffLED(TRUE); else _LED_TurnOnLED(TRUE); } // If state changed, turn all the LEDs off. if (CyBle_GetState() != previousState) _LED_TurnOffLED(TRUE); // If disconnected, turn all the LEDs off. else if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED) { previousState = CYBLE_STATE_DISCONNECTED; _LED_TurnOffLED(TRUE); } // If connected, turn the LED on. else if(CyBle_GetState() == CYBLE_STATE_CONNECTED) { previousState = CYBLE_STATE_CONNECTED; _LED_TurnOffLED(FALSE); _LED_TurnOnLED(TRUE); } /********************************************************************/ // Unlock the WDT registers for modification. CySysWdtUnlock(); // Disable Counter 1 to allow modifications. CySysWdtDisable(CY_SYS_WDT_COUNTER1_MASK); // Reset Counter 1 and give ~3 LFCLK cycles to take effect. CySysWdtResetCounters(CY_SYS_WDT_COUNTER1_RESET); CyDelayUs(WATCHDOG_REG_UPDATE_WAIT_TIME); // Write the Counter 1 match value for 500 millisecond and give // ~3 LFCLK cycles to take effect. CySysWdtWriteMatch(CY_SYS_WDT_COUNTER1, WATCHDOG_COUNTER1_PERIOD); CyDelayUs(WATCHDOG_REG_UPDATE_WAIT_TIME); // Enable Watchdog Counter 1. CySysWdtEnable(CY_SYS_WDT_COUNTER1_MASK); // Lock Watchdog to prevent any further change. CySysWdtLock(); } }