From 1135ce804d215138f92f96b74af8791c30452b6f Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 2 Apr 2016 18:18:48 -0600 Subject: [PATCH] RTC: Extend interface by adding a method to set the alarm relative to the current time --- arch | 2 +- drivers/timers/rtc.c | 65 +++++++++++++++++++++++++++++++++++++- include/nuttx/timers/rtc.h | 42 +++++++++++++++++++++--- 3 files changed, 103 insertions(+), 6 deletions(-) diff --git a/arch b/arch index 4a18471087..68a1918ab4 160000 --- a/arch +++ b/arch @@ -1 +1 @@ -Subproject commit 4a18471087626499f2f57a07238a32cfe803e6d0 +Subproject commit 68a1918ab42332510feca0a2203b768c7bb0c792 diff --git a/drivers/timers/rtc.c b/drivers/timers/rtc.c index a659b69ea9..355f41a7ee 100644 --- a/drivers/timers/rtc.c +++ b/drivers/timers/rtc.c @@ -365,7 +365,7 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg) DEBUGASSERT(alarminfo != NULL); alarmid = alarminfo->id; - DEBUGASSERT(alarminfo->id >= 0 && alarminfo->id < RTC_NALARMS); + DEBUGASSERT(alarmid >= 0 && alarmid < RTC_NALARMS); /* Is the alarm active? */ @@ -411,6 +411,69 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } break; + /* RTC_SET_RELATIVE sets the alarm time relative to the current time. + * + * Argument: A read-only reference to a struct rtc_setrelative_s containing the + * new relative alarm time to be set. + */ + + + case RTC_SET_RELATIVE: + { + FAR const struct rtc_setrelative_s *alarminfo = + (FAR const struct rtc_setrelative_s *)((uintptr_t)arg); + FAR struct rtc_alarminfo_s *upperinfo; + struct lower_setrelative_s lowerinfo; + int alarmid; + + DEBUGASSERT(alarminfo != NULL); + alarmid = alarminfo->id; + DEBUGASSERT(alarmid >= 0 && alarmid < RTC_NALARMS); + + /* Is the alarm active? */ + + upperinfo = &upper->alarminfo[alarmid]; + if (upperinfo->active) + { + /* Yes, cancel the alarm */ + + if (ops->cancelalarm) + { + (void)ops->cancelalarm(upper->lower, alarmid); + } + + upperinfo->active = false; + } + + if (ops->setrelative) + { + /* Save the signal info to be used to notify the caller when the + * alarm expires. + */ + + upperinfo->active = true; + upperinfo->signo = alarminfo->signo; + upperinfo->pid = alarminfo->pid; + upperinfo->sigvalue = alarminfo->sigvalue; + + /* Format the alarm info needed by the lower half driver */ + + lowerinfo.id = alarmid; + lowerinfo.cb = rtc_alarm_callback; + lowerinfo.priv = (FAR void *)upper; + lowerinfo.reltime = alarminfo->reltime; + + /* Then set the alarm */ + + ret = ops->setrelative(upper->lower, &lowerinfo); + if (ret < 0) + { + upperinfo->active = false; + } + } + } + break; + /* RTC_WKALRM_CANCEL cancel the alarm. * * Argument: An ALARM ID value that indicates which alarm should be diff --git a/include/nuttx/timers/rtc.h b/include/nuttx/timers/rtc.h index aef008762c..90e2f50aad 100644 --- a/include/nuttx/timers/rtc.h +++ b/include/nuttx/timers/rtc.h @@ -151,12 +151,20 @@ #define RTC_SET_ALARM _RTCIOC(0x0003) -/* RTC_WKALRM_CANCEL cancel the alarm. +/* RTC_SET_RELATIVE sets the alarm time relative to the current time. + * + * Argument: A read-only reference to a struct rtc_setrelative_s containing the + * new relative alarm time to be set. + */ + +#define RTC_SET_RELATIVE _RTCIOC(0x0004) + +/* RTC_SET_RELATIVE cancel the alarm. * * Argument: An ALARM ID value that indicates which alarm should be canceled. */ -#define RTC_CANCEL_ALARM _RTCIOC(0x004) +#define RTC_CANCEL_ALARM _RTCIOC(0x0005) /* Architecture-specific RTC IOCTLS should begin at RTC_USER_IOCBASE. For * example: @@ -166,7 +174,7 @@ * etc. */ -#define RTC_USER_IOCBASE 0x0005 +#define RTC_USER_IOCBASE 0x0006 /**************************************************************************** * Public Types @@ -207,7 +215,7 @@ struct rtc_rdalarm_s struct rtc_time time; /* Current RTC time (if enabled) */ }; -/* Structure used with the RTC_SETALARM IOCTL command. */ +/* Structure used with the RTC_SET_ALARM IOCTL command. */ struct rtc_setalarm_s { @@ -218,6 +226,17 @@ struct rtc_setalarm_s struct rtc_time time; /* Alarm time */ }; +/* Structure used with the RTC_SET_RELATIVE IOCTL command. */ + +struct rtc_setrelative_s +{ + uint8_t id; /* Indicates the alarm to be set */ + uint8_t signo; /* Signal number for alarm notification */ + pid_t pid; /* Identifies task to be notified */ + union sigval sigvalue; /* Data passed with notification */ + time_t reltime; /* Relative time in seconds */ +}; + /* Callback type used by the RTC harware to notify the RTC driver when the * alarm expires. */ @@ -233,6 +252,16 @@ struct lower_setalarm_s FAR void *priv; /* Private argurment to accompany callback */ struct rtc_time time; /* Alarm time */ }; + +/* Structure used with the setrelative method */ + +struct lower_setrelative_s +{ + uint8_t id; /* Indicates the alarm to be set */ + rtc_alarm_callback_t cb; /* Callback when the alarm expires */ + FAR void *priv; /* Private argurment to accompany callback */ + time_t reltime; /* Relative time in seconds */ +}; #endif /* The RTC driver is implemented as a common, upper-half character driver @@ -266,6 +295,11 @@ struct rtc_ops_s CODE int (*setalarm)(FAR struct rtc_lowerhalf_s *lower, FAR const struct lower_setalarm_s *alarminfo); + /* setalarm sets up a new alarm relative to the current time. */ + + CODE int (*setrelative)(FAR struct rtc_lowerhalf_s *lower, + FAR const struct lower_setrelative_s *alarminfo); + /* cancelalarm cancels the current alarm. */ CODE int (*cancelalarm)(FAR struct rtc_lowerhalf_s *lower, int alarmid);