Add support for lo- and hi-res RTC hardware

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4005 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2011-10-01 22:09:00 +00:00
parent b83c820523
commit 3f4af2fe30
13 changed files with 750 additions and 307 deletions
+5
View File
@@ -2121,3 +2121,8 @@
* configs/sam3u/touchscreen - This is the configuration that I plan to use * configs/sam3u/touchscreen - This is the configuration that I plan to use
to verify the SAM3U-EK touchscreen driver. However, as of this writing, to verify the SAM3U-EK touchscreen driver. However, as of this writing,
there is no touchscreen driver for the board. there is no touchscreen driver for the board.
* CONFIG_RTC_HIRES - Add an option to support either a high-resolution RTC
that completely replaces the system timer tick but may overflow and lose
time when the MCU is off and also for a low-resolution (1 sec/tick) RTC
that can run until 2106 with no overflow. But in this latter case, higher
resolution time must come from the system timer.
+53 -14
View File
@@ -12,7 +12,7 @@
<h1><big><font color="#3c34ec"> <h1><big><font color="#3c34ec">
<i>NuttX RTOS Porting Guide</i> <i>NuttX RTOS Porting Guide</i>
</font></big></h1> </font></big></h1>
<p>Last Updated: September 13, 2011</p> <p>Last Updated: October 1, 2011</p>
</td> </td>
</tr> </tr>
</table> </table>
@@ -1989,18 +1989,30 @@ CONFIG_SYSTEM_UTC=y
<h4>4.1.20.2 Hardware</h4> <h4>4.1.20.2 Hardware</h4>
<p> <p>
To enable hardware module use option: To enable hardware module use the following configuration options:
<p> <p>
<ul><pre> <ul><dl>
CONFIG_RTC=y <dt><code>CONFIG_RTC</code>
</pre></ul> <dd>Enables general support for a hardware RTC.
Specific architectures may require other specific settings.
<dt><code>CONFIG_RTC_HIRES</code>
<dd>The typical RTC keeps time to resolution of 1 second, usually supporting a 32-bit <code>time_t</code> value.
In this case, the RTC is used to &quot;seed&quot; the normal NuttX timer and the NuttX timer provides for higher resoution time.
If <code>CONFIG_RTC_HIRES</code> is enabled in the NuttX configuration, then the RTC provides higher resolution time and completely replaces the system timer for purpose of date and time.
<dt><code>CONFIG_RTC_FREQUENCY</code>
<dd>If <code>CONFIG_RTC_HIRES</code> is defined, then the frequency of the high resolution RTC must be provided.
If <code>CONFIG_RTC_HIRES</code> is not defined, <code>CONFIG_RTC_FREQUENCY</code> is assumed to be one.
<dt><code>CONFIG_RTC_ALARM</code>
<dd>Enable if the RTC hardware supports setting of an alarm.
A callback function will be executed when the alarm goes off
</dl></ul>
<p> <p>
which requires the following three base functions to read time: which requires the following three base functions to read time:
</p> </p>
<ul> <ul>
<li><code>up_rtcinitialize()</code></li> <li><code>up_rtcinitialize()</code></li>
<li><code>up_rtc_gettime()</code>. UTC time in seconds.</li> <li><code>up_rtc_time()</code>. UTC time in seconds.</li>
<li><code>up_rtc_getclock()</code>. Replacement for <code>g_system_tick</code></li> <li><code>up_rtc_gettime()</code>. Replacement for <code>g_system_tick</code></li>
</ul> </ul>
<p> <p>
This module depends on <code>CONFIG_SYSTEM_UTC=y</code>. This module depends on <code>CONFIG_SYSTEM_UTC=y</code>.
@@ -2024,15 +2036,17 @@ CONFIG_RTC=y
Running at rate of system base timer, used for time-slicing, and so forth. Running at rate of system base timer, used for time-slicing, and so forth.
</p> </p>
<p> <p>
If hardware RTC is present (<code>CONFIG_RTC</code>) and enabled, then after successful If hardware RTC is present (<code>CONFIG_RTC</code>) and and high-resolution timeing
initiliazation variables are overriden by calls to <code>up_rtc_getclock()</code> which is is enabled (<code>CONFIG_RTC_HIRES</code>), then after successful
initiliazation variables are overriden by calls to <code>up_rtc_gettime()</code> which is
running continously even in power-down modes. running continously even in power-down modes.
</p> </p>
<p> <p>
In the case of <code>CONFIG_RTC</code> is set the <code>g_tickcount</code> and <code>g_system_utc</code> keep In the case of <code>CONFIG_RTC_HIRES</code> is set the <code>g_tickcount</code> and
counting at rate of a system timer, which however, is disabled in power-down <code>g_system_utc</code> keep counting at rate of a system timer, which however, is
mode. By comparing this time and RTC (actual time) one may determine the disabled in power-down mode.
actual system active time. To retrieve that variable use: By comparing this time and RTC (actual time) one may determine the actual system active time.
To retrieve that variable use:
</p> </p>
<ul><pre> <ul><pre>
<li><code>clock_gettime(CLOCK_ACTIVETIME, tp)</code> <li><code>clock_gettime(CLOCK_ACTIVETIME, tp)</code>
@@ -4239,10 +4253,35 @@ build
</ul> </ul>
<h2>Device Drivers</h2> <h2>Device Drivers</h2>
<h3>RTC</h3>
<ul>
<li>
<code>CONFIG_RTC</code>:
Enables general support for a hardware RTC.
Specific architectures may require other specific settings.
</li>
<li>
<code>CONFIG_RTC_HIRES</code>:
The typical RTC keeps time to resolution of 1 second, usually supporting a 32-bit <code>time_t</code> value.
In this case, the RTC is used to &quot;seed&quot; the normal NuttX timer and the NuttX timer provides for higher resoution time.
If <code>CONFIG_RTC_HIRES</code> is enabled in the NuttX configuration, then the RTC provides higher resolution time and completely replaces the system timer for purpose of date and time.
</li>
<li>
<code>CONFIG_RTC_FREQUENCY</code>:
If <code>CONFIG_RTC_HIRES</code> is defined, then the frequency of the high resolution RTC must be provided.
If <code>CONFIG_RTC_HIRES</code> is not defined, <code>CONFIG_RTC_FREQUENCY</code> is assumed to be one.
</li>
<li>
<code>CONFIG_RTC_ALARM</code>:
Enable if the RTC hardware supports setting of an alarm.
A callback function will be executed when the alarm goes off
</li>
</ul>
<h3>SPI driver</h3> <h3>SPI driver</h3>
<ul> <ul>
<li> <li>
<code>CONFIG_SPI_OWNBUS</code> - Set if there is only one active device <code>CONFIG_SPI_OWNBUS</code>: Set if there is only one active device
on the SPI bus. No locking or SPI configuration will be performed. on the SPI bus. No locking or SPI configuration will be performed.
It is not necessary for clients to lock, re-configure, etc.. It is not necessary for clients to lock, re-configure, etc..
</li> </li>
+2 -1
View File
@@ -6,6 +6,7 @@
* *
* With extensions, modifications by: * With extensions, modifications by:
* *
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregroy Nutt <gnutt@nuttx.org> * Author: Gregroy Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -932,7 +933,7 @@ static inline void stm32_i2c_enablefsmc(uint32_t ahbenr)
} }
} }
#else #else
# define stm32_i2c_disablefsmc() (0) # define stm32_i2c_disablefsmc(priv) (0)
# define stm32_i2c_enablefsmc(ahbenr) # define stm32_i2c_enablefsmc(ahbenr)
#endif #endif
File diff suppressed because it is too large Load Diff
+1
View File
@@ -268,6 +268,7 @@ CONFIG_WIRELESS=y
# #
CONFIG_RTC=y CONFIG_RTC=y
CONFIG_RTC_HIRES=y CONFIG_RTC_HIRES=y
CONFIG_RTC_FREQUENCY=16384
CONFIG_SYSTEM_UTC=y CONFIG_SYSTEM_UTC=y
# #
+2 -3
View File
@@ -714,9 +714,8 @@ int sif_main(int argc, char *argv[])
struct timespec t_active; struct timespec t_active;
clock_gettime(CLOCK_ACTIVETIME, &t_active); clock_gettime(CLOCK_ACTIVETIME, &t_active);
fprintf(stderr, "rtc time = %u / %u, active = %u / %u, time / systick = %u / %u\n", fprintf(stderr, "rtc time = %u, active = %u / %u, time / systick = %u / %u\n",
up_rtc_gettime(), up_rtc_getclock(), up_rtc_time(), t_active.tv_sec, t_active.tv_nsec,
t_active.tv_sec, t_active.tv_nsec,
time(NULL), clock_systimer() ); time(NULL), clock_systimer() );
return -1; return -1;
} }
+1 -1
View File
@@ -172,7 +172,7 @@ extern "C" {
* *
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_RTC) || !__HAVE_KERNEL_GLOBALS #if defined(CONFIG_SYSTEM_UTC) || !__HAVE_KERNEL_GLOBALS
EXTERN uint32_t clock_systimer(void); EXTERN uint32_t clock_systimer(void);
#endif #endif
+114 -17
View File
@@ -4,6 +4,11 @@
* Copyright(C) 2011 Uros Platise. All rights reserved. * Copyright(C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu> * Author: Uros Platise <uros.platise@isotel.eu>
* *
* With extensions, modifications by:
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregroy Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@@ -44,19 +49,51 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <time.h>
#include <nuttx/clock.h>
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* Configuration ************************************************************/
/* CONFIG_RTC - Enables general support for a hardware RTC. Specific
* architectures may require other specific settings.
*
* CONFIG_RTC_HIRES - The typical RTC keeps time to resolution of 1 second,
* usually supporting a 32-bit time_t value. In this case, the RTC is
* used to "seed" the normal NuttX timer and the NuttX timer provides
* for higher resoution time.
*
* If CONFIG_RTC_HIRES is enabled in the NuttX configuration, then the
* RTC provides higher resolution time and completely replaces the system
* timer for purpose of date and time.
*
* CONFIG_RTC_FREQUENCY - If CONFIG_RTC_HIRES is defined, then the frequency
* of the high resolution RTC must be provided. If CONFIG_RTC_HIRES is
* not defined, CONFIG_RTC_FREQUENCY is assumed to be one.
*
* CONFIG_RTC_ALARM - Enable if the RTC hardware supports setting of an
* alarm. A callback function will be executed when the alarm goes off
*/
#define RTC_CLOCKS_PER_SEC 16384 #ifdef CONFIG_RTC_HIRES
#define RTC_CLOCKS_SHIFT 14 # ifndef CONFIG_RTC_FREQUENCY
# error "CONFIG_RTC_FREQUENCY is required for CONFIG_RTC_HIRES"
# endif
#else
# ifndef CONFIG_RTC_FREQUENCY
# define CONFIG_RTC_FREQUENCY 1
# endif
# if CONFIG_RTC_FREQUENCY != 1
# error "The low resolution RTC must have frequency 1Hz"
# endif
#endif
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
/* The form of an alarm callback */
typedef void (alarmcb_t)(void);
/**************************************************************************** /****************************************************************************
* Public Variables * Public Variables
@@ -83,32 +120,92 @@ extern "C" {
#define EXTERN extern #define EXTERN extern
#endif #endif
/**************************************************************************** /************************************************************************************
* Name: up_rtcinitialize * Name: up_rtcinitialize
* *
* Description: * Description:
* Initialize the periodic timer interface. This function is called once * Initialize the hardware RTC per the select configuration. This function is
* from the clock_initialize() function. * called once during the OS initialization sequence
*
* Input Parameters:
* None
* *
* Returned Value: * Returned Value:
* Returns OK if RTC has successfully started, otherwise ERROR. * Zero (OK) on success; a negated errno on failure
* *
****************************************************************************/ ************************************************************************************/
EXTERN int up_rtcinitialize(void); EXTERN int up_rtcinitialize(void);
EXTERN int up_rtcinitialize(void);
EXTERN clock_t up_rtc_getclock(void); /************************************************************************************
EXTERN void up_rtc_setclock(clock_t clock); * Name: up_rtc_time
*
* Description:
* Get the current time in seconds. This is similar to the standard time()
* function.
*
* Input Parameters:
* None
*
* Returned Value:
* The current time in seconds
*
************************************************************************************/
EXTERN time_t up_rtc_gettime(void); EXTERN time_t up_rtc_time(void);
EXTERN void up_rtc_settime(time_t time);
EXTERN clock_t up_rtc_setalarm(clock_t atclock); /************************************************************************************
* Name: up_rtc_gettime
*
* Description:
* Get the current time from the high resolution RTC clock.
*
* Input Parameters:
* tp - The location to return the high resolution time value.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
/* This callback is provided by the clock module and called by the RTC ISR */ #ifdef CONFIG_RTC_HIRES
EXTERN int up_rtc_gettime(FAR struct timespec *tp);
#endif
EXTERN void clock_rtcalarmcb(clock_t clock); /************************************************************************************
* Name: up_rtc_settime
*
* Description:
* Set the RTC to the provided time.
*
* Input Parameters:
* tp - the time to use
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
EXTERN int up_rtc_settime(FAR const struct timespec *tp);
/************************************************************************************
* Name: up_rtc_setalarm
*
* Description:
* Set up a alarm.
*
* Input Parameters:
* tp - the time to set the alarm
* callback - the function to call when the alarm expires.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
#ifdef CONFIG_RTC_ALARM
EXTERN int up_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback);
#endif
#undef EXTERN #undef EXTERN
#if defined(__cplusplus) #if defined(__cplusplus)
+1 -1
View File
@@ -77,7 +77,7 @@
* power down modes. Unit is 1 second. * power down modes. Unit is 1 second.
*/ */
#ifdef CONFIG_RTC #ifdef CONFIG_SYSTEM_UTC
# define CLOCK_ACTIVETIME 1 # define CLOCK_ACTIVETIME 1
#endif #endif
+16 -41
View File
@@ -113,7 +113,12 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
if (clock_id == CLOCK_REALTIME && tp) if (clock_id == CLOCK_REALTIME && tp)
{ {
/* If CONFIG_SYSTEM_UTC is not defined, then we have to get the time
* from g_system_timer.
*/
#ifndef CONFIG_SYSTEM_UTC #ifndef CONFIG_SYSTEM_UTC
/* Get the elapsed time since power up (in milliseconds) biased /* Get the elapsed time since power up (in milliseconds) biased
* as appropriate. * as appropriate.
*/ */
@@ -151,47 +156,18 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
tp->tv_sec = (time_t)secs; tp->tv_sec = (time_t)secs;
tp->tv_nsec = (long)nsecs; tp->tv_nsec = (long)nsecs;
#else /* if CONFIG_SYSTEM_UTC=y */ #else /* CONFIG_SYSTEM_UTC */
#ifdef CONFIG_RTC /* CONFIG_SYSTEM_UTC is defined. But we might be able to get the time
* from the hardware if a high resolution RTC is available.
*/
#ifdef CONFIG_RTC_HIRES
if (g_rtc_enabled) if (g_rtc_enabled)
{ {
/* up_rtc_gettime() returns the time in seconds and up_rtc_getclock() /* Get the hi-resolution time from the RTC */
* will return the time int RTC clock ticks. Under the hood, these
* are probably based on the same running time. However, since we
* sample this time twice, we have to add the following strange logic
* to assure that the fractional second value does not rollover to
* a full second between sampling times.
*/
clock_t rtc_frac; /* Current fractional seconds in RTC ticks */ ret = up_rtc_gettime(tp);
clock_t rtc_last; /* Previous fractional seconds in RTC ticks */
time_t rtc_sec; /* Current seconds */
/* Interrupts are disabled here only to prevent interrupts and context
* switches from interfering with the consecutive time samples. I
* expect to go through this loop 1 time 99.9% of the time and then
* only twice on the remaining cornercases.
*/
flags = irqsave();
rtc_frac = up_rtc_getclock() & (RTC_CLOCKS_PER_SEC-1);
do
{
rtc_last = rtc_frac;
rtc_sec = up_rtc_gettime();
rtc_frac = up_rtc_getclock() & (RTC_CLOCKS_PER_SEC-1);
}
while (rtc_frac < rtc_last);
irqrestore(flags);
/* Okay.. the samples should be as close together in time as possible
* and we can be assured that no fractional second rollover occurred
* between the samples.
*/
tp->tv_sec = rtc_sec;
tp->tv_nsec = rtc_frac * (1000000000/RTC_CLOCKS_PER_SEC);
} }
else else
#endif #endif
@@ -209,17 +185,16 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
tp->tv_sec = system_utc; tp->tv_sec = system_utc;
tp->tv_nsec = tickcount * (1000000000/TICK_PER_SEC); tp->tv_nsec = tickcount * (1000000000/TICK_PER_SEC);
} }
#endif #endif /* CONFIG_SYSTEM_UTC */
sdbg("Returning tp=(%d,%d)\n", sdbg("Returning tp=(%d,%d)\n", (int)tp->tv_sec, (int)tp->tv_nsec);
(int)tp->tv_sec, (int)tp->tv_nsec);
} }
/* CLOCK_ACTIVETIME is non-standard. Returns active UTC time, which is /* CLOCK_ACTIVETIME is non-standard. Returns active UTC time, which is
* disabled during power down modes. Unit is 1 second. * disabled during power down modes. Unit is 1 second.
*/ */
#ifdef CONFIG_RTC #ifdef CONFIG_SYSTEM_UTC
else if (clock_id == CLOCK_ACTIVETIME && g_rtc_enabled && tp) else if (clock_id == CLOCK_ACTIVETIME && g_rtc_enabled && tp)
{ {
/* Disable interrupts while g_system_utc and g_tickcount are sampled /* Disable interrupts while g_system_utc and g_tickcount are sampled
+73 -41
View File
@@ -54,6 +54,12 @@
* Definitions * Definitions
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_RTC
# ifndef CONFIG_SYSTEM_UTC
# error "In order to support hardware RTC system must have set the CONFIG_SYSTEM_UTC=y"
# endif
#endif
/* Standard time definitions (in units of seconds) */ /* Standard time definitions (in units of seconds) */
#define SEC_PER_MIN ((time_t)60) #define SEC_PER_MIN ((time_t)60)
@@ -85,11 +91,11 @@
****************************************************************************/ ****************************************************************************/
#if CONFIG_SYSTEM_UTC #if CONFIG_SYSTEM_UTC
volatile time_t g_system_utc = 0; volatile time_t g_system_utc;
#else #else
volatile clock_t g_system_timer = 0; volatile clock_t g_system_timer;
struct timespec g_basetime = {0,0}; struct timespec g_basetime;
uint32_t g_tickbias = 0; uint32_t g_tickbias;
#endif #endif
/************************************************************************** /**************************************************************************
@@ -102,11 +108,11 @@ uint32_t g_tickbias = 0;
#if CONFIG_SYSTEM_UTC #if CONFIG_SYSTEM_UTC
#if TICK_PER_SEC > 32767 #if TICK_PER_SEC > 32767
volatile uint32_t g_tickcount = 0; volatile uint32_t g_tickcount;
#elif TICK_PER_SEC > 255 #elif TICK_PER_SEC > 255
volatile uint16_t g_tickcount = 0; volatile uint16_t g_tickcount;
#else #else
volatile uint8_t g_tickcount = 0; volatile uint8_t g_tickcount;
#endif #endif
#endif /* CONFIG_SYSTEM_UTC */ #endif /* CONFIG_SYSTEM_UTC */
@@ -114,7 +120,7 @@ volatile uint8_t g_tickcount = 0;
* Private Functions * Private Functions
**************************************************************************/ **************************************************************************/
/**************************************************************************** /****************************************************************************
* Function: clock_timer * Function: incr_utc
* *
* Description: * Description:
* This function must be called once every time the real * This function must be called once every time the real
@@ -139,9 +145,57 @@ static inline void incr_utc(void)
#endif #endif
/**************************************************************************** /****************************************************************************
* Private Functions * Function: clock_inittime
*
* Description:
* Get the initial time value from the best source available.
*
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_RTC
#ifdef CONFIG_RTC_HIRES
static inline void clock_inittime(FAR struct timespec *tp)
{
/* Get the complete time from the hi-res RTC. */
(void)up_rtc_gettime(tp);
}
#else
static inline void clock_inittime(FAR struct timespec *tp)
{
/* Get the seconds (only) from the lo-res RTC */
tp->tv_sec = up_rtc_time();
tp->tv_nsec = 0;
}
#endif /* CONFIG_RTC_HIRES */
#else /* CONFIG_RTC */
static inline void clock_inittime(FAR struct timespec *tp)
{
time_t jdn = 0;
/* Get the EPOCH-relative julian date from the calendar year,
* month, and date
*/
jdn = clock_calendar2utc(CONFIG_START_YEAR, CONFIG_START_MONTH,
CONFIG_START_DAY);
/* Set the base time as seconds into this julian day. */
tp->tv_sec = jdn * SEC_PER_DAY;
tp->tv_nsec = 0;
}
#endif /* CONFIG_RTC */
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -156,47 +210,25 @@ static inline void incr_utc(void)
void clock_initialize(void) void clock_initialize(void)
{ {
#ifndef CONFIG_SYSTEM_UTC
time_t jdn = 0;
#endif
/* Initialize the real time close (this should be un-nesssary except on a
* restart).
*/
#ifdef CONFIG_SYSTEM_UTC #ifdef CONFIG_SYSTEM_UTC
g_system_utc = 0; struct timespec ts;
#else
g_system_timer = 0;
#endif #endif
/* Do we have hardware RTC support? */ /* Initialize the RTC hardware */
#ifdef CONFIG_RTC #ifdef CONFIG_RTC
#ifndef CONFIG_SYSTEM_UTC
# error In order to support hardware RTC system must have set the CONFIG_SYSTEM_UTC=y
#endif
up_rtcinitialize(); up_rtcinitialize();
#endif #endif
#ifndef CONFIG_SYSTEM_UTC /* Initialize the time value */
/* Get the EPOCH-relative julian date from the calendar year,
* month, and date
*/
jdn = clock_calendar2utc(CONFIG_START_YEAR, CONFIG_START_MONTH,
CONFIG_START_DAY);
/* Set the base time as seconds into this julian day. */
g_basetime.tv_sec = jdn * SEC_PER_DAY;
g_basetime.tv_nsec = 0;
/* These is no time bias from this time. */
#ifdef CONFIG_SYSTEM_UTC
clock_inittime(&ts);
g_system_utc = ts.tv_sec;
g_tickcount = ((ts.tv_nsec > 10) * CLOCKS_PER_SEC) / (1000000000 >> 10);
#else
clock_inittime(&g_basetime);
g_system_timer = 0;
g_tickbias = 0; g_tickbias = 0;
#endif #endif
} }
+23 -5
View File
@@ -43,6 +43,8 @@
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <debug.h> #include <debug.h>
#include <arch/irq.h>
#include "clock_internal.h" #include "clock_internal.h"
/************************************************************************ /************************************************************************
@@ -85,7 +87,7 @@
* *
************************************************************************/ ************************************************************************/
int clock_settime(clockid_t clock_id, const struct timespec *tp) int clock_settime(clockid_t clock_id, FAR const struct timespec *tp)
{ {
int ret = OK; int ret = OK;
@@ -116,12 +118,13 @@ int clock_settime(clockid_t clock_id, const struct timespec *tp)
#ifdef CONFIG_RTC #ifdef CONFIG_RTC
if (g_rtc_enabled) if (g_rtc_enabled)
{ {
up_rtc_settime(tp->tv_sec); up_rtc_settime(tp);
} }
else else
#endif #endif
{
g_system_utc = tp->tv_sec; g_system_utc = tp->tv_sec;
}
#endif #endif
sdbg("basetime=(%d,%d) tickbias=%d\n", sdbg("basetime=(%d,%d) tickbias=%d\n",
@@ -133,10 +136,25 @@ int clock_settime(clockid_t clock_id, const struct timespec *tp)
* disabled during power down modes. Unit is 1 second. * disabled during power down modes. Unit is 1 second.
*/ */
#ifdef CONFIG_RTC #ifdef CONFIG_SYSTEM_UTC
else if (clock_id == CLOCK_ACTIVETIME && g_rtc_enabled && tp) else if (clock_id == CLOCK_ACTIVETIME && tp)
{ {
irqstate_t flags;
uint32_t tickcount;
/* Calculate the number of ticks correspond to the nanosecond count...
* exercising care to avoid overflows. This could still overflow
* if CLOCKS_PER_SEC is very large (something like 4096).
*/
tickcount = ((tp->tv_nsec >> 10) * CLOCKS_PER_SEC) / (1000000000 >> 10);
/* Then set the UTC time (seconds) plus the tickcount (fractional seconds */
flags = irqsave();
g_system_utc = tp->tv_sec; g_system_utc = tp->tv_sec;
g_tickcount = tickcount;
irqrestore(flags);
} }
#endif #endif
+3 -11
View File
@@ -85,20 +85,12 @@ uint32_t clock_systimer(void)
uint32_t tickcount; uint32_t tickcount;
#endif #endif
/* Fetch the g_system_timer value from timer hardware, if available */ #ifdef CONFIG_RTC_HIRES
/* Fetch the g_system_timer value from timer hardware, if available.
#ifdef CONFIG_RTC
/* Check if the periodic timer is initialized
* *
* Note that the unit of the g_system_timer and and up_rtc_getclock() do * Note that the unit of the g_system_timer and and up_rtc_gettime() do
* not have the same unit. * not have the same unit.
*/ */
if (g_rtc_enabled)
{
/* return up_rtc_getclock(); */
}
#endif #endif
#ifndef CONFIG_SYSTEM_UTC #ifndef CONFIG_SYSTEM_UTC