/* Must push system to low power state of S3 (LPDS) */ i32 cc_enter_S3(void(*resume_fn)(void), u32 stack_ptr) { MAP_PRCMLPDSRestoreInfoSet(stack_ptr, (u32)resume_fn); /* Enter LPDS */ MAP_PRCMLPDSEnter(); return 0; }
STATIC NORETURN void pyb_sleep_suspend_enter (void) { // enable full RAM retention MAP_PRCMSRAMRetentionEnable(PRCM_SRAM_COL_1 | PRCM_SRAM_COL_2 | PRCM_SRAM_COL_3 | PRCM_SRAM_COL_4, PRCM_SRAM_LPDS_RET); // save the NVIC control registers nvic_reg_store->vector_table = HWREG(NVIC_VTABLE); nvic_reg_store->aux_ctrl = HWREG(NVIC_ACTLR); nvic_reg_store->int_ctrl_state = HWREG(NVIC_INT_CTRL); nvic_reg_store->app_int = HWREG(NVIC_APINT); nvic_reg_store->sys_ctrl = HWREG(NVIC_SYS_CTRL); nvic_reg_store->config_ctrl = HWREG(NVIC_CFG_CTRL); nvic_reg_store->sys_pri_1 = HWREG(NVIC_SYS_PRI1); nvic_reg_store->sys_pri_2 = HWREG(NVIC_SYS_PRI2); nvic_reg_store->sys_pri_3 = HWREG(NVIC_SYS_PRI3); nvic_reg_store->sys_hcrs = HWREG(NVIC_SYS_HND_CTRL); // save the systick registers nvic_reg_store->systick_ctrl = HWREG(NVIC_ST_CTRL); nvic_reg_store->systick_reload = HWREG(NVIC_ST_RELOAD); nvic_reg_store->systick_calib = HWREG(NVIC_ST_CAL); // save the interrupt enable registers uint32_t *base_reg_addr = (uint32_t *)NVIC_EN0; for(int32_t i = 0; i < (sizeof(nvic_reg_store->int_en) / 4); i++) { nvic_reg_store->int_en[i] = base_reg_addr[i]; } // save the interrupt priority registers base_reg_addr = (uint32_t *)NVIC_PRI0; for(int32_t i = 0; i < (sizeof(nvic_reg_store->int_priority) / 4); i++) { nvic_reg_store->int_priority[i] = base_reg_addr[i]; } // switch off the heartbeat led (this makes sure it will blink as soon as we wake up) mperror_heartbeat_switch_off(); // park the gpio pins pyb_sleep_iopark(false); // store the cpu registers sleep_store(); // save the restore info and enter LPDS MAP_PRCMLPDSRestoreInfoSet(vault_arm_registers.psp, (uint32_t)sleep_restore); MAP_PRCMLPDSEnter(); // let the cpu fade away... for ( ; ; ); }