diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.series b/soc/arm/nordic_nrf/nrf52/Kconfig.series index f2a85b91786..73db7743f3e 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.series @@ -14,9 +14,6 @@ config SOC_SERIES_NRF52X select NRF_RTC_TIMER select CLOCK_CONTROL select CLOCK_CONTROL_NRF - select SYS_POWER_LOW_POWER_STATE_SUPPORTED - select SYS_POWER_STATE_CPU_LPS_SUPPORTED - select SYS_POWER_STATE_CPU_LPS_1_SUPPORTED select SYS_POWER_DEEP_SLEEP_SUPPORTED select SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED select XIP diff --git a/soc/arm/nordic_nrf/nrf52/power.c b/soc/arm/nordic_nrf/nrf52/power.c index 7eaa5bf7dcc..dc31bab7242 100644 --- a/soc/arm/nordic_nrf/nrf52/power.c +++ b/soc/arm/nordic_nrf/nrf52/power.c @@ -7,73 +7,22 @@ #include #include -#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL #include -LOG_MODULE_DECLARE(soc); - -#if defined(CONFIG_SYS_POWER_DEEP_SLEEP) -/* System_OFF is deepest Power state available, On exiting from this - * state CPU including all peripherals reset - */ -static void _system_off(void) -{ - nrf_power_system_off(); -} -#endif - -static void _issue_low_power_command(void) -{ - __WFE(); - __SEV(); - __WFE(); -} - -/* Name: _low_power_mode - * Parameter : Low Power Task ID - * - * Set Notdic SOC specific Low Power Task and invoke - * _WFE event to put the nordic SOC into Low Power State. - */ -static void _low_power_mode(enum power_states state) -{ - switch (state) { - /* CONSTANT LATENCY TASK */ - case SYS_POWER_STATE_CPU_LPS: - nrf_power_task_trigger(NRF_POWER_TASK_CONSTLAT); - break; - /* LOW POWER TASK */ - case SYS_POWER_STATE_CPU_LPS_1: - nrf_power_task_trigger(NRF_POWER_TASK_LOWPWR); - break; - - default: - /* Unsupported State */ - LOG_ERR("Unsupported State"); - break; - } - - /* Issue __WFE*/ - _issue_low_power_command(); -} +LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ void sys_set_power_state(enum power_states state) { switch (state) { - case SYS_POWER_STATE_CPU_LPS: - _low_power_mode(SYS_POWER_STATE_CPU_LPS); - break; - case SYS_POWER_STATE_CPU_LPS_1: - _low_power_mode(SYS_POWER_STATE_CPU_LPS_1); - break; -#if defined(CONFIG_SYS_POWER_DEEP_SLEEP) +#ifdef CONFIG_SYS_POWER_DEEP_SLEEP + #ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED case SYS_POWER_STATE_DEEP_SLEEP: - _system_off(); + nrf_power_system_off(); break; + #endif #endif default: - /* Unsupported State */ - LOG_ERR("Unsupported State"); + LOG_ERR("Unsupported power state %u", state); break; } } @@ -82,38 +31,63 @@ void sys_set_power_state(enum power_states state) void sys_power_state_post_ops(enum power_states state) { switch (state) { - case SYS_POWER_STATE_CPU_LPS: - case SYS_POWER_STATE_CPU_LPS_1: - /* Enable interrupts */ - __set_BASEPRI(0); - break; -#if defined(CONFIG_SYS_POWER_DEEP_SLEEP) +#ifdef CONFIG_SYS_POWER_DEEP_SLEEP + #ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED case SYS_POWER_STATE_DEEP_SLEEP: + /* Nothing to do. */ break; + #endif #endif default: - /* Unsupported State */ - LOG_ERR("Unsupported State"); + LOG_ERR("Unsupported power state %u", state); break; } + + /* + * System is now in active mode. Reenable interrupts which were disabled + * when OS started idling code. + */ + irq_unlock(0); } bool sys_is_valid_power_state(enum power_states state) { switch (state) { +#ifdef CONFIG_SYS_POWER_LOW_POWER_STATE + #ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_SUPPORTED case SYS_POWER_STATE_CPU_LPS: - case SYS_POWER_STATE_CPU_LPS_1: -#if defined(CONFIG_SYS_POWER_DEEP_SLEEP) - case SYS_POWER_STATE_DEEP_SLEEP: -#endif return true; - break; + #endif + #ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_1_SUPPORTED + case SYS_POWER_STATE_CPU_LPS_1: + return true; + #endif + #ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_2_SUPPORTED + case SYS_POWER_STATE_CPU_LPS_2: + return true; + #endif +#endif /* CONFIG_SYS_POWER_LOW_POWER_STATE */ + +#ifdef CONFIG_SYS_POWER_DEEP_SLEEP + #ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED + case SYS_POWER_STATE_DEEP_SLEEP: + return true; + #endif + #ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_1_SUPPORTED + case SYS_POWER_STATE_DEEP_SLEEP_1: + return true; + #endif + #ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_2_SUPPORTED + case SYS_POWER_STATE_DEEP_SLEEP_2: + return true; + #endif +#endif /* CONFIG_SYS_POWER_DEEP_SLEEP */ + default: - LOG_DBG("Unsupported State"); - break; + return false; } - return false; + /* Not reached */ } /* Overrides the weak ARM implementation: diff --git a/soc/arm/nordic_nrf/nrf52/soc.h b/soc/arm/nordic_nrf/nrf52/soc.h index 00ee8107e0e..d31ca23780e 100644 --- a/soc/arm/nordic_nrf/nrf52/soc.h +++ b/soc/arm/nordic_nrf/nrf52/soc.h @@ -16,6 +16,8 @@ #include #include +#include + /* Add include for DTS generated information */ #include diff --git a/soc/arm/nordic_nrf/nrf52/soc_power.h b/soc/arm/nordic_nrf/nrf52/soc_power.h index 1680d8be2d4..f254d0a88b2 100644 --- a/soc/arm/nordic_nrf/nrf52/soc_power.h +++ b/soc/arm/nordic_nrf/nrf52/soc_power.h @@ -14,13 +14,29 @@ extern "C" { #endif enum power_states { - SYS_POWER_STATE_CPU_LPS, /* CONSTLAT Task Activited */ - SYS_POWER_STATE_CPU_LPS_1, /* LOWPWR Task Activated */ - SYS_POWER_STATE_CPU_LPS_2, /* Not supported*/ - SYS_POWER_STATE_DEEP_SLEEP, /* System Off */ - SYS_POWER_STATE_DEEP_SLEEP_1, /* Not Supported */ - SYS_POWER_STATE_DEEP_SLEEP_2, /* Not Supported */ +#ifdef CONFIG_SYS_POWER_LOW_POWER_STATE +# ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_SUPPORTED + SYS_POWER_STATE_CPU_LPS, /* Not used */ +# endif +# ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_1_SUPPORTED + SYS_POWER_STATE_CPU_LPS_1, /* Not used */ +# endif +# ifdef CONFIG_SYS_POWER_STATE_CPU_LPS_2_SUPPORTED + SYS_POWER_STATE_CPU_LPS_2, /* Not used */ +# endif +#endif /* CONFIG_SYS_POWER_LOW_POWER_STATE */ +#ifdef CONFIG_SYS_POWER_DEEP_SLEEP +# ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_SUPPORTED + SYS_POWER_STATE_DEEP_SLEEP, /* System OFF */ +# endif +# ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_1_SUPPORTED + SYS_POWER_STATE_DEEP_SLEEP_1, /* Not used */ +# endif +# ifdef CONFIG_SYS_POWER_STATE_DEEP_SLEEP_2_SUPPORTED + SYS_POWER_STATE_DEEP_SLEEP_2, /* Not used */ +# endif +#endif /* CONFIG_SYS_POWER_DEEP_SLEEP */ SYS_POWER_STATE_MAX /* Do nothing */ }; @@ -30,7 +46,7 @@ enum power_states { void sys_set_power_state(enum power_states state); /** - * @brief Check a low power state is supported by SoC + * @brief Check the low power state is supported by SoC */ bool sys_is_valid_power_state(enum power_states state);