Skip to content

Commit ff38953

Browse files
committed
STM32: lpticker: allow dynamic configuration
Step1: allow automatic fallback to LSI if LSE is not functional Step2: expose two reconfiguration APIs, so the user can check if LSE is precise enough and eventually revert to LSI
1 parent 7d59d1e commit ff38953

File tree

1 file changed

+83
-38
lines changed

1 file changed

+83
-38
lines changed

targets/TARGET_STM/lp_ticker.c

+83-38
Original file line numberDiff line numberDiff line change
@@ -126,20 +126,35 @@
126126

127127

128128
LPTIM_HandleTypeDef LptimHandle;
129+
static uint8_t using_lse = MBED_CONF_TARGET_LSE_AVAILABLE;
129130

130-
const ticker_info_t *lp_ticker_get_info()
131+
static const ticker_info_t *lp_ticker_get_info_lse()
131132
{
132-
static const ticker_info_t info = {
133-
#if MBED_CONF_TARGET_LSE_AVAILABLE
133+
const static ticker_info_t info = {
134134
LSE_VALUE / MBED_CONF_TARGET_LPTICKER_LPTIM_CLOCK,
135-
#else
135+
16
136+
};
137+
return &info;
138+
}
139+
140+
static const ticker_info_t *lp_ticker_get_info_lsi()
141+
{
142+
const static ticker_info_t info = {
136143
LSI_VALUE / MBED_CONF_TARGET_LPTICKER_LPTIM_CLOCK,
137-
#endif
138144
16
139145
};
140146
return &info;
141147
}
142148

149+
const ticker_info_t *lp_ticker_get_info()
150+
{
151+
if (using_lse) {
152+
return lp_ticker_get_info_lse();
153+
} else {
154+
return lp_ticker_get_info_lsi();
155+
}
156+
}
157+
143158
volatile uint8_t lp_Fired = 0;
144159
/* Flag and stored counter to handle delayed programing at low level */
145160
volatile bool lp_delayed_prog = false;
@@ -154,71 +169,101 @@ volatile bool sleep_manager_locked = false;
154169
static int LPTICKER_inited = 0;
155170
static void LPTIM_IRQHandler(void);
156171

157-
void lp_ticker_init(void)
158-
{
159-
/* Check if LPTIM is already configured */
160-
if (LPTICKER_inited) {
161-
lp_ticker_disable_interrupt();
162-
return;
163-
}
164-
LPTICKER_inited = 1;
165-
166-
RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = {0};
167-
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
168-
169-
#if MBED_CONF_TARGET_LSE_AVAILABLE
172+
static void configureClocksLSE(RCC_PeriphCLKInitTypeDef* RCC_PeriphCLKInitStruct,
173+
RCC_OscInitTypeDef* RCC_OscInitStruct){
170174

171175
/* Enable LSE clock */
172-
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
176+
RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_LSE;
173177
#if MBED_CONF_TARGET_LSE_BYPASS
174-
RCC_OscInitStruct.LSEState = RCC_LSE_BYPASS;
178+
RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
175179
#else
176-
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
180+
RCC_OscInitStruct->LSEState = RCC_LSE_ON;
177181
#endif
178-
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
182+
RCC_OscInitStruct->PLL.PLLState = RCC_PLL_NONE;
179183

180184
/* Select the LSE clock as LPTIM peripheral clock */
181-
RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM;
185+
RCC_PeriphCLKInitStruct->PeriphClockSelection = RCC_PERIPHCLK_LPTIM;
182186
#if (TARGET_STM32L0)
183-
RCC_PeriphCLKInitStruct.LptimClockSelection = RCC_LPTIMCLKSOURCE_LSE;
187+
RCC_PeriphCLKInitStruct->LptimClockSelection = RCC_LPTIMCLKSOURCE_LSE;
184188
#else
185189
#if (LPTIM_MST_BASE == LPTIM1_BASE)
186-
RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIMCLKSOURCE_LSE;
190+
RCC_PeriphCLKInitStruct->Lptim1ClockSelection = RCC_LPTIMCLKSOURCE_LSE;
187191
#elif (LPTIM_MST_BASE == LPTIM3_BASE) || (LPTIM_MST_BASE == LPTIM4_BASE) || (LPTIM_MST_BASE == LPTIM5_BASE)
188-
RCC_PeriphCLKInitStruct.Lptim345ClockSelection = RCC_LPTIMCLKSOURCE_LSE;
192+
RCC_PeriphCLKInitStruct->Lptim345ClockSelection = RCC_LPTIMCLKSOURCE_LSE;
189193
#endif /* LPTIM_MST_BASE == LPTIM1 */
190194
#endif /* TARGET_STM32L0 */
191-
#else /* MBED_CONF_TARGET_LSE_AVAILABLE */
195+
}
196+
197+
static void configureClocksLSI(RCC_PeriphCLKInitTypeDef* RCC_PeriphCLKInitStruct,
198+
RCC_OscInitTypeDef* RCC_OscInitStruct){
192199

193200
/* Enable LSI clock */
194201
#if TARGET_STM32WB
195-
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1;
202+
RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_LSI1;
196203
#else
197-
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
204+
RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_LSI;
198205
#endif
199-
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
200-
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
206+
RCC_OscInitStruct->LSIState = RCC_LSI_ON;
207+
RCC_OscInitStruct->PLL.PLLState = RCC_PLL_NONE;
201208

202209
/* Select the LSI clock as LPTIM peripheral clock */
203-
RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM;
210+
RCC_PeriphCLKInitStruct->PeriphClockSelection = RCC_PERIPHCLK_LPTIM;
204211
#if (TARGET_STM32L0)
205-
RCC_PeriphCLKInitStruct.LptimClockSelection = RCC_LPTIMCLKSOURCE_LSI;
212+
RCC_PeriphCLKInitStruct->LptimClockSelection = RCC_LPTIMCLKSOURCE_LSI;
206213
#else
207214
#if (LPTIM_MST_BASE == LPTIM1_BASE)
208-
RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIMCLKSOURCE_LSI;
215+
RCC_PeriphCLKInitStruct->Lptim1ClockSelection = RCC_LPTIMCLKSOURCE_LSI;
209216
#elif (LPTIM_MST_BASE == LPTIM3_BASE) || (LPTIM_MST_BASE == LPTIM4_BASE) || (LPTIM_MST_BASE == LPTIM5_BASE)
210-
RCC_PeriphCLKInitStruct.Lptim345ClockSelection = RCC_LPTIMCLKSOURCE_LSI;
217+
RCC_PeriphCLKInitStruct->Lptim345ClockSelection = RCC_LPTIMCLKSOURCE_LSI;
211218
#endif /* LPTIM_MST_BASE == LPTIM1 */
212219
#endif /* TARGET_STM32L0 */
220+
}
221+
222+
void lp_ticker_reconfigure_with_lsi() {
223+
lp_ticker_disable_interrupt();
224+
LPTICKER_inited = 0;
225+
using_lse = 0;
226+
lp_ticker_init();
227+
}
228+
229+
void lp_ticker_reconfigure_with_lse() {
230+
lp_ticker_disable_interrupt();
231+
LPTICKER_inited = 0;
232+
using_lse = 1;
233+
lp_ticker_init();
234+
}
235+
236+
void lp_ticker_init(void)
237+
{
238+
/* Check if LPTIM is already configured */
239+
if (LPTICKER_inited) {
240+
lp_ticker_disable_interrupt();
241+
return;
242+
}
243+
LPTICKER_inited = 1;
244+
245+
RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = {0};
246+
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
247+
248+
if (using_lse) {
249+
configureClocksLSE(&RCC_PeriphCLKInitStruct, &RCC_OscInitStruct);
250+
} else {
251+
configureClocksLSI(&RCC_PeriphCLKInitStruct, &RCC_OscInitStruct);
252+
}
213253

214-
#endif /* MBED_CONF_TARGET_LSE_AVAILABLE */
215254
#if defined(DUAL_CORE) && (TARGET_STM32H7)
216255
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) {
217256
}
218257
#endif /* DUAL_CORE */
219258
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
220-
error("HAL_RCC_OscConfig ERROR\n");
221-
return;
259+
260+
// retry with LSI
261+
using_lse = 0;
262+
configureClocksLSI(&RCC_PeriphCLKInitStruct, &RCC_OscInitStruct);
263+
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
264+
error("HAL_RCC_OscConfig ERROR\n");
265+
return;
266+
}
222267
}
223268

224269
if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct) != HAL_OK) {

0 commit comments

Comments
 (0)