/* 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 =====================================================*/
/* Synchronous calls to the ASP handler. */ uint8_t APP_ASP_SapHandler(AppToAspMessage_t *pMsg) { uint8_t msgStatus = gZbSuccess_c; uint32_t auxAddrAlign; #if gSCIInterface_d uint8_t byte; #endif switch(pMsg->msgType) { case aspMsgTypeGetTimeReq_c: Asp_GetTimeReq(&auxAddrAlign); pMsg->msgData.req.aspGetTimeReq.time= auxAddrAlign; break; case aspMsgTypeWakeReq_c: Asp_WakeReq(); break; case aspMsgTypeGetMacStateReq_c: msgStatus = Asp_GetMacStateReq(); break; #if gAspPowerSaveCapability_d case aspMsgTypeDozeReq_c: msgStatus = Asp_DozeReq(&pMsg->msgData.req.aspDozeReq.dozeDuration,pMsg->msgData.req.aspDozeReq.clko_en); break; case aspMsgTypeAutoDozeReq_c: Asp_AutoDozeReq(pMsg->msgData.req.aspAutoDozeReq.autoEnable, pMsg->msgData.req.aspAutoDozeReq.enableWakeIndication, &pMsg->msgData.req.aspAutoDozeReq.autoDozeInterval, pMsg->msgData.req.aspAutoDozeReq.clko_en); break; case aspMsgTypeSetMinDozeTimeReq_c: Asp_SetMinDozeTimeReq(&pMsg->msgData.req.aspSetMinDozeTimeReq.minDozeTime); break; case aspMsgTypeAcomaReq_c: msgStatus = Asp_AcomaReq(pMsg->msgData.req.aspAcomaReq.clko_en); break; case aspMsgTypeHibernateReq_c: msgStatus = Asp_HibernateReq(); break; #endif #if gAspHwCapability_d case aspMsgTypeClkoReq_c: msgStatus = Asp_ClkoReq(pMsg->msgData.req.aspClkoReq.clkoEnable, pMsg->msgData.req.aspClkoReq.clkoRate); break; case aspMsgTypeTrimReq_c: Asp_TrimReq(pMsg->msgData.req.aspTrimReq.fineTune, pMsg->msgData.req.aspTrimReq.coarseTune); break; case aspMsgTypeDdrReq_c: Asp_DdrReq(pMsg->msgData.req.aspDdrReq.directionMask); break; case aspMsgTypePortReq_c: Asp_PortReq(pMsg->msgData.req.aspPortReq.portWrite, &pMsg->msgData.req.aspPortReq.portValue); break; #endif #if gAspEventCapability_d case aspMsgTypeEventReq_c: msgStatus = Asp_EventReq(&pMsg->msgData.req.aspEventReq.eventTime); break; #endif #if gBeaconedCapability_d case aspMsgTypeGetInactiveTimeReq_c: msgStatus = Asp_GetInactiveTimeReq(&pMsg->msgData.req.aspGetInactiveTimeReq.time); break; case aspMsgTypeSetNotifyReq_c: msgStatus = Asp_SetNotifyReq(pMsg->msgData.req.aspSetNotifyReq.notifications); break; #endif #if gAspPowerLevelCapability_d case aspMsgTypeSetPowerLevel_c: msgStatus = Asp_SetPowerLevel(pMsg->msgData.req.aspSetPowerLevelReq.powerLevel); break; case aspMsgTypeGetPowerLevel_c: msgStatus = Asp_GetPowerLevel(); break; #endif case aspMsgTypeTelecTest_c: ASP_TelecTest(pMsg->msgData.req.aspTelecTest.mode); #if gSCIInterface_d if(gTestPulseTxPrbs9_c == pMsg->msgData.req.aspTelecTest.mode) { while(FALSE == UartX_GetByteFromRxBuffer(&byte)) { ASP_TelecTest(pMsg->msgData.req.aspTelecTest.mode); } UartX_UngetByte(byte); } #endif break; case aspMsgTypeTelecSetFreq_c: ASP_TelecSetFreq(pMsg->msgData.req.aspTelecsetFreq.channel); break; case aspMsgTypeTelecSendRawData_c: if((pMsg->msgData.req.aspTelecSendRawData.length >= 3) && (pMsg->msgData.req.aspTelecSendRawData.length <= 125)) { ASP_TelecSendRawData(pMsg->msgData.req.aspTelecSendRawData.length, (uint8_t*)&pMsg->msgData.req.aspTelecSendRawData.dataPtr); } else { msgStatus = gZbInvalidRequest_c; } break; default: msgStatus = gZbInvalidRequest_c; break; } /* monitoring this task */ ZTC_TaskEventMonitor(gNwkASP_SAPHandlerId_c, (uint8_t *)pMsg, msgStatus); return msgStatus; }