diff options
Diffstat (limited to 'nuttx/arch/arm/src/stm32/stm32_rtcc.c')
-rw-r--r-- | nuttx/arch/arm/src/stm32/stm32_rtcc.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/nuttx/arch/arm/src/stm32/stm32_rtcc.c b/nuttx/arch/arm/src/stm32/stm32_rtcc.c index e9e71a007..6ba69e295 100644 --- a/nuttx/arch/arm/src/stm32/stm32_rtcc.c +++ b/nuttx/arch/arm/src/stm32/stm32_rtcc.c @@ -81,9 +81,7 @@ #define SYNCHRO_TIMEOUT (0x00020000) #define INITMODE_TIMEOUT (0x00010000) -#define RTC_MAGIC (0xfacefeed) -#define RTC_PREDIV_S (0xff) -#define RTC_PREDIV_A (0x7f) +#define RTC_MAGIC (0xfacefeee) /* Debug ****************************************************************************/ @@ -437,11 +435,30 @@ static int rtc_setup(void) uint32_t regval; int ret; - /* Enable the External Low-Speed (LSE) Oscillator setup the LSE as the RTC clock\ - * source, and enable the RTC. - */ + /* We might be changing RTCSEL - to ensure such changes work, we must reset the backup domain */ + modifyreg32(STM32_RCC_BDCR, 0, RCC_BDCR_BDRST); + modifyreg32(STM32_RCC_BDCR, RCC_BDCR_BDRST, 0); + +/* Some boards do not have the external 32khz oscillator installed, for those boards we must fallback to the crummy + * internal RC clock or the external high rate clock + */ +#ifdef CONFIG_RTC_HSECLOCK + /* Use the HSE clock as the input to the RTC block */ + modifyreg32(STM32_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_HSE); + + /* Enable the RTC Clock by setting the RTCEN bit in the RCC BDCR register */ + modifyreg32(STM32_RCC_BDCR, 0, RCC_BDCR_RTCEN); +#elif defined(CONFIG_RTC_LSICLOCK) + stm32_rcc_enablelsi(); + + /* Use the LSI clock as the input to the RTC block */ + modifyreg32(STM32_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSI); + /* Enable the RTC Clock by setting the RTCEN bit in the RCC BDCR register */ + modifyreg32(STM32_RCC_BDCR, 0, RCC_BDCR_RTCEN); +#else stm32_rcc_enablelse(); +#endif /* Wait for the RTC Time and Date registers to be synchronized with RTC APB * clock. @@ -467,13 +484,19 @@ static int rtc_setup(void) regval &= ~RTC_CR_FMT; putreg32(regval, STM32_RTC_CR); - /* Configure RTC pre-scaler to the required, default values for - * use with the 32.768 KHz LSE clock: - */ + /* Configure RTC pre-scaler with the required values */ +#ifdef CONFIG_RTC_HSECLOCK + /* For a 1 MHz clock this yields 0.9999360041 Hz on the second timer - which is pretty close */ + putreg32(((uint32_t)7182 << RTC_PRER_PREDIV_S_SHIFT) | + ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), + STM32_RTC_PRER); +#else + /* Correct values for 1 32.768 KHz LSE clock */ putreg32(((uint32_t)0xff << RTC_PRER_PREDIV_S_SHIFT) | ((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT), STM32_RTC_PRER); +#endif /* Exit RTC initialization mode */ @@ -576,8 +599,6 @@ int up_rtcinitialize(void) uint32_t regval; int ret; - rtc_dumpregs("On reset"); - /* Clocking for the PWR block must be provided. However, this is done * unconditionally in stm32f40xxx_rcc.c on power up. This done unconditionally * because the PWR block is also needed to set the internal voltage regulator for @@ -590,11 +611,16 @@ int up_rtcinitialize(void) stm32_pwr_enablebkp(); - /* Check if the one-time initialization of the RTC has already been performed. + rtc_dumpregs("On reset"); + + /* Enable the External Low-Speed (LSE) Oscillator setup the LSE as the RTC clock\ + * source, and enable the RTC. + */ + + /* Check if the one-time initialization of the RTC has already been perfomagrmed. * We can determine this by checking if the magic number has been writing to * to back-up date register DR0. */ - regval = getreg32(STM32_RTC_BK0R); if (regval != RTC_MAGIC) { @@ -611,6 +637,8 @@ int up_rtcinitialize(void) /* RTC already set-up, just resume normal operation */ ret = rtc_resume(); + + rtc_dumpregs("Did resume"); } /* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts are |