88#include <soc.h>
99#include <zephyr/init.h>
1010
11- #include <stm32wbaxx_ll_utils.h>
1211#include <stm32wbaxx_ll_bus.h>
1312#include <stm32wbaxx_ll_cortex.h>
1413#include <stm32wbaxx_ll_pwr.h>
14+ #include <stm32wbaxx_ll_icache.h>
1515#include <stm32wbaxx_ll_rcc.h>
1616#include <stm32wbaxx_ll_system.h>
1717#include <clock_control/clock_stm32_ll_common.h>
1818
19+ #ifdef CONFIG_BT_STM32WBA
20+ #include "scm.h"
21+ #endif
22+
1923#include <zephyr/logging/log.h>
24+
2025LOG_MODULE_DECLARE (soc , CONFIG_SOC_LOG_LEVEL );
2126
2227void set_mode_stop (uint8_t substate_id )
2328{
29+
30+ LL_PWR_ClearFlag_STOP ();
31+ LL_RCC_ClearResetFlags ();
32+
33+ /* Erratum 2.2.15:
34+ * Disabling ICACHE is required before entering stop mode
35+ */
36+ LL_ICACHE_Disable ();
37+ while (LL_ICACHE_IsEnabled () == 1U ) {
38+ }
39+
40+
41+ #ifdef CONFIG_BT_STM32WBA
42+ scm_setwaitstates (LP );
43+ #endif
44+ /* Set SLEEPDEEP bit of Cortex System Control Register */
45+ LL_LPM_EnableDeepSleep ();
46+
47+ while (LL_PWR_IsActiveFlag_ACTVOS () == 0 ) {
48+ }
49+
2450 switch (substate_id ) {
2551 case 1 : /* enter STOP0 mode */
2652 LL_PWR_SetPowerMode (LL_PWR_MODE_STOP0 );
@@ -34,13 +60,6 @@ void set_mode_stop(uint8_t substate_id)
3460 }
3561}
3662
37- void set_mode_standby (uint8_t substate_id )
38- {
39- ARG_UNUSED (substate_id );
40- /* Select standby mode */
41- LL_PWR_SetPowerMode (LL_PWR_MODE_STANDBY );
42- }
43-
4463/* Invoke Low Power/System Off specific Tasks */
4564void pm_state_set (enum pm_state state , uint8_t substate_id )
4665{
@@ -49,24 +68,35 @@ void pm_state_set(enum pm_state state, uint8_t substate_id)
4968 set_mode_stop (substate_id );
5069 break ;
5170 case PM_STATE_STANDBY :
52- /* To be tested */
53- set_mode_standby (substate_id );
54- break ;
71+ /* Not supported today */
72+ __fallthrough ;
5573 default :
5674 LOG_DBG ("Unsupported power state %u" , state );
5775 return ;
5876 }
5977
60- /* Set SLEEPDEEP bit of Cortex System Control Register */
61- LL_LPM_EnableDeepSleep ();
62-
6378 /* Select mode entry : WFE or WFI and enter the CPU selected mode */
6479 k_cpu_idle ();
6580}
6681
6782/* Handle SOC specific activity after Low Power Mode Exit */
6883void pm_state_exit_post_ops (enum pm_state state , uint8_t substate_id )
6984{
85+ /* Erratum 2.2.15:
86+ * Enable ICACHE when exiting stop mode
87+ */
88+ LL_ICACHE_Enable ();
89+ while (LL_ICACHE_IsEnabled () == 0U ) {
90+ }
91+
92+ #ifdef CONFIG_BT_STM32WBA
93+ if (LL_PWR_IsActiveFlag_STOP () == 1U ) {
94+ scm_setup ();
95+ } else {
96+ scm_setwaitstates (RUN );
97+ }
98+ #endif
99+
70100 switch (state ) {
71101 case PM_STATE_SUSPEND_TO_IDLE :
72102 if (substate_id <= 2 ) {
@@ -87,8 +117,11 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
87117 LOG_DBG ("Unsupported power state %u" , state );
88118 break ;
89119 }
90- /* need to restore the clock */
120+
121+ /* When BLE is enabled, clock restoration is performed by SCM */
122+ #if !defined(CONFIG_BT_STM32WBA )
91123 stm32_clock_control_init (NULL );
124+ #endif
92125
93126 /*
94127 * System is now in active mode.
@@ -101,9 +134,17 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
101134/* Initialize STM32 Power */
102135static int stm32_power_init (void )
103136{
104- /* enable Power clock */
137+
138+ #ifdef CONFIG_BT_STM32WBA
139+ scm_init ();
140+ #endif
141+
105142 LL_AHB4_GRP1_EnableClock (LL_AHB4_GRP1_PERIPH_PWR );
106143
144+ LL_PWR_EnableUltraLowPowerMode ();
145+
146+ LL_FLASH_EnableSleepPowerDown ();
147+
107148 return 0 ;
108149}
109150
0 commit comments