Exemplo n.º 1
0
/* 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(&currentClock);
       #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 =====================================================*/
Exemplo n.º 2
0
/*
  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;
}