diff --git a/radio/src/targets/c14/hal.h b/radio/src/targets/c14/hal.h index 004f2aa0c..087bd2256 100644 --- a/radio/src/targets/c14/hal.h +++ b/radio/src/targets/c14/hal.h @@ -257,5 +257,3 @@ UART5: TELEMETRY_USART #define GT911_ROTATION_MODE 180 #define TOUCH_I2C_CLK_RATE 100000 - -#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH diff --git a/radio/src/targets/common/arm/stm32/rtc_driver.cpp b/radio/src/targets/common/arm/stm32/rtc_driver.cpp index ae9141c75..a1378c354 100644 --- a/radio/src/targets/common/arm/stm32/rtc_driver.cpp +++ b/radio/src/targets/common/arm/stm32/rtc_driver.cpp @@ -22,6 +22,13 @@ #include "stm32_hal.h" #include "rtc.h" +// LSEDRV resets to LOW, which is marginal for the crystals fitted on these +// boards. Override with -DLSE_DRIVE_STRENGTH if a board needs less. +#if !defined(LSE_DRIVE_STRENGTH) && \ + (defined(STM32H7) || defined(STM32H7RS) || defined(STM32H5)) + #define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH +#endif + RTC_HandleTypeDef rtc = {}; void rtcSetTime(const struct gtm * t) @@ -57,6 +64,36 @@ void rtcGetTime(struct gtm * t) t->tm_mday = RTC_DateStruct.Date; } +#if defined(LSE_DRIVE_STRENGTH) +// LSEDRV can only be written while the LSE is stopped, and it is kept in the +// backup domain, so only stop the oscillator when the drive is not already set. +static void rtcSetLSEDriveStrength() +{ + uint32_t drive = LSE_DRIVE_STRENGTH; + +#if defined(RCC_VER_X) + // rev.Y and below encode the two MEDIUM levels inverted + if ((drive == RCC_LSEDRIVE_MEDIUMLOW || drive == RCC_LSEDRIVE_MEDIUMHIGH) && + HAL_GetREVID() <= REV_ID_Y) { + drive = ~drive & RCC_BDCR_LSEDRV_Msk; + } +#endif + + if ((RCC->BDCR & RCC_BDCR_LSEDRV) == drive) return; + + RCC_OscInitTypeDef RCC_OscInitStruct = {}; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; +#if !defined(STM32H7RS) && !defined(STM32H5) + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; +#endif + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) return; + + MODIFY_REG(RCC->BDCR, RCC_BDCR_LSEDRV, drive); +} +#endif + void rtcInit() { rtc.Instance = RTC; @@ -73,8 +110,7 @@ void rtcInit() HAL_PWR_EnableBkUpAccess(); #if defined(LSE_DRIVE_STRENGTH) - __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF); - __HAL_RCC_LSEDRIVE_CONFIG(LSE_DRIVE_STRENGTH); + rtcSetLSEDriveStrength(); #endif // Enable LSE Oscillator @@ -90,10 +126,6 @@ void rtcInit() __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); } -#if defined(STM32H7) - __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_HIGH); -#endif - __HAL_RCC_RTC_ENABLE(); HAL_RTC_WaitForSynchro(&rtc); diff --git a/radio/src/targets/gx15/hal.h b/radio/src/targets/gx15/hal.h index ea19484da..396f745d6 100644 --- a/radio/src/targets/gx15/hal.h +++ b/radio/src/targets/gx15/hal.h @@ -327,6 +327,4 @@ TIM17: ROTARY_ENCODER_TIMER #define EXTI2_IRQ_Priority 9 #endif -#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH - #endif // _HAL_H_ diff --git a/radio/src/targets/h17/hal.h b/radio/src/targets/h17/hal.h index 84a49a2e4..f33db9ba9 100644 --- a/radio/src/targets/h17/hal.h +++ b/radio/src/targets/h17/hal.h @@ -298,6 +298,4 @@ TIM17: ROTARY_ENCODER_TIMER #define LANDSCAPE_LCD_STD true #define LANDSCAPE_LCD_LRG false -#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH - #endif // _HAL_H_ diff --git a/radio/src/targets/t15pro/hal.h b/radio/src/targets/t15pro/hal.h index 83be0e19c..7a46f9975 100644 --- a/radio/src/targets/t15pro/hal.h +++ b/radio/src/targets/t15pro/hal.h @@ -252,6 +252,4 @@ USART6: EXTMODULE_USART #define EXTI15_10_IRQ_Priority 9 #endif -#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH - #endif // _HAL_H_ diff --git a/radio/src/targets/t22/hal.h b/radio/src/targets/t22/hal.h index c1db554e3..cec61b2ab 100644 --- a/radio/src/targets/t22/hal.h +++ b/radio/src/targets/t22/hal.h @@ -263,6 +263,4 @@ TIM17: ROTARY_ENCODER_TIMER #define EXTI15_10_IRQ_Priority 9 #endif -#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH - -#endif // _HAL_H_ \ No newline at end of file +#endif // _HAL_H_ diff --git a/radio/src/targets/tx15/hal.h b/radio/src/targets/tx15/hal.h index 975608397..6b62fb5d3 100644 --- a/radio/src/targets/tx15/hal.h +++ b/radio/src/targets/tx15/hal.h @@ -349,6 +349,4 @@ SAI1_Block_A: PDM_CLOCK (1 MHz bit-clock output on SAI1_CK1 / PE5, !FLYSKY_GIMBA #define EXTI2_IRQ_Priority 9 #endif -#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH - #endif // _HAL_H_ diff --git a/radio/src/targets/tx16smk3/hal.h b/radio/src/targets/tx16smk3/hal.h index d0b17b872..6a3af2515 100644 --- a/radio/src/targets/tx16smk3/hal.h +++ b/radio/src/targets/tx16smk3/hal.h @@ -342,6 +342,4 @@ USART6: INTMODULE_USART #define EXTI2_IRQ_Priority 9 #endif -#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH - #endif // _HAL_H_ diff --git a/radio/src/targets/v12/hal.h b/radio/src/targets/v12/hal.h index 11a27c1c4..20152dda1 100644 --- a/radio/src/targets/v12/hal.h +++ b/radio/src/targets/v12/hal.h @@ -267,6 +267,4 @@ USART6: EXTMODULE_USART #define TRAINER_GPIO_AF LL_GPIO_AF_2 #define TRAINER_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) -#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH - #endif // _HAL_H_