Skip to content

Commit c0bfcec

Browse files
LMESTM0xc0170
authored andcommitted
STM32WB: update deep sleep sequence
Review HSE clock initialization to match with latest CUBE firmware. Also there is no need to set the full clock tree again after deep sleep exit. With this change we get a stable deep sleep mode (when allowed by CORDIO stack).
1 parent 9cf03e3 commit c0bfcec

File tree

3 files changed

+205
-166
lines changed

3 files changed

+205
-166
lines changed

targets/TARGET_STM/TARGET_STM32WB/TARGET_STM32WB55xG/TARGET_NUCLEO_WB55RG/system_clock.c

Lines changed: 115 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include "stm32wbxx.h"
3535
#include "mbed_error.h"
3636
#include "stm32wbxx_ll_hsem.h"
37+
#include "stm32wbxx_ll_hsem.h"
38+
#include "otp.h"
3739
#include "hw_conf.h" /* Common BLE file where BLE shared resources are defined */
3840

3941
// Clock source is selected with CLOCK_SOURCE in json config
@@ -56,7 +58,59 @@ uint8_t SetSysClock_PLL_HSI(void);
5658
uint8_t SetSysClock_PLL_MSI(void);
5759
#endif /* ((CLOCK_SOURCE) & USE_PLL_MSI) */
5860

59-
void Configure_RF_Clock_Sources(void);
61+
static void Configure_RF_Clock_Sources(void)
62+
{
63+
static uint8_t RF_ON = 0;
64+
65+
if ( !RF_ON ) {
66+
// Reset backup domain
67+
if ((LL_RCC_IsActiveFlag_PINRST()) && (!LL_RCC_IsActiveFlag_SFTRST())) {
68+
// Write twice the value to flush the APB-AHB bridge
69+
// This bit shall be written in the register before writing the next one
70+
HAL_PWR_EnableBkUpAccess();
71+
HAL_PWR_EnableBkUpAccess();
72+
__HAL_RCC_BACKUPRESET_FORCE();
73+
__HAL_RCC_BACKUPRESET_RELEASE();
74+
}
75+
76+
/**
77+
* Select LSE clock
78+
*/
79+
LL_RCC_LSE_Enable();
80+
while (!LL_RCC_LSE_IsReady());
81+
82+
/**
83+
* Select wakeup source of BLE RF
84+
*/
85+
LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE);
86+
87+
/**
88+
* Switch OFF LSI
89+
*/
90+
LL_RCC_LSI1_Disable();
91+
92+
RF_ON = 1;
93+
}
94+
95+
return;
96+
}
97+
98+
static void Config_HSE(void)
99+
{
100+
OTP_ID0_t * p_otp;
101+
102+
/**
103+
* Read HSE_Tuning from OTP
104+
*/
105+
p_otp = (OTP_ID0_t *) OTP_Read(0);
106+
if (p_otp)
107+
{
108+
LL_RCC_HSE_SetCapacitorTuning(p_otp->hse_tuning);
109+
}
110+
111+
return;
112+
}
113+
60114

61115
/**
62116
* @brief Configures the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers
@@ -112,43 +166,69 @@ void SetSysClock(void)
112166
/******************************************************************************/
113167
uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
114168
{
115-
LL_RCC_HSE_Enable();
116-
117-
/**
118-
* Switch to HSE as Sys clok source
119-
* All Peripehrals (HCLK, HCLK2, HCLK4, PCLK1, PCLK2) will be clocked
120-
* @ 32MHZ. This is not optimal but a stable setting for enter and exit
121-
* deep sleep mode (STOP mode).
122-
*
123-
*/
124-
while(!LL_RCC_HSE_IsReady());
125-
LL_RCC_SetSysClkSource( LL_RCC_SYS_CLKSOURCE_HSE );
126-
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
127-
128-
/**
129-
* Set RNG on HSI48
130-
*/
131-
LL_RCC_HSI48_Enable();
132-
while (!LL_RCC_HSI48_IsReady());
133-
LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_HSI48);
134-
135-
/**
136-
* Switch OFF MSI and HSI
137-
*/
138-
LL_RCC_MSI_Disable();
139-
LL_RCC_HSI_Disable();
169+
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
170+
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
171+
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
140172

141-
// Output clock on MCO1 pin(PA8) for debugging purpose
142-
#if DEBUG_MCO == 2
143-
if (bypass == 0) {
144-
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_4); // 8 MHz
145-
} else {
146-
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_2); // 4 MHz
147-
}
148-
#endif
173+
Config_HSE();
149174

150-
return 1;
175+
/** Configure the main internal regulator output voltage
176+
*/
177+
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
178+
/** Initializes the CPU, AHB and APB busses clocks
179+
*/
180+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI1
181+
|RCC_OSCILLATORTYPE_HSE;
182+
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
183+
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
184+
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
185+
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
186+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
187+
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
188+
{
189+
return 0; // FAIL
190+
}
191+
/** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
192+
*/
193+
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4|RCC_CLOCKTYPE_HCLK2
194+
|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
195+
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
196+
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
197+
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
198+
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
199+
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
200+
RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV1;
201+
RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;
202+
203+
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
204+
{
205+
return 0; // FAIL
206+
}
207+
/** Initializes the peripherals clocks
208+
*/
209+
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS|RCC_PERIPHCLK_RFWAKEUP
210+
|RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1
211+
|RCC_PERIPHCLK_LPUART1;
212+
PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
213+
PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
214+
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
215+
PeriphClkInitStruct.RFWakeUpClockSelection = RCC_RFWKPCLKSOURCE_LSI;
216+
PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSE;
217+
PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE0;
218+
219+
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
220+
{
221+
return 0; // FAIL
222+
}
223+
224+
/**
225+
* Select HSI as system clock source after Wake Up from Stop mode
226+
*/
227+
LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);
228+
229+
return 1;
151230
}
231+
152232
#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */
153233

154234
#if ((CLOCK_SOURCE) & USE_PLL_HSI)
@@ -271,33 +351,3 @@ uint8_t SetSysClock_PLL_MSI(void)
271351
}
272352
#endif /* ((CLOCK_SOURCE) & USE_PLL_MSI) */
273353

274-
void Configure_RF_Clock_Sources(void)
275-
{
276-
// Reset backup domain
277-
if ((LL_RCC_IsActiveFlag_PINRST()) && (!LL_RCC_IsActiveFlag_SFTRST())) {
278-
// Write twice the value to flush the APB-AHB bridge
279-
// This bit shall be written in the register before writing the next one
280-
HAL_PWR_EnableBkUpAccess();
281-
HAL_PWR_EnableBkUpAccess();
282-
__HAL_RCC_BACKUPRESET_FORCE();
283-
__HAL_RCC_BACKUPRESET_RELEASE();
284-
}
285-
286-
/**
287-
* Select LSE clock
288-
*/
289-
LL_RCC_LSE_Enable();
290-
while (!LL_RCC_LSE_IsReady());
291-
292-
/**
293-
* Select wakeup source of BLE RF
294-
*/
295-
LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE);
296-
297-
/**
298-
* Switch OFF LSI
299-
*/
300-
LL_RCC_LSI1_Disable();
301-
302-
return;
303-
}

0 commit comments

Comments
 (0)