void enter_vlls0_nopor(void) { volatile unsigned int dummyread; int i; /* Write to PMPROT to allow all possible power modes */ SMC_PMPROT = SMC_PMPROT_AVLLS_MASK; if ((SMC_PMSTAT & SMC_PMSTAT_PMSTAT_MASK)== 4){ SMC_PMCTRL &= ~SMC_PMCTRL_RUNM_MASK; // go back to RUN mode temporarily for (i=0;i<0xff;i++) { if ((SMC_PMSTAT & SMC_PMSTAT_PMSTAT_MASK)== 1) break; } } /* Set the STOPM field to 0b100 for VLLS0 mode */ SMC_PMCTRL &= ~SMC_PMCTRL_STOPM_MASK; SMC_PMCTRL |= SMC_PMCTRL_STOPM(0x4); /* set VLLSM = 00 * and PORPO = 1 */ SMC_STOPCTRL &= ~SMC_STOPCTRL_VLLSM_MASK; SMC_STOPCTRL = SMC_STOPCTRL_VLLSM(0) | SMC_STOPCTRL_PORPO_MASK; /*wait for write to complete to SMC before stopping core */ dummyread = SMC_STOPCTRL; dummyread = dummyread + 1; /* Now execute the stop instruction to go into VLLS0 */ #ifdef CMSIS /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP) */ SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK; __wfi(); #else stop(); #endif }
void enter_vlls1(void) { volatile unsigned int dummyread; SMC_PMPROT = SMC_PMPROT_AVLLS_MASK; /* Write to PMPROT to allow all possible power modes */ /* Set the STOPM field to 0b100 for VLLS1 mode */ SMC_PMCTRL &= ~SMC_PMCTRL_STOPM_MASK; SMC_PMCTRL |= SMC_PMCTRL_STOPM(0x4); /* set VLLSM = 0b01 */ SMC_STOPCTRL = SMC_STOPCTRL_VLLSM(1); /*wait for write to complete to SMC before stopping core */ dummyread = SMC_STOPCTRL; dummyread++; SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK; __wfi(); /* Now execute the stop instruction to go into VLLS1 */ // #ifdef CMSIS // /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP) */ // SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK; // __wfi(); //#else // stop(); //#endif }
void enter_vlls0(unsigned char PORPO_value ) { int i; /* Write to PMPROT to allow all possible power modes */ SMC_PMPROT = SMC_PMPROT_AVLLS_MASK; if ((SMC_PMSTAT & SMC_PMSTAT_PMSTAT_MASK)== 4){ SMC_PMCTRL &= ~SMC_PMCTRL_RUNM_MASK; // go back to RUN mode temporarily for (i=0;i<0xff;i++) { if ((SMC_PMSTAT & SMC_PMSTAT_PMSTAT_MASK)== 1) break; } } /* Set the STOPM field to 0b100 for VLLS0 mode */ SMC_PMCTRL &= ~SMC_PMCTRL_STOPM_MASK; SMC_PMCTRL |= SMC_PMCTRL_STOPM(0x4); /* set VLLSM = 0b00 */ SMC_STOPCTRL &= ~SMC_STOPCTRL_VLLSM_MASK; SMC_STOPCTRL &= ~SMC_STOPCTRL_PORPO_MASK; SMC_STOPCTRL |= (PORPO_value <<SMC_STOPCTRL_PORPO_SHIFT) | SMC_STOPCTRL_VLLSM(0); /*wait for write to complete to SMC before stopping core */ PORPO_value = SMC_STOPCTRL; /* Now execute the stop instruction to go into VLLS0 */ SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK; __wfi(); // #ifdef CMSIS // /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP) */ // SCB_SCR |= SCB_SCR_SLEEPDEEP_MASK; // __wfi(); //#else // stop(); //#endif }
/* ===================================================================*/ 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_RUN: /* SCB_SCR: SLEEPDEEP=0,SLEEPONEXIT=0 */ SCB_SCR &= (uint32_t)~(uint32_t)( SCB_SCR_SLEEPDEEP_MASK | SCB_SCR_SLEEPONEXIT_MASK ); 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_STOPCTRL: PSTOPO=0,PORPO=0,??=0,??=0,VLLSM=0 */ SMC_STOPCTRL = (SMC_STOPCTRL_PSTOPO(0x00) | SMC_STOPCTRL_VLLSM(0x00)); /* 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=0 */ SCB_SCR &= (uint32_t)~(uint32_t)(SCB_SCR_SLEEPONEXIT_MASK); PE_WFI(); break; case DOM_STOP: break; default: return ERR_PARAM_MODE; } return ERR_OK; }
/*---------------------------------------------------------------------------- MAIN function *----------------------------------------------------------------------------*/ int main (void) { #if USE_VLPR == 1 // enter low power run SIM->CLKDIV1 = (0x1 << SIM_CLKDIV1_OUTDIV1_SHIFT) | (0x5 << SIM_CLKDIV1_OUTDIV4_SHIFT); // reduce core clock < 4 MHz and flash < 1 MHz MCG->C6 &= ~MCG_C6_CME0_MASK; // disable MCG clock monitor MCG->C2 |= MCG_C2_IRCS_MASK; // don't use slow internal reference clock MCG->C1 |= MCG_C1_CLKS(2); // enter BLPE mode MCG->C1 &= ~MCG_C1_IREFS_MASK; MCG->C6 &= ~MCG_C6_PLLS_MASK; while(!(MCG->S & MCG_S_IREFST_MASK >> MCG_S_IREFST_SHIFT)); // wait to ensure clock change MCG->C2 |= MCG_C2_LP_MASK; #endif Init_RGB_LEDs(); #if DEBUG_SIGNALS == 1 Init_Debug_Signals(); #endif // I2C and MMA i2c_init(); /* init i2c */ if (!init_mma()) { /* init mma peripheral */ Control_RGB_LEDs(1, 0, 0); /* Light red error LED */ while (1) /* not able to initialize mma */ ; } #if RUN_I2C_FAST == 1 // increase i2c baud rate I2C_DISABLE; I2C0->F = (I2C_F_ICR(0x00) | I2C_F_MULT(0)); I2C_ENABLE; #endif // configure low power modes SMC->PMPROT = SMC_PMPROT_ALLS_MASK | SMC_PMPROT_AVLP_MASK; // allow low leakage stop mode SMC->PMCTRL = SMC_PMCTRL_RUNM(2) | SMC_PMCTRL_STOPM(3); // enable low power run mode (10) and low leakage stop mode (011) SMC->STOPCTRL = SMC_STOPCTRL_PSTOPO(0) | SMC_STOPCTRL_VLLSM(3); // normal stop mode and VLL stop3 (not needed?) // configure low leakage wakeup unit (LLWU) LLWU->ME |= LLWU_ME_WUME0_MASK; // internal module 0 is wakeup source which is apparently the LPTMR // enable stop mode (deep sleep) SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // LPTMR Init_LPTMR(); Start_LPTMR(); __enable_irq(); while (1) { // read acceleration every 100 ms if (run_Read_Accel){ run_Read_Accel = 0; Read_Accel(); } // update LEDs every 500 ms; keep them on for 10 ms if (run_Update_LEDs){ run_Update_LEDs = 0; Update_LEDs(); #if USE_PWM == 1 #if PWM_SLEEP == 1 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; // switch to regular sleep mode #if USE_SLEEP_MODES == 1 #if DEBUG_SIGNALS == 1 PTE->PSOR |= MASK(30); #endif __wfi(); // PWM does not work in LLS mode #endif SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // switch back to LLS mode #else while(led_on_period); // poll -> bad solution #endif #endif } #if USE_SLEEP_MODES == 1 #if DEBUG_SIGNALS == 1 PTE->PSOR |= MASK(30); #endif __wfi(); // go to sleep #endif } }