From 7220862da0ffb07f1b58df0581870cb5ae8f8b08 Mon Sep 17 00:00:00 2001 From: irsla Date: Thu, 24 Sep 2020 13:41:55 +0100 Subject: [PATCH 1/2] modify deepsleep to allow wakeup on X1 or X18 (to be tested !) on a SF2/6W example machine.deepsleep([time_ms | 0 for infinity], [WKUP_PINS_X1/X18], [WKUP_PINS_X1/X18_RISING/FALLING]) machine.deepsleep() machine.deepsleep(20000) machine.deepsleep(10000, machine.WKUP_X1, machine.WKUP_X1_RISING) machine.deepsleep(0, machine.WKUP_X1, machine.WKUP_X1_RISING) machine.deepsleep(0, machine.WKUP_X1, machine.WKUP_X1_FALLING) Prior to this commit only the timer wakeup would work for a deepsleep. This was the case because for the STM32F7 all wakeup pins were cleared out before entering in deepsleep this commit is a work in progress for technical discussions. --- ports/stm32/modmachine.c | 52 ++++++++++++++++++++++++++++++++++++++++ ports/stm32/powerctrl.c | 2 +- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c index ac4d8712397e4..01b525967873f 100644 --- a/ports/stm32/modmachine.c +++ b/ports/stm32/modmachine.c @@ -89,6 +89,16 @@ #define PYB_RESET_HARD (2) #define PYB_RESET_WDT (3) #define PYB_RESET_DEEPSLEEP (4) +#if defined(STM32F7) +#define PYB_RESET_DEEPSLEEP_X1 (5) +#define PYB_RESET_DEEPSLEEP_X18 (6) +#define PYB_PWR_WKUP_X1 (PWR_CSR2_EWUP1) +#define PYB_PWR_WKUP_X1_FALLING (PWR_CSR2_EWUP1) +#define PYB_PWR_WKUP_X1_RISING (0) +#define PYB_PWR_WKUP_X18 (PWR_CSR2_EWUP4) +#define PYB_PWR_WKUP_X18_FALLING (PWR_CSR2_EWUP4) +#define PYB_PWR_WKUP_X18_RISING (0) +#endif STATIC uint32_t reset_cause; @@ -104,6 +114,14 @@ void machine_init(void) { // came out of standby reset_cause = PYB_RESET_DEEPSLEEP; PWR->CR1 |= PWR_CR1_CSBF; + if (PWR->CSR2 & PWR_CSR2_WUPF1) { + reset_cause = PYB_RESET_DEEPSLEEP_X1; + PWR->CR2 |= PWR_CR2_CWUPF1; + } else if (PWR->CSR2 & PWR_CSR2_WUPF4) { + reset_cause = PYB_RESET_DEEPSLEEP_X18; + PWR->CR2 |= PWR_CR2_CWUPF4; + } + } else #elif defined(STM32H7) if (PWR->CPUCR & PWR_CPUCR_SBF || PWR->CPUCR & PWR_CPUCR_STOPF) { @@ -366,14 +384,38 @@ STATIC mp_obj_t machine_lightsleep(size_t n_args, const mp_obj_t *args) { MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_lightsleep_obj, 0, 1, machine_lightsleep); STATIC mp_obj_t machine_deepsleep(size_t n_args, const mp_obj_t *args) { + // disable X1 and X18 flags +#if defined(STM32F7) + PWR->CSR2 &= ~(PWR_CSR2_EWUP4 | PWR_CSR2_EWUP1); + PWR->CR2 &= ~(PWR_CR2_WUPP4 | PWR_CR2_WUPP1); +#endif if (n_args != 0) { +#if defined(STM32F7) + int ts_value = mp_obj_get_int(args[0]); + if (ts_value != 0) { +#endif mp_obj_t args2[2] = {MP_OBJ_NULL, args[0]}; pyb_rtc_wakeup(2, args2); +#if defined(STM32F7) + } + if (n_args == 3) { + uint32_t pins = mp_obj_get_int(args[1]); + uint32_t falling = mp_obj_get_int(args[2]); + if ((pins | (PWR_CSR2_EWUP1 | PWR_CSR2_EWUP4)) != 0) { + PWR->CSR2 |= pins; + PWR->CR2 |= falling; + } + } +#endif } powerctrl_enter_standby_mode(); return mp_const_none; } +#if defined(STM32F7) +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_deepsleep_obj, 0, 3, machine_deepsleep); +#else MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_deepsleep_obj, 0, 1, machine_deepsleep); +#endif STATIC mp_obj_t machine_reset_cause(void) { return MP_OBJ_NEW_SMALL_INT(reset_cause); @@ -435,6 +477,16 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(PYB_RESET_WDT) }, { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_ROM_INT(PYB_RESET_DEEPSLEEP) }, { MP_ROM_QSTR(MP_QSTR_SOFT_RESET), MP_ROM_INT(PYB_RESET_SOFT) }, + #if defined(STM32F7) + { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_X1_RESET), MP_ROM_INT(PYB_RESET_DEEPSLEEP_X1) }, + { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_X18_RESET), MP_ROM_INT(PYB_RESET_DEEPSLEEP_X18) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X1), MP_ROM_INT(PYB_PWR_WKUP_X1) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X1_FALLING), MP_ROM_INT(PYB_PWR_WKUP_X1_FALLING) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X1_RISING), MP_ROM_INT(PYB_PWR_WKUP_X1_RISING) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X18), MP_ROM_INT(PYB_PWR_WKUP_X18) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X18_FALLING), MP_ROM_INT(PYB_PWR_WKUP_X18_FALLING) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X18_RISING), MP_ROM_INT(PYB_PWR_WKUP_X18_RISING) }, + #endif #if 0 { MP_ROM_QSTR(MP_QSTR_WLAN_WAKE), MP_ROM_INT(PYB_SLP_WAKED_BY_WLAN) }, { MP_ROM_QSTR(MP_QSTR_PIN_WAKE), MP_ROM_INT(PYB_SLP_WAKED_BY_GPIO) }, diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c index 946185fba09d3..33fd441ba81dc 100644 --- a/ports/stm32/powerctrl.c +++ b/ports/stm32/powerctrl.c @@ -630,7 +630,7 @@ void powerctrl_enter_standby_mode(void) { #if defined(STM32F7) // disable wake-up flags - PWR->CSR2 &= ~(PWR_CSR2_EWUP6 | PWR_CSR2_EWUP5 | PWR_CSR2_EWUP4 | PWR_CSR2_EWUP3 | PWR_CSR2_EWUP2 | PWR_CSR2_EWUP1); + PWR->CSR2 &= ~(PWR_CSR2_EWUP6 | PWR_CSR2_EWUP5 | PWR_CSR2_EWUP3 | PWR_CSR2_EWUP2); // clear global wake-up flag PWR->CR2 |= PWR_CR2_CWUPF6 | PWR_CR2_CWUPF5 | PWR_CR2_CWUPF4 | PWR_CR2_CWUPF3 | PWR_CR2_CWUPF2 | PWR_CR2_CWUPF1; #elif defined(STM32H7) From 5072df0d83f0f55bc35bc2972de62a7daa2815ac Mon Sep 17 00:00:00 2001 From: irsla Date: Thu, 1 Oct 2020 11:02:35 +0100 Subject: [PATCH 2/2] Proposal #2 this includes patch for PR6494 and allows both patch to co-exists Users can then choose between 2 ways machine.deepsleep([ms]) pyb.standby([ms], [wakeup Pins X1|X18], [wakeup trigger FALLING|RISING]) -- tested 1.13 machine.deepsleep(2000) # OK machine.deepsleep(5000) # OK machine.deepsleep(10000) # OK machine.deepsleep(20000) # OK machine.deepsleep() # OK waited 2 minutes -- tested new firmware machine.deepsleep(2000) # OK machine.deepsleep(5000) # OK machine.deepsleep(10000) # OK machine.deepsleep(20000) # OK machine.deepsleep() # OK waited 2 minutes pyb.standby(0) # OK waited for 2 minutes pyb.standby(2000) # OK pyb.standby(5000) # OK pyb.standby(10000) # OK pyb.standby(20000) # OK pyb.standby() # OK waited for 2 minutes pyb.standby(0, pyb.WKUP_X1, pyb.WKUP_X1_FALLING) # OK wake up on interrupt within 10 sec pyb.standby(2000, pyb.WKUP_X1, pyb.WKUP_X1_FALLING) # OK wakes up after 2sec pyb.standby(5000, pyb.WKUP_X1, pyb.WKUP_X1_FALLING) # OK wakes up after 5 sec pyb.standby(10000, pyb.WKUP_X1, pyb.WKUP_X1_FALLING) # OK wakes up after 10 sec and wakes up on interrupt within 10 sec pyb.standby(20000, pyb.WKUP_X1, pyb.WKUP_X1_FALLING) # OK wakes up after 20 sec and wakes up on interrupt within 20 sec pyb.standby(0, pyb.WKUP_X18, pyb.WKUP_X18_FALLING) # OK wake up on interrupt within 10 sec pyb.standby(2000, pyb.WKUP_X18, pyb.WKUP_X18_FALLING) # OK wakes up after 2sec pyb.standby(5000, pyb.WKUP_X18, pyb.WKUP_X18_FALLING) # OK wakes up after 5 sec pyb.standby(10000, pyb.WKUP_X18, pyb.WKUP_X18_FALLING) # OK wakes up after 10 sec and wakes up on interrupt within 10 sec pyb.standby(20000, pyb.WKUP_X18, pyb.WKUP_X18_FALLING) # OK wakes up after 20 sec and wakes up on interrupt within 20 sec -- TO TEST pyb.standby(0, pyb.WKUP_X1 | pyb.WKUP_X18, pyb.WKUP_X1_FALLING | pyb.WKUP_X18_FALLING) # machine.deepsleep with upower.py --- ports/stm32/modmachine.c | 45 ++++---------------------------- ports/stm32/modpyb.c | 56 +++++++++++++++++++++++++++++++++++++++- ports/stm32/powerctrl.c | 6 ++++- 3 files changed, 65 insertions(+), 42 deletions(-) diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c index 01b525967873f..a34a569730902 100644 --- a/ports/stm32/modmachine.c +++ b/ports/stm32/modmachine.c @@ -92,12 +92,6 @@ #if defined(STM32F7) #define PYB_RESET_DEEPSLEEP_X1 (5) #define PYB_RESET_DEEPSLEEP_X18 (6) -#define PYB_PWR_WKUP_X1 (PWR_CSR2_EWUP1) -#define PYB_PWR_WKUP_X1_FALLING (PWR_CSR2_EWUP1) -#define PYB_PWR_WKUP_X1_RISING (0) -#define PYB_PWR_WKUP_X18 (PWR_CSR2_EWUP4) -#define PYB_PWR_WKUP_X18_FALLING (PWR_CSR2_EWUP4) -#define PYB_PWR_WKUP_X18_RISING (0) #endif STATIC uint32_t reset_cause; @@ -115,11 +109,11 @@ void machine_init(void) { reset_cause = PYB_RESET_DEEPSLEEP; PWR->CR1 |= PWR_CR1_CSBF; if (PWR->CSR2 & PWR_CSR2_WUPF1) { - reset_cause = PYB_RESET_DEEPSLEEP_X1; - PWR->CR2 |= PWR_CR2_CWUPF1; + reset_cause = PYB_RESET_DEEPSLEEP_X1; + PWR->CR2 |= PWR_CR2_CWUPF1; } else if (PWR->CSR2 & PWR_CSR2_WUPF4) { - reset_cause = PYB_RESET_DEEPSLEEP_X18; - PWR->CR2 |= PWR_CR2_CWUPF4; + reset_cause = PYB_RESET_DEEPSLEEP_X18; + PWR->CR2 |= PWR_CR2_CWUPF4; } } else @@ -384,38 +378,15 @@ STATIC mp_obj_t machine_lightsleep(size_t n_args, const mp_obj_t *args) { MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_lightsleep_obj, 0, 1, machine_lightsleep); STATIC mp_obj_t machine_deepsleep(size_t n_args, const mp_obj_t *args) { - // disable X1 and X18 flags -#if defined(STM32F7) - PWR->CSR2 &= ~(PWR_CSR2_EWUP4 | PWR_CSR2_EWUP1); - PWR->CR2 &= ~(PWR_CR2_WUPP4 | PWR_CR2_WUPP1); -#endif if (n_args != 0) { -#if defined(STM32F7) - int ts_value = mp_obj_get_int(args[0]); - if (ts_value != 0) { -#endif mp_obj_t args2[2] = {MP_OBJ_NULL, args[0]}; pyb_rtc_wakeup(2, args2); -#if defined(STM32F7) - } - if (n_args == 3) { - uint32_t pins = mp_obj_get_int(args[1]); - uint32_t falling = mp_obj_get_int(args[2]); - if ((pins | (PWR_CSR2_EWUP1 | PWR_CSR2_EWUP4)) != 0) { - PWR->CSR2 |= pins; - PWR->CR2 |= falling; - } - } -#endif } powerctrl_enter_standby_mode(); return mp_const_none; } -#if defined(STM32F7) -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_deepsleep_obj, 0, 3, machine_deepsleep); -#else + MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_deepsleep_obj, 0, 1, machine_deepsleep); -#endif STATIC mp_obj_t machine_reset_cause(void) { return MP_OBJ_NEW_SMALL_INT(reset_cause); @@ -480,12 +451,6 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { #if defined(STM32F7) { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_X1_RESET), MP_ROM_INT(PYB_RESET_DEEPSLEEP_X1) }, { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_X18_RESET), MP_ROM_INT(PYB_RESET_DEEPSLEEP_X18) }, - { MP_ROM_QSTR(MP_QSTR_WKUP_X1), MP_ROM_INT(PYB_PWR_WKUP_X1) }, - { MP_ROM_QSTR(MP_QSTR_WKUP_X1_FALLING), MP_ROM_INT(PYB_PWR_WKUP_X1_FALLING) }, - { MP_ROM_QSTR(MP_QSTR_WKUP_X1_RISING), MP_ROM_INT(PYB_PWR_WKUP_X1_RISING) }, - { MP_ROM_QSTR(MP_QSTR_WKUP_X18), MP_ROM_INT(PYB_PWR_WKUP_X18) }, - { MP_ROM_QSTR(MP_QSTR_WKUP_X18_FALLING), MP_ROM_INT(PYB_PWR_WKUP_X18_FALLING) }, - { MP_ROM_QSTR(MP_QSTR_WKUP_X18_RISING), MP_ROM_INT(PYB_PWR_WKUP_X18_RISING) }, #endif #if 0 { MP_ROM_QSTR(MP_QSTR_WLAN_WAKE), MP_ROM_INT(PYB_SLP_WAKED_BY_WLAN) }, diff --git a/ports/stm32/modpyb.c b/ports/stm32/modpyb.c index c92090699108e..68d81cd715293 100644 --- a/ports/stm32/modpyb.c +++ b/ports/stm32/modpyb.c @@ -56,8 +56,54 @@ #include "extmod/vfs.h" #include "extmod/utime_mphal.h" +#if defined(STM32F7) +#include "powerctrl.h" +#define PYB_PWR_WKUP_X1 (PWR_CSR2_EWUP1) +#define PYB_PWR_WKUP_X1_FALLING (PWR_CSR2_EWUP1) +#define PYB_PWR_WKUP_X1_RISING (0) +#define PYB_PWR_WKUP_X18 (PWR_CSR2_EWUP4) +#define PYB_PWR_WKUP_X18_FALLING (PWR_CSR2_EWUP4) +#define PYB_PWR_WKUP_X18_RISING (0) +#endif + char pyb_country_code[2]; +STATIC mp_obj_t pyb_standby(size_t n_args, const mp_obj_t *args) { + char has_args = false; + int ms_value = 0; + + #if defined(STM32F7) + // make sure all pins are cleared + PWR->CSR2 &= ~(PWR_CSR2_EWUP6 | PWR_CSR2_EWUP5 | PWR_CSR2_EWUP4 | PWR_CSR2_EWUP3 | PWR_CSR2_EWUP2 | PWR_CSR2_EWUP1); + if (n_args != 0) { + has_args = true; + ms_value = mp_obj_get_int(args[0]); + + if (n_args == 3) { + uint32_t pins = mp_obj_get_int(args[1]); + uint32_t falling = mp_obj_get_int(args[2]); + + if ((pins | (PYB_PWR_WKUP_X1 | PYB_PWR_WKUP_X18)) != 0) { + PWR->CSR2 |= pins; + } + if ((falling | (PYB_PWR_WKUP_X1_FALLING | PYB_PWR_WKUP_X18_FALLING)) != 0) { + PWR->CR2 |= falling; + } + } + } + #endif + if (has_args == true && ms_value != 0) { + mp_obj_t args2[2] = {MP_OBJ_NULL, args[0]}; + + pyb_rtc_wakeup(2, args2); + } + powerctrl_enter_standby_mode(); + + return mp_const_none; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_standby_obj, 0, 3, pyb_standby); + STATIC mp_obj_t pyb_fault_debug(mp_obj_t value) { pyb_hard_fault_debug = mp_obj_is_true(value); return mp_const_none; @@ -155,7 +201,7 @@ STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = { #if MICROPY_PY_PYB_LEGACY { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&machine_lightsleep_obj) }, - { MP_ROM_QSTR(MP_QSTR_standby), MP_ROM_PTR(&machine_deepsleep_obj) }, + { MP_ROM_QSTR(MP_QSTR_standby), MP_ROM_PTR(&pyb_standby_obj) }, #endif { MP_ROM_QSTR(MP_QSTR_main), MP_ROM_PTR(&pyb_main_obj) }, { MP_ROM_QSTR(MP_QSTR_repl_uart), MP_ROM_PTR(&pyb_repl_uart_obj) }, @@ -257,6 +303,14 @@ STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = { #if MICROPY_HW_HAS_LCD { MP_ROM_QSTR(MP_QSTR_LCD), MP_ROM_PTR(&pyb_lcd_type) }, #endif + #if defined(STM32F7) + { MP_ROM_QSTR(MP_QSTR_WKUP_X1), MP_ROM_INT(PYB_PWR_WKUP_X1) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X1_FALLING), MP_ROM_INT(PYB_PWR_WKUP_X1_FALLING) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X1_RISING), MP_ROM_INT(PYB_PWR_WKUP_X1_RISING) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X18), MP_ROM_INT(PYB_PWR_WKUP_X18) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X18_FALLING), MP_ROM_INT(PYB_PWR_WKUP_X18_FALLING) }, + { MP_ROM_QSTR(MP_QSTR_WKUP_X18_RISING), MP_ROM_INT(PYB_PWR_WKUP_X18_RISING) }, + #endif }; STATIC MP_DEFINE_CONST_DICT(pyb_module_globals, pyb_module_globals_table); diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c index 33fd441ba81dc..4011061395ca8 100644 --- a/ports/stm32/powerctrl.c +++ b/ports/stm32/powerctrl.c @@ -629,10 +629,14 @@ void powerctrl_enter_standby_mode(void) { RTC->ISR &= ~ISR_BITS; #if defined(STM32F7) + // Save user EWUP state + uint32_t csr2_ewup = PWR->CSR2 & (PWR_CSR2_EWUP6 | PWR_CSR2_EWUP5 | PWR_CSR2_EWUP4 | PWR_CSR2_EWUP3 | PWR_CSR2_EWUP2 | PWR_CSR2_EWUP1); // disable wake-up flags - PWR->CSR2 &= ~(PWR_CSR2_EWUP6 | PWR_CSR2_EWUP5 | PWR_CSR2_EWUP3 | PWR_CSR2_EWUP2); + PWR->CSR2 &= ~(PWR_CSR2_EWUP6 | PWR_CSR2_EWUP5 | PWR_CSR2_EWUP4 | PWR_CSR2_EWUP3 | PWR_CSR2_EWUP2 | PWR_CSR2_EWUP1); // clear global wake-up flag PWR->CR2 |= PWR_CR2_CWUPF6 | PWR_CR2_CWUPF5 | PWR_CR2_CWUPF4 | PWR_CR2_CWUPF3 | PWR_CR2_CWUPF2 | PWR_CR2_CWUPF1; + // Restore state + PWR->CSR2 |= csr2_ewup; #elif defined(STM32H7) // TODO #elif defined(STM32L4) || defined(STM32WB)