Library for Real Time Clock module MCP97410 based on Library for DS1307
Fork of RTC-DS1307 by
Rtc_Mcp97410.h
00001 /* Rtc_Mcp97410.h */ 00002 /* 00003 Support for Michrochip RTC MCP97410 00004 Should work for MCP97410, MCP97411, MCP97412 - see datasheet 00005 Based on Library for DS1307 00006 Chips are similar but not equal! 00007 Ported for MCP97410 by Karl Zweimueller 00008 00009 Original Copyright (c) 2013 Henry Leinen (henry[dot]leinen [at] online [dot] de) 00010 00011 Permission is hereby granted, free of charge, to any person obtaining a copy 00012 of this software and associated documentation files (the "Software"), to deal 00013 in the Software without restriction, including without limitation the rights 00014 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00015 copies of the Software, and to permit persons to whom the Software is 00016 furnished to do so, subject to the following conditions: 00017 00018 The above copyright notice and this permission notice shall be included in 00019 all copies or substantial portions of the Software. 00020 00021 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00022 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00023 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00024 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00025 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00026 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00027 THE SOFTWARE. 00028 */ 00029 #ifndef __RTC_MCP97410_H__ 00030 #define __RTC_MCP97410_H__ 00031 00032 00033 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00034 // GLOBAL CONSTANTS RTCC - ADDRESSES 00035 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00036 #define ADDR_EEPROM 0xaf // DEVICE ADDR for EEPROM 00037 #define ADDR_RTCC 0xdf // DEVICE ADDR for RTCC MCHP 00038 //................................................................................. 00039 #define SRAM_PTR 0x20 // pointer of the SRAM area (RTCC) 00040 #define ADDR_EEPROM_SR 0xff // STATUS REGISTER in the EEPROM 00041 //................................................................................. 00042 #define ADDR_SEC 0x00 // address of SECONDS register 00043 #define ADDR_MIN 0x01 // address of MINUTES register 00044 #define ADDR_HOUR 0x02 // address of HOURS register 00045 #define ADDR_DAY 0x03 // address of DAY OF WK register 00046 #define ADDR_STAT 0x03 // address of STATUS register 00047 #define ADDR_DATE 0x04 // address of DATE register 00048 #define ADDR_MNTH 0x05 // address of MONTH register 00049 #define ADDR_YEAR 0x06 // address of YEAR register 00050 #define ADDR_CTRL 0x07 // address of CONTROL register 00051 #define ADDR_CAL 0x08 // address of CALIB register 00052 #define ADDR_ULID 0x09 // address of UNLOCK ID register 00053 //................................................................................. 00054 #define ADDR_ALM0SEC 0x0a // address of ALARMO SEC register 00055 #define ADDR_ALM0MIN 0x0b // address of ALARMO MIN register 00056 #define ADDR_ALM0HR 0x0c // address of ALARMO HOUR register 00057 #define ADDR_ALM0CTL 0x0d // address of ALARM0 CONTR register 00058 #define ADDR_ALM0DAT 0x0e // address of ALARMO DATE register 00059 #define ADDR_ALM0MTH 0x0f // address of ALARMO MONTH register 00060 //................................................................................. 00061 #define ADDR_ALM1SEC 0x11 // address of ALARM1 SEC register 00062 #define ADDR_ALM1MIN 0x12 // address of ALARM1 MIN register 00063 #define ADDR_ALM1HR 0x13 // address of ALARM1 HOUR register 00064 #define ADDR_ALM1CTL 0x14 // address of ALARM1 CONTR register 00065 #define ADDR_ALM1DAT 0x15 // address of ALARM1 DATE register 00066 #define ADDR_ALM1MTH 0x16 // address of ALARM1 MONTH register 00067 //................................................................................. 00068 #define ADDR_SAVtoBAT_MIN 0x18 // address of T_SAVER MIN(VDD->BAT) 00069 #define ADDR_SAVtoBAT_HR 0x19 // address of T_SAVER HR (VDD->BAT) 00070 #define ADDR_SAVtoBAT_DAT 0x1a // address of T_SAVER DAT(VDD->BAT) 00071 #define ADDR_SAVtoBAT_MTH 0x1b // address of T_SAVER MTH(VDD->BAT) 00072 //.................................................................................. 00073 #define ADDR_SAVtoVDD_MIN 0x1c // address of T_SAVER MIN(BAT->VDD) 00074 #define ADDR_SAVtoVDD_HR 0x1d // address of T_SAVER HR (BAT->VDD) 00075 #define ADDR_SAVtoVDD_DAT 0x1e // address of T_SAVER DAT(BAT->VDD) 00076 #define ADDR_SAVtoVDD_MTH 0x1f // address of T_SAVER MTH(BAT->VDD) 00077 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00078 // GLOBAL CONSTANTS RTCC - INITIALIZATION 00079 //.................................................................................. 00080 #define START_32KHZ 0x80 // start crystal: ST = b7 (ADDR_SEC) 00081 #define LP 0x20 // mask for the leap year bit(MONTH REG) 00082 #define HOUR_12 0x40 // 12 hours format (ADDR_HOUR) 00083 #define PM 0x20 // post-meridian bit (ADDR_HOUR) 00084 #define OUT_PIN 0x80 // = b7 (ADDR_CTRL) 00085 #define SQWE 0x40 // SQWE = b6 (ADDR_CTRL) 00086 #define ALM_NO 0x00 // no alarm activated (ADDR_CTRL) 00087 #define ALM_0 0x10 // ALARM0 is activated (ADDR_CTRL) 00088 #define ALM_1 0x20 // ALARM1 is activated (ADDR_CTRL) 00089 #define ALM_01 0x30 // both alarms are activated (ADDR_CTRL) 00090 #define MFP_01H 0x00 // MFP = SQVAW(01 HERZ) (ADDR_CTRL) 00091 #define MFP_04K 0x01 // MFP = SQVAW(04 KHZ) (ADDR_CTRL) 00092 #define MFP_08K 0x02 // MFP = SQVAW(08 KHZ) (ADDR_CTRL) 00093 #define MFP_32K 0x03 // MFP = SQVAW(32 KHZ) (ADDR_CTRL) 00094 #define MFP_64H 0x04 // MFP = SQVAW(64 HERZ) (ADDR_CTRL) 00095 #define ALMx_POL 0x80 // polarity of MFP on alarm (ADDR_ALMxCTL) 00096 #define ALMxC_SEC 0x00 // ALARM compare on SEC (ADDR_ALMxCTL) 00097 #define ALMxC_MIN 0x10 // ALARM compare on MIN (ADDR_ALMxCTL) 00098 #define ALMxC_HR 0x20 // ALARM compare on HOUR (ADDR_ALMxCTL) 00099 #define ALMxC_DAY 0x30 // ALARM compare on DAY (ADDR_ALMxCTL) 00100 #define ALMxC_DAT 0x40 // ALARM compare on DATE (ADDR_ALMxCTL) 00101 #define ALMxC_ALL 0x70 // ALARM compare on all param(ADDR_ALMxCTL) 00102 #define ALMx_IF 0x08 // MASK of the ALARM_IF (ADDR_ALMxCTL) 00103 #define OSCON 0x20 // state of the oscillator(running or not) 00104 #define VBATEN 0x08 // enable battery for back-up 00105 00106 /** Class Rtc_Mcp97410 implements the real time clock module MCP97410 00107 * 00108 * You can read the clock and set a new time and date. 00109 * It is also possible to start and stop the clock. 00110 * Rtc_Mcp97410 allows you to display the time in a 12h or 24h format. 00111 * Based on Library for DS1307 by Henry Leinen. 00112 * Ported for MC97410 by Karl Zweimueller. 00113 */ 00114 class Rtc_Mcp97410 00115 { 00116 public: 00117 /** Structure which is used to exchange the time and date 00118 */ 00119 typedef struct { 00120 int sec ; /*!< seconds [0..59] */ 00121 int min ; /*!< minutes {0..59] */ 00122 int hour ; /*!< hours [0..23] */ 00123 int wday ; /*!< weekday [1..7, where 1 = sunday, 2 = monday, ... */ 00124 int date ; /*!< day of month [0..31] */ 00125 int mon ; /*!< month of year [1..12] */ 00126 int year ; /*!< year [2000..2255] */ 00127 } Time_rtc; 00128 00129 00130 /** RateSelect specifies the valid frequency values for the square wave output 00131 */ 00132 typedef enum { 00133 RS1Hz = 0, 00134 RS4kHz = 1, 00135 RS8kHz = 2, 00136 RS32kHz = 3 00137 } SqwRateSelect_t; 00138 00139 00140 protected: 00141 I2C* _i2c; 00142 00143 static const char *m_weekDays[]; 00144 00145 public: 00146 /** public constructor which creates the real time clock object 00147 * 00148 * @param i2c : Pointer to I2C-Object for I2C-Interface. 00149 * 00150 */ 00151 Rtc_Mcp97410(I2C* i2c); 00152 00153 ~Rtc_Mcp97410(); 00154 00155 /** Read the current time from RTC chip 00156 * 00157 * @param time : reference to a struct tm which will be filled with the time from rtc 00158 * 00159 * @returns true if successful, otherwise an acknowledge error occured 00160 */ 00161 virtual bool getTime(Time_rtc& time); 00162 00163 /** Write the given time onto the RTC chip (and enable Battery-Backup) 00164 * 00165 * @param time : refereence to a struct which contains valid date and time information 00166 * 00167 * @param start : contains true if the clock shall start (or keep on running). 00168 * 00169 * @param thm : 12-hour-mode if set to true, otherwise 24-hour-mode will be set. 00170 * 00171 * @returns true if successful, otherwise an acknowledge error occured 00172 */ 00173 virtual bool setTime(Time_rtc& time, bool start, bool thm); 00174 00175 /** Start the clock. Please note that the seconds register need to be read and 00176 * written in order to start or stop the clock. This can lead to an error 00177 * in the time value. The recommended way of starting and stoping the clock is 00178 * to write the actual date and time and set the start bit accordingly. 00179 * 00180 * @returns true if the clock was started, false if a communication error occured 00181 */ 00182 bool startClock(); 00183 00184 /** Stop the clock. Please note that the seconds register need to be read and 00185 * written in order to start or stop the clock. This can lead to an error 00186 * in the time value. The recommended way of starting and stoping the clock is 00187 * to write the actual date and time and set the start bit accordingly. 00188 * 00189 * @returns true if the clock was stopped, false if a communication error occured 00190 */ 00191 bool stopClock(); 00192 00193 /** Service function to convert a weekday into a string representation 00194 * 00195 * @param wday : day of week to convert (starting with sunday = 1, monday = 2, ..., saturday = 7 00196 * 00197 * @returns the corresponding string representation 00198 */ 00199 const char* weekdayToString( int wday ) { 00200 return m_weekDays[wday%7]; 00201 } 00202 00203 /** Enable Square Wave output. The function enables or disables the square wave output 00204 * of the module and sets the desired frequency. 00205 * 00206 * @param ena : if set to true, the square wave output is enabled. 00207 * 00208 * @param rs : rate select, can be either one of the four values defined by type /c RateSelect_t 00209 * 00210 * @return true if the operation was successful or false otherwise 00211 */ 00212 bool setSquareWaveOutput(bool ena, SqwRateSelect_t rs); 00213 00214 /** enable write-Operations to EEPROM 00215 * 00216 * 00217 */ 00218 bool enableEEPROMWrite(); 00219 00220 /** disable write-Operations to EEPROM 00221 * 00222 * 00223 */ 00224 bool disableEEPROMWrite(); 00225 00226 /** read the OSCTRIM-Register (0x08) 00227 * 00228 * -127 .. +127 00229 * bit 7 is Sign 00230 * bit 0:6 Trim-Value 00231 */ 00232 uint8_t readTrim(); 00233 00234 /** Increment TRIM-Value 00235 * 00236 * Increment TRIM-Value by one 00237 */ 00238 bool incTrim(); 00239 00240 /** Derement TRIM-Value 00241 * 00242 * Decrement TRIM-Value by one 00243 */ 00244 bool decTrim(); 00245 00246 00247 /** read from EEPROM 00248 * 00249 * address from 0x00 to 0x7F 00250 * all 128 Bytes can be read in one chunk 00251 * 00252 * @param address : start address to read from 00253 * 00254 * @param *buffer : buffer of char to write the result to. Be sure to have enough storage 00255 * 00256 * @param len : number of bytes to read 00257 **/ 00258 bool readEEPROM(int address, char* buffer, int len); 00259 00260 /** write to EEPROM 00261 * 00262 * address from 0x00 to 0x7F 00263 * only maximum 8 Bytes can be written in one chunk 00264 * 00265 * @param address : start address to write 00266 * 00267 * @param *buffer : buffer of chars to write 00268 * 00269 * @param len : number of bytes to write 00270 **/ 00271 bool writeEEPROM(int address, char* buffer, int len); 00272 00273 00274 00275 /** read 6Byte EUI-48 address from EEPROM 00276 * 00277 * @param eui48 : array to hold 6 Bytes of EUI48 00278 * 00279 */ 00280 bool readEUI48(uint8_t* eui48); 00281 00282 /** write 6Byte EUI-48 address to EEPROM 00283 * 00284 * be sure to enable EUI-write-Operation (UNLOCK) before 00285 * @param eui48 : array with 6 Bytes of EUI48 00286 * 00287 */ 00288 bool writeEUI48(uint8_t* eui48); 00289 00290 /** read 8Byte EUI-64 address from EEPROM 00291 * 00292 * @param eui64 : array to hold 8 Bytes of EUI64 00293 * 00294 */ 00295 bool readEUI64(uint8_t* eui64); 00296 00297 /** write 8Byte EUI-64 address to EEPROM 00298 * 00299 * be sure to enable EUI-write-Operation (UNLOCK) before 00300 * @param eui64 : array with 8 Bytes of EUI64 00301 * 00302 */ 00303 bool writeEUI64(uint8_t* eui64); 00304 00305 /** unlock the EUI area in the EEPROM 00306 * 00307 * write operation must immediatly follow the unlock procedure 00308 * after a write the EEPROM is automatically locked again 00309 * 00310 */ 00311 bool unlockEUI(); 00312 00313 private: 00314 // read from a memory area RTC/SRAM or EEPROM. specify correct control_byte 00315 bool read(int control_byte, int address, char* buffer, int len); 00316 // write to a memory area RTC/SRAM or EEPROM. specify correct control_byte 00317 bool write(int control_byte, int address, char* buffer, int len); 00318 // read from RTC/SRAM 00319 bool readRTC(int address, char* buffer, int len); 00320 //wrtie to RTC/SRAM 00321 bool writeRTC(int address, char* buffer, int len); 00322 00323 00324 static int bcdToDecimal(int bcd) { 00325 return ((bcd&0xF0)>>4)*10 + (bcd&0x0F); 00326 } 00327 00328 static int decimalToBcd(int dec) { 00329 return (dec%10) + ((dec/10)<<4); 00330 } 00331 }; 00332 00333 00334 00335 typedef void (*RtcCallback_t) (void); 00336 00337 00338 class RtcCls : public Rtc_Mcp97410 00339 { 00340 protected: 00341 InterruptIn m_sqw; 00342 bool m_bUseSqw; 00343 time_t m_time; // Only used in case SQW is used 00344 00345 bool m_bAlarmEnabled; 00346 RtcCallback_t m_alarmfunc; 00347 time_t m_alarmTime; 00348 00349 public: 00350 RtcCls(I2C* i2c, PinName sqw, bool bUseSqw); 00351 00352 protected: 00353 void _callback(void); 00354 00355 public: 00356 time_t getTime(); 00357 virtual bool getTime(Time_rtc& time) { return Rtc_Mcp97410::getTime(time); } 00358 void setTime(time_t time); 00359 virtual bool setTime(Time_rtc& time, bool start, bool thm) { return Rtc_Mcp97410::setTime(time, start, thm); } 00360 public: 00361 void setAlarm(int nSeconds, RtcCallback_t alarmfunc) { 00362 m_alarmfunc = alarmfunc; 00363 m_alarmTime = m_time + nSeconds; 00364 m_bAlarmEnabled = (alarmfunc == NULL) ? false : true; 00365 } 00366 }; 00367 00368 #endif // __RTC_MCP97410_H__
Generated on Tue Jul 12 2022 22:54:37 by
