From 3b892e4a18c4d71769f48f9615b79d1b4527b912 Mon Sep 17 00:00:00 2001 From: andrewmcg1 Date: Wed, 16 Oct 2024 05:20:49 -0400 Subject: [PATCH] Added functions for entering l4 power modes --- include/libopencm3/cm3/scb.h | 4 ++++ include/libopencm3/stm32/l4/pwr.h | 8 ++++++++ lib/cm3/scb.c | 20 ++++++++++++++++++ lib/stm32/l4/pwr.c | 34 +++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+) diff --git a/include/libopencm3/cm3/scb.h b/include/libopencm3/cm3/scb.h index 74ac623b..9083efbd 100644 --- a/include/libopencm3/cm3/scb.h +++ b/include/libopencm3/cm3/scb.h @@ -554,6 +554,10 @@ struct scb_exception_stack_frame { } while (0) void scb_reset_system(void) __attribute__((noreturn)); +void scb_set_sleepdeep(void); +void scb_clear_sleepdeep(void); +void scb_set_sleeponexit(void); +void scb_clear_sleeponexit(void); /* Those defined only on ARMv7 and above */ #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) diff --git a/include/libopencm3/stm32/l4/pwr.h b/include/libopencm3/stm32/l4/pwr.h index 04919327..6a4b6581 100644 --- a/include/libopencm3/stm32/l4/pwr.h +++ b/include/libopencm3/stm32/l4/pwr.h @@ -77,11 +77,15 @@ specific memorymap.h header before including this header file.*/ #define PWR_CR1_LPMS_SHIFT 0 #define PWR_CR1_LPMS_MASK 0x07 +/** @defgroup pwr_cr1_lpms LPMS mode selection + * @ingroup STM32L4_pwr_defines + @{*/ #define PWR_CR1_LPMS_STOP_0 0 #define PWR_CR1_LPMS_STOP_1 1 #define PWR_CR1_LPMS_STOP_2 2 #define PWR_CR1_LPMS_STANDBY 3 #define PWR_CR1_LPMS_SHUTDOWN 4 +/**@}*/ /* --- PWR_CR2 values ------------------------------------------------------- */ @@ -173,6 +177,10 @@ void pwr_set_vos_scale(enum pwr_vos_scale scale); void pwr_disable_backup_domain_write_protect(void); void pwr_enable_backup_domain_write_protect(void); +void pwr_enable_low_power_run(void); +void pwr_disable_low_power_run(void); +void pwr_set_low_power_mode_selection(uint32_t lpms); + END_DECLS #endif diff --git a/lib/cm3/scb.c b/lib/cm3/scb.c index 52f38e81..8d5b2f0f 100644 --- a/lib/cm3/scb.c +++ b/lib/cm3/scb.c @@ -58,6 +58,26 @@ void scb_reset_system(void) while (1); } +void scb_set_sleepdeep(void) +{ + SCB_SCR |= SCB_SCR_SLEEPDEEP; +} + +void scb_clear_sleepdeep(void) +{ + SCB_SCR &= ~SCB_SCR_SLEEPDEEP; +} + +void scb_set_sleeponexit(void) +{ + SCB_SCR |= SCB_SCR_SLEEPONEXIT; +} + +void scb_clear_sleeponexit(void) +{ + SCB_SCR &= ~SCB_SCR_SLEEPONEXIT; +} + /* Those are defined only on CM3 or CM4 */ #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) void scb_set_priority_grouping(uint32_t prigroup) diff --git a/lib/stm32/l4/pwr.c b/lib/stm32/l4/pwr.c index e6bd877a..3bdd903e 100644 --- a/lib/stm32/l4/pwr.c +++ b/lib/stm32/l4/pwr.c @@ -72,4 +72,38 @@ void pwr_enable_backup_domain_write_protect(void) PWR_CR1 &= ~PWR_CR1_DBP; } +/** Enable Low Power Run + * + * This enables low power run mode. The clock frequency is limited to 2 MHz in this mode + * and must be set before entering low power run mode. + */ +void pwr_enable_low_power_run(void) +{ + PWR_CR1 |= PWR_CR1_LPR; +} + +/** Disable Low Power Run + * + * This disables low power run mode + */ +void pwr_disable_low_power_run(void) +{ + PWR_CR1 &= ~PWR_CR1_LPR; +} + +/** @brief Select the low power mode used in deep sleep. + * + * Set which power mode is entered when the processor enters deep sleep. + * + * @param[in] lpms low power mode @ref pwr_cr1_lpms + */ +void pwr_set_low_power_mode_selection(uint32_t lpms) +{ + uint32_t reg32; + + reg32 = PWR_CR1; + reg32 &= ~(PWR_CR1_LPMS_MASK << PWR_CR1_LPMS_SHIFT); + PWR_CR1 = (reg32 | (lpms << PWR_CR1_LPMS_SHIFT)); +} + /**@}*/