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) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy