diff --git a/arch/arm/src/stm32/Make.defs b/arch/arm/src/stm32/Make.defs index 7f61348530..a6b4e874e6 100644 --- a/arch/arm/src/stm32/Make.defs +++ b/arch/arm/src/stm32/Make.defs @@ -181,6 +181,9 @@ CHIP_CSRCS += stm32_rtc.c ifeq ($(CONFIG_RTC_ALARM),y) CHIP_CSRCS += stm32_exti_alarm.c endif +ifeq ($(CONFIG_RTC_DRIVER),y) +CHIP_CSRCS += stm32_rtc_lowerhalf.c +endif endif ifeq ($(CONFIG_ADC),y) diff --git a/arch/arm/src/stm32/stm32_rtc.h b/arch/arm/src/stm32/stm32_rtc.h index b27a4ffb9e..0021aa2c47 100644 --- a/arch/arm/src/stm32/stm32_rtc.h +++ b/arch/arm/src/stm32/stm32_rtc.h @@ -98,6 +98,27 @@ extern "C" * Public Functions ************************************************************************************/ +/************************************************************************************ + * Name: stm32_rtc_setdatetime + * + * Description: + * Set the RTC to the provided time. RTC implementations which provide + * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide this + * function. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +#ifdef CONFIG_RTC_DATETIME +struct tm; +int stm32_rtc_setdatetime(FAR const struct tm *tp); +#endif + /************************************************************************************ * Name: stm32_rtc_setalarm * @@ -136,6 +157,33 @@ int stm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback); int stm32_rtc_cancelalarm(void); #endif +/**************************************************************************** + * Name: stm32_rtc_lowerhalf + * + * Description: + * Instantiate the RTC lower half driver for the STM32. General usage: + * + * #include + * #include "stm32_rtc.h> + * + * struct rtc_lowerhalf_s *lower; + * lower = stm32_rtc_lowerhalf(); + * rtc_initialize(0, lower); + * + * Input Parameters: + * None + * + * Returned Value: + * On success, a non-NULL RTC lower interface is returned. NULL is + * returned on any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RTC_DRIVER +struct rtc_lower_half_s; +struct rtc_lower_half_s *stm32_rtc_lowerhalf(void); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/stm32/stm32_rtc_lowerhalf.c b/arch/arm/src/stm32/stm32_rtc_lowerhalf.c new file mode 100644 index 0000000000..394d95e4eb --- /dev/null +++ b/arch/arm/src/stm32/stm32_rtc_lowerhalf.c @@ -0,0 +1,147 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_rtc_lowerhalf.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "chip.h" +#include "stm32_rtc.h" + +#ifdef CONFIG_RTC_DRIVER + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This is the private type for the RTC state. It must be cast compatible + * with struct rtc_lowerhalf_s. + */ + +struct stm32_lowerhalf_s +{ + /* This is the contained reference to the read-only, lower-half + * operations vtable (which may lie in FLASH or ROM) + */ + + FAR const struct rtc_ops_s *ops; + + /* Data following is private to this driver and not visible outside of + * this file. + */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Prototypes for static methods in struct rtc_ops_s */ +/* To be provided */ + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* STM32 RTC driver operations */ + +static const struct rtc_ops_s g_rtc_ops = +{ + .rdtime = NULL, + .settime = NULL, + .almread = NULL, + .almset = NULL, + .irqpread = NULL, + .irqpset = NULL, + .aie = NULL, + .uie = NULL, + .pie = NULL, + .rdepoch = NULL, + .setepoch = NULL, + .rdwkalm = NULL, + .setwkalm = NULL, + .destroy = NULL, +}; + +/* STM32 RTC device state */ + +static struct stm32_lowerhalf_s g_rtc_lowerhalf = +{ + .ops = &g_rtc_ops, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rtc_lowerhalf + * + * Description: + * Instantiate the RTC lower half driver for the STM32. General usage: + * + * #include + * #include "stm32_rtc.h> + * + * struct rtc_lowerhalf_s *lower; + * lower = stm32_rtc_lowerhalf(); + * rtc_initialize(0, lower); + * + * Input Parameters: + * None + * + * Returned Value: + * On success, a non-NULL RTC lower interface is returned. NULL is + * returned on any failure. + * + ****************************************************************************/ + +struct rtc_lower_half_s *stm32_rtc_lowerhalf(void) +{ + return (struct rtc_lower_half_s *)&g_rtc_lowerhalf; +} + +#endif /* CONFIG_RTC_DRIVER */ diff --git a/arch/arm/src/stm32/stm32_rtcc.c b/arch/arm/src/stm32/stm32_rtcc.c index 29840b7b6a..ed2e2f06de 100644 --- a/arch/arm/src/stm32/stm32_rtcc.c +++ b/arch/arm/src/stm32/stm32_rtcc.c @@ -821,11 +821,12 @@ int up_rtc_getdatetime(FAR struct tm *tp) } /************************************************************************************ - * Name: up_rtc_settime + * Name: stm32_rtc_setdatetime * * Description: - * Set the RTC to the provided time. All RTC implementations must be able to - * set their time based on a standard timespec. + * Set the RTC to the provided time. RTC implementations which provide + * up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide this + * function. * * Input Parameters: * tp - the time to use @@ -835,17 +836,13 @@ int up_rtc_getdatetime(FAR struct tm *tp) * ************************************************************************************/ -int up_rtc_settime(FAR const struct timespec *tp) +int stm32_rtc_setdatetime(FAR const struct tm *tp) { - FAR struct tm newtime; uint32_t tr; uint32_t dr; int ret; - /* Break out the time values (not that the time is set only to units of seconds) */ - - (void)gmtime_r(&tp->tv_sec, &newtime); - rtc_dumptime(&newtime, "Setting time"); + rtc_dumptime(tp, "Setting time"); /* Then write the broken out values to the RTC */ @@ -854,9 +851,9 @@ int up_rtc_settime(FAR const struct timespec *tp) * register. */ - tr = (rtc_bin2bcd(newtime.tm_sec) << RTC_TR_SU_SHIFT) | - (rtc_bin2bcd(newtime.tm_min) << RTC_TR_MNU_SHIFT) | - (rtc_bin2bcd(newtime.tm_hour) << RTC_TR_HU_SHIFT); + tr = (rtc_bin2bcd(tp->tm_sec) << RTC_TR_SU_SHIFT) | + (rtc_bin2bcd(tp->tm_min) << RTC_TR_MNU_SHIFT) | + (rtc_bin2bcd(tp->tm_hour) << RTC_TR_HU_SHIFT); tr &= ~RTC_TR_RESERVED_BITS; /* Now convert the fields in struct tm format to the RTC date register fields: @@ -868,9 +865,9 @@ int up_rtc_settime(FAR const struct timespec *tp) * years 2000-2099? I'll assume so. */ - dr = (rtc_bin2bcd(newtime.tm_mday) << RTC_DR_DU_SHIFT) | - ((rtc_bin2bcd(newtime.tm_mon + 1)) << RTC_DR_MU_SHIFT) | - ((rtc_bin2bcd(newtime.tm_year - 100)) << RTC_DR_YU_SHIFT); + dr = (rtc_bin2bcd(tp->tm_mday) << RTC_DR_DU_SHIFT) | + ((rtc_bin2bcd(tp->tm_mon + 1)) << RTC_DR_MU_SHIFT) | + ((rtc_bin2bcd(tp->tm_year - 100)) << RTC_DR_YU_SHIFT); dr &= ~RTC_DR_RESERVED_BITS; /* Disable the write protection for RTC registers */ @@ -902,6 +899,31 @@ int up_rtc_settime(FAR const struct timespec *tp) return ret; } +/************************************************************************************ + * Name: up_rtc_settime + * + * Description: + * Set the RTC to the provided time. All RTC implementations must be able to + * set their time based on a standard timespec. + * + * Input Parameters: + * tp - the time to use + * + * Returned Value: + * Zero (OK) on success; a negated errno on failure + * + ************************************************************************************/ + +int up_rtc_settime(FAR const struct timespec *tp) +{ + FAR struct tm newtime; + + /* Break out the time values (not that the time is set only to units of seconds) */ + + (void)gmtime_r(&tp->tv_sec, &newtime); + return stm32_rtc_setdatetime(&newtime); +} + /************************************************************************************ * Name: stm32_rtc_setalarm * @@ -939,6 +961,7 @@ int stm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback) ret = OK; } + return ret; } #endif diff --git a/include/nuttx/rtc.h b/include/nuttx/rtc.h index ff337a1d4c..213fbd90cc 100644 --- a/include/nuttx/rtc.h +++ b/include/nuttx/rtc.h @@ -47,6 +47,9 @@ #include #include + +#include + #include #ifdef CONFIG_RTC @@ -314,7 +317,6 @@ struct rtc_wkalrm struct rtc_lowerhalf_s; struct rtc_ops_s { - /* rdtime() returns the current RTC time. */ CODE int (*rdtime)(FAR struct rtc_lowerhalf_s *lower,