This is a library for managing the mbed real time clock, including functions for setting and getting the rtc in text format, getting and setting the timezone offset, and getting and setting the calibration register, both directly, and by using an adjustment API to automatically set the calibration value.
Revision 5:fbbdf57675c3, committed 2011-10-30
- Comitter:
- WiredHome
- Date:
- Sun Oct 30 23:42:43 2011 +0000
- Parent:
- 4:dfb2e93f804a
- Child:
- 6:a517fee06e2e
- Commit message:
- v1.03 Added API to adjust the calibration based on an accumulated error over a period of time (typically >= 1 day).
Changed in this revision
TimeUtilities.cpp | Show annotated file Show diff for this revision Revisions of this file |
TimeUtilities.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/TimeUtilities.cpp Sat Jul 16 16:57:22 2011 +0000 +++ b/TimeUtilities.cpp Sun Oct 30 23:42:43 2011 +0000 @@ -15,19 +15,13 @@ /// /// @author David Smart, Smartware Computing /// -/// Version History -/// 20110616 -/// \li minor documentation changes -/// 20110601 -/// \li discovered the CCALEN flag to enable calibration -/// 20110529 -/// \li original version -/// #ifndef WIN32 // embedded build #include "mbed.h" #endif +#define VERSION "1.03" + #include "TimeUtilities.h" #include <time.h> #include <string.h> @@ -38,7 +32,8 @@ // Fake it out for Win32 development and testing struct LPC { unsigned long CCR; // Clock Control register - unsigned long GPREG0; // General Purpose Register - Battery backed + unsigned long GPREG0; // General Purpose Register #0 - 32-bit Battery backed + unsigned long GPREG1; // General Purpose Register #1 - 32-bit Battery backed unsigned long CALIBRATION; // Calibration Register }; struct LPC X; @@ -48,6 +43,10 @@ static int tzOffsetHr = 0; ///!< time zone offset hours to print time in local time static int tzOffsetMin = 0; ///!< time zone offset minutes to print time in local time +static time_t timeWhenLastSet = 0; + + +static const char ver[] = VERSION; static int SignOf(const int i) { return (i >= 0) ? 1 : -1; @@ -56,12 +55,25 @@ RealTimeClock::RealTimeClock() { GetTimeOffsetStore(); + GetTimeLastSetStore(); } RealTimeClock::~RealTimeClock() { } +const char * RealTimeClock::GetVersion() { + return ver; +} + +time_t RealTimeClock::GetTimeValue() { + return time(NULL); +} + +time_t RealTimeClock::GetTimeValueWhenSet() { + return timeWhenLastSet; +} + void RealTimeClock::GetTimeString(char *buf, time_t tValue) { GetTimeOffsetStore(); // Load the time zone offset values from the battery ram @@ -126,6 +138,13 @@ tzOffsetMin = (LPC_RTC->GPREG0 & 0xFF); } +void RealTimeClock::SetTimeLastSetStore() { + LPC_RTC->GPREG1 = timeWhenLastSet; +} + +void RealTimeClock::GetTimeLastSetStore() { + timeWhenLastSet = LPC_RTC->GPREG1; +} // MM/DD/YYYY HH:MM:SS [(+/-hh:mm)] bool RealTimeClock::SetTime(char * timestring) { @@ -168,6 +187,8 @@ seconds = mktime(t); seconds = seconds - (time_t)(tzOffsetHr * 3600 + tzOffsetMin * 60); set_time(seconds); + timeWhenLastSet = seconds; + SetTimeLastSetStore(); } } } @@ -177,3 +198,34 @@ return success; } +bool RealTimeClock::AdjustBySeconds(int32_t adjustSeconds) { + if (timeWhenLastSet != 0) { + time_t seconds = time(NULL); // get "now" according to the rtc + int32_t delta = seconds - timeWhenLastSet; + int32_t curCal = GetTimeCalibration(); + int32_t calMAX = 131071; + int32_t secPerDay = 86400; + float errSecPerDay; + + // Make the clock correct + seconds = seconds + adjustSeconds; + set_time(seconds); + + // Convert the current calibration and the adjustment into + // the new calibration value + // assume it is +10sec and it has been 2days, then the adjustment + // needs to be +5 sec per day, or one adjustment every 1/5th + // of a day, or 1 adjustment every 86400/5 counts. + // delta = now - then (number of elapsed seconds) + if (adjustSeconds != 0 && delta != 0) { + int32_t calFactor; + errSecPerDay = (float)adjustSeconds / ((float)(delta)/secPerDay); + calFactor = (int32_t)((float)secPerDay/errSecPerDay); + if (abs(calFactor) < calMAX) + SetTimeCalibration(calFactor); + } + return true; + } else { + return false; + } +} \ No newline at end of file
--- a/TimeUtilities.h Sat Jul 16 16:57:22 2011 +0000 +++ b/TimeUtilities.h Sun Oct 30 23:42:43 2011 +0000 @@ -19,6 +19,9 @@ /// /// @note /// History +/// v1.03 20111030 +/// \li Adding an API to adjust time and calibration based on how far it is +/// off "now", based on when it was set. /// v1.02 /// \li 20110716 Minor documentation update /// \li 20110616 Minor documentation updates @@ -31,10 +34,8 @@ #define TIMEUTILITIES_H #ifndef WIN32 -// embedded build #include "mbed.h" #else -// fake it for Windows build typedef int int32_t; #endif @@ -84,6 +85,26 @@ /// ~RealTimeClock(); + /// GetTimeValue gets the current time in time_t format + /// + /// Gets the current time from the rtc and returns the time in time_t format. + /// This is functionally identical to "return time(NULL);", + /// simply wrapped in this class for convenience. + /// + /// @returns current time in time_t format + /// + time_t GetTimeValue(); + + /// GetTimeValueWhenSet gets the time in time_t seconds when the clock was last set + /// + /// This value represents the time_t time when the clock was set. + /// This value is not preserved through power cycles, or resets, in which + /// case it will return 0. + /// + /// @returns time in time_t format when the clock was last set + /// + time_t GetTimeValueWhenSet(); + /// GetTimeString gets the formatted time applying the internal time-zone offset of hours and minutes /// /// It places the formatted string into the buffer in the format of @@ -132,24 +153,6 @@ /// void SetTimeOffset(int offsetHour, int offsetMinute); - /// SetTimeOffsetStore will store the timezone offset values in RTC ram - /// - /// This takes the current timezone offset values and stores them in - /// the RTC battery backed ram. - /// - /// @returns nothing - /// - void SetTimeOffsetStore(); - - /// GetTimeOffsetStore will extract the timezone offset values from RTC ram - /// - /// This extracts the timezone offset values that were stored in RTC - /// battery backed ram and uses them for time information. - /// - /// @returns nothing - /// - void GetTimeOffsetStore(); - /// GetTimeCalibration will return the calibration register value /// /// This is the raw register value as a signed 32-bit value (even though @@ -163,7 +166,11 @@ /// /// This accepts a signed value to be used to set the calibration /// registers. Setting the calibration value to zero disables the - /// calibration function. + /// calibration function. + /// It is important to know the register function in order to use + /// this command, and this API is normally not used by external + /// application code. @See AdjustBySeconds for a user-friendly + /// API. /// /// @param calibration value to use ranging from -131071 to +131071 /// @returns nothing @@ -184,6 +191,79 @@ /// @returns true if the time was set /// bool SetTime(char * timestring); + + + /// AdjustBySeconds adjusts both the time and the calibration by seconds + /// + /// This will take a signed value, which is the current adjustment in seconds + /// to put the clock on the correct time. So, if the clock is behind by + /// 3 seconds, the value should be +3 to advance the clock accordingly. + /// It will then adjust the time, and it will attempt to adjust the + /// calibration factor to make the time more accurate. + /// + /// The adjustment can only be made if it has retained when the clock was + /// last set, in order to know by how much to adjust it. It is also most + /// accurate if several days have elapsed since the time was set. + /// + /// @note The current version only works if the calibration value + /// is zero when this adjustment is made. + /// + /// @param adjustSeconds is the signed value by which to adjust the time to + /// correct it to the current actual time. + /// @returns true if the adjustment was made + /// @returns false if the adjustment could not be made + /// + bool AdjustBySeconds(int32_t adjustSeconds); + + /// GetVersion will return a pointer to a constant text string + /// + /// This returns a pointer to a constant string which represents + /// the version of this component. + /// + /// @returns pointer to a character string holding the version. + /// + const char * GetVersion(); + +private: + + /// SetTimeOffsetStore will store the timezone offset values in RTC ram + /// + /// This takes the current timezone offset values and stores them in + /// the RTC battery backed ram. + /// + /// @returns nothing + /// + void SetTimeOffsetStore(); + + /// GetTimeOffsetStore will extract the timezone offset values from RTC ram + /// + /// This extracts the timezone offset values that were stored in RTC + /// battery backed ram and uses them for time information. + /// + /// @returns nothing + /// + void GetTimeOffsetStore(); + + /// SetTimeLastSetStore will store the time_t when last set in RTC ram + /// + /// When the clock is correctly set, the time value will be stored + /// which permits later adjustments to the calibration based on + /// elapsed time and knowing when it was set. + /// + /// @returns nothing + /// + void SetTimeLastSetStore(); + + /// GetTimeLastSetStore will extract the time_t when last set from RTC ram + /// + /// When the clock is correctly set, the time value will have been stored + /// which permits later adjustments to the calibration based on + /// elapsed time and knowing when it was set. This function retrieves it. + /// + /// @returns nothing + /// + void GetTimeLastSetStore(); + }; #endif