/* VLLS1 mode entry routine. Puts the processor into VLLS1 mode from * normal run mode or VLPR. * * Mode transitions: * RUN -> VLLS1 * VLPR -> VLLS1 * * NOTE: VLLSx modes will always exit to RUN mode even if you were * in VLPR mode before entering VLLSx. * * Wakeup from VLLSx mode is controlled by the LLWU module. Most * modules cannot issue a wakeup interrupt in VLLSx mode, so make * sure to setup the desired wakeup sources in the LLWU before * calling this function. * * Parameters: * none */ void enter_vlls1(void) { /* Write to PMPROT to allow all possible power modes */ /* Set the VLLSM field to 0b100 for VLLS1 mode - Need to retain state of LPWUI bit 8 */ SMC_PMCTRL = (SMC_PMCTRL & (SMC_PMCTRL_RUNM_MASK |SMC_PMCTRL_LPWUI_MASK)) | SMC_PMCTRL_STOPM(0x4) ; // retain LPWUI SMC_VLLSCTRL = SMC_VLLSCTRL_VLLSM(1); // set VLLSM = 0b01 /* Now execute the stop instruction to go into VLLS1 */ stop(); }
/* VLLS2 mode entry routine. Puts the processor into VLLS2 mode from * normal run mode or VLPR. * * Mode transitions: * RUN -> VLLS2 * VLPR -> VLLS2 * * NOTE: VLLSx modes will always exit to RUN mode even if you were * in VLPR mode before entering VLLSx. * * Wakeup from VLLSx mode is controlled by the LLWU module. Most * modules cannot issue a wakeup interrupt in VLLSx mode, so make * sure to setup the desired wakeup sources in the LLWU before * calling this function. * * Parameters: * none */ void enter_vlls2(void) { /* Write to PMPROT to allow VLLS2 power modes */ SMC_PMPROT = SMC_PMPROT_AVLLS_MASK; /* Set the VLLSM field to 0b100 for VLLS2 mode - Need to retain state of LPWUI bit 8 */ SMC_PMCTRL = (SMC_PMCTRL & (SMC_PMCTRL_RUNM_MASK |SMC_PMCTRL_LPWUI_MASK)) | SMC_PMCTRL_STOPM(0x4) ; // retain LPWUI SMC_VLLSCTRL = SMC_VLLSCTRL_VLLSM(2); // set VLLSM = 0b10 /* Now execute the stop instruction to go into VLLS2 */ stop(); }
inline void vlls0_nopor( void ) { #if defined(__MK66FX1M0__) #if F_CPU > 120000000 SMC_PMCTRL = SMC_PMCTRL_RUNM( 0x03 ) | SMC_PMCTRL_STOPM( 0x04 ); ( void ) SMC_PMCTRL; #else SMC_PMCTRL = SMC_PMCTRL_STOPM( 0x03 ) ; ( void ) SMC_PMCTRL; #endif #else SMC_PMCTRL = SMC_PMCTRL_STOPM( 0x03 ) ; ( void ) SMC_PMCTRL; #endif SMC_VLLSCTRL = SMC_VLLSCTRL_VLLSM( 0x00 );// set VLLSM = 0b00 ( void ) SMC_VLLSCTRL; // Now execute the stop instruction to go into VLLS0 #if defined(__MK66FX1M0__) kinetis_hsrun_enable( ); #endif }
inline void vlls1( void ) { #if defined(__MK66FX1M0__) #if F_CPU > 120000000 kinetis_hsrun_disable( ); SMC_PMCTRL = SMC_PMCTRL_STOPM( 0x04 ); ( void ) SMC_PMCTRL; #else SMC_PMCTRL = SMC_PMCTRL_STOPM( 0x04 ) ; ( void ) SMC_PMCTRL; #endif #else SMC_PMCTRL = SMC_PMCTRL_STOPM( 0x04 ) ; ( void ) SMC_PMCTRL; #endif SMC_VLLSCTRL = SMC_VLLSCTRL_VLLSM( 0x01 );// set VLLSM = 0b01 ( void ) SMC_VLLSCTRL; // Now execute the stop instruction to go into VLLS1 stop( ); #if defined(__MK66FX1M0__) #if F_CPU > 120000000 kinetis_hsrun_enable( ); #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 }