RTC: A little more clean-up of the RTC driver

This commit is contained in:
Gregory Nutt 2015-02-15 08:19:23 -06:00
parent 8337710084
commit 5cb233f712
4 changed files with 147 additions and 18 deletions

View File

@ -79,12 +79,10 @@ struct stm32_lowerhalf_s
****************************************************************************/
/* Prototypes for static methods in struct rtc_ops_s */
#ifdef CONFIG_RTC_DATETIME
static int stm32_rdtime(FAR struct rtc_lowerhalf_s *lower,
FAR struct rtc_time *rtctime);
static int stm32_settime(FAR struct rtc_lowerhalf_s *lower,
FAR const struct rtc_time *rtctime);
#endif
/****************************************************************************
* Private Data
@ -93,24 +91,33 @@ static int stm32_settime(FAR struct rtc_lowerhalf_s *lower,
static const struct rtc_ops_s g_rtc_ops =
{
#ifdef CONFIG_RTC_DATETIME
.rdtime = stm32_rdtime,
.settime = stm32_settime,
#else
.rdtime = NULL,
.settime = NULL,
#endif
#ifdef CONFIG_RTC_ALARM
.almread = NULL,
.almset = NULL,
#endif
#ifdef CONFIG_RTC_PERIODIC
.irqpread = NULL,
.irqpset = NULL,
#endif
#ifdef CONFIG_RTC_ALARM
.aie = NULL,
#endif
#ifdef CONFIG_RTC_ONESEC
.uie = NULL,
#endif
#ifdef CONFIG_RTC_PERIODIC
.pie = NULL,
#endif
#ifdef CONFIG_RTC_EPOCHYEAR
.rdepoch = NULL,
.setepoch = NULL,
#endif
#ifdef CONFIG_RTC_ALARM
.rdwkalm = NULL,
.setwkalm = NULL,
#endif
.destroy = NULL,
};
@ -141,17 +148,62 @@ static struct stm32_lowerhalf_s g_rtc_lowerhalf =
*
****************************************************************************/
#ifdef CONFIG_RTC_DATETIME
static int stm32_rdtime(FAR struct rtc_lowerhalf_s *lower,
FAR struct rtc_time *rtctime)
{
#if defined(CONFIG_RTC_DATETIME)
/* This operation depends on the fact that struct rtc_time is cast
* compatible with struct tm.
*/
return up_rtc_getdatetime((FAR struct tm *)rtctime);
}
#elif defined(CONFIG_RTC_HIRES)
FAR struct timespec ts;
int ret;
/* Get the higher resolution time */
int ret = up_rtc_gettime(&ts);
if (ret < 0)
{
goto errout_with_errno;
}
/* Convert the one second epoch time to a struct tm. This operation
* depends on the fact that struct rtc_time and struct tm are cast
* compatible.
*/
if (!gmtime_r(&ts.tv_sec, (FAR struct tm *)rtctime)
{
goto errout_with_errno;
}
errout_with_errno;
ret = get_errno();
DEBUGASSERT(ret > 0);
return -ret;
#else
FAR struct time_t timer;
/* The resolution of time is only 1 second */
timer = up_rtc_time();
/* Convert the one second epoch time to a struct tm */
if (!gmtime_r(&timer, rtctime)
{
int errcode = get_errno();
DEBUGASSERT(errcode > 0);
return -errcode;
}
return OK;
#endif
}
/****************************************************************************
* Name: stm32_settime
@ -169,17 +221,32 @@ static int stm32_rdtime(FAR struct rtc_lowerhalf_s *lower,
*
****************************************************************************/
#ifdef CONFIG_RTC_DATETIME
static int stm32_settime(FAR struct rtc_lowerhalf_s *lower,
FAR const struct rtc_time *rtctime)
{
#ifdef CONFIG_RTC_DATETIME
/* This operation depends on the fact that struct rtc_time is cast
* compatible with struct tm.
*/
return stm32_rtc_setdatetime((FAR const struct tm *)rtctime);
}
#else
struct timespec ts;
int ret;
/* Convert the struct rtc_time to a time_t. Here we assume that struct
* rtc_time is cast compatible with struct tm.
*/
ts.tv_sec = mktime((FAR const struct tm *)rtctime)
ts.tv_nsec = 0;
/* Now set the time (to one second accuracy) */
return up_rtc_settime(&ts);
#endif
}
/****************************************************************************
* Public Functions

View File

@ -61,13 +61,6 @@ config RTC_FREQUENCY
endif # !RTC_DATETIME
config RTC_ALARM
bool "RTC Alarm Support"
default n
---help---
Enable if the RTC hardware supports setting of an alarm. A callback
function will be executed when the alarm goes off.
config RTC_DRIVER
bool "RTC Driver Support"
default n
@ -76,6 +69,45 @@ config RTC_DRIVER
driver. See include/nuttx/rtc.h for further RTC driver
information.
if RTC_DRIVER
config RTC_ALARM
bool "RTC Alarm Support"
default n
---help---
Enable if the RTC hardware supports setting of an alarm. A callback
function will be executed when the alarm goes off.
config RTC_PERIODIC
bool "RTC Periodic Interrupts"
default n
depends on EXPERIMENTAL
---help---
Add interrupt controls for RTCs that support periodic interrupts.
config RTC_ONESEC
bool "RTC Once-per-second interrupts"
default n
depends on EXPERIMENTAL
---help---
Add interrupt controls for RTCs that support once-per-second interrupts.
config RTC_EPOCHYEAR
bool "RTC epoch year"
default n
depends on EXPERIMENTAL
---help---
Add controls for RTCs that support epoch year settings.
Many RTCs encode the year in an 8-bit register which is either interpreted
as an 8-bit binary number or as a BCD number. In both cases, the number is
interpreted relative to this RTC's Epoch. The RTC's Epoch is initialized to
1900 on most systems but on Alpha and MIPS it might also be initialized to
1952, 1980, or 2000, depending on the value of an RTC register for the year.
With some RTCs, these operations can be used to read or to set the RTC's
Epoch, respectively.
endif # RTC_DRIVER
endif # RTC
menuconfig WATCHDOG

View File

@ -264,6 +264,7 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
break;
#ifdef CONFIG_RTC_ALARM
/* RTC_ALM_READ reads the alarm time (for RTCs that support alarms)
*
* Argument: A writeable reference to a struct rtc_time to receive the
@ -298,7 +299,9 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
}
break;
#endif /* CONFIG_RTC_ALARM */
#ifdef CONFIG_RTC_PERIODIC
/* RTC_IRQP_READ read the frequency for periodic interrupts (for RTCs
* that support periodic interrupts)
*
@ -331,7 +334,9 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
}
break;
#endif /* CONFIG_RTC_PERIODIC */
#ifdef CONFIG_RTC_ALARM
/* RTC_AIE_ON enable alarm interrupts (for RTCs that support alarms)
*
* Argument: None
@ -360,7 +365,9 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
}
break;
#endif /* CONFIG_RTC_ALARM */
#ifdef CONFIG_RTC_ONESEC
/* RTC_UIE_ON enable the interrupt on every clock update (for RTCs that
* support this once-per-second interrupt).
*
@ -390,7 +397,9 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
}
break;
#endif /* CONFIG_RTC_ONESEC */
#ifdef CONFIG_RTC_PERIODIC
/* RTC_PIE_ON enable the periodic interrupt (for RTCs that support these
* periodic interrupts).
*
@ -420,7 +429,9 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
}
break;
#endif /* CONFIG_RTC_PERIODIC */
#ifdef CONFIG_RTC_EPOCHYEAR
/* RTC_EPOCH_READ read the Epoch.
*
* Argument: A reference to a writeable unsigned low variable that will
@ -452,7 +463,9 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
}
break;
#endif /* CONFIG_RTC_EPOCHYEAR */
#ifdef CONFIG_RTC_ALARM
/* RTC_WKALM_RD read the current alarm
*
* Argument: A writeable reference to struct rtc_wkalrm to receive the
@ -487,6 +500,7 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
}
break;
#endif /* CONFIG_RTC_ALARM */
default:
ret = -ENOTTY;

View File

@ -286,6 +286,7 @@ struct rtc_time
int tm_isdst; /* unused */
};
#ifdef CONFIG_RTC_ALARM
/* Structure used with the RTC_WKALM_RD and RTC_WKALM_SET IOCTL commands.
*
* The enabled flag is used to enable or disable the alarm interrupt, or to
@ -302,6 +303,7 @@ struct rtc_wkalrm
unsigned char pending;
struct rtc_time time;
};
#endif
/* The RTC driver is implemented as a common, upper-half character driver
* that provides the RTC driver structure and a lower-level, hardware
@ -328,6 +330,7 @@ struct rtc_ops_s
CODE int (*settime)(FAR struct rtc_lowerhalf_s *lower,
FAR const struct rtc_time *rtctime);
#ifdef CONFIG_RTC_ALARM
/* almread reads the alarm time (for RTCs that support alarms) */
CODE int (*almread)(FAR struct rtc_lowerhalf_s *lower,
@ -337,7 +340,9 @@ struct rtc_ops_s
CODE int (*almset)(FAR struct rtc_lowerhalf_s *lower,
FAR const struct rtc_time *almtime);
#endif
#ifdef CONFIG_RTC_PERIODIC
/* irqpread the frequency for periodic interrupts (for RTCs that support
* periodic interrupts)
*/
@ -351,23 +356,31 @@ struct rtc_ops_s
CODE int (*irqpset)(FAR struct rtc_lowerhalf_s *lower,
unsigned long irqpfreq);
#endif
#ifdef CONFIG_RTC_ALARM
/* aie enable/disable alarm interrupts (for RTCs that support alarms) */
CODE int (*aie)(FAR struct rtc_lowerhalf_s *lower, bool enable);
#endif
#ifdef CONFIG_RTC_ONESEC
/* uie enable/disable the interrupt on every clock update (for RTCs that
* support this once-per-second interrupt).
*/
CODE int (*uie)(FAR struct rtc_lowerhalf_s *lower, bool enable);
#endif
#ifdef CONFIG_RTC_PERIODIC
/* pie enable the periodic interrupt (for RTCs that support these periodic
* interrupts).
*/
CODE int (*pie)(FAR struct rtc_lowerhalf_s *lower, bool enable);
#endif
#ifdef CONFIG_RTC_EPOCHYEAR
/* rdepoch read the Epoch. */
CODE int (*rdepoch)(FAR struct rtc_lowerhalf_s *lower,
@ -377,7 +390,9 @@ struct rtc_ops_s
CODE int (*setepoch)(FAR struct rtc_lowerhalf_s *lower,
unsigned long epoch);
#endif
#ifdef CONFIG_RTC_ALARM
/* rdwkalm read the current alarm */
CODE int (*rdwkalm)(FAR struct rtc_lowerhalf_s *lower,
@ -387,6 +402,7 @@ struct rtc_ops_s
CODE int (*setwkalm)(FAR struct rtc_lowerhalf_s *lower,
FAR const struct rtc_wkalrm *wkalrm);
#endif
/* The driver has been unlinked and there are no further open references
* to the driver.