From 9a52743e90152091c6cf1eabeee839c93948864c Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 11 Dec 2011 20:05:55 +0000 Subject: RTC. Setting and getting time works on STM32F4x git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/rtc_dev@3596 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32F4xx/hal_lld.h | 1 + os/hal/platforms/STM32F4xx/rtc_lld.c | 67 +++++++++++++++++++++++------------- os/hal/platforms/STM32F4xx/rtc_lld.h | 17 ++++++--- 3 files changed, 57 insertions(+), 28 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 40064787c..496c4304f 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -320,6 +320,7 @@ /* RTC attributes.*/ #define STM32_HAS_RTC TRUE +#define RTC_HAS_SUBSECONDS TRUE /* SDIO attributes.*/ #define STM32_HAS_SDIO TRUE diff --git a/os/hal/platforms/STM32F4xx/rtc_lld.c b/os/hal/platforms/STM32F4xx/rtc_lld.c index da7f73890..cdf3aff81 100644 --- a/os/hal/platforms/STM32F4xx/rtc_lld.c +++ b/os/hal/platforms/STM32F4xx/rtc_lld.c @@ -31,6 +31,24 @@ #if HAL_USE_RTC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Notes. */ +/*===========================================================================*/ +/* +This structure is used to hold the values representing a calendar time. +It contains the following members, with the meanings as shown. + +int tm_sec // seconds after minute [0-61] (61 allows for 2 leap-seconds) +int tm_min // minutes after hour [0-59] +int tm_hour // hours after midnight [0-23] +int tm_mday // day of the month [1-31] +int tm_mon // month of year [0-11] +int tm_year // current year-1900 +int tm_wday // days since Sunday [0-6] +int tm_yday // days since January 1st [0-365] +int tm_isdst // daylight savings indicator (1 = yes, 0 = no, -1 = unknown) +*/ + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -65,7 +83,11 @@ RTCDriver RTCD1; * @notapi */ void rtc_lld_init(void){ - uint32_t preload; + /* Asynchronous part of preloader. Set it to maximum value. */ + #define PREDIV_A ((uint32_t)0x7F) + + /* Add async part to preload value. */ + uint32_t preload = PREDIV_A << 16; /* Enables access to BKP registers.*/ PWR->CR |= PWR_CR_DBP; @@ -77,35 +99,35 @@ void rtc_lld_init(void){ } #if STM32_RTC == STM32_RTC_LSE + #define RTC_CLK STM32_LSECLK if (!(RCC->BDCR & RCC_BDCR_LSEON)) { RCC->BDCR |= RCC_BDCR_LSEON; while (!(RCC->BDCR & RCC_BDCR_LSERDY)) ; } - preload = STM32_LSECLK - 1; + #elif STM32_RTC == STM32_RTC_LSI + #define RTC_CLK STM32_LSICLK /* TODO: Move the LSI clock initialization in the HAL low level driver.*/ RCC->CSR |= RCC_CSR_LSION; while (!(RCC->CSR & RCC_CSR_LSIRDY)) ; - /* According to errata sheet we must wait additional 100 uS for - stabilization. - TODO: Change this code, software loops are not reliable.*/ - uint32_t tmo = (STM32_SYSCLK / 1000000) * 100; - while (tmo--) - ; - preload = STM32_LSICLK - 1; + #elif STM32_RTC == STM32_RTC_HSE - preload = (STM32_HSICLK / 128) - 1; + #define RTC_CLK (STM32_HSICLK / 31) #endif + /* Add sync part to preload value. */ + preload |= ((RTC_CLK / (PREDIV_A + 1)) - 1) & 0x7FFF; + /* Selects clock source (previously enabled and stabilized).*/ RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | STM32_RTC; /* RTC enabled regardless its previous status.*/ RCC->BDCR |= RCC_BDCR_RTCEN; - if (!(RTC->ISR & RTC_ISR_INITS)){/* Calendar not init yet. */ + /* If calendar not init yet. */ + if (!(RTC->ISR & RTC_ISR_INITS)){ /* Disable write protection on RTC registers. */ RTC->WPR = 0xCA; RTC->WPR = 0x53; @@ -115,13 +137,9 @@ void rtc_lld_init(void){ while(!(RTC->ISR & RTC_ISR_INITF)) ; /* Prescaler registers must be written in by two separate writes. */ - RTC->PRER = 0x007F00FF; - RTC->PRER = 0x007F00FF; + RTC->PRER = preload; + RTC->PRER = preload; RTC->ISR &= ~RTC_ISR_INIT; - - /* Wait until calendar data will updated. */ - while(!(RTC->ISR & RTC_ISR_RSF)) - ; } /* Callback initially disabled.*/ @@ -147,10 +165,6 @@ void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec) { RTC->TR = timespec->tv_time; RTC->DR = timespec->tv_date; RTC->ISR &= ~RTC_ISR_INIT; - - /* Wait until calendar data will updated. */ - while(!(RTC->ISR & RTC_ISR_RSF)) - ; } /** @@ -168,13 +182,19 @@ void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec) { * the frequency of RTCCLK, BYPSHAD must be set to ‘1’ .*/ /* Wait until calendar data will updated. */ - while(!(RTC->ISR & RTC_ISR_RSF)) - ; + while(!(RTC->ISR & RTC_ISR_RSF)) + ; timespec->tv_time = RTC->TR; timespec->tv_date = RTC->DR; +#if RTC_HAS_SUBSECONDS + timespec->tv_msec = ((RTC->PRER & 0x7FFF) - RTC->SSR) / ((RTC->PRER & 0x7FFF) + 1); +#else + timespec->tv_msec = 0; +#endif /* STM32_RTC_HAS_SUBSECONDS */ } + /** * @brief Set alarm time. * @@ -189,7 +209,6 @@ void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec) { void rtc_lld_set_alarm(RTCDriver *rtcp, rtcalarm_t alarm, const RTCAlarm *alarmspec) { - (void)rtcp; (void)alarm; (void)alarmspec; diff --git a/os/hal/platforms/STM32F4xx/rtc_lld.h b/os/hal/platforms/STM32F4xx/rtc_lld.h index 529215483..dd5a4160e 100644 --- a/os/hal/platforms/STM32F4xx/rtc_lld.h +++ b/os/hal/platforms/STM32F4xx/rtc_lld.h @@ -41,7 +41,7 @@ #define RTC_SUPPORTS_CALLBACKS TRUE /** - * @brief One alarm comparator available. + * @brief Two alarm comparators available on STM32F4x. */ #define RTC_ALARMS 2 @@ -62,6 +62,10 @@ #error "invalid source selected for RTC clock" #endif +#if RTC_SUPPORTS_CALLBACKS && !(HAL_USE_EXT) +#error "interrupts from STM32 RTC works only through EXTI" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -97,13 +101,18 @@ typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); */ struct RTCTime { /** - * @brief RTC date register in BCD format. + * @brief RTC date register in STM32 BCD format. */ uint32_t tv_date; /** - * @brief RTC time register in BCD format. + * @brief RTC time register in STM32 BCD format. */ uint32_t tv_time; + /** + * @brief Fractional part of time. + * @note If platform does not support subseconds than always zero. + */ + uint16_t tv_msec; }; @@ -112,7 +121,7 @@ struct RTCTime { */ struct RTCAlarm { /** - * @brief Date and time of alarm in BCD. + * @brief Date and time of alarm in STM32 BCD. */ uint32_t tv_datetime; }; -- cgit v1.2.3