Commit 8f7ff854 authored by T S's avatar T S Committed by Damien George
Browse files

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.
parent 8bfa11b1
...@@ -160,9 +160,14 @@ void rtc_init(void) { ...@@ -160,9 +160,14 @@ void rtc_init(void) {
STATIC void RTC_CalendarConfig(void); STATIC void RTC_CalendarConfig(void);
#if defined(MICROPY_HW_RTC_USE_LSE) && MICROPY_HW_RTC_USE_LSE
STATIC bool rtc_use_lse = true;
#else
STATIC bool rtc_use_lse = false;
#endif
void rtc_init(void) { void rtc_init(void) {
RTCHandle.Instance = RTC; RTCHandle.Instance = RTC;
RTC_DateTypeDef date;
/* Configure RTC prescaler and RTC data registers */ /* Configure RTC prescaler and RTC data registers */
/* RTC configured as follow: /* RTC configured as follow:
...@@ -179,38 +184,52 @@ void rtc_init(void) { ...@@ -179,38 +184,52 @@ void rtc_init(void) {
RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
// if LTE enabled & ready --> no need to (re-)init RTC
if ((RCC->BDCR & (RCC_BDCR_LSEON | RCC_BDCR_LSERDY)) == (RCC_BDCR_LSEON | RCC_BDCR_LSERDY)) { if ((RCC->BDCR & (RCC_BDCR_LSEON | RCC_BDCR_LSERDY)) == (RCC_BDCR_LSEON | RCC_BDCR_LSERDY)) {
// LSE is enabled & ready --> no need to (re-)init RTC
// remove Backup Domain write protection // remove Backup Domain write protection
#if defined(MCU_SERIES_F7) HAL_PWR_EnableBkUpAccess();
PWR->CR1 |= PWR_CR1_DBP;
#else
PWR->CR |= PWR_CR_DBP;
#endif
// Clear source Reset Flag // Clear source Reset Flag
__HAL_RCC_CLEAR_RESET_FLAGS(); __HAL_RCC_CLEAR_RESET_FLAGS();
// provide some status information // provide some status information
rtc_info |= 0x40000 | (RCC->BDCR & 7) | (RCC->CSR & 3) << 8; rtc_info |= 0x40000 | (RCC->BDCR & 7) | (RCC->CSR & 3) << 8;
return; return;
} else if ((RCC->BDCR & RCC_BDCR_RTCSEL) == RCC_BDCR_RTCSEL_1) {
// LSI is already active
// remove Backup Domain write protection
HAL_PWR_EnableBkUpAccess();
// Clear source Reset Flag
__HAL_RCC_CLEAR_RESET_FLAGS();
RCC->CSR |= 1;
// provide some status information
rtc_info |= 0x80000 | (RCC->BDCR & 7) | (RCC->CSR & 3) << 8;
return;
} }
mp_uint_t tick = HAL_GetTick(); mp_uint_t tick = HAL_GetTick();
if (HAL_RTC_Init(&RTCHandle) != HAL_OK) { if (HAL_RTC_Init(&RTCHandle) != HAL_OK) {
if (rtc_use_lse) {
// fall back to LSI...
rtc_use_lse = false;
PWR->CR |= PWR_CR_DBP;
RTCHandle.State = HAL_RTC_STATE_RESET;
if (HAL_RTC_Init(&RTCHandle) != HAL_OK) {
rtc_info = 0x0100ffff; // indicate error
return;
}
} else {
// init error // init error
rtc_info = 0xffff; // indicate error rtc_info = 0xffff; // indicate error
return; return;
} }
}
// record how long it took for the RTC to start up // record how long it took for the RTC to start up
rtc_info = HAL_GetTick() - tick; rtc_info = HAL_GetTick() - tick;
HAL_RTC_GetDate(&RTCHandle, &date, FORMAT_BIN);
if (date.Year == 0 && date.Month ==0 && date.Date == 0) {
// fresh reset; configure RTC Calendar // fresh reset; configure RTC Calendar
RTC_CalendarConfig(); RTC_CalendarConfig();
} else {
// RTC was previously set, so leave it alone
if(__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET) { if(__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET) {
// power on reset occurred // power on reset occurred
rtc_info |= 0x10000; rtc_info |= 0x10000;
...@@ -221,7 +240,6 @@ void rtc_init(void) { ...@@ -221,7 +240,6 @@ void rtc_init(void) {
} }
// Clear source Reset Flag // Clear source Reset Flag
__HAL_RCC_CLEAR_RESET_FLAGS(); __HAL_RCC_CLEAR_RESET_FLAGS();
}
} }
STATIC void RTC_CalendarConfig(void) { STATIC void RTC_CalendarConfig(void) {
...@@ -275,24 +293,24 @@ void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc) { ...@@ -275,24 +293,24 @@ void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc) {
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
#if defined(MICROPY_HW_RTC_USE_LSE) && MICROPY_HW_RTC_USE_LSE if (rtc_use_lse) {
RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.LSIState = RCC_LSI_OFF; RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
#else } else {
RCC_OscInitStruct.LSEState = RCC_LSE_OFF; RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.LSIState = RCC_LSI_ON;
#endif }
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
//Error_Handler(); //Error_Handler();
return; return;
} }
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
#if defined(MICROPY_HW_RTC_USE_LSE) && MICROPY_HW_RTC_USE_LSE if (rtc_use_lse) {
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
#else } else {
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
#endif }
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
//Error_Handler(); //Error_Handler();
return; return;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment