A time interface class. This class replicates the normal time functions, but goes a couple of steps further. mbed library 82 and prior has a defective gmtime function. Also, this class enables access to setting the time, and adjusting the accuracy of the RTC.

Dependencies:   CalendarPage

Dependents:   CI-data-logger-server WattEye X10Svr SSDP_Server

TimeInterface.h

Committer:
WiredHome
Date:
2014-06-14
Revision:
1:2ee90f546f54
Parent:
0:61112ca9193b
Child:
2:65e0a25c7551

File content as of revision 1:2ee90f546f54:


#ifndef TIMEINTERFACE_H
#define TIMEINTERFACE_H
#include "mbed.h"

// Special Registers and their usage:
// GPREG0: 32 bits
//      low word: time zone offset (-720 to +720)
//      high word: 2's complement of low word for integrity checking
// GPREG1: 32 bits
//      time_t value when the clock was last set


extern "C" {
#include "time.h"
}

struct tm_ex
{
    int   tm_sec;       ///<! seconds, 0 to 59.
    int   tm_min;       ///<! minutes, 0 to 59.
    int   tm_hour;      ///<! hours,   0 to 23.
    int   tm_mday;      ///<! monthday 1 to 31.
    int   tm_mon;       ///<! month    0 to 11.
    int   tm_year;      ///<! years since 1900.
    int   tm_wday;      ///<! days since sunday 0 to 6.
    int   tm_yday;      ///<! days since 1 Jan 0 to 365.
    int   tm_isdst;     ///<! is daylight savings time.
    int   tm_tzo_min;   ///<! localtime zone offset in minutes
};

/// TimeInterface class is much like the normal c-style time.h
/// interface, but is extended with time-zone support, and
/// clock-adjustment support (which permits tuning the clock)
/// for more accuracy.
///
/// Within this class are the normal time.h methods, simply
/// exposed here for one consistent interface.
///
/// @note This class uses the special battery backed registers
///     GPREG0 and GPREG1 for TimeInterface data.
///
/// @note In mbed library ver 84, the gmtime method is defective,
///     and calls to this function return junk data. The 
///     gmtime method in this library actually uses localtime,
///     but manages the time-zone offset as it does so.
///
class TimeInterface
    {
public:
    TimeInterface();
    
    ~TimeInterface();
    
    /// Gets the system elapsed time in CLOCKS_PER_SEC tics.
    ///
    /// Divide the returned value by CLOCKS_PER_SEC to get time in seconds.
    ///
    /// @code
    /// clock_t tstart, tend;
    /// tstart = clock();
    /// // do something long
    /// tend = clock();
    /// printf("Elapsed time is %5.3f\r\n", (float)(tend - tstart)/CLOCKS_PER_SEC);
    /// @endcode
    ///
    /// @returns elapsed tics.
    ///
    clock_t clock(void);
    
    /// Gets the current time as a time value, optionally writing it
    /// to a provided buffer.
    ///
    /// This reads the real time clock and returns the current time.
    ///
    /// @code
    /// time_t t_ref1, t_ref2, t_ref3;
    /// t_ref1 = time(NULL); t_ref2 = t.time(); t.time(&t_ref3);
    /// @endcode
    ///
    /// @param[inout] timer is an optional pointer to a time_t value that will be written. 
    ///     This pointer is ignored when NULL.
    /// @returns time value.
    ///
    time_t time(time_t * timer = NULL);

    /// Gets the current local time as a time value, optionally writing it
    /// to a provided buffer.
    ///
    /// This reads the real time clock and returns the current time, adjusted
    /// for the local timezone.
    ///
    /// @code
    /// time_t t_ref2, t_ref3;
    /// t_ref2 = t.time(); t.timelocal(&t_ref3);
    /// @endcode
    ///
    /// @param[inout] timer is an optional pointer to a time_t value that will be written. 
    ///     This pointer is ignored when NULL.
    /// @returns the time value adjusted for the local time zone.
    ///
    time_t timelocal(time_t * timer = NULL);

    /// Convert a time value structure into an ASCII printable time Www Mmm dd hh:mm:ss yyyy
    ///
    /// @note Watch out for race conditions as this returns a pointer to a
    ///     shared buffer.
    /// @note Unlike the standard ctime function, this version DOES NOT append 
    ///     a newline character to the buffer.
    ///
    /// @param[in] timeptr is a pointer to a tm structure containing the time to convert.
    /// @returns a pointer to a private buffer containing the string.
    ///
    char * ctime(const time_t * timer);

    /// Convert a tm structure into an ASCII printable time Www Mmm dd hh:mm:ss yyyy
    ///
    /// @note Watch out for race conditions as this returns a pointer to a
    ///     shared buffer.
    /// @note Unlike the standard ctime function, this version DOES NOT append 
    ///     a newline character to the buffer.
    ///
    /// @param[in] timeptr is a pointer to a tm structure containing the time to convert.
    /// @returns a pointer to a private buffer containing the string.
    ///
    char * asctime(const struct tm_ex *timeptr);

    /// Compute the difference in seconds between two time values.
    ///
    /// @param[in] end is the end time to compare to the beginning time.
    /// @param[in] beginning time is compared to the end time.
    /// @return the difference in seconds, as a double.
    ///
    double difftime(time_t end, time_t beginning);
    
    /// Convert the referenced time_t value to a tm structure in UTC/GMT format.
    ///
    /// @note Watch out for race conditions as this returns a pointer to a
    ///     shared buffer.
    ///
    /// @param[in] timer is a pointer to a time_t structure to convert.
    /// @returns pointer to a tm structure.
    ///
    struct tm_ex * gmtime(const time_t * timer);
    
    
    /// Convert the referenced time_t value to a tm structure in local format.
    ///
    /// This method leverages the time zone offset applied with @see set_tzo().
    ///
    /// @note Watch out for race conditions as this returns a pointer to a
    ///     shared buffer.
    ///
    /// @param[in] timer is a pointer to a time_t structure to convert.
    /// @returns pointer to a tm structure.
    ///
    struct tm_ex * localtime(const time_t * timer);
    
    /// Convert a tm_ex structure (an extended time structure) to a time_t
    /// value.
    ///
    /// @param[in] timeptr is a pointer to a tm_ex structure.
    /// @returns the computed time_t value.
    ///
    time_t mktime(struct tm_ex * timeptr);
    
    /// Presents a time value in a user specified format, into a user specified buffer.
    ///
    /// @param[out] ptr is a pointer to the user buffer.
    /// @param[in] maxsize is the size of the user buffer.
    /// @param[in] format is a pointer to the special strftime format specification.
    /// @param[in] timeptr is a pointer to the tm_ex structure.
    /// @returns the total number of characters copied into the buffer.
    ///
    size_t strftime(char * ptr, size_t maxsize, const char * format, const struct tm_ex * timeptr);
    
    // time zone functions
    
    /// Set the internal RTC (clock) to the time value. The time value
    /// should be the UTC time, which then permits gmtime and 
    /// localtime to be used appropriately.
    ///
    /// @param[in] t is the UTC time value to set the clock to. If the available 
    ///     time value is local time, the optional time zone offset can
    ///     be provided.
    /// @param[in] tzo is the optional time zone offset in minutes when it is in
    ///     the range of -720 to +720 (-12 hours to + 12 hours). Any
    ///     other value is illegal and no change will be made.
    ///
    void set_time(time_t t, int16_t tzo_min = 0);
    
    /// Set the time zone offset in minutes.
    ///
    /// This API should be used before any other methods that fetch
    /// the RTC info.
    ///
    /// @param[in] tzo is the time zone offset in minutes when it is in
    ///     the range of -720 to +720 (-12 hours to + 12 hours). Any
    ///     other value is illegal and no change will be made.
    ///
    void set_tzo_min(int16_t tzo_min);
    
    /// Get the time zone offset in minutes.
    ///
    /// @returns the time zone offset value in minutes. If the tzo was
    /// never initialized, this returns zero.
    ///
    int16_t get_tzo_min(void);
    
    /// Get the time value when the clock was last set. This is most
    /// often used in calibration of the clock.
    ///
    /// @returns time last set as a UTC time value.
    ///
    time_t get_timelastset(void);
    
    /// get_cal will return the calibration register value
    ///
    /// This is the raw register value as a signed 32-bit value (even though
    /// it is actually a 17-bit unsigned value with an additional 'direction' flag).
    ///
    /// @returns calibration settings ranging from -131071 to +131071
    ///
    int32_t get_cal();

    /// set_cal will set the calibration register value
    ///
    /// This accepts a signed value to be used to set the calibration
    /// registers. Setting the calibration value to zero disables the
    /// 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[in] calibration value to use ranging from -131071 to +131071
    /// @returns nothing
    ///
    void set_cal(int32_t calibration);

    /// adjust_sec 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[in] 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 adjust_sec(int32_t adjustSeconds);

    
    // ntp interface functions
    
private:
    char result[30];    // holds the converted to text time string
    time_t tresult;     // holds the converted time structure.
    struct tm_ex tm_ext;
    };

#endif // TIMEINTERFACE_H