x

Dependents:   20180621_FT813

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MCP79412.h Source File

MCP79412.h

00001 /** mbded library for driving the PMAXIM DS3231 Real Time Clock
00002 * datasheet link : http://datasheets.maximintegrated.com/en/ds/DS3231.pdf
00003 * breakout       : MACETECH ChronoDot V2.1 High Precision RTC
00004 * remi cormier 2012
00005 * WARNING : sda and sdl should be pulled up with 2.2k resistor
00006 */
00007 
00008 /** Example code
00009 * @code
00010 // DS3231 Library test program
00011 // remi cormier 2012
00012 
00013 #include "mbed.h"
00014 #include "DS3231.h"
00015 
00016 Serial pc(USBTX, USBRX);
00017 
00018 int hour;
00019 int minute;
00020 int second;
00021 
00022 int dayOfWeek;
00023 int date;
00024 int month;
00025 int year;  
00026    
00027 DS3231 RTC(p28,p27);
00028 
00029 
00030 int main()
00031     {printf("\r\n\nDS3231 Library test program\r\nremi cormier 2012\r\n\n");
00032     
00033      RTC.setI2Cfrequency(400000);
00034     
00035      //RTC.writeRegister(DS3231_Aging_Offset,0); // uncomment to set Aging Offset 1LSB = approx. 0.1 ppm according from datasheet = 0.05 ppm @ 21 °C from my measurments
00036      
00037      RTC.convertTemperature();
00038       
00039      int reg=RTC.readRegister(DS3231_Aging_Offset);
00040      if (reg>127)
00041         {reg=reg-256;}
00042      pc.printf("Aging offset : %i\r\n",reg);
00043          
00044      pc.printf("OSF flag : %i",RTC.OSF());
00045      pc.printf("\r\n");
00046      
00047      RTC.readDate(&date,&month,&year);
00048      pc.printf("date : %02i-%02i-%02i",date,month,year);
00049      pc.printf("\r\n");
00050      
00051      //RTC.setTime(19,48,45); // uncomment to set time
00052      
00053      RTC.readTime(&hour,&minute,&second);
00054      pc.printf("time : %02i:%02i:%02i",hour,minute,second);
00055      pc.printf("\r\n");
00056      
00057      //RTC.setDate(6,22,12,2012); // uncomment to set date
00058      
00059      RTC.readDateTime(&dayOfWeek,&date,&month,&year,&hour,&minute,&second);
00060      pc.printf("date time : %i / %02i-%02i-%02i %02i:%02i:%02i",dayOfWeek,date,month,year,hour,minute,second);
00061      pc.printf("\r\n");
00062      
00063      pc.printf("temperature :%6.2f",RTC.readTemp());
00064      pc.printf("\r\n");
00065     }
00066 * @endcode
00067 */
00068 
00069 /*
00070 http://www.cplusplus.com/reference/ctime/strftime/
00071 %a   Abbreviated weekday name *  Thu
00072 %A   Full weekday name * Thursday
00073 %b   Abbreviated month name *    Aug
00074 %B   Full month name *   August
00075 %d   Day of the month, zero-padded (01-31)   23
00076 %e   Day of the month, space-padded ( 1-31)  23
00077 %F   Short YYYY-MM-DD date, equivalent to %Y-%m-%d   2001-08-23
00078 %H   Hour in 24h format (00-23)  14
00079 %j   Day of the year (001-366)   235
00080 %m   Month as a decimal number (01-12)   08
00081 %M   Minute (00-59)  55
00082 %R   24-hour HH:MM time, equivalent to %H:%M 14:55
00083 %S   Second (00-61)  02
00084 %T   ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S 14:55:02
00085 %u   ISO 8601 weekday as number with Monday as 1 (1-7)   4
00086 %V   ISO 8601 week number (00-53)    34
00087 %w   Weekday as a decimal number with Sunday as 0 (0-6)  4
00088 %W   Week number with the first Monday as the first day of week one (00-53)  34
00089 %X   Time representation *   14:55:02
00090 %y   Year, last two digits (00-99)   01
00091 %Y   Year    2001
00092 
00093 http://www.cplusplus.com/reference/ctime/tm/
00094 Member   Type    Meaning                        Range
00095 tm_sec   int     seconds after the minute       0-61*
00096 tm_min   int     minutes after the hour         0-59
00097 tm_hour  int     hours since midnight           0-23
00098 tm_mday  int     day of the month               1-31
00099 tm_mon   int     months since January           0-11
00100 tm_year  int     years since 1900    
00101 tm_wday  int     days since Sunday              0-6     (0 = Sunday)
00102 tm_yday  int     days since January 1           0-365
00103 tm_isdst         int Daylight Saving Time flag   
00104 The Daylight Saving Time flag (tm_isdst) is greater than zero if Daylight Saving Time is in effect,
00105 zero if Daylight Saving Time is not in effect, and less than zero if the information is not available.
00106 * tm_sec is generally 0-59. The extra range is to accommodate for leap seconds in certain systems.
00107 
00108 http://www.epochconverter.com/programming/c
00109 Convert from epoch to human readable date
00110     time_t     now;
00111     struct tm  ts;
00112     char       buf[80];
00113     // Get current time
00114     time(&now);
00115     // Format time, "ddd yyyy-mm-dd hh:mm:ss zzz"
00116     ts = *localtime(&now);
00117     strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
00118     printf("%s\n", buf);
00119 
00120 Convert from human readable date to epoch
00121     struct tm t;
00122     time_t t_of_day;
00123     t.tm_year = 2011-1900;
00124     t.tm_mon = 7;           // Month, 0 - jan
00125     t.tm_mday = 8;          // Day of the month
00126     t.tm_hour = 16;
00127     t.tm_min = 11;
00128     t.tm_sec = 42;
00129     t.tm_isdst = -1;        // Is DST on? 1 = yes, 0 = no, -1 = unknown
00130     t_of_day = mktime(&t);
00131     printf("seconds since the Epoch: %ld\n", (long) t_of_day)
00132 
00133 https://github.com/raburton/esp8266/blob/master/drivers/ds3231.c
00134 https://github.com/raburton/esp8266/blob/master/drivers/ds3231.h
00135 
00136     // https://www.unixtimestamp.com/
00137 
00138 */
00139 #include "mbed.h"
00140 #include "macros.h"
00141 #include "TableSummerTime.h"
00142 #include "TableDayLight.h"
00143 
00144 #ifndef __MCP79412__H_
00145 #define __MCP79412__H_
00146 
00147 // MCP7941x I2C Addresses
00148 #define MCP79412_RTC_ADDR       0x6F
00149 #define MCP79412_EEPROM_ADDR    0x57
00150 #define MAC_LOCATION 0xF2   // Starts at 0xF0 but we are only interested in 6 bytes.
00151 #define RTC_LOCATION 0x00
00152 
00153 //MCP7941x Register Addresses
00154 #define TIME_REG            0x00    // 7 registers, Seconds, Minutes, Hours, DOW, Date, Month, Year
00155 #define DAY_REG             0x03    // the RTC Day register contains the OSCON, VBAT, and VBATEN bits
00156 #define YEAR_REG            0x06    // RTC year register
00157 #define CTRL_REG            0x07    // control register
00158 #define CALIB_REG           0x08    // calibration register
00159 #define UNLOCK_ID_REG       0x09    // unlock ID register
00160 #define ALM0_REG            0x0A    // alarm 0, 6 registers, Seconds, Minutes, Hours, DOW, Date, Month
00161 #define ALM1_REG            0x11    // alarm 1, 6 registers, Seconds, Minutes, Hours, DOW, Date, Month
00162 #define ALM0_DAY            0x0D    // DOW register has alarm config/flag bits
00163 #define PWRDWN_TS_REG       0x18    // power-down timestamp, 4 registers, Minutes, Hours, Date, Month
00164 #define PWRUP_TS_REG        0x1C    // power-up timestamp, 4 registers, Minutes, Hours, Date, Month
00165 #define TIMESTAMP_SIZE      8       // number of bytes in the two timestamp registers
00166 #define SRAM_START_ADDR     0x20    // first SRAM address
00167 #define SRAM_END_ADDR       0x5F    // last SRAM address
00168 #define SRAM_SIZE           64      // number of bytes of SRAM
00169 #define EEPROM_SIZE         128     // number of bytes of EEPROM
00170 #define EEPROM_PAGE_SIZE    8       // number of bytes on an EEPROM page
00171 #define UNIQUE_ID_ADDR      0xF0    // starting address for unique ID
00172 #define UNIQUE_ID_SIZE      8       // number of bytes in unique ID
00173 
00174 #define UNLOCK_ID_CODE1     0x55    // PROTECTED EEPROM UNLOCK SEQUENCE
00175 #define UNLOCK_ID_CODE2     0xAA    // PROTECTED EEPROM UNLOCK SEQUENCE
00176 
00177 //Control Register bits
00178 #define OUT     7   // sets logic level on MFP when not used as square wave output
00179 #define SQWE    6   // set to enable square wave output
00180 #define ALM1    5   // alarm 1 is active
00181 #define ALM0    4   // alarm 0 is active
00182 #define EXTOSC  3   // set to drive the RTC registers from an external oscillator instead of a crystal
00183 #define RS2     2   // RS2:0 set square wave output frequency: 0==1Hz, 1==4096Hz, 2==8192Hz, 3=32768Hz
00184 #define RS1     1
00185 #define RS0     0
00186 
00187 //Other Control Bits
00188 #define ST      7   // Seconds register (TIME_REG) oscillator start/stop bit, 1==Start, 0==Stop
00189 #define HR1224  6   // Hours register (TIME_REG+2) 12 or 24 hour mode (24 hour mode==0)
00190 #define AMPM    5   // Hours register (TIME_REG+2) AM/PM bit for 12 hour mode
00191 #define OSCON   5   // Day register (TIME_REG+3) oscillator running (set and cleared by hardware)
00192 #define VBAT    4   // Day register (TIME_REG+3) set by hardware when Vcc fails and RTC runs on battery.
00193                     // VBAT is cleared by software, clearing VBAT also clears the timestamp registers
00194 #define VBATEN  3   // Day register (TIME_REG+3) VBATEN==1 enables backup battery, VBATEN==0 disconnects the VBAT pin (e.g. to save battery)
00195 #define LP      5   // Month register (TIME_REG+5) leap year bit
00196 
00197 //Alarm Control Bits
00198 #define ALMPOL  7   // Alarm Polarity: Defines the logic level for the MFP when an alarm is triggered.
00199 #define ALMC2   6   // Alarm configuration bits determine how alarms match. See ALM_MATCH defines below.
00200 #define ALMC1   5
00201 #define ALMC0   4
00202 #define ALMIF   3   // Alarm Interrupt Flag: Set by hardware when an alarm was triggered, cleared by software.
00203 // Note ALM_MATCH_DAY triggers alarm at midnight
00204 #define ALARM_0 0   // constants for calling functions
00205 #define ALARM_1 1
00206 
00207 #define MCP79412_SET        0
00208 #define MCP79412_CLEAR      1
00209 #define MCP79412_REPLACE    2
00210 
00211 #define NTP_OFFSET          2208988800ULL
00212 
00213 //convenience macros to convert to and from tm years 
00214 #define  tmYearToCalendar(Y) ((Y) + 1970)  // full four digit year 
00215 #define  CalendarYrToTm(Y)   ((Y) - 1970)
00216 #define  tmYearToY2k(Y)      ((Y) - 30)    // offset is from 2000
00217 #define  y2kYearToTm(Y)      ((Y) + 30)   
00218 
00219 enum Sqwave {
00220     SQWAVE_1_HZ, 
00221     SQWAVE_4096_HZ, 
00222     SQWAVE_8192_HZ, 
00223     SQWAVE_32768_HZ, 
00224     SQWAVE_NONE
00225 };
00226 
00227 enum {
00228     ALM_MATCH_SECONDS, 
00229     ALM_MATCH_MINUTES, 
00230     ALM_MATCH_HOURS, 
00231     ALM_MATCH_DAY, 
00232     ALM_MATCH_DATE, 
00233     ALM_RESERVED_5, 
00234     ALM_RESERVED_6, 
00235     ALM_MATCH_DATETIME, 
00236     ALM_DISABLE
00237 };
00238 
00239 typedef struct DateTime {
00240        int year;
00241        int mon;
00242        int mday;
00243        int wday;
00244        int yday;
00245        int hour;
00246        int min;
00247        int sec;
00248 };
00249 
00250 class MCP79412 {
00251 public:
00252     DateTime datetime;
00253     struct tm *t;
00254     time_t secondsEpoch;
00255     uint8_t second, minute, hour, dayOfWeek, dayOfMonth, month, year;
00256 
00257     MCP79412(PinName sda, PinName scl);
00258     void setI2Cfrequency(int freq);
00259     bool getFlag(char reg, char mask, char *flag);
00260     void setFlag(char reg, char bits, char mode);
00261     int readRegister(char reg);
00262     void readRegisters(char reg, char *outbuf, char length);
00263     void writeRegister(int reg, char byte);
00264     void writeRegisters(int reg, char *inbuf, char length);
00265     void getMacAddress(char *mac_address);
00266     void writeMacAddress(char *mac_address);
00267     void unlockUniqueID();
00268     void setRtcDateTime(uint8_t second, uint8_t minute, uint8_t hour, uint8_t dayOfWeek, uint8_t dayOfMonth, uint8_t month, uint8_t year);
00269     void getRtcDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *dayOfWeek, uint8_t *dayOfMonth, uint8_t *month, uint8_t *year);
00270     bool checkTimeLost(void);
00271     void enableClock();
00272     void disableClock();
00273     void enableBattery();
00274 
00275     void writeRamByte(uint8_t location, uint8_t data);
00276     uint8_t writeRamBytes(uint8_t location, uint8_t *data, uint8_t length);
00277     uint8_t readRamByte(uint8_t location);
00278     uint8_t readRamBytes(uint8_t location, uint8_t *data, uint8_t length);
00279 
00280     void writeSramByte(uint8_t location, uint8_t data);
00281     uint8_t writeSramBytes(uint8_t location, uint8_t *data, uint8_t length);
00282     uint8_t readSramByte(uint8_t location);
00283     uint8_t readSramBytes(uint8_t location, uint8_t *data, uint8_t length);
00284 
00285     void writeEepromByte(uint8_t location, uint8_t data);
00286     uint8_t writeEepromBytes(uint8_t location, uint8_t *data, uint8_t length);
00287     uint8_t readEepromByte(uint8_t location);
00288     uint8_t readEepromBytes(uint8_t location, uint8_t *data, uint8_t length);
00289     
00290     int calibRead(void);
00291     void calibWrite(int value);
00292     void readUniqueId(char *uniqueID);
00293     void getEUI64(char *uniqueID);
00294     bool powerFail(time_t *powerDown, time_t *powerUp);
00295     void squareWave(Sqwave freq);
00296     void setAlarm(uint8_t alarmNumber, time_t alarmTime);
00297     void enableAlarm(uint8_t alarmNumber, uint8_t alarmType);
00298     bool alarm(uint8_t alarmNumber);
00299     void out(bool level);
00300     void alarmPolarity(bool polarity);
00301     bool isRunning(void);
00302     void vbaten(bool enable);
00303     
00304 //    bool getSummerTime(void);
00305 //    int dayOfYearC(void);
00306 //    char * getSunRise(void);
00307 //    char * getSunSet(void);
00308 //    char * getDayLength(void);
00309 //    int getSunRiseMinute(void);
00310 //    int getSunSetMinute(void);
00311 //    bool checkSunRise(void);
00312     
00313     void substr(char *s, char *d, int pos, int len);
00314     char * substr(char *s, int pos, int len);
00315     
00316     // Mbed dateTime
00317     struct tm setSystemDateTime(uint8_t second, uint8_t minute, uint8_t hour, uint8_t dayOfMonth, uint8_t month, uint8_t year);
00318     void getSystemDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *dayOfWeek, uint8_t *dayOfMonth, uint8_t *month, uint8_t *year);
00319     void setRtcToSystemDateTime(void);
00320     void setSystemToRtcDateTime(void);
00321     void setRtcFromTm(struct tm *t);
00322     struct tm getTmFromRtc(void);
00323     
00324     time_t getSecondsEpoch(void);
00325     void setSecondsEpoch(time_t t);
00326 
00327     void getRtcDateTimeAsTm(void);
00328     time_t convertDateTimeToTimestamp(uint8_t second, uint8_t minute, uint8_t hour, uint8_t dayOfMonth, uint8_t month, uint8_t year);
00329     uint8_t getWeekdayFromDate(uint8_t dayOfMonth, uint8_t month, uint8_t year);
00330 
00331     int bcd2dec(int k); // bcd to decimal conversion
00332     int dec2bcd(int k); // decimal to bcd conversion
00333     int decToBcd(int val);
00334     int bcdToDec(int val);
00335     
00336 private :
00337     I2C _i2c;
00338     char _address_RTC;
00339     char buffer[32];
00340     bool _error;
00341 
00342 
00343 };
00344 
00345 #endif