_mqx_uint _lpm_set_cpu_operation_mode ( /* [IN] Specification of CPU core low power operation modes available */ const LPM_CPU_OPERATION_MODE _PTR_ operation_modes, /* [IN] Low power operation mode identifier */ LPM_OPERATION_MODE target_mode ) { #ifndef PE_LDD_VERSION const LPM_CPU_POWER_MODE _PTR_ 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_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; MC_PMCTRL = LPM_CPU_POWER_MODES_KINETIS[LPM_CPU_POWER_MODE_RUN].PMCTRL; while (0 == (PMC_REGSC & PMC_REGSC_REGONS_MASK)) { }; /* Go to VLPW through VLPR */ if (LPM_CPU_POWER_MODE_VLPW == index) { MC_PMCTRL = LPM_CPU_POWER_MODES_KINETIS[LPM_CPU_POWER_MODE_VLPR].PMCTRL; while (0 == (PMC_REGSC & PMC_REGSC_VLPRS_MASK)) { }; } /* 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; } /* Keep status of MCG before mode change */ mcg = MCG_S & MCG_S_CLKST_MASK; /* Operation mode setup */ MC_PMCTRL = mode_ptr->PMCTRL; /* Wait for proper setup of VLPR */ if (LPM_CPU_POWER_MODE_VLPR == index) { /* K40 P2.2, K60 P2.2 and K20 P1 use different macro from previous chips */ while (0 == (PMC_REGSC & PMC_REGSC_VLPRS_MASK)) { }; } /* Go to sleep if required */ if (flags & LPM_CPU_POWER_MODE_FLAG_USE_WFI) { _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 }
_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 }
_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 }