x
Diff: MCP79412.h
- 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