x

Dependents:   20180621_FT813

Revision:
0:04311b121ac4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP79412.h	Mon Jul 23 12:24:33 2018 +0000
@@ -0,0 +1,345 @@
+/** mbded library for driving the PMAXIM DS3231 Real Time Clock
+* datasheet link : http://datasheets.maximintegrated.com/en/ds/DS3231.pdf
+* breakout       : MACETECH ChronoDot V2.1 High Precision RTC
+* remi cormier 2012
+* WARNING : sda and sdl should be pulled up with 2.2k resistor
+*/
+
+/** Example code
+* @code
+// DS3231 Library test program
+// remi cormier 2012
+
+#include "mbed.h"
+#include "DS3231.h"
+
+Serial pc(USBTX, USBRX);
+
+int hour;
+int minute;
+int second;
+
+int dayOfWeek;
+int date;
+int month;
+int year;  
+   
+DS3231 RTC(p28,p27);
+
+
+int main()
+    {printf("\r\n\nDS3231 Library test program\r\nremi cormier 2012\r\n\n");
+    
+     RTC.setI2Cfrequency(400000);
+    
+     //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
+     
+     RTC.convertTemperature();
+      
+     int reg=RTC.readRegister(DS3231_Aging_Offset);
+     if (reg>127)
+        {reg=reg-256;}
+     pc.printf("Aging offset : %i\r\n",reg);
+         
+     pc.printf("OSF flag : %i",RTC.OSF());
+     pc.printf("\r\n");
+     
+     RTC.readDate(&date,&month,&year);
+     pc.printf("date : %02i-%02i-%02i",date,month,year);
+     pc.printf("\r\n");
+     
+     //RTC.setTime(19,48,45); // uncomment to set time
+     
+     RTC.readTime(&hour,&minute,&second);
+     pc.printf("time : %02i:%02i:%02i",hour,minute,second);
+     pc.printf("\r\n");
+     
+     //RTC.setDate(6,22,12,2012); // uncomment to set date
+     
+     RTC.readDateTime(&dayOfWeek,&date,&month,&year,&hour,&minute,&second);
+     pc.printf("date time : %i / %02i-%02i-%02i %02i:%02i:%02i",dayOfWeek,date,month,year,hour,minute,second);
+     pc.printf("\r\n");
+     
+     pc.printf("temperature :%6.2f",RTC.readTemp());
+     pc.printf("\r\n");
+    }
+* @endcode
+*/
+
+/*
+http://www.cplusplus.com/reference/ctime/strftime/
+%a   Abbreviated weekday name *  Thu
+%A   Full weekday name * Thursday
+%b   Abbreviated month name *    Aug
+%B   Full month name *   August
+%d   Day of the month, zero-padded (01-31)   23
+%e   Day of the month, space-padded ( 1-31)  23
+%F   Short YYYY-MM-DD date, equivalent to %Y-%m-%d   2001-08-23
+%H   Hour in 24h format (00-23)  14
+%j   Day of the year (001-366)   235
+%m   Month as a decimal number (01-12)   08
+%M   Minute (00-59)  55
+%R   24-hour HH:MM time, equivalent to %H:%M 14:55
+%S   Second (00-61)  02
+%T   ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S 14:55:02
+%u   ISO 8601 weekday as number with Monday as 1 (1-7)   4
+%V   ISO 8601 week number (00-53)    34
+%w   Weekday as a decimal number with Sunday as 0 (0-6)  4
+%W   Week number with the first Monday as the first day of week one (00-53)  34
+%X   Time representation *   14:55:02
+%y   Year, last two digits (00-99)   01
+%Y   Year    2001
+
+http://www.cplusplus.com/reference/ctime/tm/
+Member   Type    Meaning                        Range
+tm_sec   int     seconds after the minute       0-61*
+tm_min   int     minutes after the hour         0-59
+tm_hour  int     hours since midnight           0-23
+tm_mday  int     day of the month               1-31
+tm_mon   int     months since January           0-11
+tm_year  int     years since 1900    
+tm_wday  int     days since Sunday              0-6     (0 = Sunday)
+tm_yday  int     days since January 1           0-365
+tm_isdst         int Daylight Saving Time flag   
+The Daylight Saving Time flag (tm_isdst) is greater than zero if Daylight Saving Time is in effect,
+zero if Daylight Saving Time is not in effect, and less than zero if the information is not available.
+* tm_sec is generally 0-59. The extra range is to accommodate for leap seconds in certain systems.
+
+http://www.epochconverter.com/programming/c
+Convert from epoch to human readable date
+    time_t     now;
+    struct tm  ts;
+    char       buf[80];
+    // Get current time
+    time(&now);
+    // Format time, "ddd yyyy-mm-dd hh:mm:ss zzz"
+    ts = *localtime(&now);
+    strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
+    printf("%s\n", buf);
+
+Convert from human readable date to epoch
+    struct tm t;
+    time_t t_of_day;
+    t.tm_year = 2011-1900;
+    t.tm_mon = 7;           // Month, 0 - jan
+    t.tm_mday = 8;          // Day of the month
+    t.tm_hour = 16;
+    t.tm_min = 11;
+    t.tm_sec = 42;
+    t.tm_isdst = -1;        // Is DST on? 1 = yes, 0 = no, -1 = unknown
+    t_of_day = mktime(&t);
+    printf("seconds since the Epoch: %ld\n", (long) t_of_day)
+
+https://github.com/raburton/esp8266/blob/master/drivers/ds3231.c
+https://github.com/raburton/esp8266/blob/master/drivers/ds3231.h
+
+    // https://www.unixtimestamp.com/
+
+*/
+#include "mbed.h"
+#include "macros.h"
+#include "TableSummerTime.h"
+#include "TableDayLight.h"
+
+#ifndef __MCP79412__H_
+#define __MCP79412__H_
+
+// MCP7941x I2C Addresses
+#define MCP79412_RTC_ADDR       0x6F
+#define MCP79412_EEPROM_ADDR    0x57
+#define MAC_LOCATION 0xF2   // Starts at 0xF0 but we are only interested in 6 bytes.
+#define RTC_LOCATION 0x00
+
+//MCP7941x Register Addresses
+#define TIME_REG            0x00    // 7 registers, Seconds, Minutes, Hours, DOW, Date, Month, Year
+#define DAY_REG             0x03    // the RTC Day register contains the OSCON, VBAT, and VBATEN bits
+#define YEAR_REG            0x06    // RTC year register
+#define CTRL_REG            0x07    // control register
+#define CALIB_REG           0x08    // calibration register
+#define UNLOCK_ID_REG       0x09    // unlock ID register
+#define ALM0_REG            0x0A    // alarm 0, 6 registers, Seconds, Minutes, Hours, DOW, Date, Month
+#define ALM1_REG            0x11    // alarm 1, 6 registers, Seconds, Minutes, Hours, DOW, Date, Month
+#define ALM0_DAY            0x0D    // DOW register has alarm config/flag bits
+#define PWRDWN_TS_REG       0x18    // power-down timestamp, 4 registers, Minutes, Hours, Date, Month
+#define PWRUP_TS_REG        0x1C    // power-up timestamp, 4 registers, Minutes, Hours, Date, Month
+#define TIMESTAMP_SIZE      8       // number of bytes in the two timestamp registers
+#define SRAM_START_ADDR     0x20    // first SRAM address
+#define SRAM_END_ADDR       0x5F    // last SRAM address
+#define SRAM_SIZE           64      // number of bytes of SRAM
+#define EEPROM_SIZE         128     // number of bytes of EEPROM
+#define EEPROM_PAGE_SIZE    8       // number of bytes on an EEPROM page
+#define UNIQUE_ID_ADDR      0xF0    // starting address for unique ID
+#define UNIQUE_ID_SIZE      8       // number of bytes in unique ID
+
+#define UNLOCK_ID_CODE1     0x55    // PROTECTED EEPROM UNLOCK SEQUENCE
+#define UNLOCK_ID_CODE2     0xAA    // PROTECTED EEPROM UNLOCK SEQUENCE
+
+//Control Register bits
+#define OUT     7   // sets logic level on MFP when not used as square wave output
+#define SQWE    6   // set to enable square wave output
+#define ALM1    5   // alarm 1 is active
+#define ALM0    4   // alarm 0 is active
+#define EXTOSC  3   // set to drive the RTC registers from an external oscillator instead of a crystal
+#define RS2     2   // RS2:0 set square wave output frequency: 0==1Hz, 1==4096Hz, 2==8192Hz, 3=32768Hz
+#define RS1     1
+#define RS0     0
+
+//Other Control Bits
+#define ST      7   // Seconds register (TIME_REG) oscillator start/stop bit, 1==Start, 0==Stop
+#define HR1224  6   // Hours register (TIME_REG+2) 12 or 24 hour mode (24 hour mode==0)
+#define AMPM    5   // Hours register (TIME_REG+2) AM/PM bit for 12 hour mode
+#define OSCON   5   // Day register (TIME_REG+3) oscillator running (set and cleared by hardware)
+#define VBAT    4   // Day register (TIME_REG+3) set by hardware when Vcc fails and RTC runs on battery.
+                    // VBAT is cleared by software, clearing VBAT also clears the timestamp registers
+#define VBATEN  3   // Day register (TIME_REG+3) VBATEN==1 enables backup battery, VBATEN==0 disconnects the VBAT pin (e.g. to save battery)
+#define LP      5   // Month register (TIME_REG+5) leap year bit
+
+//Alarm Control Bits
+#define ALMPOL  7   // Alarm Polarity: Defines the logic level for the MFP when an alarm is triggered.
+#define ALMC2   6   // Alarm configuration bits determine how alarms match. See ALM_MATCH defines below.
+#define ALMC1   5
+#define ALMC0   4
+#define ALMIF   3   // Alarm Interrupt Flag: Set by hardware when an alarm was triggered, cleared by software.
+// Note ALM_MATCH_DAY triggers alarm at midnight
+#define ALARM_0 0   // constants for calling functions
+#define ALARM_1 1
+
+#define MCP79412_SET        0
+#define MCP79412_CLEAR      1
+#define MCP79412_REPLACE    2
+
+#define NTP_OFFSET          2208988800ULL
+
+//convenience macros to convert to and from tm years 
+#define  tmYearToCalendar(Y) ((Y) + 1970)  // full four digit year 
+#define  CalendarYrToTm(Y)   ((Y) - 1970)
+#define  tmYearToY2k(Y)      ((Y) - 30)    // offset is from 2000
+#define  y2kYearToTm(Y)      ((Y) + 30)   
+
+enum Sqwave {
+    SQWAVE_1_HZ, 
+    SQWAVE_4096_HZ, 
+    SQWAVE_8192_HZ, 
+    SQWAVE_32768_HZ, 
+    SQWAVE_NONE
+};
+
+enum {
+    ALM_MATCH_SECONDS, 
+    ALM_MATCH_MINUTES, 
+    ALM_MATCH_HOURS, 
+    ALM_MATCH_DAY, 
+    ALM_MATCH_DATE, 
+    ALM_RESERVED_5, 
+    ALM_RESERVED_6, 
+    ALM_MATCH_DATETIME, 
+    ALM_DISABLE
+};
+
+typedef struct DateTime {
+       int year;
+       int mon;
+       int mday;
+       int wday;
+       int yday;
+       int hour;
+       int min;
+       int sec;
+};
+
+class MCP79412 {
+public:
+    DateTime datetime;
+    struct tm *t;
+    time_t secondsEpoch;
+    uint8_t second, minute, hour, dayOfWeek, dayOfMonth, month, year;
+
+    MCP79412(PinName sda, PinName scl);
+    void setI2Cfrequency(int freq);
+    bool getFlag(char reg, char mask, char *flag);
+    void setFlag(char reg, char bits, char mode);
+    int readRegister(char reg);
+    void readRegisters(char reg, char *outbuf, char length);
+    void writeRegister(int reg, char byte);
+    void writeRegisters(int reg, char *inbuf, char length);
+    void getMacAddress(char *mac_address);
+    void writeMacAddress(char *mac_address);
+    void unlockUniqueID();
+    void setRtcDateTime(uint8_t second, uint8_t minute, uint8_t hour, uint8_t dayOfWeek, uint8_t dayOfMonth, uint8_t month, uint8_t year);
+    void getRtcDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *dayOfWeek, uint8_t *dayOfMonth, uint8_t *month, uint8_t *year);
+    bool checkTimeLost(void);
+    void enableClock();
+    void disableClock();
+    void enableBattery();
+
+    void writeRamByte(uint8_t location, uint8_t data);
+    uint8_t writeRamBytes(uint8_t location, uint8_t *data, uint8_t length);
+    uint8_t readRamByte(uint8_t location);
+    uint8_t readRamBytes(uint8_t location, uint8_t *data, uint8_t length);
+
+    void writeSramByte(uint8_t location, uint8_t data);
+    uint8_t writeSramBytes(uint8_t location, uint8_t *data, uint8_t length);
+    uint8_t readSramByte(uint8_t location);
+    uint8_t readSramBytes(uint8_t location, uint8_t *data, uint8_t length);
+
+    void writeEepromByte(uint8_t location, uint8_t data);
+    uint8_t writeEepromBytes(uint8_t location, uint8_t *data, uint8_t length);
+    uint8_t readEepromByte(uint8_t location);
+    uint8_t readEepromBytes(uint8_t location, uint8_t *data, uint8_t length);
+    
+    int calibRead(void);
+    void calibWrite(int value);
+    void readUniqueId(char *uniqueID);
+    void getEUI64(char *uniqueID);
+    bool powerFail(time_t *powerDown, time_t *powerUp);
+    void squareWave(Sqwave freq);
+    void setAlarm(uint8_t alarmNumber, time_t alarmTime);
+    void enableAlarm(uint8_t alarmNumber, uint8_t alarmType);
+    bool alarm(uint8_t alarmNumber);
+    void out(bool level);
+    void alarmPolarity(bool polarity);
+    bool isRunning(void);
+    void vbaten(bool enable);
+    
+//    bool getSummerTime(void);
+//    int dayOfYearC(void);
+//    char * getSunRise(void);
+//    char * getSunSet(void);
+//    char * getDayLength(void);
+//    int getSunRiseMinute(void);
+//    int getSunSetMinute(void);
+//    bool checkSunRise(void);
+    
+    void substr(char *s, char *d, int pos, int len);
+    char * substr(char *s, int pos, int len);
+    
+    // Mbed dateTime
+    struct tm setSystemDateTime(uint8_t second, uint8_t minute, uint8_t hour, uint8_t dayOfMonth, uint8_t month, uint8_t year);
+    void getSystemDateTime(uint8_t *second, uint8_t *minute, uint8_t *hour, uint8_t *dayOfWeek, uint8_t *dayOfMonth, uint8_t *month, uint8_t *year);
+    void setRtcToSystemDateTime(void);
+    void setSystemToRtcDateTime(void);
+    void setRtcFromTm(struct tm *t);
+    struct tm getTmFromRtc(void);
+    
+    time_t getSecondsEpoch(void);
+    void setSecondsEpoch(time_t t);
+
+    void getRtcDateTimeAsTm(void);
+    time_t convertDateTimeToTimestamp(uint8_t second, uint8_t minute, uint8_t hour, uint8_t dayOfMonth, uint8_t month, uint8_t year);
+    uint8_t getWeekdayFromDate(uint8_t dayOfMonth, uint8_t month, uint8_t year);
+
+    int bcd2dec(int k); // bcd to decimal conversion
+    int dec2bcd(int k); // decimal to bcd conversion
+    int decToBcd(int val);
+    int bcdToDec(int val);
+    
+private :
+    I2C _i2c;
+    char _address_RTC;
+    char buffer[32];
+    bool _error;
+
+
+};
+
+#endif