diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h index 1264c5bd8..ddb495205 100644 --- a/os/hal/include/rtc.h +++ b/os/hal/include/rtc.h @@ -85,15 +85,18 @@ extern "C" { void rtcInit(void); void rtcSetTime(RTCDriver *rtcp, const RTCTime *timespec); void rtcGetTime(RTCDriver *rtcp, RTCTime *timespec); + #if RTC_ALARMS > 0 void rtcSetAlarm(RTCDriver *rtcp, rtcalarm_t alarm, const RTCAlarm *alarmspec); void rtcGetAlarm(RTCDriver *rtcp, rtcalarm_t alarm, RTCAlarm *alarmspec); -#endif +#endif /* RTC_ALARMS > 0 */ + #if RTC_SUPPORTS_CALLBACKS - void rtcSetCallback(RTCDriver *rtcp, rtccb_t callback); -#endif + void rtcSetCallback(RTCDriver *rtcp, RTCCallbackConfig *cb_cfg); +#endif /* RTC_SUPPORTS_CALLBACKS */ + #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.c b/os/hal/platforms/STM32/RTCv1/rtc_lld.c index 1a6c85d8b..1330e106e 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.c @@ -280,8 +280,8 @@ void rtc_lld_set_alarm(RTCDriver *rtcp, * * @note Default value after BKP domain reset is 0xFFFFFFFF. * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] alarm alarm identifier + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier * @param[out] alarmspec pointer to a @p RTCAlarm structure * * @notapi diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h index e3ce0e365..6e682db61 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -20,7 +20,7 @@ /** * @file STM32/RTCv1/rtc_lld.h - * @brief STM32 RTC subsystem low level driver header. + * @brief STM32F1xx RTC subsystem low level driver header. * * @addtogroup RTC * @{ @@ -67,12 +67,18 @@ /*===========================================================================*/ /** - * @brief Type of a structure representing an RTC alarm stamp. + * @brief Type of a structure representing an RTC alarm time stamp. */ typedef struct RTCAlarm RTCAlarm; +/** + * @brief Type of a structure representing an RTC callbacks config. + */ +typedef struct RTCCallbackConfig RTCCallbackConfig; + /** * @brief Type of an RTC alarm. + * @details Meaningful on platforms with more than 1 alarm comparator. */ typedef uint32_t rtcalarm_t; @@ -90,6 +96,18 @@ typedef enum { */ typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); +/** + * @brief Structure representing an RTC callbacks config. + */ +struct RTCCallbackConfig{ +#if RTC_SUPPORTS_CALLBACKS + /** + * @brief Generic RTC callback pointer. + */ + rtccb_t rtc_cb; +#endif /* RTC_SUPPORTS_CALLBACKS */ +}; + /** * @brief Structure representing an RTC time stamp. */ @@ -105,7 +123,7 @@ struct RTCTime { }; /** - * @brief Structure representing an RTC alarm specification. + * @brief Structure representing an RTC alarm time stamp. */ struct RTCAlarm { /** diff --git a/os/hal/platforms/STM32/RTCv2/rtc_lld.c b/os/hal/platforms/STM32/RTCv2/rtc_lld.c new file mode 100644 index 000000000..f549dc62d --- /dev/null +++ b/os/hal/platforms/STM32/RTCv2/rtc_lld.c @@ -0,0 +1,367 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/RTCv2/rtc_lld.c + * @brief STM32L1xx/STM32F2xx/STM32F4xx RTC low level driver header. + * + * @addtogroup RTC + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#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. */ +/*===========================================================================*/ + +/** + * @brief RTC driver identifier. + */ +RTCDriver RTCD1; + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Enable access to registers and initialize RTC if BKP domain + * was previously reseted. + * @note: Cold start time of LSE oscillator on STM32 platform + * takes about 3 seconds. + * + * @notapi + */ +void rtc_lld_init(void){ + RTCD1.id_rtc = RTC; + + /* Asynchronous part of preloader. Set it to maximum value. */ + #define PREDIV_A ((uint32_t)0x7F) + + /* Add async part to preload value. */ + volatile uint32_t preload = PREDIV_A << 16; + + /* Enables access to BKP registers.*/ + PWR->CR |= PWR_CR_DBP; + + /* If the RTC is not enabled then performs a reset of the backup domain.*/ + if (!(RCC->BDCR & RCC_BDCR_RTCEN)) { + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + +#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)) + ; + } + +#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)) + ; + +#elif STM32_RTC == STM32_RTC_HSE + #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; + + /* Disable write protection on RTC registers. */ + RTCD1.id_rtc->WPR = 0xCA; + RTCD1.id_rtc->WPR = 0x53; + + /* If calendar not init yet. */ + if (!(RTC->ISR & RTC_ISR_INITS)){ + /* Enter in init mode. */ + RTCD1.id_rtc->ISR |= RTC_ISR_INIT; + while(!(RTC->ISR & RTC_ISR_INITF)) + ; + /* Prescaler registers must be written in by two separate writes. */ + RTCD1.id_rtc->PRER = preload; + RTCD1.id_rtc->PRER = preload; + RTCD1.id_rtc->ISR &= ~RTC_ISR_INIT; + } +} + + +/** + * @brief Set current time. + * @note Fractional part will be silently ignored. There is no possibility + * to change it on STM32F1xx platform. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] timespec pointer to a @p RTCTime structure + * + * @notapi + */ +void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec) { + (void)rtcp; + + RTCD1.id_rtc->ISR |= RTC_ISR_INIT; + while(!(RTC->ISR & RTC_ISR_INITF)) + ; + RTCD1.id_rtc->TR = timespec->tv_time; + RTCD1.id_rtc->DR = timespec->tv_date; + RTCD1.id_rtc->ISR &= ~RTC_ISR_INIT; +} + +/** + * @brief Get current time. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] timespec pointer to a @p RTCTime structure + * + * @notapi + */ +void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec) { + (void)rtcp; + + /* TODO: If the frequency of the APB1 clock is less than seven times + * the frequency of RTCCLK, BYPSHAD must be set to ‘1’ .*/ + + /* Wait until calendar data will updated. */ + while(!(RTC->ISR & RTC_ISR_RSF)) + ; + + timespec->tv_time = RTCD1.id_rtc->TR; + timespec->tv_date = RTCD1.id_rtc->DR; +#if RTC_HAS_SUBSECONDS + timespec->tv_msec = ((RTCD1.id_rtc->PRER & 0x7FFF) - RTCD1.id_rtc->SSR) / + ((RTCD1.id_rtc->PRER & 0x7FFF) + 1); +#else + timespec->tv_msec = 0; +#endif /* STM32_RTC_HAS_SUBSECONDS */ +} + +/** + * @brief Set alarm time. + * + * @note Default value after BKP domain reset for both comparators is 0. + * @note Function does not performs any checks of alarm time validity. + * + * @param[in] rtcp Pointer to RTC driver structure. + * @param[in] alarm Alarm identifier. Can be 1 or 2. + * @param[in] alarmspec Pointer to a @p RTCAlarm structure. + * + * @notapi + */ +void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec) { + if (alarm == 1){ + rtcp->id_rtc->CR &= ~RTC_CR_ALRAE; + while(!(rtcp->id_rtc->ISR & RTC_ISR_ALRAWF)) + ; + rtcp->id_rtc->ALRMAR = alarmspec->tv_datetime; + rtcp->id_rtc->CR |= RTC_CR_ALRAE; + } + else{ + rtcp->id_rtc->CR &= ~RTC_CR_ALRBE; + while(!(rtcp->id_rtc->ISR & RTC_ISR_ALRBWF)) + ; + rtcp->id_rtc->ALRMAR = alarmspec->tv_datetime; + rtcp->id_rtc->CR |= RTC_CR_ALRBE; + } +} + +/** + * @brief Get alarm time. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier + * @param[out] alarmspec pointer to a @p RTCAlarm structure + * + * @notapi + */ +void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + RTCAlarm *alarmspec) { + if (alarm == 1) + alarmspec->tv_datetime = rtcp->id_rtc->ALRMAR; + else + alarmspec->tv_datetime = rtcp->id_rtc->ALRMBR; +} + +/** + * @brief Sets time of periodic wakeup. + * + * @note Default value after BKP domain reset is 0x0000FFFF + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] wakeupspec pointer to a @p RTCWakeup structure + * + * @notapi + */ +void rtc_lld_set_periodic_wakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec){ + chDbgCheck((wakeupspec->wakeup != 0x30000), + "rtc_lld_set_periodic_wakeup, forbidden combination"); + + rtcp->id_rtc->CR &= ~RTC_CR_WUTE; + while(!(rtcp->id_rtc->ISR & RTC_ISR_WUTWF)) + ; + rtcp->id_rtc->WUTR = wakeupspec->wakeup & 0xFFFF; + rtcp->id_rtc->CR = (wakeupspec->wakeup >> 16) & 0x7; + rtcp->id_rtc->CR |= RTC_CR_WUTE; +} + +/** + * @brief Gets time of periodic wakeup. + * + * @note Default value after BKP domain reset is 0x0000FFFF + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] wakeupspec pointer to a @p RTCWakeup structure + * + * @notapi + */ +void rtc_lld_get_periodic_wakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec){ + wakeupspec->wakeup = 0; + wakeupspec->wakeup |= rtcp->id_rtc->WUTR; + wakeupspec->wakeup |= (((uint32_t)rtcp->id_rtc->CR) & 0x7) << 16; +} + + +#if RTC_SUPPORTS_CALLBACKS + +static const EXTConfig rtc_extcfg = { + { + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_RISING_EDGE, NULL}, //17, RTC alarm + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_DISABLED, NULL}, + {EXT_CH_MODE_RISING_EDGE, NULL}, //21 RTC tamper + {EXT_CH_MODE_RISING_EDGE, NULL} //22 RTC wakeup + }, + EXT_MODE_EXTI(0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0) +}; + + + +/** + * @brief Enables or disables RTC callbacks. + * @details TODO: + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] cb_cfg pointer to configuration structure with callbacks + * + * @notapi + */ +void rtc_lld_set_callback(RTCDriver *rtcp, RTCCallbackConfig *cb_cfg) { + + /* To configure callback we must confugure EXTI interrupt on + * corresponding line. + * And then enable interrupts in RTC CR register. */ + + if (cb_cfg->alarm_cb != NULL){ + rtc_extcfg.channels[STM32_RTC_ALARM_EXTI_CH].cb = cb_cfg->alarm_cb; + rtcp->id_rtc->CR |= RTC_CR_ALRBIE; + rtcp->id_rtc->CR |= RTC_CR_ALRAIE; + } + else{ + extChannelDisable(&EXTD1, STM32_RTC_ALARM_EXTI_CH); + } + + if (cb_cfg->tamper_timestapm_cb != NULL){ + rtc_extcfg.channels[STM32_RTC_TAMPER_TIMESTAMP_EXTI_CH].cb = cb_cfg->tamper_timestapm_cb; + rtcp->id_rtc->CR |= RTC_CR_TSIE; + } + else{ + extChannelDisable(&EXTD1, STM32_RTC_TAMPER_TIMESTAMP_EXTI_CH); + } + + if (cb_cfg->wakeup_cb != NULL){ + rtc_extcfg.channels[STM32_RTC_WAKEUP_EXTI_CH].cb = cb_cfg->wakeup_cb; + rtcp->id_rtc->CR |= RTC_CR_WUTIE; + } + else{ + extChannelDisable(&EXTD1, STM32_RTC_WAKEUP_EXTI_CH); + } + + extStart(&EXTD1, &rtc_extcfg); +} +#endif /* RTC_SUPPORTS_CALLBACKS */ + +#endif /* HAL_USE_RTC */ + +/** @} */ diff --git a/os/hal/platforms/STM32/RTCv2/rtc_lld.h b/os/hal/platforms/STM32/RTCv2/rtc_lld.h new file mode 100644 index 000000000..3780945c4 --- /dev/null +++ b/os/hal/platforms/STM32/RTCv2/rtc_lld.h @@ -0,0 +1,231 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/RTCv2/rtc_lld.h + * @brief STM32L1xx/STM32F2xx/STM32F4xx RTC low level driver header. + * + * @addtogroup RTC + * @{ + */ + +#ifndef _RTC_LLD_H_ +#define _RTC_LLD_H_ + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief This RTC implementation supports callbacks. + */ +#if !defined(RTC_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__) +#define RTC_SUPPORTS_CALLBACKS FALSE +#endif + +/** + * @brief Two alarm comparators available on STM32F4x. + */ +#define RTC_ALARMS 2 + +/** + * @brief EXTI channel numbers for different RTC events. + */ +#define STM32_RTC_ALARM_EXTI_CH 17 +#define STM32_RTC_TAMPER_TIMESTAMP_EXTI_CH 21 +#define STM32_RTC_WAKEUP_EXTI_CH 22 + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if HAL_USE_RTC && !STM32_HAS_RTC +#error "RTC not present in the selected device" +#endif + +#if !(STM32_RTC == STM32_RTC_LSE) && !(STM32_RTC == STM32_RTC_LSI) && \ + !(STM32_RTC == STM32_RTC_HSE) +#error "invalid source selected for RTC clock" +#endif + +#if RTC_SUPPORTS_CALLBACKS && !(HAL_USE_EXT) +#error "interrupts from RTC works only through EXTI on this platform" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a structure representing an RTC alarm time stamp. + */ +typedef struct RTCAlarm RTCAlarm; + +/** + * @brief Type of a structure representing an RTC wakeup period. + */ +typedef struct RTCWakeup RTCWakeup; + +/** + * @brief Type of a structure representing an RTC callbacks config. + */ +typedef struct RTCCallbackConfig RTCCallbackConfig; + +/** + * @brief Type of an RTC alarm. + * @details Meaningful on platforms with more than 1 alarm comparator. + */ +typedef uint32_t rtcalarm_t; + +/** + * @brief Type of an RTC event. + */ +typedef enum { + RTC_EVENT_WAKEUP = 0, /** Triggered every wakeup event. */ + RTC_EVENT_ALARM_A = 1, /** Triggered on alarm A. */ + RTC_EVENT_ALARM_B = 2, /** Triggered on alarm B. */ + RTC_EVENT_TAMPER = 3, /** Triggered on Tamper event. */ + RTC_EVENT_TIMESTAMP = 4, /** Triggered on TimeStamp event. */ +} rtcevent_t; + +/** + * @brief Type of a generic RTC callback. + */ +typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); + +/** + * @brief Structure representing an RTC time stamp. + */ +struct RTCTime { + /** + * @brief RTC date register in STM32 BCD format. + */ + uint32_t tv_date; + /** + * @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. + */ + uint32_t tv_msec; +}; + +/** + * @brief Structure representing an RTC alarm time stamp. + */ +struct RTCAlarm { + /** + * @brief Date and time of alarm in STM32 BCD. + */ + uint32_t tv_datetime; +}; + +/** + * @brief Structure representing an RTC periodic wakeup period. + */ +struct RTCWakeup { + /** + * @brief RTC WUTR register. + * @details Bits [15:0] contain value of WUTR register + * Bits [18:16] contain value of WUCKSEL bits in CR register + * + * @notes ((WUTR == 0) || (WUCKSEL == 3)) is forbidden combination. + */ + uint32_t wakeup; +}; + +/** + * @brief Structure representing an RTC callbacks config. + */ +struct RTCCallbackConfig{ +#if RTC_SUPPORTS_CALLBACKS + /** + * @brief Alarm callback pointer. + */ + rtccb_t alarm_cb; + /** + * @brief Tamper or TimeStamp callback pointer. + */ + rtccb_t tamper_timestapm_cb; + /** + * @brief Periodic wakeup callback pointer. + */ + rtccb_t wakeup_cb; +#endif /* RTC_SUPPORTS_CALLBACKS */ +}; + +/** + * @brief Structure representing an RTC driver. + */ +struct RTCDriver{ + /** + * @brief Pointer to the RTC registers block. + */ + RTC_TypeDef *id_rtc; + /** + * @brief Current configuration data. + */ + const RTCCallbackConfig *cb_config; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern RTCDriver RTCD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void rtc_lld_init(void); + void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec); + void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec); + void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec); + void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + RTCAlarm *alarmspec); + void rtc_lld_set_periodic_wakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec); + void rtc_lld_get_periodic_wakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec); + void rtc_lld_set_callback(RTCDriver *rtcp, RTCCallbackConfig *cb_cfg); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_RTC */ + +#endif /* _RTC_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 16bb84cbf..1e34f9728 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -182,6 +182,7 @@ #define STM32_SPI3_TX_DMA_CHN 0x00000000 #define STM32_HAS_RTC TRUE +#define STM32_RTC_HAS_SUBSECONDS TRUE /* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index 108854ff7..77672ad01 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -193,6 +193,7 @@ /* RTC attributes.*/ #define STM32_HAS_RTC TRUE +#define STM32_RTC_HAS_SUBSECONDS TRUE /* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index 9a612b0ee..60c3b421a 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -185,6 +185,7 @@ /* RTC attributes.*/ #define STM32_HAS_RTC TRUE +#define STM32_RTC_HAS_SUBSECONDS TRUE /* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE diff --git a/os/hal/platforms/STM32F2xx/hal_lld.h b/os/hal/platforms/STM32F2xx/hal_lld.h index cad926330..43a4a5c27 100644 --- a/os/hal/platforms/STM32F2xx/hal_lld.h +++ b/os/hal/platforms/STM32F2xx/hal_lld.h @@ -180,6 +180,7 @@ #define STM32_I2C3_TX_DMA_CHN 0x00030000 #define STM32_HAS_RTC TRUE +#define STM32_RTC_HAS_SUBSECONDS FALSE #define STM32_HAS_SDIO TRUE diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index 1bb69958e..1aeed4755 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -218,6 +218,12 @@ #define STM32_MCO2SEL_HSE (2U << 30) /**< HSE clock on MCO2 pin. */ #define STM32_MCO2SEL_PLL (3U << 30) /**< PLL clock on MCO2 pin. */ +#define STM32_RTC_NOCLOCK (0 << 8) /**< No clock. */ +#define STM32_RTC_LSE (1 << 8) /**< LSE used as RTC clock. */ +#define STM32_RTC_LSI (2 << 8) /**< LSI used as RTC clock. */ +#define STM32_RTC_HSE (3 << 8) /**< HSE divided by programmable + prescaler used as RTC clock*/ + /** * @name RCC_PLLI2SCFGR register bits definitions * @{ @@ -314,6 +320,7 @@ /* RTC attributes.*/ #define STM32_HAS_RTC TRUE +#define STM32_RTC_HAS_SUBSECONDS TRUE /* SDIO attributes.*/ #define STM32_HAS_SDIO TRUE @@ -418,8 +425,9 @@ #define WWDG_IRQHandler Vector40 /**< Window Watchdog. */ #define PVD_IRQHandler Vector44 /**< PVD through EXTI Line detect. */ -#define TAMPER_IRQHandler Vector48 /**< Tamper. */ -#define RTC_IRQHandler Vector4C /**< RTC. */ +#define TAMP_STAMP_IRQHandler Vector48 /**< Tamper and TimeStamp + through EXTI Line. */ +#define RTC_WKUP_IRQHandler Vector4C /**< RTC wakeup EXTI Line. */ #define FLASH_IRQHandler Vector50 /**< Flash. */ #define RCC_IRQHandler Vector54 /**< RCC. */ #define EXTI0_IRQHandler Vector58 /**< EXTI Line 0. */ @@ -458,8 +466,8 @@ #define USART2_IRQHandler VectorD8 /**< USART2. */ #define USART3_IRQHandler VectorDC /**< USART3. */ #define EXTI15_10_IRQHandler VectorE0 /**< EXTI Line 15..10. */ -#define RTC_Alarm_IRQHandler VectorE4 /**< RTC alarm through EXTI - line. */ +#define RTC_Alarm_IRQHandler VectorE4 /**< RTC alarms (A and B) + through EXTI line. */ #define OTG_FS_WKUP_IRQHandler VectorE8 /**< USB OTG FS Wakeup through EXTI line. */ #define TIM8_BRK_IRQHandler VectorEC /**< TIM8 Break. */ diff --git a/os/hal/platforms/STM32F4xx/platform.mk b/os/hal/platforms/STM32F4xx/platform.mk index 449b40731..5f6f4f32f 100644 --- a/os/hal/platforms/STM32F4xx/platform.mk +++ b/os/hal/platforms/STM32F4xx/platform.mk @@ -10,9 +10,13 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F4xx/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/i2c_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c + ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/RTCv2/rtc_lld.c \ # Required include directories PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F4xx \ ${CHIBIOS}/os/hal/platforms/STM32 \ - ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 + ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 \ + ${CHIBIOS}/os/hal/platforms/STM32/RTCv2 \ + + diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 8d6cfd6f0..fce1a80f6 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -217,6 +217,7 @@ /* RTC attributes.*/ #define STM32_HAS_RTC TRUE +#define STM32_RTC_HAS_SUBSECONDS FALSE /* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index dda5a9c95..52e35fd22 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -117,8 +117,8 @@ void rtcSetAlarm(RTCDriver *rtcp, * @note If an alarm has not been set then the returned alarm specification * is not meaningful. * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] alarm alarm identifier + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier * @param[out] alarmspec pointer to a @p RTCAlarm structure * * @api @@ -134,25 +134,49 @@ void rtcGetAlarm(RTCDriver *rtcp, } #endif /* RTC_ALARMS > 0 */ +/** + * @brief Sets periodic wakeup period. + */ +void rtcSetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) { + chDbgCheck((rtcp != NULL) && (wakeupspec != NULL), "rtcSetPeriodicWakeup"); + rtc_lld_set_periodic_wakeup(rtcp, wakeupspec); +} +/** + * @brief Gets periodic wakeup period. + */ +void rtcGetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) { + chDbgCheck((rtcp != NULL) && (wakeupspec != NULL), "rtcGetPeriodicWakeup"); + rtc_lld_get_periodic_wakeup(rtcp, wakeupspec); +} + + + + + + + #if RTC_SUPPORTS_CALLBACKS || defined(__DOXYGEN__) /** * @brief Enables or disables RTC callbacks. - * @details This function enables or disables callbacks, use a @p NULL pointer - * in order to disable a callback. + * @details TODO: * * @param[in] rtcp pointer to RTC driver structure - * @param[in] callback callback function pointer or @p NULL + * @param[in] cb_cfg callback configuration struct * * @api */ -void rtcSetCallback(RTCDriver *rtcp, rtccb_t callback) { +void rtcSetCallback(RTCDriver *rtcp, RTCCallbackConfig *cb_cfg) { - chDbgCheck((rtcp != NULL), "rtcSetCallback"); + chDbgCheck(((rtcp != NULL) && (cb_cfg != NULL)), "rtcSetCallback"); - rtc_lld_set_callback(rtcp, callback); + rtc_lld_set_callback(rtcp, cb_cfg); } #endif /* RTC_SUPPORTS_CALLBACKS */ + + + + #endif /* HAL_USE_RTC */ /** @} */ diff --git a/testhal/STM32F1xx/RTC/main.c b/testhal/STM32F1xx/RTC/main.c index ea7155f47..19043a02a 100644 --- a/testhal/STM32F1xx/RTC/main.c +++ b/testhal/STM32F1xx/RTC/main.c @@ -24,7 +24,7 @@ RTCTime timespec; RTCAlarm alarmspec; -#define TEST_ALARM_WAKEUP FALSE +#define TEST_ALARM_WAKEUP TRUE #if TEST_ALARM_WAKEUP @@ -45,9 +45,9 @@ int main(void) { chThdCreateStatic(blinkWA, sizeof(blinkWA), NORMALPRIO, blink_thd, NULL); /* set alarm in near future */ - rtcGetTime(×pec); + rtcGetTime(&RTCD1, ×pec); alarmspec.tv_sec = timespec.tv_sec + 60; - rtcSetAlarm(&alarmspec); + rtcSetAlarm(&RTCD1, 0, &alarmspec); while (TRUE){ chThdSleepSeconds(10);