From 41fd0fb5fb2d446605e7a99c11f46d7c28071500 Mon Sep 17 00:00:00 2001 From: barthess Date: Sun, 25 Sep 2011 10:03:59 +0000 Subject: RTC. API changes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3405 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/rtc.h | 18 +- os/hal/platforms/STM32/RTCv1/rtc_lld.c | 334 +++++++++++++++++++++++++++++++++ os/hal/platforms/STM32/RTCv1/rtc_lld.h | 131 +++++++++++++ os/hal/platforms/STM32/rtc_lld.c | 321 ------------------------------- os/hal/platforms/STM32/rtc_lld.h | 114 ----------- os/hal/platforms/STM32F1xx/platform.mk | 5 +- os/hal/src/rtc.c | 38 ++-- 7 files changed, 504 insertions(+), 457 deletions(-) create mode 100644 os/hal/platforms/STM32/RTCv1/rtc_lld.c create mode 100644 os/hal/platforms/STM32/RTCv1/rtc_lld.h delete mode 100644 os/hal/platforms/STM32/rtc_lld.c delete mode 100644 os/hal/platforms/STM32/rtc_lld.h diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h index 5adf9559c..02aec2ceb 100644 --- a/os/hal/include/rtc.h +++ b/os/hal/include/rtc.h @@ -74,10 +74,20 @@ extern "C" { rtccb_t secondcb, rtccb_t alarmcb); #endif /* RTC_SUPPORTS_CALLBACKS */ - void rtcSetTime(uint32_t tv_sec); - uint32_t rtcGetTime(uint16_t *msec); - void rtcSetAlarm(uint32_t tv_alarm); - uint32_t rtcGetAlarm(void); + void rtcSetTime(RTCDateTime *timespec); + void rtcGetTime(RTCDateTime *timespec); + + + + + void rtcSetAlarm(RTCDateTime *timespec); + void rtcGetAlarm(RTCDateTime *timespec); + + + + + + #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.c b/os/hal/platforms/STM32/RTCv1/rtc_lld.c new file mode 100644 index 000000000..a3329544e --- /dev/null +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.c @@ -0,0 +1,334 @@ +/* + 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/rtc_lld.c + * @brief STM32 RTC subsystem low level driver header. + * + * @addtogroup RTC + * @{ + */ + +#include "ch.h" +#include "hal.h" + + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief RTC driver identifier.*/ +RTCDriver RTCD; + + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Shared IRQ handler. + * + * @param[in] rtcp pointer to a @p RTCDriver object + * + * @notapi + */ +#if RTC_SUPPORTS_CALLBACKS + +static void rtc_lld_serve_interrupt(RTCDriver *rtcp){ + chSysLockFromIsr(); + + if ((RTC->CRH & RTC_CRH_SECIE) && \ + (RTC->CRL & RTC_CRL_SECF) && \ + (rtcp->second_cb != NULL)){ + rtcp->second_cb(rtcp); + RTC->CRL &= ~RTC_CRL_SECF; + } + if ((RTC->CRH & RTC_CRH_ALRIE) && \ + (RTC->CRL & RTC_CRL_ALRF) && \ + (rtcp->alarm_cb != NULL)){ + rtcp->alarm_cb(rtcp); + RTC->CRL &= ~RTC_CRL_ALRF; + } + if ((RTC->CRH & RTC_CRH_OWIE) && \ + (RTC->CRL & RTC_CRL_OWF) && \ + (rtcp->overflow_cb != NULL)){ + rtcp->overflow_cb(rtcp); + RTC->CRL &= ~RTC_CRL_OWF; + } + + chSysUnlockFromIsr(); +} +#endif /* RTC_SUPPORTS_CALLBACKS */ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief RTC interrupt handler. + * @isr + */ +#if RTC_SUPPORTS_CALLBACKS + +CH_IRQ_HANDLER(RTC_IRQHandler) { + CH_IRQ_PROLOGUE(); + rtc_lld_serve_interrupt(&RTCD); + CH_IRQ_EPILOGUE(); +} + +#endif /* RTC_SUPPORTS_CALLBACKS */ + +/*===========================================================================*/ +/* 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){ + uint32_t preload = 0; + + rccEnableBKPInterface(FALSE); + + /* enable access to BKP registers */ + PWR->CR |= PWR_CR_DBP; + /* select clock source */ + RCC->BDCR |= STM32_RTC; + +#if STM32_RTC == STM32_RTC_LSE + if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ + RCC->BDCR |= RCC_BDCR_LSEON; + while(!(RCC->BDCR & RCC_BDCR_LSERDY)) + ; + RCC->BDCR |= RCC_BDCR_RTCEN; + } + preload = STM32_LSECLK - 1; + +#elif STM32_RTC == STM32_RTC_LSI + RCC->CSR |= RCC_CSR_LSION; + while(!(RCC->CSR & RCC_CSR_LSIRDY)) + ; + /* According to errata sheet we must wait additional 100 uS for stabilization */ + uint32_t tmo = (STM32_SYSCLK / 1000000 ) * 100; + while(tmo--) + ; + RCC->BDCR |= RCC_BDCR_RTCEN; + preload = STM32_LSICLK - 1; + +#elif STM32_RTC == STM32_RTC_HSE + preload = (STM32_HSICLK / 128) - 1; + +#else +#error "RTC clock source not selected" +#endif + + /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling + * clocking on APB1, because these values only update when APB1 functioning.*/ + RTC->CRL &= ~(RTC_CRL_RSF); + while (!(RTC->CRL & RTC_CRL_RSF)) + ; + + /* Write preload register only if its value changed */ + if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLL)){ + while(!(RTC->CRL & RTC_CRL_RTOFF)) + ; + + RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ + RTC->PRLH = (uint16_t)((preload >> 16) & 0b1111); /* write preloader */ + RTC->PRLL = (uint16_t)(preload & 0xFFFF); + RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ + + while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ + ; + } + + /* disable all interrupts and clear all even flags just to be safe */ + RTC->CRH &= ~(RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE); + RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); + +#if RTC_SUPPORTS_CALLBACKS + RTCD.alarm_cb = NULL; + RTCD.overflow_cb = NULL; + RTCD.second_cb = NULL; +#endif /* RTC_SUPPORTS_CALLBACKS */ +} + +/** + * @brief Enables and disables callbacks on the fly. + * + * @details Pass callback function(s) in argument(s) to enable callback(s). + * Pass NULL to disable callback. + * + * @pre To use this function you must set @p RTC_SUPPORTS_CALLBACKS + * to @p TRUE. + * + * @param[in] rtcp pointer to RTC driver structure. + * @param[in] overflowcb overflow callback function. + * @param[in] secondcb every second callback function. + * @param[in] alarmcb alarm callback function. + * + * @notapi + */ +#if RTC_SUPPORTS_CALLBACKS +void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflowcb, + rtccb_t secondcb, rtccb_t alarmcb){ + + uint16_t isr_flags = 0; + + if (overflowcb != NULL){ + rtcp->overflow_cb = *overflowcb; + isr_flags |= RTC_CRH_OWIE; + } + else{ + rtcp->overflow_cb = NULL; + isr_flags &= ~RTC_CRH_OWIE; + } + + if (alarmcb != NULL){ + rtcp->alarm_cb = *alarmcb; + isr_flags |= RTC_CRH_ALRIE; + } + else{ + rtcp->alarm_cb = NULL; + isr_flags &= ~RTC_CRH_ALRIE; + } + + if (secondcb != NULL){ + rtcp->second_cb = *secondcb; + isr_flags |= RTC_CRH_SECIE; + } + else{ + rtcp->second_cb = NULL; + isr_flags &= ~RTC_CRH_SECIE; + } + + if(isr_flags != 0){ + NVICEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY)); + RTC->CRH |= isr_flags; + } + else{ + NVICDisableVector(RTC_IRQn); + RTC->CRH = 0; + } +} +#endif /* RTC_SUPPORTS_CALLBACKS */ + +/** + * @brief Set current time. + * + * @param[in] timespec pointer to variable storing time. + * + * @note Fractional part will be silently ignored. There is no possibility + * to change it on STM32F1xx platform. + * @notapi + */ +void rtc_lld_set_time(RTCDateTime *timespec){ + + while(!(RTC->CRL & RTC_CRL_RTOFF)) + ; + + RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ + RTC->CNTH = (uint16_t)((timespec->tv_sec >> 16) & 0xFFFF); + RTC->CNTL = (uint16_t)(timespec->tv_sec & 0xFFFF); + RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ + + while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ + ; +} + +/** + * @brief Get current time. + * + * @param[in] msec pointer to variable for storing fractional part of + * time (milliseconds). + * + * @notapi + */ +inline void rtc_lld_get_time(RTCDateTime *timespec){ + uint32_t time_frac = 0; + time_frac = (((uint32_t)RTC->DIVH) << 16) + (RTC->DIVL); + + timespec->tv_msec = (uint16_t)(((STM32_LSECLK - time_frac) * 1000) / STM32_LSECLK); + timespec->tv_sec = (RTC->CNTH << 16) + RTC->CNTL; +} + +/** + * @brief Set alarm time. + * + * @param[in] timespec pointer to variable storing time of alarm. + * + * @note Fractional part will be silently ignored. There is no possibility + * to change it on STM32F1xx platform. + * + * @note Default value after BKP domain reset is 0xFFFFFFFF + * + * @notapi + */ +void rtc_lld_set_alarm(RTCDateTime *timespec){ + + while(!(RTC->CRL & RTC_CRL_RTOFF)) + ; + + RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ + RTC->ALRH = (uint16_t)((timespec->tv_sec >> 16) & 0xFFFF); + RTC->ALRL = (uint16_t)(timespec->tv_sec & 0xFFFF); + RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ + +#if !(RTC_SUPPORTS_CALLBACKS) + RTC->CRL &= ~RTC_CRL_ALRF; + RTC->CRH |= RTC_CRH_ALRIE; +#endif /* !(RTC_SUPPORTS_CALLBACKS) */ + + while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ + ; +} + +/** + * @brief Get current alarm time. + * + * @param[in] timespec pointer to variable storing time of alarm. + * + * @note Fractional part will be silently ignored. There is no possibility + * to change it on STM32F1xx platform. + * + * @note Default value after BKP domain reset is 0xFFFFFFFF + * + * @notapi + */ +inline void rtc_lld_get_alarm(RTCDateTime *timespec){ + timespec->tv_sec = ((RTC->ALRH << 16) + RTC->ALRL); +} + + +#endif /* HAL_USE_RTC */ + +/** @} */ diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h new file mode 100644 index 000000000..125b6c11e --- /dev/null +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -0,0 +1,131 @@ +/* + 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/rtc_lld.h + * @brief STM32 RTC subsystem low level driver header. + * + * @addtogroup RTC + * @{ + */ + +#ifndef _RTC_LLD_H_ +#define _RTC_LLD_H_ + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ +/** + * @brief Switch to TRUE if you need callbacks from RTC. Switch to FALSE + * if you need only time keeping. + * @note Default is true. + */ +#if !defined(RTC_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__) +#define RTC_SUPPORTS_CALLBACKS TRUE +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if HAL_USE_RTC && !STM32_HAS_RTC +#error "RTC not present in the selected device" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + + + + + +typedef struct { + uint32_t tv_sec; + uint32_t tv_msec; +}RTCDateTime; + + + + + + + +/** + * @brief Structure representing an RTC driver. + * @note This driver if dummy when callbacks disabled. + */ +struct RTCDriver{ +#if RTC_SUPPORTS_CALLBACKS + /** + * @brief Overflow callback. Set it to NULL if not used. + */ + rtccb_t overflow_cb; + + /** + * @brief Every second callback. Set it to NULL if not used. + */ + rtccb_t second_cb; + + /** + * @brief Alarm callback. Set it to NULL if not used. + */ + rtccb_t alarm_cb; +#endif /* RTC_SUPPORTS_CALLBACKS */ +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +extern RTCDriver RTCD; + + +#ifdef __cplusplus +extern "C" { +#endif + void rtc_lld_init(void); + void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflow_cb, + rtccb_t second_cb, rtccb_t alarm_cb); + + void rtc_lld_set_time(RTCDateTime *timespec); + void rtc_lld_get_time(RTCDateTime *timespec); + + void rtc_lld_get_alarm(RTCDateTime *timespec); + void rtc_lld_set_alarm(RTCDateTime *timespec); +#ifdef __cplusplus +} +#endif + + +#endif /* HAL_USE_RTC */ +#endif /* _RTC_LLD_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32/rtc_lld.c b/os/hal/platforms/STM32/rtc_lld.c deleted file mode 100644 index c1163d1a1..000000000 --- a/os/hal/platforms/STM32/rtc_lld.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - 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/rtc_lld.c - * @brief STM32 RTC subsystem low level driver header. - * - * @addtogroup RTC - * @{ - */ - -#include "ch.h" -#include "hal.h" - - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief RTC driver identifier.*/ -RTCDriver RTCD; - - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Shared IRQ handler. - * - * @param[in] rtcp pointer to a @p RTCDriver object - * - * @notapi - */ -#if RTC_SUPPORTS_CALLBACKS - -static void rtc_lld_serve_interrupt(RTCDriver *rtcp){ - chSysLockFromIsr(); - - if ((RTC->CRH & RTC_CRH_SECIE) && \ - (RTC->CRL & RTC_CRL_SECF) && \ - (rtcp->second_cb != NULL)){ - rtcp->second_cb(rtcp); - RTC->CRL &= ~RTC_CRL_SECF; - } - if ((RTC->CRH & RTC_CRH_ALRIE) && \ - (RTC->CRL & RTC_CRL_ALRF) && \ - (rtcp->alarm_cb != NULL)){ - rtcp->alarm_cb(rtcp); - RTC->CRL &= ~RTC_CRL_ALRF; - } - if ((RTC->CRH & RTC_CRH_OWIE) && \ - (RTC->CRL & RTC_CRL_OWF) && \ - (rtcp->overflow_cb != NULL)){ - rtcp->overflow_cb(rtcp); - RTC->CRL &= ~RTC_CRL_OWF; - } - - chSysUnlockFromIsr(); -} -#endif /* RTC_SUPPORTS_CALLBACKS */ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief RTC interrupt handler. - * @isr - */ -#if RTC_SUPPORTS_CALLBACKS - -CH_IRQ_HANDLER(RTC_IRQHandler) { - CH_IRQ_PROLOGUE(); - rtc_lld_serve_interrupt(&RTCD); - CH_IRQ_EPILOGUE(); -} - -#endif /* RTC_SUPPORTS_CALLBACKS */ - -/*===========================================================================*/ -/* 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){ - uint32_t preload = 0; - - rccEnableBKPInterface(FALSE); - - /* enable access to BKP registers */ - PWR->CR |= PWR_CR_DBP; - /* select clock source */ - RCC->BDCR |= STM32_RTC; - -#if STM32_RTC == STM32_RTC_LSE - if (! ((RCC->BDCR & RCC_BDCR_RTCEN) || (RCC->BDCR & RCC_BDCR_LSEON))){ - RCC->BDCR |= RCC_BDCR_LSEON; - while(!(RCC->BDCR & RCC_BDCR_LSERDY)) - ; - RCC->BDCR |= RCC_BDCR_RTCEN; - } - preload = STM32_LSECLK - 1; - -#elif STM32_RTC == STM32_RTC_LSI - RCC->CSR |= RCC_CSR_LSION; - while(!(RCC->CSR & RCC_CSR_LSIRDY)) - ; - /* According to errata sheet we must wait additional 100 uS for stabilization */ - uint32_t tmo = (STM32_SYSCLK / 1000000 ) * 100; - while(tmo--) - ; - RCC->BDCR |= RCC_BDCR_RTCEN; - preload = STM32_LSICLK - 1; - -#elif STM32_RTC == STM32_RTC_HSE - preload = (STM32_HSICLK / 128) - 1; - -#else -#error "RTC clock source not selected" -#endif - - /* Ensure that RTC_CNT and RTC_DIV contain actual values after enabling - * clocking on APB1, because these values only update when APB1 functioning.*/ - RTC->CRL &= ~(RTC_CRL_RSF); - while (!(RTC->CRL & RTC_CRL_RSF)) - ; - - /* Write preload register only if its value changed */ - if (preload != ((((uint32_t)(RTC->PRLH)) << 16) + RTC->PRLL)){ - while(!(RTC->CRL & RTC_CRL_RTOFF)) - ; - - RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ - RTC->PRLH = (uint16_t)((preload >> 16) & 0b1111); /* write preloader */ - RTC->PRLL = (uint16_t)(preload & 0xFFFF); - RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ - ; - } - - /* disable all interrupts and clear all even flags just to be safe */ - RTC->CRH &= ~(RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE); - RTC->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); - -#if RTC_SUPPORTS_CALLBACKS - RTCD.alarm_cb = NULL; - RTCD.overflow_cb = NULL; - RTCD.second_cb = NULL; -#endif /* RTC_SUPPORTS_CALLBACKS */ -} - -/** - * @brief Enables and disables callbacks on the fly. - * - * @details Pass callback function(s) in argument(s) to enable callback(s). - * Pass NULL to disable callback. - * - * @pre To use this function you must set @p RTC_SUPPORTS_CALLBACKS - * to @p TRUE. - * - * @param[in] rtcp pointer to RTC driver structure. - * @param[in] overflowcb overflow callback function. - * @param[in] secondcb every second callback function. - * @param[in] alarmcb alarm callback function. - * - * @notapi - */ -#if RTC_SUPPORTS_CALLBACKS -void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflowcb, - rtccb_t secondcb, rtccb_t alarmcb){ - - uint16_t isr_flags = 0; - - if (overflowcb != NULL){ - rtcp->overflow_cb = *overflowcb; - isr_flags |= RTC_CRH_OWIE; - } - else{ - rtcp->overflow_cb = NULL; - isr_flags &= ~RTC_CRH_OWIE; - } - - if (alarmcb != NULL){ - rtcp->alarm_cb = *alarmcb; - isr_flags |= RTC_CRH_ALRIE; - } - else{ - rtcp->alarm_cb = NULL; - isr_flags &= ~RTC_CRH_ALRIE; - } - - if (secondcb != NULL){ - rtcp->second_cb = *secondcb; - isr_flags |= RTC_CRH_SECIE; - } - else{ - rtcp->second_cb = NULL; - isr_flags &= ~RTC_CRH_SECIE; - } - - if(isr_flags != 0){ - NVICEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY)); - RTC->CRH |= isr_flags; - } - else{ - NVICDisableVector(RTC_IRQn); - RTC->CRH = 0; - } -} -#endif /* RTC_SUPPORTS_CALLBACKS */ - -/** - * @brief Set current time. - * - * @param[in] tv_sec time value in UNIX notation. - * - * @notapi - */ -void rtc_lld_set_time(uint32_t tv_sec){ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) - ; - - RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ - RTC->CNTH = (uint16_t)((tv_sec >> 16) & 0xFFFF); /* write time */ - RTC->CNTL = (uint16_t)(tv_sec & 0xFFFF); - RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ - ; -} - -/** - * @brief Return return seconds since UNIX epoch. - * - * @param[in] msec pointer to variable for storing fractional part of - * time (milliseconds). - * - * @notapi - */ -inline uint32_t rtc_lld_get_time(uint16_t *msec){ - uint32_t time_frac = 0; - if(msec != NULL){ - time_frac = (((uint32_t)RTC->DIVH) << 16) + (RTC->DIVL); - *msec = (uint16_t)(((STM32_LSECLK - time_frac) * 1000) / STM32_LSECLK); - } - return ((RTC->CNTH << 16) + RTC->CNTL); -} - -/** - * @brief Set alarm date in UNIX notation. - * @note Default value after BKP domain reset is 0xFFFFFFFF - * - * @notapi - */ -void rtc_lld_set_alarm(uint32_t tv_alarm){ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) - ; - - RTC->CRL |= RTC_CRL_CNF; /* switch on configure mode */ - RTC->ALRH = (uint16_t)((tv_alarm >> 16) & 0xFFFF); /* write time */ - RTC->ALRL = (uint16_t)(tv_alarm & 0xFFFF); - RTC->CRL &= ~RTC_CRL_CNF; /* switch off configure mode */ - -#if !(RTC_SUPPORTS_CALLBACKS) - RTC->CRL &= ~RTC_CRL_ALRF; - RTC->CRH |= RTC_CRH_ALRIE; -#endif /* !(RTC_SUPPORTS_CALLBACKS) */ - - while(!(RTC->CRL & RTC_CRL_RTOFF)) /* wait for completion */ - ; -} - -/** - * @brief Get current alarm date in UNIX notation. - * @note Default value after BKP domain reset is 0xFFFFFFFF - * - * @notapi - */ -inline uint32_t rtc_lld_get_alarm(void){ - return ((RTC->ALRH << 16) + RTC->ALRL); -} - - -#endif /* HAL_USE_RTC */ - -/** @} */ diff --git a/os/hal/platforms/STM32/rtc_lld.h b/os/hal/platforms/STM32/rtc_lld.h deleted file mode 100644 index d73d35091..000000000 --- a/os/hal/platforms/STM32/rtc_lld.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - 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/rtc_lld.h - * @brief STM32 RTC subsystem low level driver header. - * - * @addtogroup RTC - * @{ - */ - -#ifndef _RTC_LLD_H_ -#define _RTC_LLD_H_ - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ -/** - * @brief Switch to TRUE if you need callbacks from RTC. Switch to FALSE - * if you need only time keeping. - * @note Default is true. - */ -#if !defined(RTC_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__) -#define RTC_SUPPORTS_CALLBACKS TRUE -#endif - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if HAL_USE_RTC && !STM32_HAS_RTC -#error "RTC not present in the selected device" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Structure representing an RTC driver. - * @note This driver if dummy when callbacks disabled. - */ -struct RTCDriver{ -#if RTC_SUPPORTS_CALLBACKS - /** - * @brief Overflow callback. Set it to NULL if not used. - */ - rtccb_t overflow_cb; - - /** - * @brief Every second callback. Set it to NULL if not used. - */ - rtccb_t second_cb; - - /** - * @brief Alarm callback. Set it to NULL if not used. - */ - rtccb_t alarm_cb; -#endif /* RTC_SUPPORTS_CALLBACKS */ -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -extern RTCDriver RTCD; - - -#ifdef __cplusplus -extern "C" { -#endif - void rtc_lld_init(void); - void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t overflow_cb, - rtccb_t second_cb, rtccb_t alarm_cb); - void rtc_lld_set_time(uint32_t tv_sec); - uint32_t rtc_lld_get_time(uint16_t *msec); - uint32_t rtc_lld_get_alarm(void); - void rtc_lld_set_alarm(uint32_t); -#ifdef __cplusplus -} -#endif - - -#endif /* HAL_USE_RTC */ -#endif /* _RTC_LLD_H_ */ - -/** @} */ diff --git a/os/hal/platforms/STM32F1xx/platform.mk b/os/hal/platforms/STM32F1xx/platform.mk index 51601731e..a73f1b4f3 100644 --- a/os/hal/platforms/STM32F1xx/platform.mk +++ b/os/hal/platforms/STM32F1xx/platform.mk @@ -15,11 +15,12 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F1xx/hal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv1/pal_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/DMAv1/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/USBv1/usb_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/rtc_lld.c + ${CHIBIOS}/os/hal/platforms/STM32/RTCv1/rtc_lld.c # Required include directories PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F1xx \ ${CHIBIOS}/os/hal/platforms/STM32 \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv1 \ ${CHIBIOS}/os/hal/platforms/STM32/DMAv1 \ - ${CHIBIOS}/os/hal/platforms/STM32/USBv1 + ${CHIBIOS}/os/hal/platforms/STM32/USBv1 \ + ${CHIBIOS}/os/hal/platforms/STM32/RTCv1 diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index 3b4b5824b..0c8959ea6 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -83,36 +83,42 @@ void rtcSetCallback(RTCDriver *rtcp, rtccb_t overflowcb, /** * @brief Set current time. - * @param[in] tv_sec - time value in UNIX notation. + * + * @param[in] timespec pointer to variable storing time. */ -void rtcSetTime(uint32_t tv_sec){ - rtc_lld_set_time(tv_sec); +void rtcSetTime(RTCDateTime *timespec){ + chDbgCheck((timespec != NULL), "rtcSetTime"); + rtc_lld_set_time(timespec); } /** - * @brief Return return seconds since UNIX epoch. - * - * @param[in] msec pointer to variable for storing fractional part of - * time (milliseconds). + * @brief Get current time. * - * @notapi + * @param[in] timespec pointer to variable storing time. */ -inline uint32_t rtcGetTime(uint16_t *msec){ - return rtc_lld_get_time(msec); +void rtcGetTime(RTCDateTime *timespec){ + chDbgCheck((timespec != NULL), "rtcGetTime"); + rtc_lld_get_time(timespec); } /** - * @brief Set alarm date in UNIX notation. + * @brief Set alarm time. + * + * @param[in] timespec pointer to variable storing time of alarm. */ -void rtcSetAlarm(uint32_t tv_alarm){ - rtc_lld_set_alarm(tv_alarm); +void rtcSetAlarm(RTCDateTime *timespec){ + chDbgCheck((timespec != NULL), "rtcSetAlarm"); + rtc_lld_set_alarm(timespec); } /** - * @brief Get current alarm date in UNIX notation. + * @brief Get current alarm. + * + * @param[in] timespec pointer to variable to store alarm time. */ -inline uint32_t rtcGetAlarm(void){ - return rtc_lld_get_alarm(); +void rtcGetAlarm(RTCDateTime *timespec){ + chDbgCheck((timespec != NULL), "rtcGetAlarm"); + rtc_lld_get_alarm(timespec); } #endif /* HAL_USE_RTC */ -- cgit v1.2.3