8000 stmhal/rtc: LSx oscillator is only initialized upon initial power up. · cpforbes/circuitpython@8f7ff85 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8f7ff85

Browse files
T Sdpgeorge
T S
authored andcommitted
stmhal/rtc: LSx oscillator is only initialized upon initial power up.
Initial power up also includes VBAT. If LSE is configured but fails to start, LSI is used until next full power cycle. Also handles STM32F7xx variant.
1 parent 8bfa11b commit 8f7ff85

File tree

1 file changed

+56
-38
lines changed

1 file changed

+56
-38
lines changed

stmhal/rtc.c

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,14 @@ void rtc_init(void) {
160160

161161
STATIC void RTC_CalendarConfig(void);
162162

163+
#if defined(MICROPY_HW_RTC_USE_LSE) && MICROPY_HW_RTC_USE_LSE
164+
STATIC bool rtc_use_lse = true;
165+
#else
166+
STATIC bool rtc_use_lse = false;
167+
#endif
168+
163169
void rtc_init(void) {
164170
RTCHandle.Instance = RTC;
165-
RTC_DateTypeDef date;
166171

167172
/* Configure RTC prescaler and RTC data registers */
168173
/* RTC configured as follow:
@@ -179,49 +184,62 @@ void rtc_init(void) {
179184
RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
180185
RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
181186

182-
// if LTE enabled & ready --> no need to (re-)init RTC
183187
if ((RCC->BDCR & (RCC_BDCR_LSEON | RCC_BDCR_LSERDY)) == (RCC_BDCR_LSEON | RCC_BDCR_LSERDY)) {
188+
// LSE is enabled & ready --> no need to (re-)init RTC
184189
// remove Backup Domain write protection
185-
#if defined(MCU_SERIES_F7)
186-
PWR->CR1 |= PWR_CR1_DBP;
187-
#else
188-
PWR->CR |= PWR_CR_DBP;
189-
#endif
190+
HAL_PWR_EnableBkUpAccess();
190191
// Clear source Reset Flag
191192
__HAL_RCC_CLEAR_RESET_FLAGS();
192193
// provide some status information
193194
rtc_info |= 0x40000 | (RCC->BDCR & 7) | (RCC->CSR & 3) << 8;
194195
return;
196+
} else if ((RCC->BDCR & RCC_BDCR_RTCSEL) == RCC_BDCR_RTCSEL_1) {
197+
// LSI is already active
198+
// remove Backup Domain write protection
199+
HAL_PWR_EnableBkUpAccess();
200+
// Clear source Reset Flag
201+
__HAL_RCC_CLEAR_RESET_FLAGS();
202+
RCC->CSR |= 1;
203+
// provide some status information
204+
rtc_info |= 0x80000 | (RCC->BDCR & 7) | (RCC->CSR & 3) << 8;
205+
return;
195206
}
196207

197208
mp_uint_t tick = HAL_GetTick();
198209

199210
if (HAL_RTC_Init(&RTCHandle) != HAL_OK) {
200-
// init error
201-
rtc_info = 0xffff; // indicate error
202-
return;
211+
if (rtc_use_lse) {
212+
// fall back to LSI...
213+
rtc_use_lse = false;
214+
PWR->CR |= PWR_CR_DBP;
215+
RTCHandle.State = HAL_RTC_STATE_RESET;
216+
if (HAL_RTC_Init(&RTCHandle) != HAL_OK) {
217+
rtc_info = 0x0100ffff; // indicate error
218+
return;
219+
}
220+
} else {
221+
// init error
222+
rtc_info = 0xffff; // indicate error
223+
return;
224+
}
203225
}
204226

205227
// record how long it took for the RTC to start up
206228
rtc_info = HAL_GetTick() - tick;
207229

208-
HAL_RTC_GetDate(&RTCHandle, &date, FORMAT_BIN);
209-
if (date.Year == 0 && date.Month ==0 && date.Date == 0) {
210-
// fresh reset; configure RTC Calendar
211-
RTC_CalendarConfig();
212-
} else {
213-
// RTC was previously set, so leave it alone
214-
if(__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET) {
215-
// power on reset occurred
216-
rtc_info |= 0x10000;
217-
}
218-
if(__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET) {
219-
// external reset occurred
220-
rtc_info |= 0x20000;
221-
}
222-
// Clear source Reset Flag
223-
__HAL_RCC_CLEAR_RESET_FLAGS();
230+
// fresh reset; configure RTC Calendar
231+
RTC_CalendarConfig();
232+
233+
if(__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET) {
234+
// power on reset occurred
235+
rtc_info |= 0x10000;
236+
}
237+
if(__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET) {
238+
// external reset occurred
239+
rtc_info |= 0x20000;
224240
}
241+
// Clear source Reset Flag
242+
__HAL_RCC_CLEAR_RESET_FLAGS();
225243
}
226244

227245
STATIC void RTC_CalendarConfig(void) {
@@ -275,24 +293,24 @@ void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc) {
275293

276294
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
277295
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
278-
#if defined(MICROPY_HW_RTC_USE_LSE) && MICROPY_HW_RTC_USE_LSE
279-
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
280-
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
281-
#else
282-
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
283-
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
284-
#endif
296+
if (rtc_use_lse) {
297+
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
298+
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
299+
} else {
300+
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
301+
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
302+
}
285303
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
286304
//Error_Handler();
287305
return;
288306
}
289307

290308
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
291-
#if defined(MICROPY_HW_RTC_USE_LSE) && MICROPY_HW_RTC_USE_LSE
292-
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
293-
#else
294-
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
295-
#endif
309+
if (rtc_use_lse) {
310+
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
311+
} else {
312+
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
313+
}
296314
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
297315
//Error_Handler();
298316
return;

0 commit comments

Comments
 (0)
0