Skip to content

Commit 2496f1d

Browse files
committed
STM32 SLEEP update for easy maintenance
1 parent 6b226ff commit 2496f1d

File tree

1 file changed

+31
-59
lines changed

1 file changed

+31
-59
lines changed

targets/TARGET_STM/sleep.c

Lines changed: 31 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -51,56 +51,38 @@ static void wait_loop(uint32_t timeout)
5151
}
5252

5353

54-
// On L4 platforms we've seen unstable PLL CLK configuraiton
55-
// when DEEP SLEEP exits just few µs after being entered
56-
// So we need to force MSI usage before setting clocks again
5754
static void ForcePeriphOutofDeepSleep(void)
5855
{
5956
uint32_t pFLatency = 0;
6057
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
6158

62-
#if (TARGET_STM32L4 || TARGET_STM32L1) /* MSI used for L4 */
6359
/* Get the Clocks configuration according to the internal RCC registers */
6460
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
6561

66-
// Select HSI ss system clock source as a first step
67-
#ifdef RCC_CLOCKTYPE_PCLK2
68-
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
69-
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
70-
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
71-
#else
72-
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
73-
| RCC_CLOCKTYPE_PCLK1);
74-
#endif
75-
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
76-
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
77-
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
78-
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK) {
79-
error("clock issue\r\n");
80-
}
81-
#else /* HSI used on others */
82-
/* Get the Clocks configuration according to the internal RCC registers */
83-
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
84-
85-
/**Initializes the CPU, AHB and APB busses clocks
86-
*/
8762
#ifdef RCC_CLOCKTYPE_PCLK2
8863
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
8964
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
9065
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
91-
#else
66+
#else /* RCC_CLOCKTYPE_PCLK2 */
9267
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
9368
| RCC_CLOCKTYPE_PCLK1);
94-
#endif
69+
#endif /* RCC_CLOCKTYPE_PCLK2 */
70+
71+
#if defined (RCC_SYSCLKSOURCE_MSI) /* STM32Lx */
72+
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
73+
#else /* defined RCC_SYSCLKSOURCE_MSI */
9574
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
96-
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
97-
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
75+
#endif /* defined RCC_SYSCLKSOURCE_MSI */
76+
77+
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
78+
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
79+
9880
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK) {
99-
error("clock issue");
81+
error("ForcePeriphOutofDeepSleep clock issue\r\n");
10082
}
101-
#endif // TARGET_STM32L4
10283
}
10384

85+
10486
static void ForceOscOutofDeepSleep(void)
10587
{
10688
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
@@ -111,47 +93,32 @@ static void ForceOscOutofDeepSleep(void)
11193
/* Get the Oscillators configuration according to the internal RCC registers */
11294
HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
11395

114-
#if (TARGET_STM32L4 || TARGET_STM32L1) /* MSI used for L4 */
115-
/**Initializes the CPU, AHB and APB busses clocks
116-
*/
96+
#if defined (RCC_SYSCLKSOURCE_MSI) /* STM32Lx */
11797
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
11898
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
11999
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
120100
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; // Intermediate freq, 1MHz range
121101
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
122-
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
123-
error("clock issue\r\n");
124-
}
125-
#else /* HSI used on others */
126-
/**Initializes the CPU, AHB and APB busses clocks
127-
*/
102+
#else /* defined RCC_SYSCLKSOURCE_MSI */
128103
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
129104
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
130105
RCC_OscInitStruct.HSICalibrationValue = 16;
131106
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
107+
#endif /* defined RCC_SYSCLKSOURCE_MSI */
108+
132109
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
133-
error("clock issue");
110+
error("ForceOscOutofDeepSleep clock issue\r\n");
134111
}
135-
#endif // TARGET_STM32L4
136112
}
137113

138-
/* The content of this function has been split into 2 separate functions
139-
so that the involved structures are not allocated on the stack in parallel.
140-
This will reduce the maximum stack usage in case on non-optimized / debug
141-
compilers settings */
142-
static void ForceClockOutofDeepSleep(void)
143-
{
144-
ForceOscOutofDeepSleep();
145-
ForcePeriphOutofDeepSleep();
146-
}
147114

148115
void hal_sleep(void)
149116
{
150117
// Disable IRQs
151118
core_util_critical_section_enter();
152119

153120
// Request to enter SLEEP mode
154-
#if TARGET_STM32L4
121+
#ifdef PWR_CR1_LPR
155122
// State Transitions (see 5.3 Low-power modes, Fig. 13):
156123
// * (opt): Low Power Run (LPR) Mode -> Run Mode
157124
// * Run Mode -> Sleep
@@ -160,7 +127,7 @@ void hal_sleep(void)
160127
// * (opt): Run Mode -> Low Power Run Mode
161128

162129
// [5.4.1 Power control register 1 (PWR_CR1)]
163-
// LPR: When this bit is set, the regulator is switched from main mode (MR) to low-power mode (LPR).
130+
// LPR: When this bit is set, the regulator is switched from main mode (MR) to low-power mode (LPR).
164131
int lowPowerMode = PWR->CR1 & PWR_CR1_LPR;
165132
if (lowPowerMode) {
166133
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
@@ -186,7 +153,7 @@ void hal_deepsleep(void)
186153
* This is tracked in mbed issue 4408.
187154
* For now, we're checking all Serial HW FIFO. If any transfer is ongoing
188155
* we're not entering deep sleep and returning immediately. */
189-
if(serial_is_tx_ongoing()) {
156+
if (serial_is_tx_ongoing()) {
190157
return;
191158
}
192159

@@ -196,7 +163,7 @@ void hal_deepsleep(void)
196163
save_timer_ctx();
197164

198165
// Request to enter STOP mode with regulator in low power mode
199-
#if TARGET_STM32L4
166+
#ifdef PWR_CR1_LPMS_STOP2 /* STM32L4 */
200167
int pwrClockEnabled = __HAL_RCC_PWR_IS_CLK_ENABLED();
201168
int lowPowerModeEnabled = PWR->CR1 & PWR_CR1_LPR;
202169

@@ -215,16 +182,21 @@ void hal_deepsleep(void)
215182
if (!pwrClockEnabled) {
216183
__HAL_RCC_PWR_CLK_DISABLE();
217184
}
218-
#else /* TARGET_STM32L4 */
185+
#else /* PWR_CR1_LPMS_STOP2 */
219186
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
220-
#endif /* TARGET_STM32L4 */
187+
#endif /* PWR_CR1_LPMS_STOP2 */
221188

222189
/* Prevent HAL_GetTick() from using ticker_read_us() to read the
223190
* us_ticker timestamp until the us_ticker context is restored. */
224191
mbed_sdk_inited = 0;
225192

226-
// Verify Clock Out of Deep Sleep
227-
ForceClockOutofDeepSleep();
193+
/* We've seen unstable PLL CLK configuration when DEEP SLEEP exits just few µs after being entered
194+
* So we need to force clock init out of Deep Sleep.
195+
* This init has been split into 2 separate functions so that the involved structures are not allocated on the stack in parallel.
196+
* This will reduce the maximum stack usage in case on non-optimized / debug compilers settings
197+
*/
198+
ForceOscOutofDeepSleep();
199+
ForcePeriphOutofDeepSleep();
228200

229201
// After wake-up from STOP reconfigure the PLL
230202
SetSysClock();

0 commit comments

Comments
 (0)