/* Please see in PWRLib.h for description */ PWRLib_WakeupReason_t PWR_HandleDeepSleep( zbClock24_t DozeDuration) { PWRLib_WakeupReason_t Res; Res.AllBits = 0; (void) DozeDuration; #if (cPWR_UsePowerDownMode) /* Insure that Key Wakeup interrupts are enabled!! Note insert next line of code if you always need the keyboard irq enabled while entering sleep. KBISC |= cKBI1SC; */ /*---------------------------------------------------------------------------*/ #if (cPWR_DeepSleepMode==0) Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; Res.AllBits = 0xff | (uint8_t) DozeDuration; // Last part to avoid unused warning /* No code */ /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==1) #if (cPWR_KBIWakeupEnable==1) if (PWR_Stop3AndOff() != FALSE) { Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; PWR_RunAgain(); } #else #error "*** ERROR: cPWR_KBIWakeupEnable has to be set to 1" #endif /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==2) #if (cPWR_KBIWakeupEnable==0) PWRLib_RTIClockStart( cPWR_RTITickTime, DozeDuration); if (PWR_Stop3AndOff() != FALSE) { while ( PWRLib_RTIClockCheck() > 0) { PWRLib_MCUStop3(); } PWRLib_RTIClockStop(); #if (gTMR_EnableLowPowerTimers_d) /* Sync. the low power timers */ TMR_SyncLpmTimers(MillisToSyncLpmTimers(notCountedTimeBeforeSleep)); #endif /* #if (gTMR_EnableLowPowerTimers_d) */ Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; Res.Bits.DeepSleepTimeout = 1; PWR_RunAgain(); cPWR_DeepSleepWakeupStackProc; /* User function called only on timeout */ } #else #error "*** ERROR: cPWR_KBIWakeupEnable has to be set to 0" #endif /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==3) #if (cPWR_KBIWakeupEnable) PWRLib_MCU_WakeupReason.Bits.FromKBI = FALSE; // Clear any prior KBI wakeup flag PWRLib_RTIClockStart( cPWR_RTITickTime, DozeDuration); if (PWR_Stop3AndOff() != FALSE) { while ((PWRLib_MCU_WakeupReason.Bits.FromKBI == 0 ) && ( PWRLib_RTIClockCheck() > 0)) { (void) PWRLib_MCUStop3(); } PWRLib_RTIClockStop(); #if (gTMR_EnableLowPowerTimers_d) /* Sync. the low power timers */ TMR_SyncLpmTimers(MillisToSyncLpmTimers(notCountedTimeBeforeSleep)); #endif /* #if (gTMR_EnableLowPowerTimers_d) */ Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; PWR_RunAgain(); if ( PWRLib_RTIClockCheck() == 0) { Res.Bits.DeepSleepTimeout = 1; cPWR_DeepSleepWakeupStackProc; /* User function called only on timeout */ } } #else #error "*** ERROR: cPWR_KBIWakeupEnable has to be set to 1" #endif //--------------------------------------------------------------------------- /* Mode 4: Radio in hibernate, MCU in STOP3, RTI int clock 1024 mS wakeup, KBI enabled */ #elif (cPWR_DeepSleepMode==4) PWRLib_MCU_WakeupReason.Bits.FromKBI = FALSE; // Clear any prior KBI wakeup flag #ifdef PROCESSOR_HCS08 PWRLib_ICG_Mode(SCM, LOW_CLOCK); // Put MCU into Self-Clocked Mode (SCM) #endif #ifdef PROCESSOR_QE128 ICSC1 |= 0x04; /* Set IREFS */ while(!(ICSSC & 0x10)); /* Wait for the FLL to lock on the internal clock source */ #endif if (PWRLib_RadioHibernateReq() != FALSE) { PWRLib_SetMCUIOForPowerSavingMode(); PWRLib_RTIClockStart( cPWR_RTITickTime, DozeDuration); while (( PWRLib_MCU_WakeupReason.Bits.FromKBI == 0) && ( PWRLib_RTIClockCheck() > 0)) { (void) PWRLib_MCUStop3(); } PWRLib_RTIClockStop(); /* Sync. the low power timers */ #if (gTMR_EnableLowPowerTimers_d) TMR_SyncLpmTimers(MillisToSyncLpmTimers(notCountedTimeBeforeSleep)); #endif /*#if (gTMR_EnableLowPowerTimers_d) */ Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; // Wake radio MC1319xDrv_AttEnable(); /* Set att. pin high so we do not waste any power..*/ WAIT_6_NOPS(); WAIT_6_NOPS(); MC1319xDrv_AttDisable(); /* Set att. pin high so we do not waste any power..*/ // Wait for attn irq to arrive... while ( PowerManager_GetPowerMode() != gSeqPowerModeAwake_c){} /* At this point the MCU Clock has been restored by the WakeUp ISR (triggered by ATTN) */ mRADIO_SetStatus( RADIO_Idle); PWRLib_ResetMCUIOAfterPowerSavingMode(); if ( PWRLib_RTIClockCheck() == 0) { Res.Bits.DeepSleepTimeout = 1; cPWR_DeepSleepWakeupStackProc; // User function called only on timeout } } else // Didn't make it into hibernate; restore clock PWRLib_ClockSetup( Normal_16MHz); //--------------------------------------------------------------------------- /* Mode 5: Radio in acoma/doze, clockout enabled, MCU in STOP3, RTI on ext clock 1024 mS wakeup */ /* KBI enabled */ /* NOTE: must select RTI on external clock via cPWR_RTIFromExternalClock in PWR_Config.h, else int clock */ /* NOTE: MCU's internal RTI clock will NOT run in DEBUG (BDM) mode; therefore select ext clock for this */ /* NOTE: Radio clockout will be changed to 32.786 kHz to make RTI timeout same as with internal MCU clock */ #elif (cPWR_DeepSleepMode==5) PWRLib_MCU_WakeupReason.Bits.FromKBI = FALSE; // Clear any prior KBI wakeup flag #ifdef PROCESSOR_HCS08 PWRLib_ICG_Mode(SCM, LOW_CLOCK); // Put MCU into Self-Clocked Mode (SCM) #endif #ifdef PROCESSOR_QE128 ICSC1 |= 0x04; /* Set IREFS */ while(!(ICSSC & 0x10)); /* Wait for the FLL to lock on the internal clock source */ #endif /* On the QE128 processor the RTI division on the external clock source is 2 times bigger than on HCS08 */ #ifdef PROCESSOR_HCS08 MC1319xDrv_WriteSpi(ABEL_regA, RADIO_CLKO_32_78KHZ); // Change RTI clock source to give same timeout as internal clock #endif #ifdef PROCESSOR_QE128 MC1319xDrv_WriteSpi(ABEL_regA, RADIO_CLKO_62_50KHZ); // Change RTI clock source to give same timeout as internal clock #endif if (PWRLib_RadioAcomaDozeReq(TRUE) != FALSE) // Put radio into acoma/doze, clockout enabled { PWRLib_SetMCUIOForPowerSavingMode(); PWRLib_RTIClockStart( cPWR_RTITickTime, DozeDuration); // Setup and start the RTI while (( PWRLib_MCU_WakeupReason.Bits.FromKBI == 0) && ( PWRLib_RTIClockCheck() > 0)) { (void) PWRLib_MCUStop3(); // STOP3 loop } PWRLib_RTIClockStop(); /* Sync. the low power timers */ #if (gTMR_EnableLowPowerTimers_d) TMR_SyncLpmTimers(MillisToSyncLpmTimers(notCountedTimeBeforeSleep)); #endif /* #if (gTMR_EnableLowPowerTimers_d) */ Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; // Make attn pulse instead of calling AbelWakeUp() in MAC/PHY // This is done because we have clk0 running (TRUE on the ..Dozereq function call) // If this is changed to FALSE, call AbelWakeUp() instead. MC1319xDrv_AttEnable(); /* Set att. pin high so we do not waste any power..*/ WAIT_6_NOPS(); WAIT_6_NOPS(); MC1319xDrv_AttDisable(); /* Set att. pin high so we do not waste any power..*/ // Wait for attn irq to arrive... while ( PowerManager_GetPowerMode() != gSeqPowerModeAwake_c){} /* At this point the MCU Clock has been restored by the WakeUp ISR (triggered by ATTN) */ mRADIO_SetStatus( RADIO_Idle); PWRLib_ResetMCUIOAfterPowerSavingMode(); if ( PWRLib_RTIClockCheck() == 0) { Res.Bits.DeepSleepTimeout = 1; cPWR_DeepSleepWakeupStackProc; // User function called only on timeout } } // PWRLib_RadioAcomaDozeReq else PWRLib_ClockSetup( Normal_16MHz); /*---------------------------------------------------------------------------*/ /* Mode 6: Radio in doze mode, supplying 62.5KHz to MCU, MCU in STOP3 */ /* Radio wakeup after cPWR_DozeDurationMs */ /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==6) { #if (gTMR_EnableLowPowerTimers_d) zbClock24_t currentClock; // only used for low power timers sync #endif if(!mPWR_DozeDurationSymbols) { /* Calculate doze time based on the Radio Event Time frequency - 62.5 KHz*/ /* The DozeDuration value is computed by the preprocessor.*/ DozeDuration = (zbClock24_t)(((zbClock24_t)mPWR_DozeDurationMs * 625) / 10) & (zbClock24_t)0xFFFFFF; } else { DozeDuration = mPWR_DozeDurationMs; } PWRLib_MCU_WakeupReason.Bits.FromKBI = FALSE; // Clear any prior KBI wakeup flag #if (gTMR_EnableLowPowerTimers_d) // Get current clock from ABEL. Only needed for low power timers sync LowLevelReadClockAsync(¤tClock); #endif #ifdef PROCESSOR_HCS08 PWRLib_ICG_Mode(SCM, LOW_CLOCK); // Put MCU into Self-Clocked Mode (SCM) #endif #ifdef PROCESSOR_QE128 ICSC1 |= 0x04; /* Set IREFS */ while(!(ICSSC & 0x10)); /* Wait for the FLL to lock on the internal clock source */ #endif /* Request Radio Doze with clock output */ if(Asp_DozeReq(&DozeDuration, TRUE) == 0) { mRADIO_SetStatus(RADIO_Doze); PWRLib_SetMCUIOForPowerSavingMode(); (void)PWRLib_MCUStop3(); // STOP3 Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; if(PowerManager_GetPowerMode() != gSeqPowerModeAwake_c) { // Attn pulse in case MCU wakes before doze expiration time */ MC1319xDrv_AttEnable(); /* Set att. pin high so we do not waste any power.*/ WAIT_6_NOPS(); WAIT_6_NOPS(); MC1319xDrv_AttDisable(); /* Set att. pin high so we do not waste any power.*/ // Wait for attn irq to arrive... while ( PowerManager_GetPowerMode() != gSeqPowerModeAwake_c){} } else { Res.Bits.DeepSleepTimeout = 1; /* Sleep timeout ran out */ Res.Bits.FromTimer = 1; /* Wakeup by radio timer */ } /* At this point the MCU Clock has been restored by the WakeUp ISR. * This was triggered either by the doze finish event or by ATTN. */ // Get current clock from ABEL LowLevelReadClockAsync(&lastLPMExitRadioTime); /* Sync. the low power timers */ #if (gTMR_EnableLowPowerTimers_d) DozeDuration = (zbClock24_t)((lastLPMExitRadioTime - currentClock) & 0xFFFFFF); // Transform doze time in ms DozeDuration = (zbClock24_t)(((uint32_t)DozeDuration * 10) / 625); TMR_SyncLpmTimers(DozeDuration + notCountedTimeBeforeSleep); #endif /* #if (gTMR_EnableLowPowerTimers_d) */ mRADIO_SetStatus(RADIO_Idle); PWRLib_ResetMCUIOAfterPowerSavingMode(); if(Res.Bits.DeepSleepTimeout == 1) { cPWR_DeepSleepWakeupStackProc; // User function called only on timeout } } else { // Didn't make it into doze mode; restore clock PWRLib_ClockSetup( Normal_16MHz); } } #elif (cPWR_DeepSleepMode==30) #error "*** ERROR: cPWR_DeepSleepMode == 30 not allowed" /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==31) #if (cPWR_KBIWakeupEnable) if ( PWR_RemainingLoops > 0) { PWR_RemainingLoops--; PWRLib_RTIClockStart( cSRTISC_Int1024ms, DozeDuration); if (PWR_Stop3AndOff() != FALSE) { while (( PWRLib_MCU_WakeupReason.Bits.FromKBI == 0) && ( PWRLib_RTIClockCheck() > 0)) { (void) PWRLib_MCUStop3(); } PWRLib_RTIClockStop(); /* Sync. the low power timers */ #if (gTMR_EnableLowPowerTimers_d) TMR_SyncLpmTimers(MillisToSyncLpmTimers(notCountedTimeBeforeSleep)); #endif /* #if (gTMR_EnableLowPowerTimers_d) */ Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; PWR_RunAgain(); if ( PWRLib_RTIClockCheck() == 0) { Res.Bits.DeepSleepTimeout = 1; cPWR_DeepSleepWakeupStackProc; /* User function called only on timeout*/ } } } #else #error "*** ERROR: cPWR_KBIWakeupEnable has to be set to 1" #endif /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==33) PWRLib_SetMCUIOForPowerSavingMode(); PWRLib_MCUWait(); Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==34) PWRLib_SetMCUIOForPowerSavingMode(); PWRLib_MCUStop3(); Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==35) PWRLib_SetMCUIOForPowerSavingMode(); PWRLib_MCUStop2(); Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==36) PWRLib_SetMCUIOForPowerSavingMode(); PWRLib_MCUStop1(); Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==37) /*IrqControlLib_DisableAllIrqs(); */ (void) PWRLib_RadioDozeReq(0x0ffff0, FALSE); Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==38) /*IrqControlLib_DisableAllIrqs(); */ (void) PWRLib_RadioAcomaDozeReq( FALSE); Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==39) /* IrqControlLib_DisableAllIrqs(); */ PWRLib_RadioHibernateReq(); Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; /*---------------------------------------------------------------------------*/ #elif (cPWR_DeepSleepMode==40) /* IrqControlLib_DisableAllIrqs(); */ PWRLib_RadioHibernateReq(); /* IrqControlLib_DisableAllIrqs(); */ PWRLib_RadioOffReq(); Res.AllBits = PWRLib_MCU_WakeupReason.AllBits; /*---------------------------------------------------------------------------*/ #else #error "*** ERROR: Not a valid cPWR_DeepSleepMode chosen" #endif PWRLib_MCU_WakeupReason.AllBits = 0; return Res; #else /* #if (cPWR_UsePowerDownMode) else */ Res.AllBits = 0xff | (uint8_t) DozeDuration; /* Last part to avoid unused warning*/ PWRLib_MCU_WakeupReason.AllBits = 0; return Res; /*(PWRLib_WakeupReason_t) DozeDuration;*/ #endif /* #if (cPWR_UsePowerDownMode) end*/ } /* PWR_HandleDeepSleep =====================================================*/
static void PWR_HandleDeepSleepMode_7(void) { #if (cPWR_GENFSK_LL_Enable) #if (gTMR_EnableLowPowerTimers_d) uint32_t notCountedTicksBeforeSleep= 0; #endif uint8_t clkMode; uint32_t lptmrTicks; uint32_t lptmrFreq; uint32_t sleepTimeMs; bool_t enterLowPower = TRUE; #if (gTMR_EnableLowPowerTimers_d) && (cPWR_CheckLowPowerTimers) /* Get the expire time of the first programmed Low Power Timer */ sleepTimeMs = TMR_GetFirstExpireTime(gTmrLowPowerTimer_c); if(mPWR_DeepSleepTimeMs < sleepTimeMs) #endif /* (gTMR_EnableLowPowerTimers_d) && (cPWR_CheckLowPowerTimers) */ { sleepTimeMs = mPWR_DeepSleepTimeMs; } PWRLib_MCU_WakeupReason.AllBits = 0; PWRLib_LPTMR_GetTimeSettings(sleepTimeMs ,&clkMode ,&lptmrTicks, &lptmrFreq); PWRLib_LPTMR_ClockStart(clkMode,lptmrTicks); #if (gTMR_EnableLowPowerTimers_d) /* If more low power timers are running, stop the hardware timer * and save the spend time in ticks that wasn't counted. */ notCountedTicksBeforeSleep = TMR_NotCountedTicksBeforeSleep(); #endif if(enterLowPower && (READ_REGISTER_FIELD(RSIM->DSM_CONTROL,RSIM_DSM_CONTROL_GEN_SLEEP_REQUEST) == 0)) { enterLowPower &= PWR_HandleGenfskDsmEnter(); } if(enterLowPower) { uint32_t rfOscEn; if(gpfPWR_LowPowerEnterCb != NULL) { gpfPWR_LowPowerEnterCb(); } BOARD_BLPEtoBLPI(); rfOscEn = RSIM_CONTROL_READ_FIELD(RSIM_CONTROL_RF_OSC_EN); RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RF_OSC_EN, 0); PWRLib_MCU_Enter_LLS3(); RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RF_OSC_EN, rfOscEn); BOARD_BLPItoBLPE(); if(gpfPWR_LowPowerExitCb != NULL) { gpfPWR_LowPowerExitCb(); } PWRLib_LLWU_UpdateWakeupReason(); PWR_HandleGenfskDsmExit(); } PWRLib_LPTMR_ClockStop(); /* Sync. the low power timers */ #if (gTMR_EnableLowPowerTimers_d) { uint64_t timerTicks; timerTicks = ((uint64_t)PWRLib_LPTMR_ClockCheck() * TMR_GetTimerFreq()) / lptmrFreq; timerTicks += notCountedTicksBeforeSleep; TMR_SyncLpmTimers((uint32_t)timerTicks); } #endif #else PWRLib_MCU_WakeupReason.AllBits = 0; #endif }
static void PWR_HandleDeepSleepMode_2_3(void) { #if (gTMR_EnableLowPowerTimers_d) uint32_t notCountedTicksBeforeSleep = 0; #endif uint8_t clkMode; uint32_t lptmrTicks; uint32_t lptmrFreq; uint32_t sleepTimeMs; #if cPWR_BLE_LL_Enable uint16_t bleEnabledInt; #endif PWRLib_MCU_WakeupReason.AllBits = 0; #if cPWR_BLE_LL_Enable if(RSIM_CONTROL_READ_FIELD(RSIM_CONTROL_BLE_RF_OSC_REQ_STAT) == 0) /* BLL in DSM */ { return; } #endif #if (gTMR_EnableLowPowerTimers_d) && (cPWR_CheckLowPowerTimers) /* Get the expire time of the first programmed Low Power Timer */ sleepTimeMs = TMR_GetFirstExpireTime(gTmrLowPowerTimer_c); if(mPWR_DeepSleepTimeMs < sleepTimeMs) #endif { sleepTimeMs = mPWR_DeepSleepTimeMs; } PWRLib_LPTMR_GetTimeSettings(sleepTimeMs ,&clkMode ,&lptmrTicks, &lptmrFreq); PWRLib_LPTMR_ClockStart(clkMode,lptmrTicks); #if (gTMR_EnableLowPowerTimers_d) /* if more low power timers are running, stop the hardware timer and save the spend time in ticks that wasn't counted. */ notCountedTicksBeforeSleep = TMR_NotCountedTicksBeforeSleep(); #endif #if cPWR_BLE_LL_Enable /* At this point the BLE_LL should be in idle state. BLE stack should assure that before allowing device to sleep */ bleEnabledInt = PWRLib_BLL_GetIntEn(); PWRLib_BLL_ClearInterrupts(bleEnabledInt); PWRLib_BLL_DisableInterrupts(bleEnabledInt); #endif if(gpfPWR_LowPowerEnterCb != NULL) { gpfPWR_LowPowerEnterCb(); } { uint32_t rfOscEn; uint8_t lpMode; lpMode = PWRLib_GetDeepSleepMode(); BOARD_BLPEtoBLPI(); rfOscEn = RSIM_CONTROL_READ_FIELD(RSIM_CONTROL_RF_OSC_EN); RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RF_OSC_EN, 0); if(lpMode == 2) { PWRLib_MCU_Enter_LLS2(); } else { PWRLib_MCU_Enter_LLS3(); } RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RF_OSC_EN, rfOscEn); BOARD_BLPItoBLPE(); } if(gpfPWR_LowPowerExitCb != NULL) { gpfPWR_LowPowerExitCb(); } PWRLib_LLWU_UpdateWakeupReason(); #if cPWR_BLE_LL_Enable PWRLib_BLL_EnableInterrupts(bleEnabledInt); #endif PWRLib_LPTMR_ClockStop(); /* Sync. the low power timers */ #if (gTMR_EnableLowPowerTimers_d) { uint64_t timerTicks; timerTicks = ((uint64_t)PWRLib_LPTMR_ClockCheck()*TMR_GetTimerFreq())/lptmrFreq; timerTicks += notCountedTicksBeforeSleep; TMR_SyncLpmTimers((uint32_t)timerTicks); } #endif }
static void PWR_HandleDeepSleepMode_6(void) { #if (gTMR_EnableLowPowerTimers_d) uint32_t notCountedTicksBeforeSleep = 0; #endif uint8_t clkMode; uint32_t lptmrTicks; uint32_t lptmrFreq; uint32_t sysTickCtrl; uint32_t sleepTimeMs; PWRLib_MCU_WakeupReason.AllBits = 0; #if cPWR_BLE_LL_Enable if(RSIM_CONTROL_READ_FIELD(RSIM_CONTROL_BLE_RF_OSC_REQ_STAT) == 0) /* BLL in DSM */ { return; } #endif #if (gTMR_EnableLowPowerTimers_d) && (cPWR_CheckLowPowerTimers) /* Get the expire time of the first programmed Low Power Timer */ sleepTimeMs = TMR_GetFirstExpireTime(gTmrLowPowerTimer_c); if(mPWR_DeepSleepTimeMs < sleepTimeMs) #endif { sleepTimeMs = mPWR_DeepSleepTimeMs; } PWRLib_LPTMR_GetTimeSettings(sleepTimeMs ,&clkMode ,&lptmrTicks, &lptmrFreq); PWRLib_LPTMR_ClockStart(clkMode,lptmrTicks); #if (gTMR_EnableLowPowerTimers_d) /* If more low power timers are running, stop the hardware timer * and save the spend time in ticks that wasn't counted. */ notCountedTicksBeforeSleep = TMR_NotCountedTicksBeforeSleep(); #endif /* Disable SysTick counter and interrupt */ sysTickCtrl = SysTick->CTRL & (SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk); SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk); { uint32_t rfOscEn = RSIM_CONTROL_READ_FIELD(RSIM_CONTROL_RF_OSC_EN); RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RF_OSC_EN, 0x3); BOARD_BLPEtoBLPI(); RSIM->CONTROL |= RSIM_CONTROL_RSIM_STOP_ACK_OVRD_EN_MASK | RSIM_CONTROL_RSIM_STOP_ACK_OVRD_MASK; SIM->FCFG1 |= SIM_FCFG1_FLASHDOZE_MASK; PWRLib_MCU_Enter_Stop(); SIM->FCFG1 &= ~SIM_FCFG1_FLASHDOZE_MASK; RSIM->CONTROL &= ~RSIM_CONTROL_RSIM_STOP_ACK_OVRD_EN_MASK; BOARD_BLPItoBLPE(); RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RF_OSC_EN, rfOscEn); } /* Restore the state of SysTick */ SysTick->CTRL |= sysTickCtrl; /* Checks sources of wakeup */ PWRLib_StopUpdateWakeupReason(); PWRLib_LPTMR_ClockStop(); /* Sync. the low power timers */ #if (gTMR_EnableLowPowerTimers_d) { uint64_t timerTicks; timerTicks = ((uint64_t)PWRLib_LPTMR_ClockCheck()*TMR_GetTimerFreq())/lptmrFreq; timerTicks += notCountedTicksBeforeSleep; TMR_SyncLpmTimers((uint32_t)timerTicks); } #endif }
static void PWR_HandleDeepSleepMode_1(void) { #if cPWR_BLE_LL_Enable #if (gTMR_EnableLowPowerTimers_d) uint32_t notCountedTicksBeforeSleep = 0; #endif /* (gTMR_EnableLowPowerTimers_d) */ uint8_t clkMode; uint32_t lptmrTicks; uint32_t lptmrFreq; uint32_t sleepTimeMs; bool_t enterLowPower = TRUE; #if (gTMR_EnableLowPowerTimers_d) && (cPWR_CheckLowPowerTimers) /* Get the expire time of the first programmed Low Power Timer */ sleepTimeMs = TMR_GetFirstExpireTime(gTmrLowPowerTimer_c); if(mPWR_DeepSleepTimeMs < sleepTimeMs) #endif /* (gTMR_EnableLowPowerTimers_d) && (cPWR_CheckLowPowerTimers) */ { sleepTimeMs = mPWR_DeepSleepTimeMs; } PWRLib_MCU_WakeupReason.AllBits = 0; PWRLib_LPTMR_GetTimeSettings(sleepTimeMs ,&clkMode ,&lptmrTicks, &lptmrFreq); PWRLib_LPTMR_ClockStart(clkMode,lptmrTicks); #if (gTMR_EnableLowPowerTimers_d) /* If more low power timers are running, stop the hardware timer * and save the spend time in ticks that wasn't counted. */ notCountedTicksBeforeSleep = TMR_NotCountedTicksBeforeSleep(); #endif /* (gTMR_EnableLowPowerTimers_d) */ if(RSIM_CONTROL_READ_FIELD(RSIM_CONTROL_BLE_RF_OSC_REQ_STAT)) /* If false it means that BLE_LL is already in DSM */ { uint16_t distanceToNextInstant; uint16_t nextInstant; uint16_t offsetBeforeDsmExit; if(BLE_LL_REG(CLOCK_CONFIG) & BLE_LL_CLOCK_CONFIG_LLH_IDLE_MASK) { RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RSIM_DSM_EXIT, 0); distanceToNextInstant = PWR_BLE_GetNearestInstant(&nextInstant); offsetBeforeDsmExit = PWRLib_BLL_GetOffsetSlotsBeforeDsmExit(); if(distanceToNextInstant > offsetBeforeDsmExit + 1) { PWRLib_BLL_SetWakeupInstant(nextInstant); PWRLib_BLL_EnterDSM(); } else { enterLowPower = FALSE; } } else { enterLowPower = FALSE; } } if(enterLowPower) { uint32_t rfOscEn; if(gpfPWR_LowPowerEnterCb != NULL) { gpfPWR_LowPowerEnterCb(); } BOARD_BLPEtoBLPI(); rfOscEn = RSIM_CONTROL_READ_FIELD(RSIM_CONTROL_RF_OSC_EN); RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RF_OSC_EN, 0); PWRLib_MCU_Enter_LLS3(); RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RF_OSC_EN, rfOscEn); BOARD_BLPItoBLPE(); if(gpfPWR_LowPowerExitCb != NULL) { gpfPWR_LowPowerExitCb(); } PWRLib_LLWU_UpdateWakeupReason(); if(RSIM_CONTROL_READ_FIELD(RSIM_CONTROL_BLE_RF_OSC_REQ_INT) == 0) { RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RSIM_DSM_EXIT, 1); } RSIM->CONTROL = RSIM_CONTROL_MODIFY_FIELD(RSIM_CONTROL_RSIM_DSM_EXIT, 0); } PWRLib_LPTMR_ClockStop(); /* Sync. the low power timers */ #if (gTMR_EnableLowPowerTimers_d) { uint64_t timerTicks; timerTicks = ((uint64_t)PWRLib_LPTMR_ClockCheck()*TMR_GetTimerFreq())/lptmrFreq; timerTicks += notCountedTicksBeforeSleep; TMR_SyncLpmTimers((uint32_t)timerTicks); } #endif /* (gTMR_EnableLowPowerTimers_d) */ #else PWRLib_MCU_WakeupReason.AllBits = 0; #endif /* cPWR_BLE_LL_Enable */ }