예제 #1
0
파일: lpm_smc.c 프로젝트: BillyZhangZ/wifi
_mqx_uint _lpm_set_cpu_operation_mode
    (
        /* [IN] Specification of CPU core low power operation modes available */
        const LPM_CPU_OPERATION_MODE  *operation_modes,

        /* [IN] Low power operation mode identifier */
        LPM_OPERATION_MODE                 target_mode
    )
{

#ifndef PE_LDD_VERSION

    const LPM_CPU_POWER_MODE              *mode_ptr;
    _mqx_uint                              scr, flags, mcg, index, cme;

    /* Check parameters */
    if ((NULL == operation_modes) || (LPM_OPERATION_MODES <= (_mqx_uint)target_mode))
    {
        return MQX_INVALID_PARAMETER;
    }
    index = operation_modes[target_mode].MODE_INDEX;

    if (LPM_CPU_POWER_MODES <= index)
    {
        return MQX_INVALID_CONFIGURATION;
    }
    mode_ptr = &(LPM_CPU_POWER_MODES_KINETIS[index]);
    flags = mode_ptr->FLAGS | (operation_modes[target_mode].FLAGS & LPM_CPU_POWER_MODE_FLAG_USER_MASK);

    /* Go through Kinetis Run */
    scr = (SCB_SCR & (~ (SCB_SCR_SLEEPDEEP_MASK | SCB_SCR_SLEEPONEXIT_MASK)));
    SCB_SCR = scr;
    SMC_PMCTRL = LPM_CPU_POWER_MODES_KINETIS[LPM_CPU_POWER_MODE_RUN].PMCTRL;
    while (0 == (PMC_REGSC & PMC_REGSC_REGONS_MASK))
        { };
    while (SMC_PMSTAT_PMSTAT(1) != SMC_PMSTAT)
        { };
#if MQX_ENABLE_HSRUN
    /* Go to HSRUN through RUN */
    if (LPM_CPU_POWER_MODE_HSRUN == index)
    {
        SMC_PMCTRL = LPM_CPU_POWER_MODES_KINETIS[LPM_CPU_POWER_MODE_HSRUN].PMCTRL;
        while (SMC_PMSTAT_PMSTAT(128) != SMC_PMSTAT)
            { };
    }
#endif
    /* Go to VLPW through VLPR */
    if (LPM_CPU_POWER_MODE_VLPW == index)
    {
        SMC_PMCTRL = LPM_CPU_POWER_MODES_KINETIS[LPM_CPU_POWER_MODE_VLPR].PMCTRL;
        while (SMC_PMSTAT_PMSTAT(4) != SMC_PMSTAT)
            { };
    }

    /* Setup ARM System control register */
    if (flags & LPM_CPU_POWER_MODE_FLAG_DEEP_SLEEP)
    {
        scr |= SCB_SCR_SLEEPDEEP_MASK;
    }
    if (flags & LPM_CPU_POWER_MODE_FLAG_SLEEP_ON_EXIT)
    {
        scr |= SCB_SCR_SLEEPONEXIT_MASK;
    }
    SCB_SCR = scr;

    /* Setup wakeup unit for LLS mode */
    if (LPM_CPU_POWER_MODE_LLS == index)
    {
        LLWU_PE1 = operation_modes[target_mode].PE1;
        LLWU_PE2 = operation_modes[target_mode].PE2;
        LLWU_PE3 = operation_modes[target_mode].PE3;
        LLWU_PE4 = operation_modes[target_mode].PE4;
        LLWU_ME = operation_modes[target_mode].ME;
        LLWU_F1 = 0xFF;
        LLWU_F2 = 0xFF;
        LLWU_F3 = 0xFF;
    }

    /* Setup wake up unit for VLLSx mode */
    if ((LPM_CPU_POWER_MODE_VLLS3 == index)
        || (LPM_CPU_POWER_MODE_VLLS2 == index)
        || (LPM_CPU_POWER_MODE_VLLS1 == index))
    {
        LLWU_PE1 = operation_modes[target_mode].PE1;
        LLWU_PE2 = operation_modes[target_mode].PE2;
        LLWU_PE3 = operation_modes[target_mode].PE3;
        LLWU_PE4 = operation_modes[target_mode].PE4;
        LLWU_ME = operation_modes[target_mode].ME;
        LLWU_F1 = 0xFF;
        LLWU_F2 = 0xFF;
        LLWU_F3 = 0xFF;
#if LLWU_RST_LLRSTE_MASK
        LLWU_RST |= LLWU_RST_LLRSTE_MASK;
#endif
    }

    /* Keep status of MCG before mode change */
    mcg = MCG_S & MCG_S_CLKST_MASK;

    /* Disable CME if enabled before entering changing Power mode */
    cme = MCG_C6 & MCG_C6_CME0_MASK;            /* Save CME state */
    MCG_C6 &= ~(MCG_C6_CME0_MASK);              /* Clear CME */

    /* Operation mode setup */
    SMC_PMCTRL = mode_ptr->PMCTRL;

    /* VLLSx setup */
    switch (index)
    {
#if (BSP_TWR_K22F120M || BSP_TWR_K22F120M256R || BSP_LMQ1 || BSP_K22FSH)
        case LPM_CPU_POWER_MODE_VLLS3:
            SMC_STOPCTRL = SMC_STOPCTRL_LLSM(3);
            break;
        case LPM_CPU_POWER_MODE_VLLS2:
            SMC_STOPCTRL = SMC_STOPCTRL_LLSM(2);
            break;
        case LPM_CPU_POWER_MODE_VLLS1:
            SMC_STOPCTRL = SMC_STOPCTRL_LLSM(1);
            break;
        default:
            break;
#else
        case LPM_CPU_POWER_MODE_VLLS3:
            SMC_VLLSCTRL = SMC_VLLSCTRL_VLLSM(3);
            break;
        case LPM_CPU_POWER_MODE_VLLS2:
            SMC_VLLSCTRL = SMC_VLLSCTRL_VLLSM(2);
            break;
        case LPM_CPU_POWER_MODE_VLLS1:
            SMC_VLLSCTRL = SMC_VLLSCTRL_VLLSM(1);
            break;
        default:
            break;
#endif
    }

    /* Wait for proper setup of VLPR */
    if (LPM_CPU_POWER_MODE_VLPR == index)
    {
        while (SMC_PMSTAT_PMSTAT(4) != SMC_PMSTAT)
            { };
    }

    /* Go to sleep if required */
    if (flags & LPM_CPU_POWER_MODE_FLAG_USE_WFI)
    {
/* ENGR00178898 workaround  Shut down SPI0, SPI1 pripheral. Preventing entering stop mode for some reason */
#ifdef SIM_SCGC6_SPI0_MASK
        SIM_SCGC6 &= ~SIM_SCGC6_SPI0_MASK;
#endif
#ifdef SIM_SCGC6_SPI1_MASK
        SIM_SCGC6 &= ~SIM_SCGC6_SPI1_MASK;
#endif
        _ASM_SLEEP(NULL);
#ifdef SIM_SCGC6_SPI0_MASK
        SIM_SCGC6 |= SIM_SCGC6_SPI0_MASK;
#endif
#ifdef SIM_SCGC6_SPI1_MASK
        SIM_SCGC6 |= SIM_SCGC6_SPI1_MASK;
#endif
    }

    /* After stop modes, reconfigure MCG if needed */
    if ( (LPM_CPU_POWER_MODE_STOP == index)
      || (LPM_CPU_POWER_MODE_VLPS == index)
      || (LPM_CPU_POWER_MODE_LLS == index)
      || (LPM_CPU_POWER_MODE_VLLS3 == index)
      || (LPM_CPU_POWER_MODE_VLLS2 == index)
      || (LPM_CPU_POWER_MODE_VLLS1 == index) )
    {
#ifdef BSP_CLOCK_USE_FLL
        if ((MCG_S_CLKST(0) == mcg) && (MCG_S_CLKST(1) == (MCG_S & MCG_S_CLKST_MASK)))
        {
            MCG_C1 &= (~ (MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK));
            while (0 != (MCG_S & MCG_S_CLKST(3)))
                { };
        }
#else
        if ((MCG_S_CLKST(3) == mcg) && (MCG_S_CLKST(2) == (MCG_S & MCG_S_CLKST_MASK)))
        {
            MCG_C1 &= (~ (MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK));
            while (0 == (MCG_S & MCG_S_LOCK0_MASK))
                { };
        }
#endif
    }

    /* Restore CME */
    MCG_C6 |= cme;

    return MQX_OK;

#else

#ifdef Cpu_SetOperationMode_METHOD_ENABLED
    if (LPM_OPERATION_MODES <= (_mqx_uint)target_mode)
    {
        return MQX_INVALID_PARAMETER;
    }
    return Cpu_SetOperationMode (LPM_PE_OPERATION_MODE_MAP[target_mode], NULL, NULL);
#else
    #error Undefined method Cpu_SetOperationMode() in PE CPU component!
#endif

#endif

}
예제 #2
0
_mqx_uint _lpm_set_cpu_operation_mode
    (
        /* [IN] Specification of CPU core low power operation modes available */
        const LPM_CPU_OPERATION_MODE  *operation_modes,

        /* [IN] Low power operation mode identifier */
        LPM_OPERATION_MODE                 target_mode
    )
{

#ifndef PE_LDD_VERSION

    const LPM_CPU_POWER_MODE              *mode_ptr;
    _mqx_uint                              scr, flags, mcg, index;

    /* Check parameters */
    if ((NULL == operation_modes) || (LPM_OPERATION_MODES <= (_mqx_uint)target_mode))
    {
        return MQX_INVALID_PARAMETER;
    }
    index = operation_modes[target_mode].MODE_INDEX;

    if (LPM_CPU_POWER_MODES <= index)
    {
        return MQX_INVALID_CONFIGURATION;
    }
    mode_ptr = &(LPM_CPU_POWER_MODES_CFPLUS[index]);
    flags = mode_ptr->FLAGS;

    /* Go through Run */
    SIM_SOPT4 |= SIM_SOPT4_WAITE_MASK;
    SMC_PMCTRL = LPM_CPU_POWER_MODES_CFPLUS[LPM_CPU_POWER_MODE_RUN].PMCTRL;
    while (0 == (PMC_REGSC & PMC_REGSC_REGONS_MASK))
        { };
    while (SMC_PMSTAT_PMSTAT(1) != (SMC_PMSTAT & SMC_PMSTAT_PMSTAT_MASK))
        { };

    /* Go to VLPW through VLPR */
    if (LPM_CPU_POWER_MODE_VLPW == index)
    {
        SMC_PMCTRL = LPM_CPU_POWER_MODES_CFPLUS[LPM_CPU_POWER_MODE_VLPR].PMCTRL;
        while (SMC_PMSTAT_PMSTAT(4) != (SMC_PMSTAT & SMC_PMSTAT_PMSTAT_MASK))
            { };
    }

    /* Setup wakeup unit for LLS mode */
    if (LPM_CPU_POWER_MODE_LLS == index)
    {
        LLWU_PE1 = operation_modes[target_mode].PE1;
        LLWU_PE2 = operation_modes[target_mode].PE2;
        LLWU_PE3 = operation_modes[target_mode].PE3;
        LLWU_PE4 = operation_modes[target_mode].PE4;
        LLWU_ME = operation_modes[target_mode].ME;
        LLWU_FILT1 = operation_modes[target_mode].FILT1;
        LLWU_FILT2 = operation_modes[target_mode].FILT2;
        LLWU_F1 = 0xFF;
        LLWU_F2 = 0xFF;
        LLWU_F3 = 0xFF;
    }

    /* Keep status of MCG before mode change */
    mcg = MCG_S & MCG_S_CLKST_MASK;

    /* Operation mode setup */
    SMC_PMCTRL = mode_ptr->PMCTRL;

    /* Wait for proper setup of VLPR */
    if (LPM_CPU_POWER_MODE_VLPR == index)
    {
        while (SMC_PMSTAT_PMSTAT(4) != (SMC_PMSTAT & SMC_PMSTAT_PMSTAT_MASK))
            { };
    }

    /* Go to sleep if required */
    if (flags & (LPM_CPU_POWER_MODE_FLAG_WAITE | LPM_CPU_POWER_MODE_FLAG_STOPE))
    {
        if (flags & LPM_CPU_POWER_MODE_FLAG_STOPE)
        {
            SIM_SOPT4 &= (~ SIM_SOPT4_WAITE_MASK);
        }

        _ASM_SLEEP();
    }

    /* After stop modes, reconfigure MCG if needed */
    if ( (LPM_CPU_POWER_MODE_STOP == index)
      || (LPM_CPU_POWER_MODE_VLPS == index)
      || (LPM_CPU_POWER_MODE_LLS == index) )
    {
        if ((MCG_S_CLKST(3) == mcg) && (MCG_S_CLKST(2) == (MCG_S & MCG_S_CLKST_MASK)))
        {
            MCG_C1 &= (~ (MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK));
            while (0 == (MCG_S & MCG_S_LOCK_MASK))
                { };
        }
    }

    return MQX_OK;

#else

#ifdef Cpu_SetOperationMode_METHOD_ENABLED
    if (LPM_OPERATION_MODES <= (_mqx_uint)target_mode)
    {
        return MQX_INVALID_PARAMETER;
    }
    return Cpu_SetOperationMode (LPM_PE_OPERATION_MODE_MAP[target_mode], NULL, NULL);
#else
    #error Undefined method Cpu_SetOperationMode() in PE CPU component!
#endif

#endif

}
예제 #3
0
파일: bsp_cm.c 프로젝트: BillyZhangZ/wifi
/*
** ===================================================================
**     Method      :  Cpu_SetOperationMode (component MK22FN512VDC12)
**
**     Description :
**         This method requests to change the component's operation
**         mode (RUN, WAIT, SLEEP, STOP). The target operation mode
**         will be entered immediately.
**         See <Operation mode settings> for further details of the
**         operation modes mapping to low power modes of the cpu.
**     Parameters  :
**         NAME            - DESCRIPTION
**         OperationMode   - Requested driver
**                           operation mode
**         ModeChangeCallback - Callback to
**                           notify the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**       * ModeChangeCallbackParamPtr
**                           - Pointer to callback parameter to notify
**                           the upper layer once a mode has been
**                           changed. Parameter is ignored, only for
**                           compatibility of API with other components.
**     Returns     :
**         ---             - Error code
**                           ERR_OK - OK
**                           ERR_PARAM_MODE - Invalid operation mode
** ===================================================================
*/
LDD_TError Cpu_SetOperationMode(LDD_TDriverOperationMode OperationMode, LDD_TCallback ModeChangeCallback, LDD_TCallbackParam *ModeChangeCallbackParamPtr)
{
  (void) ModeChangeCallback;           /* Parameter is not used, suppress unused argument warning */
  (void) ModeChangeCallbackParamPtr;   /* Parameter is not used, suppress unused argument warning */
  switch (OperationMode) {
      case DOM_HSRUN:
      SMC_PMPROT = SMC_PMPROT_AHSRUN_MASK;
      SMC_PMCTRL |= SMC_PMCTRL_RUNM(3); /*HS RUN */
      while((SMC_PMSTAT & SMC_PMSTAT_PMSTAT_MASK) != SMC_PMSTAT_PMSTAT(0x80)) {  /* HS RUN status */
      };
       /* SCB_SCR: SLEEPDEEP=0,SLEEPONEXIT=0 */
      SCB_SCR &= (uint32_t)~(uint32_t)(
                  SCB_SCR_SLEEPDEEP_MASK |
                  SCB_SCR_SLEEPONEXIT_MASK
                 );
      if  (ClockConfigurationID != 2U) {
        if ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) { /* If in PBE mode, switch to PEE. PEE to PBE transition was caused by wakeup from low power mode. */
          /* MCG_C1: CLKS=0,IREFS=0 */
	  MCG_C1 &= (uint8_t)~(uint8_t)((MCG_C1_CLKS(0x03) | MCG_C1_IREFS_MASK));
          while( (MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait for PLL lock */
          }
        }
      }
      break;
    case DOM_RUN:
      SMC_PMCTRL &= ~(SMC_PMCTRL_RUNM(3)); /*Normal RUN */
      while((SMC_PMSTAT & SMC_PMSTAT_PMSTAT_MASK) != SMC_PMSTAT_PMSTAT(0x1)) {  /* Normal RUN status */
      };
      /* SCB_SCR: SLEEPDEEP=0,SLEEPONEXIT=0 */
      SCB_SCR &= (uint32_t)~(uint32_t)(
                  SCB_SCR_SLEEPDEEP_MASK |
                  SCB_SCR_SLEEPONEXIT_MASK
                 );
      if  (ClockConfigurationID != 2U) {
        if ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) { /* If in PBE mode, switch to PEE. PEE to PBE transition was caused by wakeup from low power mode. */
          /* MCG_C1: CLKS=0,IREFS=0 */
	  MCG_C1 &= (uint8_t)~(uint8_t)((MCG_C1_CLKS(0x03) | MCG_C1_IREFS_MASK));
          while( (MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait for PLL lock */
          }
        }
      }
      break;
    case DOM_WAIT:
      /* SCB_SCR: SLEEPDEEP=0 */
      SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPDEEP_MASK);
      /* SCB_SCR: SLEEPONEXIT=0 */
      SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPONEXIT_MASK);
      PE_WFI();
      break;
    case DOM_SLEEP:
      /* SCB_SCR: SLEEPDEEP=1 */
      SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK;
      /* SMC_PMCTRL: STOPM=0 */
      SMC_PMCTRL &= (uint8_t)~(uint8_t)(SMC_PMCTRL_STOPM(0x07));
      (void)(SMC_PMCTRL == 0U);        /* Dummy read of SMC_PMCTRL to ensure the register is written before enterring low power mode */
      /* SCB_SCR: SLEEPONEXIT=1 */
      SCB_SCR |= SCB_SCR_SLEEPONEXIT_MASK;
      PE_WFI();
      break;
    case DOM_STOP:
      break;
    default:
      return ERR_PARAM_MODE;
  }
  return ERR_OK;
}