x

Dependents:   20180621_FT813

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MCP79412.cpp Source File

MCP79412.cpp

00001 #include "MCP79412.h"
00002 
00003 MCP79412::MCP79412(PinName sda, PinName scl) : _i2c(sda, scl)
00004 {
00005     _address_RTC = MCP79412_RTC_ADDR << 1;
00006     squareWave(SQWAVE_1_HZ);
00007 //    setTimeZone(1);
00008 //    dayLightSaving = true;
00009     setI2Cfrequency(400000);
00010 }
00011 
00012 void MCP79412::setI2Cfrequency(int freq)
00013 {
00014     _i2c.frequency(freq);
00015 }
00016 
00017 // get a uint8_t containing just the requested bits
00018 // pass the register address to read, a mask to apply to the register and
00019 // an uint* for the output
00020 // you can test this value directly as true/false for specific bit mask
00021 // of use a mask of 0xff to just return the whole register uint8_t
00022 // returns true to indicate success
00023     /** Get flag
00024     * @param reg : register address
00025     * @param mask : flag mask
00026     * @return The register content
00027     */     
00028 bool MCP79412::getFlag(char reg, char mask, char *flag)
00029 {
00030     char buf[1];
00031     buf[0] = reg;
00032     int w = _i2c.write(_address_RTC, buf, 1);
00033     int r = _i2c.read(_address_RTC, buf, 1);
00034     _error = ((w != 0) || (r != 0));
00035     // return only requested flag
00036     *flag = (buf[0] & mask);
00037     return flag == 0 ? false : true;
00038 }
00039 
00040 // set/clear bits in a uint8_t register, or replace the uint8_t altogether
00041 // pass the register address to modify, a uint8_t to replace the existing
00042 // value with or containing the bits to set/clear and one of
00043 // MCP79412_SET/MCP79412_CLEAR/MCP79412_REPLACE
00044 // returns true to indicate success
00045     /** Set flag
00046     * @param reg : register address
00047     * @param bits : bits to set or reset
00048     * @param mode : MCP79412_REPLACE, MCP79412_SET, MCP79412_CLEAR
00049     * @return none
00050     */     
00051 void MCP79412::setFlag(char reg, char bits, char mode)
00052 {
00053     char buf[2];
00054     buf[0] = reg;
00055     // get status register
00056     int w = _i2c.write(_address_RTC, buf, 1);
00057     int r = _i2c.read(_address_RTC, buf+1, 1);
00058     // clear the flag
00059     if (mode == MCP79412_REPLACE)
00060         buf[1] = bits;
00061     else if (mode == MCP79412_SET)
00062         buf[1] |= bits;
00063     else
00064         buf[1] &= ~bits;
00065     int w2 = _i2c.write(_address_RTC, buf, 2);
00066     _error = ((w != 0) || (r != 0) || (w2 != 0));
00067 }
00068 
00069 // read a register
00070 int MCP79412::readRegister(char reg)
00071 {
00072 //    int w = _i2c.write(_address_RTC, &reg, 1);
00073 //    char rtn;
00074 //    int r = _i2c.read(_address_RTC, &rtn, 1);
00075 //    _error = ((w != 0) || (r != 0));
00076 //    return rtn;
00077 
00078     char buf[1];
00079     buf[0] = reg;
00080     int w = _i2c.write(_address_RTC, buf, 1);
00081     int r = _i2c.read(_address_RTC, buf, 1);
00082     _error = ((w != 0) || (r != 0));
00083     return(buf[0]);
00084 }
00085 
00086 // read registers
00087 void MCP79412::readRegisters(char reg, char *outbuf, char length)
00088 {
00089     char buf[1];
00090     buf[0] = reg;
00091     int w = _i2c.write(_address_RTC, buf, 1);
00092     int r = _i2c.read(_address_RTC, outbuf, length);
00093     _error = ((w != 0) || (r != 0));
00094 }
00095 
00096 // write a register
00097 void MCP79412::writeRegister(int reg, char uint8_t)
00098 {
00099     char buf[2];
00100     buf[0] = reg;
00101     buf[1] = uint8_t;
00102     int w = _i2c.write(_address_RTC, buf, 2);
00103     _error = (w != 0);
00104 }
00105 
00106 // write registers
00107 void MCP79412::writeRegisters(int reg, char *inbuf, char length)
00108 {
00109     char buf[32];
00110     buf[0] = reg;
00111     for (int i = 1; i <= length; i++) {
00112         buf[i] = inbuf[i-1];
00113     }
00114     int w = _i2c.write(_address_RTC, buf, length+1);
00115     _error = (w != 0);
00116 }
00117 
00118 
00119 // Function to read the mac address from the eeprom
00120 void MCP79412::getMacAddress(char *mac_address)
00121 {
00122     char buf[1];
00123     buf[0] = MAC_LOCATION;
00124     int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 1);
00125     int r = _i2c.read(MCP79412_EEPROM_ADDR, mac_address, 6);
00126     _error = ((w != 0) || (r != 0));
00127 }
00128 
00129 // Unlock the unique id area and write in the mac address
00130 void MCP79412::writeMacAddress(char *mac_address)
00131 {
00132     char buf[7];
00133     unlockUniqueID();
00134     buf[0] = MAC_LOCATION;
00135     for (int i = 1; i <= 6; i++) {
00136         buf[i] = mac_address[i-1];
00137     }
00138     int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 7);
00139 
00140     _error = (w != 0);
00141 }
00142 
00143 // Unlock the unique id area ready for writing
00144 void MCP79412::unlockUniqueID()
00145 {
00146     // Write 0x55 to the memory location 0x09
00147     char buf[2];
00148     buf[0] = UNLOCK_ID_REG;
00149     buf[1] = UNLOCK_ID_CODE1;
00150     int w1 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
00151 
00152     // Write 0xAA to the memory location 0x09
00153     buf[0] = UNLOCK_ID_REG;
00154     buf[1] = UNLOCK_ID_CODE2;
00155     int w2 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
00156 
00157     _error = ((w1 != 0) || (w2 != 0));
00158 }
00159 
00160 // Set the date/time, set to 24hr and enable the clock
00161 // (assumes you're passing in valid numbers)
00162 void MCP79412::setRtcDateTime(
00163   uint8_t second,        // 0-59
00164   uint8_t minute,        // 0-59
00165   uint8_t hour,          // 1-23
00166   uint8_t dayOfWeek,     // 1-7
00167   uint8_t dayOfMonth,    // 1-31
00168   uint8_t month,         // 1-12
00169   uint8_t year)          // 0-99
00170 {
00171     char buf[8];
00172     buf[0] = RTC_LOCATION;
00173     buf[1] = decToBcd(second) & 0x7f;               // set seconds and disable clock (01111111, Bit 7, ST = 0)
00174     buf[2] = decToBcd(minute) & 0x7f;               // set minutes (01111111)
00175     buf[3] = decToBcd(hour) & 0x3f;                 // set hours and to 24hr format (00111111, Bit 6 = 0)
00176     buf[4] = _BV(VBATEN) | (decToBcd(dayOfWeek) & 0x07);   // set the day and enable battery backup (00000111)|(00001000, Bit 3 = 1)
00177     buf[5] = decToBcd(dayOfMonth) & 0x3f;           // set the date in month (00111111)
00178     buf[6] = decToBcd(month) & 0x1f;                // set the month (00011111)
00179     buf[7] = decToBcd(year);                        // set the year (11111111)
00180     int w1 = _i2c.write(MCP79412_RTC_ADDR, buf, 8);
00181 
00182     // Start Clock:
00183     buf[0] = RTC_LOCATION;
00184     buf[1] = _BV(ST) | decToBcd(second);            // set seconds and enable clock (10000000)
00185     int w2 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
00186 
00187     _error = ((w1 != 0) || (w2 != 0));
00188 }
00189 
00190 // Get the date/time
00191 void MCP79412::getRtcDateTime(
00192   uint8_t *second,
00193   uint8_t *minute,
00194   uint8_t *hour,
00195   uint8_t *dayOfWeek,
00196   uint8_t *dayOfMonth,
00197   uint8_t *month,
00198   uint8_t *year)
00199 {
00200     char buf[8];
00201 
00202     buf[0] = RTC_LOCATION;
00203     int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00204     int r = _i2c.read(MCP79412_RTC_ADDR, buf, 7);
00205 
00206     _error = ((w != 0) || (r != 0));
00207 
00208     // A few of these need masks because certain bits are control bits
00209     *second     = bcdToDec(buf[0] & 0x7f);  // 01111111 0-59
00210     *minute     = bcdToDec(buf[1] & 0x7f);  // 01111111 0-59
00211     *hour       = bcdToDec(buf[2] & 0x3f);  // 00111111 1-23
00212     *dayOfWeek  = bcdToDec(buf[3] & 0x07);  // 00000111 1-7
00213     *dayOfMonth = bcdToDec(buf[4] & 0x3f);  // 00111111 1-31
00214     *month      = bcdToDec(buf[5] & 0x1f);  // 00011111 1-12
00215     *year       = bcdToDec(buf[6]);         // 11111111 0-99
00216 }
00217 
00218 bool MCP79412::checkTimeLost(void)
00219 {
00220     char buf[8];
00221     uint8_t second, minute, hour, dayOfWeek, dayOfMonth, month, year;
00222     buf[0] = RTC_LOCATION;
00223     int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00224     int r = _i2c.read(MCP79412_RTC_ADDR, buf, 7);
00225 
00226     _error = ((w != 0) || (r != 0));
00227 
00228     // A few of these need masks because certain bits are control bits
00229     second     = bcdToDec(buf[0] & 0x7f);  // 01111111 0-59
00230     minute     = bcdToDec(buf[1] & 0x7f);  // 01111111 0-59
00231     hour       = bcdToDec(buf[2] & 0x3f);  // 00111111 1-23
00232     dayOfWeek  = bcdToDec(buf[3] & 0x07);  // 00000111 1-7
00233     dayOfMonth = bcdToDec(buf[4] & 0x3f);  // 00111111 1-31
00234     month      = bcdToDec(buf[5] & 0x1f);  // 00011111 1-12
00235     year       = bcdToDec(buf[6]);         // 11111111 0-99
00236     return (year <= 15) ? true : false;
00237 }
00238 
00239 // Enable the clock without changing the date/time
00240 void MCP79412::enableClock()
00241 {
00242     // Get the current seconds value as the enable/disable bit is in the same
00243     // byte of memory as the seconds value:
00244     char buf[2];
00245     buf[0] = RTC_LOCATION;
00246     int w1 = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00247     int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
00248 
00249     int second = bcdToDec(buf[0] & 0x7f);  // 01111111
00250 
00251     // Start Clock:
00252     buf[0] = RTC_LOCATION;
00253     buf[1] = _BV(ST) | decToBcd(second);     // set seconds and enable clock (10000000, Bit 7, ST = 1)
00254     int w2 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
00255 
00256     _error = ((w1 != 0) || (r != 0) || (w2 != 0));
00257 }
00258 
00259 // Disable the clock without changing the date/time
00260 void MCP79412::disableClock()
00261 {
00262     // Get the current seconds value as the enable/disable bit is in the same
00263     // uint8_t of memory as the seconds value:
00264     char buf[2];
00265     buf[0] = RTC_LOCATION;
00266     int w1 = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00267     int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
00268   
00269     int second = bcdToDec(buf[0] & 0x7f);  // 01111111
00270 
00271     // Stop Clock:
00272     buf[0] = RTC_LOCATION;
00273     buf[1] = decToBcd(second);     // set seconds and disable clock (01111111, Bit 7, ST = 0)
00274     int w2 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
00275 
00276     _error = ((w1 != 0) || (r != 0) || (w2 != 0));
00277 }
00278 
00279 // Enable the battery
00280 void MCP79412::enableBattery()
00281 {
00282     // Get the current day value as the enable/disable bit is in the same
00283     // uint8_t of memory as the seconds value:
00284     char buf[2];
00285     buf[0] = DAY_REG;
00286     int w1 = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00287     int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
00288   
00289     int day = bcdToDec(buf[0] & 0x07);  // 00000111
00290 
00291     // Start Clock:
00292     buf[0] = DAY_REG;
00293     buf[1] = _BV(VBATEN) | decToBcd(day);     // set day and enable battery (00001000)
00294     int w2 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
00295 
00296     _error = ((w1 != 0) || (r != 0) || (w2 != 0));
00297 }
00298 
00299 
00300 // Write a single byte of data to RAM
00301 void MCP79412::writeRamByte(uint8_t location, uint8_t data)
00302 {
00303     writeRamBytes(location, &data, 1);
00304 //    char buf[2];
00305 //    if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
00306 //    {
00307 //        buf[0] = location;
00308 //        buf[1] = data;
00309 //        int w = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
00310 //        _error = (w != 0);
00311 //    }
00312 }
00313 
00314 // Write multiple bytes of data to RAM
00315 uint8_t MCP79412::writeRamBytes(uint8_t location, uint8_t *data, uint8_t length)
00316 {
00317     uint8_t bytesWritten = 0;
00318     char buf[1];
00319     buf[0] = location;
00320     int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00321     _error = (w != 0);
00322     for (uint8_t i = 0; i < length; i++) {
00323         buf[0] = data[i];
00324         int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1); // Returns 0 on success (ack), non-0 on failure (nack)
00325         bytesWritten++;
00326         if (_error == false) {
00327             _error = (w != 0);
00328         }
00329     }
00330     return bytesWritten;
00331 }
00332 
00333 // Read a single byte of data from RAM
00334 uint8_t MCP79412::readRamByte(uint8_t location)
00335 {
00336     uint8_t data;
00337     readRamBytes(location, &data, 1);
00338     return data;
00339 //    char buf[2];
00340 //    if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
00341 //    {
00342 //        buf[0] = location;
00343 //        int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00344 //        int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
00345 //
00346 //        _error = ((w != 0) || (r != 0));
00347 //
00348 //        return buf[0];
00349 //    }
00350 //    return 0;
00351 }
00352 
00353 // Read multiple bytes of data from RAM
00354 uint8_t MCP79412::readRamBytes(uint8_t location, uint8_t *data, uint8_t length)
00355 {
00356     uint8_t bytesRead = 0;
00357     char buf[1];
00358     buf[0] = location;
00359     int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00360     _error = (w != 0);
00361     for (uint8_t i = 0; i < length; i++) {
00362         int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
00363         bytesRead++;
00364         data[i] = buf[0];
00365         if (_error == false) {
00366             _error = (r != 0);
00367         }
00368     }
00369     return bytesRead;
00370 }
00371 
00372 // 64 Bytes SRAM, Battery Backed
00373 // Write a single byte of data to SRAM
00374 void MCP79412::writeSramByte(uint8_t location, uint8_t data)
00375 {
00376     writeSramBytes(location, &data, 1);
00377 //    char buf[2];
00378 //    if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
00379 //    {
00380 //        buf[0] = location;
00381 //        buf[1] = data;
00382 //        int w = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
00383 //        _error = (w != 0);
00384 //    }
00385 }
00386 
00387 // 64 Bytes SRAM, Battery Backed
00388 // Write multiple bytes of data to SRAM
00389 uint8_t MCP79412::writeSramBytes(uint8_t location, uint8_t *data, uint8_t length)
00390 {
00391     uint8_t bytesWritten = 0;
00392     char buf[1];
00393     buf[0] = location;
00394     int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00395     _error = (w != 0);
00396     for (uint8_t i = 0; i < length; i++) {
00397         if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
00398         {
00399             buf[0] = data[i];
00400             int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1); // Returns 0 on success (ack), non-0 on failure (nack)
00401             bytesWritten++;
00402             if (_error == false) {
00403                 _error = (w != 0);
00404             }
00405         }
00406         location++;
00407     }
00408     return bytesWritten;
00409 }
00410 
00411 // 64 Bytes SRAM, Battery Backed
00412 // Read a single byte of data from SRAM
00413 uint8_t MCP79412::readSramByte(uint8_t location)
00414 {
00415     uint8_t data;
00416     readSramBytes(location, &data, 1);
00417     return data;
00418 //    char buf[2];
00419 //    if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
00420 //    {
00421 //        buf[0] = location;
00422 //        int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00423 //        int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
00424 //
00425 //        _error = ((w != 0) || (r != 0));
00426 //
00427 //        return buf[0];
00428 //    }
00429 //    return 0;
00430 }
00431 
00432 // 64 Bytes SRAM, Battery Backed
00433 // Read multiple bytes of data from SRAM
00434 uint8_t MCP79412::readSramBytes(uint8_t location, uint8_t *data, uint8_t length)
00435 {
00436     uint8_t bytesRead = 0;
00437     char buf[1];
00438     buf[0] = location;
00439     int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00440     _error = (w != 0);
00441     for (uint8_t i = 0; i < length; i++) {
00442         if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
00443         {
00444             int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
00445             bytesRead++;
00446             data[i] = buf[0];
00447             if (_error == false) {
00448                 _error = (r != 0);
00449             }
00450         }
00451         location++;
00452     }
00453     return bytesRead;
00454 }
00455 
00456 // 128 Bytes EEPROM
00457 // Write a single byte of data to EEPROM
00458 void MCP79412::writeEepromByte(uint8_t location, uint8_t data)
00459 {
00460     writeEepromBytes(location, &data, 1);
00461 //    char buf[2];
00462 //    unlockUniqueID();
00463 //    buf[0] = location & (EEPROM_SIZE - 1);
00464 //    buf[1] = data;
00465 //    int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 2);
00466 //    _error = (w != 0);
00467 }
00468 
00469 // 128 Bytes EEPROM
00470 // Unlock the unique id area and write multiple of bytes to EEPROM
00471 uint8_t MCP79412::writeEepromBytes(uint8_t location, uint8_t *data, uint8_t length)
00472 {
00473     uint8_t bytesWritten = 0;
00474     char buf[1];
00475     unlockUniqueID();
00476     buf[0] = location & (EEPROM_SIZE - 1);  // location & 0x7f
00477     int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 1);
00478     _error = (w != 0);
00479     for (uint8_t i = 0; i < length; i++) {
00480         if (location < EEPROM_SIZE)
00481         {
00482             buf[0] = data[i];
00483             int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 1); // Returns 0 on success (ack), non-0 on failure (nack)
00484             bytesWritten++;
00485             if (_error == false) {
00486                 _error = (w != 0);
00487             }
00488         }
00489         location++;
00490     }
00491     return bytesWritten;
00492 }
00493 
00494 // 128 Bytes EEPROM
00495 // Read a single byte of data from EEPROM
00496 uint8_t MCP79412::readEepromByte(uint8_t location)
00497 {
00498     uint8_t data;
00499     readEepromBytes(location, &data, 1);
00500     return data;
00501 //    char buf[2];
00502 //    if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
00503 //    {
00504 //        buf[0] = location;
00505 //        int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00506 //        int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
00507 //
00508 //        _error = ((w != 0) || (r != 0));
00509 //
00510 //        return buf[0];
00511 //    }
00512 //    return 0;
00513 }
00514 
00515 // 128 Bytes EEPROM
00516 // Read multiple bytes of data from EEPROM
00517 uint8_t MCP79412::readEepromBytes(uint8_t location, uint8_t *data, uint8_t length)
00518 {
00519     uint8_t bytesRead = 0;
00520     char buf[1];
00521     buf[0] = location & (EEPROM_SIZE - 1);  // location & 0x7f
00522     int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 1);
00523     _error = (w != 0);
00524     for (uint8_t i = 0; i < length; i++) {
00525         if (location < EEPROM_SIZE)
00526         {
00527             int r = _i2c.read(MCP79412_EEPROM_ADDR, buf, 1);
00528             bytesRead++;
00529             data[i] = buf[0];
00530             if (_error == false) {
00531                 _error = (r != 0);
00532             }
00533         }
00534         location++;
00535     }
00536     return bytesRead;
00537 }
00538 
00539 /*----------------------------------------------------------------------*
00540  * Read the calibration register.                                       *
00541  * The calibration value is not a twos-complement number. The MSB is    *
00542  * the sign bit, and the 7 LSBs are an unsigned number, so we convert   *
00543  * it and return it to the caller as a regular twos-complement integer. *
00544  *----------------------------------------------------------------------*/
00545 int MCP79412::calibRead(void)
00546 {
00547     uint8_t val = readRamByte(CALIB_REG);
00548 
00549     if ( val & 0x80 ) {
00550         return -(val & 0x7F);
00551     }
00552     return val;
00553 }
00554 
00555 /*----------------------------------------------------------------------*
00556  * Write the calibration register.                                      *
00557  * Calibration value must be between -127 and 127, others result        *
00558  * in no action. See note above on the format of the calibration value. *
00559  *----------------------------------------------------------------------*/
00560 void MCP79412::calibWrite(int value)
00561 {
00562     uint8_t calibVal;
00563 
00564     if (value >= -127 && value <= 127) {
00565         calibVal = abs(value);
00566         if (value < 0) {
00567             calibVal += 128;
00568         }
00569         writeRamByte(CALIB_REG, calibVal);
00570     }
00571 }
00572 
00573 /*----------------------------------------------------------------------*
00574  * Read the unique ID.                                                  *
00575  * User or factory programmable, Protected area                         *
00576  * For the MCP79411 (EUI-48), the first two bytes will contain 0xFF.    *
00577  * Caller must provide an 8-byte array to contain the results.          *
00578  *----------------------------------------------------------------------*/
00579 void MCP79412::readUniqueId(char *uniqueID)
00580 {
00581     char buf[1];
00582     buf[0] = UNIQUE_ID_ADDR;
00583     int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 1);
00584     int r = _i2c.read(MCP79412_EEPROM_ADDR, uniqueID, UNIQUE_ID_SIZE);
00585     _error = ((w != 0) || (r != 0));
00586 }
00587 
00588 /*----------------------------------------------------------------------------*
00589  * Returns an EUI-64 ID. For an MCP79411, the EUI-48 ID is converted to       *
00590  * EUI-64. For an MCP79412, calling this function is equivalent to            *
00591  * calling readUniqueId(). For an MCP79412, if the RTC type is known, calling *
00592  * readUniqueId() will be a bit more efficient.                               *
00593  * Caller must provide an 8-byte array to contain the results.                *
00594  *----------------------------------------------------------------------------*/
00595 void MCP79412::getEUI64(char *uniqueID)
00596 {
00597     char rtcID[8];
00598 
00599     readUniqueId(rtcID);
00600     if ((rtcID[0] == 0xFF) && (rtcID[1] == 0xFF)) {
00601         rtcID[0] = rtcID[2];
00602         rtcID[1] = rtcID[3];
00603         rtcID[2] = rtcID[4];
00604         rtcID[3] = 0xFF;
00605         rtcID[4] = 0xFE;
00606     }
00607     for (uint8_t i = 0; i < UNIQUE_ID_SIZE; i++) {
00608         uniqueID[i] = rtcID[i];
00609     }
00610 }
00611 
00612 /*----------------------------------------------------------------------*
00613  * Check to see if a power failure has occurred. If so, returns TRUE    *
00614  * as the function value, and returns the power down and power up       *
00615  * timestamps. After returning the time stamps, the RTC's timestamp     *
00616  * registers are cleared and the VBAT bit which indicates a power       *
00617  * failure is reset.                                                    *
00618  *                                                                      *
00619  * Note that the power down and power up timestamp registers do not     *
00620  * contain values for seconds or for the year. The returned time stamps *
00621  * will therefore contain the current year from the RTC. However, there *
00622  * is a chance that a power outage spans from one year to the next.     *
00623  * If we find the power down timestamp to be later (larger) than the    *
00624  * power up timestamp, we will assume this has happened, and well       *
00625  * subtract one year from the power down timestamp.                     *
00626  *                                                                      *
00627  * Still, there is an assumption that the timestamps are being read     *
00628  * in the same year as that when the power up occurred.                 *
00629  *                                                                      *
00630  * Finally, note that once the RTC records a power outage, it must be   *
00631  * cleared before another will be recorded.                             *
00632  *----------------------------------------------------------------------*/
00633 bool MCP79412::powerFail(time_t *powerDown, time_t *powerUp)
00634 {
00635     uint8_t day, yr;                //copies of the RTC Day and Year registers
00636     struct tm dn, up;               //power down and power up times
00637     char buf[8];
00638 
00639     readRamBytes(DAY_REG, &day, 1);
00640     readRamBytes(YEAR_REG, &yr, 1);
00641     yr = y2kYearToTm(bcdToDec(yr));
00642     if ( day & _BV(VBAT) ) {
00643         buf[0] = PWRDWN_TS_REG;
00644         int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00645 
00646         int r = _i2c.read(MCP79412_RTC_ADDR, buf, 8);       //read both timestamp registers, 8 bytes total
00647         dn.tm_sec     = 0;
00648         dn.tm_min     = bcdToDec(buf[0]);
00649         dn.tm_hour    = bcdToDec(buf[1] & ~_BV(HR1224));     //assumes 24hr clock
00650         dn.tm_mday    = bcdToDec(buf[2]);
00651         dn.tm_mon     = bcdToDec(buf[3] & 0x1F);             //mask off the day, we don't need it
00652         dn.tm_year    = yr;                                 //assume current year
00653         up.tm_sec     = 0;
00654         up.tm_min     = bcdToDec(buf[4]);
00655         up.tm_hour    = bcdToDec(buf[5] & ~_BV(HR1224));     //assumes 24hr clock
00656         up.tm_mday    = bcdToDec(buf[6]);
00657         up.tm_mon     = bcdToDec(buf[7] & 0x1F);             //mask off the day, we don't need it
00658         up.tm_year    = yr;                                 //assume current year
00659         
00660         *powerDown = mktime(&dn);
00661         *powerUp   = mktime(&up);
00662 
00663         //clear the VBAT bit, which causes the RTC hardware to clear the timestamps too.
00664         //I suppose there is a risk here that the day has changed since we read it,
00665         //but the Day of Week is actually redundant data and the makeTime() function
00666         //does not use it. This could be an issue if someone is reading the RTC
00667         //registers directly, but as this library is meant to be used with the Time library,
00668         //and also because we don't provide a method to read the RTC clock/calendar
00669         //registers directly, we won't lose any sleep about it at this point unless
00670         //some issue is actually brought to our attention ;-)
00671         day &= ~_BV(VBAT);
00672         writeRamBytes(DAY_REG, &day , 1);
00673 
00674         //adjust the powerDown timestamp if needed (see notes above)
00675         if (*powerDown > *powerUp) {
00676             --dn.tm_year;
00677             *powerDown = mktime(&dn);
00678         }
00679         return true;
00680     }
00681     return false;
00682 }
00683 
00684 /*----------------------------------------------------------------------*
00685  * Enable or disable the square wave output.                            *
00686  *----------------------------------------------------------------------*/
00687 void MCP79412::squareWave(Sqwave freq)
00688 {
00689     uint8_t ctrlReg;
00690 
00691     readRamBytes(CTRL_REG, &ctrlReg, 1);
00692     if (freq > 3) {
00693         ctrlReg &= ~_BV(SQWE);
00694     }
00695     else {
00696         ctrlReg = (ctrlReg & 0xF8) | _BV(SQWE) | freq;
00697     }
00698     writeRamByte(CTRL_REG, ctrlReg);
00699 }
00700 
00701 /*----------------------------------------------------------------------*
00702  * Set an alarm time. Sets the alarm registers only, does not enable    *
00703  * the alarm. See enableAlarm().                                        *
00704  *----------------------------------------------------------------------*/
00705 void MCP79412::setAlarm(uint8_t alarmNumber, time_t alarmTime)
00706 {
00707     struct tm *t;
00708     uint8_t day;                        // Need to preserve bits in the day (of week) register
00709 
00710     alarmNumber &= 0x01;                // Ensure a valid alarm number
00711     readRamBytes(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG) , &day, 1);
00712     t = localtime(&alarmTime);            // Put the time_t into the tm structure
00713     
00714     char buf[7];
00715     buf[0] = ALM0_REG + alarmNumber * (ALM1_REG - ALM0_REG);
00716     buf[1] = dec2bcd(t->tm_sec);
00717     buf[2] = dec2bcd(t->tm_min);
00718     buf[3] = dec2bcd(t->tm_hour);       // Sets 24 hour format (Bit 6 == 0)
00719     buf[4] = (day & 0xF8) + t->tm_wday;
00720     buf[5] = dec2bcd(t->tm_mday);
00721     buf[6] = dec2bcd(t->tm_mon);
00722     int w = _i2c.write(MCP79412_RTC_ADDR, buf, 7);
00723     _error = (w != 0);
00724 }
00725 
00726 /*----------------------------------------------------------------------*
00727  * Enable or disable an alarm, and set the trigger criteria,            *
00728  * e.g. match only seconds, only minutes, entire time and date, etc.    *
00729  *----------------------------------------------------------------------*/
00730 void MCP79412::enableAlarm(uint8_t alarmNumber, uint8_t alarmType)
00731 {
00732     uint8_t day;                //alarm day register has config & flag bits
00733     uint8_t ctrl;               //control register has alarm enable bits
00734 
00735     alarmNumber &= 0x01;        //ensure a valid alarm number
00736     readRamBytes(CTRL_REG, &ctrl, 1);
00737     if (alarmType < ALM_DISABLE) {
00738         readRamBytes(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
00739         day = ( day & 0x87 ) | alarmType << 4;  //reset interrupt flag, OR in the config bits
00740         writeRamByte(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), day);
00741         ctrl |= _BV(ALM0 + alarmNumber);        //enable the alarm
00742     }
00743     else {
00744         ctrl &= ~(_BV(ALM0 + alarmNumber));     //disable the alarm
00745     }
00746     writeRamByte(CTRL_REG, ctrl);
00747 }
00748 
00749 /*----------------------------------------------------------------------*
00750  * Returns true or false depending on whether the given alarm has been  *
00751  * triggered, and resets the alarm "interrupt" flag. This is not a real *
00752  * interrupt, just a bit that's set when an alarm is triggered.         *
00753  *----------------------------------------------------------------------*/
00754 bool MCP79412::alarm(uint8_t alarmNumber)
00755 {
00756     uint8_t day;                //alarm day register has config & flag bits
00757 
00758     alarmNumber &= 0x01;        //ensure a valid alarm number
00759     readRamBytes( ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
00760     if (day & _BV(ALMIF)) {
00761         day &= ~_BV(ALMIF);     //turn off the alarm "interrupt" flag
00762         writeRamByte(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), day);
00763         return true;
00764     }
00765     return false;
00766 }
00767 
00768 /*----------------------------------------------------------------------*
00769  * Sets the logic level on the MFP when it's not being used as a        *
00770  * square wave or alarm output. The default is HIGH.                    *
00771  *----------------------------------------------------------------------*/
00772 void MCP79412::out(bool level)
00773 {
00774     uint8_t ctrlReg;
00775 
00776     readRamBytes(CTRL_REG, &ctrlReg, 1);
00777     if (level)
00778         ctrlReg |= _BV(OUT);
00779     else
00780         ctrlReg &= ~_BV(OUT);
00781     writeRamByte(CTRL_REG, ctrlReg);
00782 }
00783 
00784 /*----------------------------------------------------------------------*
00785  * Specifies the logic level on the Multi-Function Pin (MFP) when an    *
00786  * alarm is triggered. The default is LOW. When both alarms are         *
00787  * active, the two are ORed together to determine the level of the MFP. *
00788  * With alarm polarity set to LOW (the default), this causes the MFP    *
00789  * to go low only when BOTH alarms are triggered. With alarm polarity   *
00790  * set to HIGH, the MFP will go high when EITHER alarm is triggered.    *
00791  *                                                                      *
00792  * Note that the state of the MFP is independent of the alarm           *
00793  * "interrupt" flags, and the alarm() function will indicate when an    *
00794  * alarm is triggered regardless of the polarity.                       *
00795  *----------------------------------------------------------------------*/
00796 void MCP79412::alarmPolarity(bool polarity)
00797 {
00798     uint8_t alm0Day;
00799 
00800     readRamBytes(ALM0_DAY, &alm0Day, 1);
00801     if (polarity)
00802         alm0Day |= _BV(OUT);
00803     else
00804         alm0Day &= ~_BV(OUT);
00805     writeRamByte(ALM0_DAY, alm0Day);
00806 }
00807 
00808 /*----------------------------------------------------------------------*
00809  * Check to see if the RTC's oscillator is started (ST bit in seconds   *
00810  * register). Returns true if started.                                  *
00811  *----------------------------------------------------------------------*/
00812 bool MCP79412::isRunning(void)
00813 {
00814     char buf[1];
00815     buf[0] = (uint8_t)TIME_REG;
00816     int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
00817     int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
00818     _error = ((w != 0) || (r != 0));
00819     return buf[0] & _BV(ST);
00820 }
00821 
00822 /*----------------------------------------------------------------------*
00823  * Set or clear the VBATEN bit. Setting the bit powers the clock and    *
00824  * SRAM from the backup battery when Vcc falls. Note that setting the   *
00825  * time via set() or write() sets the VBATEN bit.                       *
00826  *----------------------------------------------------------------------*/
00827 void MCP79412::vbaten(bool enable)
00828 {
00829     uint8_t day;
00830 
00831     readRamBytes(DAY_REG, &day, 1);
00832     if (enable)
00833         day |= _BV(VBATEN);
00834     else
00835         day &= ~_BV(VBATEN);
00836 
00837     writeRamByte(DAY_REG, day);
00838     return;
00839 }
00840 
00841 
00842 
00843 //bool MCP79412::getSummerTime(void)
00844 //{
00845 //    getDateTime(&t);
00846 //
00847 //    time_t secondsEpoch = mktime(&t);   // seconds since the Epoch
00848 //    t = *localtime(&secondsEpoch);
00849 //    strftime(buffer, 32, "%j", localtime(&secondsEpoch));
00850 //    int dayOfYearC = atoi(buffer);
00851 //
00852 //    strftime(buffer, 32, "%Y", localtime(&secondsEpoch));
00853 //    int year = atoi(buffer);
00854 //
00855 //    int index  = (year - 2011) * 5;
00856 //    if (index < 0)
00857 //        index = 0;
00858 //    if (index > 440)                    // (2099 - 2011) * 5 = 440
00859 //        index = 440;
00860 //    
00861 //    int monthS = atoi(SummerTime[index+1]);
00862 //    int dayS   = atoi(SummerTime[index+2]);
00863 //
00864 //    t.tm_mon   = monthS - 1;            // adjust for tm structure required values
00865 //    t.tm_mday  = dayS;
00866 //    secondsEpoch = mktime(&t);   // seconds since the Epoch
00867 //    t = *localtime(&secondsEpoch);
00868 //    strftime(buffer, 32, "%j", localtime(&secondsEpoch));
00869 //    int dayOfYearS = atoi(buffer);
00870 //
00871 //    int monthE = atoi(SummerTime[index+3]);
00872 //    int dayE   = atoi(SummerTime[index+4]);
00873 //
00874 //    t.tm_mon   = monthE - 1;            // adjust for tm structure required values
00875 //    t.tm_mday  = dayE;
00876 //    secondsEpoch = mktime(&t);   // seconds since the Epoch
00877 //    t = *localtime(&secondsEpoch);
00878 //    strftime(buffer, 32, "%j", localtime(&secondsEpoch));
00879 //    int dayOfYearE = atoi(buffer);
00880 //
00881 //    return ((dayOfYearC >= dayOfYearS) && (dayOfYearC < dayOfYearE)) ? true : false;
00882 //}
00883 //
00884 //int MCP79412::dayOfYearC(void)
00885 //{
00886 //    getDateTime(&t);
00887 //
00888 //    time_t secondsEpoch = mktime(&t);   // seconds since the Epoch
00889 //    strftime(buffer, 32, "%j", localtime(&secondsEpoch));
00890 //    return atoi(buffer);
00891 //}
00892 //
00893 //char * MCP79412::getSunRise(void)
00894 //{
00895 //    return (char*) SunRise[dayOfYearC()];
00896 //}
00897 //
00898 //char * MCP79412::getSunSet(void)
00899 //{
00900 //    return (char*) SunSet[dayOfYearC()];
00901 //}
00902 //
00903 //char * MCP79412::getDayLength(void)
00904 //{
00905 //    return (char*) DayLength[dayOfYearC()];
00906 //}
00907 //
00908 //int MCP79412::getSunRiseMinute(void)
00909 //{
00910 //    int doy = dayOfYearC();
00911 //    int h = atoi(substr((char*)SunRise[doy], 0, 2));
00912 //    int m = atoi(substr((char*)SunRise[doy], 3, 2));
00913 //    return h * 60 + m;
00914 //}
00915 //
00916 //int MCP79412::getSunSetMinute(void)
00917 //{
00918 //    int doy = dayOfYearC();
00919 //    int h = atoi(substr((char*)SunSet[doy], 0, 2));
00920 //    int m = atoi(substr((char*)SunSet[doy], 3, 2));
00921 //    return h * 60 + m;
00922 //}
00923 //
00924 //bool MCP79412::checkSunRise(void)
00925 //{
00926 //    int dayOfWeek, mday, month, year, hours, minutes, seconds;
00927 //    readDateTime(&dayOfWeek, &mday, &month, &year, &hours, &minutes, &seconds);
00928 //
00929 //    int absMinute     = hours * 60 + minutes;
00930 //    int SunRiseMinute = getSunRiseMinute();
00931 //    int SunSetMinute  = getSunSetMinute();
00932 //
00933 //    return ((absMinute >= SunRiseMinute) && (absMinute < SunSetMinute)) ? true : false;
00934 //}
00935 
00936 
00937 void MCP79412::substr(char *s, char *d, int pos, int len)
00938 {
00939     char *t;
00940     s = s+pos;
00941     t = s+len;
00942     while (s != t) {
00943         *d=*s;
00944         s++;
00945         d++;
00946     }
00947     *d='\0';
00948 }
00949 
00950 char * MCP79412::substr(char *s, int pos, int len)
00951 {
00952     char *t;
00953     char *d;
00954     d = buffer;
00955     s = s+pos;
00956     t = s+len;
00957     while (s != t) {
00958         *d=*s;
00959         s++;
00960         d++;
00961     }
00962     *d='\0';
00963     return buffer;
00964 }
00965 
00966 
00967 
00968 
00969 struct tm MCP79412::setSystemDateTime(
00970   uint8_t second,        // 0-59
00971   uint8_t minute,        // 0-59
00972   uint8_t hour,          // 1-23
00973   uint8_t dayOfMonth,    // 1-31
00974   uint8_t month,         // 1-12
00975   uint8_t year)          // 0-99
00976 {
00977     uint8_t dayOfWeek = 1;          // Will be determined
00978     // Convert to unix time structure
00979     t->tm_sec   = second;           // 0-59
00980     t->tm_min   = minute;           // 0-59
00981     t->tm_hour  = hour;             // 0-23
00982     t->tm_wday  = dayOfWeek - 1;    // 0-6     (0 = Sunday)
00983     t->tm_mday  = dayOfMonth;       // 1-31
00984     t->tm_mon   = month - 1;        // 0-11
00985     t->tm_year  = year + 100;       // 100-199 year since 1900
00986     t->tm_isdst = 0;
00987     
00988 //    printf("-> Debug %d %02d-%02d-%03d %02d:%02d:%02d\n", t->tm_wday, t->tm_mday, t->tm_mon, t->tm_year, t->tm_hour, t->tm_min, t->tm_sec);
00989 
00990     secondsEpoch = mktime(t);   // seconds since the Epoch
00991     set_time(secondsEpoch);
00992 
00993     // Get weekday 0-6, Sunday as 0 for RTC
00994     t = localtime(&secondsEpoch);
00995 //    printf("-> Debug %d %02d-%02d-%03d %02d:%02d:%02d\n", t->tm_wday, t->tm_mday, t->tm_mon, t->tm_year, t->tm_hour, t->tm_min, t->tm_sec);
00996     return *t;
00997 }
00998 
00999 void MCP79412::getSystemDateTime(
01000   uint8_t *second,          // 0-59
01001   uint8_t *minute,          // 0-59
01002   uint8_t *hour,            // 0-23
01003   uint8_t *dayOfWeek,       // 1-7     (1 = Sunday) 
01004   uint8_t *dayOfMonth,      // 1-31
01005   uint8_t *month,           // 1-12
01006   uint8_t *year)            // 0-99 year since 2000
01007 {
01008 //    struct tm *t;
01009 //    time_t secondsEpoch;
01010 
01011     // Get system DateTime
01012     secondsEpoch = time(NULL);
01013     t = localtime(&secondsEpoch);
01014 
01015     // time/date data
01016     *second     = (t->tm_sec);          // 0-59
01017     *minute     = (t->tm_min);          // 0-59
01018     *hour       = (t->tm_hour);         // 0-23
01019     *dayOfWeek  = (t->tm_wday + 1);     // 1-7     (1 = Sunday)
01020     *dayOfMonth = (t->tm_mday);         // 1-31
01021     *month      = (t->tm_mon + 1);      // 1-12
01022     *year       = (t->tm_year - 100);   // 0-99 year since 2000
01023 }
01024 
01025 void MCP79412::setRtcToSystemDateTime(void)
01026 {
01027     // Get system DateTime
01028     secondsEpoch = time(NULL);
01029     t = localtime(&secondsEpoch);
01030 
01031     // Convert from unix time structure
01032     uint8_t second     = (t->tm_sec);           // 0-59
01033     uint8_t minute     = (t->tm_min);           // 0-59
01034     uint8_t hour       = (t->tm_hour);          // 0-23
01035     uint8_t dayOfWeek  = (t->tm_wday + 1);      // 1-7     (1 = Sunday)
01036     uint8_t dayOfMonth = (t->tm_mday);          // 1-31
01037     uint8_t month      = (t->tm_mon + 1);       // 1-12
01038     uint8_t year       = (t->tm_year - 100);    // 0-99 year since 2000
01039 
01040     // Set RTC DateTime
01041     setRtcDateTime(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
01042 }
01043 
01044 void MCP79412::setSystemToRtcDateTime(void)
01045 {
01046     // Get RTC DateTime
01047     getRtcDateTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
01048 
01049     // Convert to unix time structure
01050     t->tm_sec   = second;           // 0-59
01051     t->tm_min   = minute;           // 0-59
01052     t->tm_hour  = hour;             // 0-23
01053     t->tm_wday  = dayOfWeek - 1;    // 0-6     (0 = Sunday)
01054     t->tm_mday  = dayOfMonth;       // 1-31
01055     t->tm_mon   = month - 1;        // 0-11
01056     t->tm_year  = year + 100;       // 100-199 year since 1900
01057     t->tm_isdst = 0;
01058     
01059     // Set system DateTime
01060     secondsEpoch = mktime(t);   // seconds since the Epoch
01061     set_time(secondsEpoch);
01062 }
01063 
01064 void MCP79412::setRtcFromTm(struct tm *t)
01065 {
01066 //    // Get system DateTime
01067 //    secondsEpoch = time(NULL);
01068 //    t = localtime(&secondsEpoch);
01069 
01070     // Convert from unix time structure
01071     uint8_t second     = (t->tm_sec);           // 0-59
01072     uint8_t minute     = (t->tm_min);           // 0-59
01073     uint8_t hour       = (t->tm_hour);          // 0-23
01074     uint8_t dayOfWeek  = (t->tm_wday + 1);      // 1-7     (1 = Sunday)
01075     uint8_t dayOfMonth = (t->tm_mday);          // 1-31
01076     uint8_t month      = (t->tm_mon + 1);       // 1-12
01077     uint8_t year       = (t->tm_year - 100);    // 0-99 year since 2000
01078 
01079 //    printf("setRtcFromTm %d %02d-%02d-%03d %02d:%02d:%02d\n", dayOfWeek, dayOfMonth, month, year, hour, minute, second);
01080 
01081     // Set RTC DateTime
01082     setRtcDateTime(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
01083 }
01084 
01085 struct tm MCP79412::getTmFromRtc(void)
01086 {
01087     // Get RTC DateTime
01088     getRtcDateTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
01089 
01090     // Convert to unix time structure
01091     t->tm_sec   = second;           // 0-59
01092     t->tm_min   = minute;           // 0-59
01093     t->tm_hour  = hour;             // 0-23
01094     t->tm_wday  = dayOfWeek - 1;    // 0-6     (0 = Sunday)
01095     t->tm_mday  = dayOfMonth;       // 1-31
01096     t->tm_mon   = month - 1;        // 0-11
01097     t->tm_year  = year + 100;       // 100-199 year since 1900
01098     t->tm_isdst = 0;
01099     
01100     return *t;
01101 //    // Set system DateTime
01102 //    secondsEpoch = mktime(t);   // seconds since the Epoch
01103 //    set_time(secondsEpoch);
01104 }
01105 
01106 time_t MCP79412::getSecondsEpoch(void)
01107 {
01108     secondsEpoch = time(NULL);
01109     return secondsEpoch;
01110 }
01111 
01112 void MCP79412::setSecondsEpoch(time_t t)
01113 {
01114     secondsEpoch = t;
01115     set_time(secondsEpoch);
01116 }
01117 
01118 void MCP79412::getRtcDateTimeAsTm(void)
01119 {
01120     // Get RTC DateTime
01121     getRtcDateTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
01122 
01123     // Convert to unix time structure
01124     t->tm_sec   = second;           // 0-59
01125     t->tm_min   = minute;           // 0-59
01126     t->tm_hour  = hour;             // 0-23
01127     t->tm_wday  = dayOfWeek - 1;    // 0-6     (0 = Sunday)
01128     t->tm_mday  = dayOfMonth;       // 1-31
01129     t->tm_mon   = month - 1;        // 0-11
01130     t->tm_year  = year + 100;       // 100-199 year since 1900
01131     t->tm_isdst = 0;
01132     
01133     // Set system DateTime
01134     secondsEpoch = mktime(t);   // seconds since the Epoch
01135 //    time_t t = time(secondsEpoch);
01136     
01137 //    set_time(secondsEpoch);
01138 }
01139 
01140 time_t MCP79412::convertDateTimeToTimestamp(
01141   uint8_t second,        // 0-59
01142   uint8_t minute,        // 0-59
01143   uint8_t hour,          // 0-23
01144   uint8_t dayOfMonth,    // 1-31
01145   uint8_t month,         // 1-12
01146   uint8_t year)          // 0-99 year since 2000
01147 {
01148     // setup time structure for Wed, 28 Oct 2009 11:35:37
01149     struct tm t;
01150     t.tm_sec  = second;         // 0-59
01151     t.tm_min  = minute;         // 0-59
01152     t.tm_hour = hour;           // 0-23
01153     t.tm_mday = dayOfMonth;     // 1-31
01154     t.tm_mon  = month - 1;      // 0-11
01155     t.tm_year = year + 100;     // 100-199 year since 1900
01156 
01157 //    printf("Debug %d %02d-%02d-%03d %02d:%02d:%02d\n", t.tm_wday, t.tm_mday, t.tm_mon, t.tm_year, t.tm_hour, t.tm_min, t.tm_sec);
01158 
01159     // convert to timestamp and display (1256729737)
01160     time_t seconds = mktime(&t);
01161 //    printf("Time as seconds since January 1, 1970 = %d\n", seconds);
01162 
01163 //    char buffer[32];
01164 //    strftime(buffer, 32, "%a %d-%m-%Y %H:%M:%S\n", localtime(&seconds));
01165 //    printf("Time: %s", buffer);
01166 
01167     // Get weekday Sunday as 0 (0-6) for RTC
01168     struct tm *t2;
01169     t2 = localtime(&seconds);
01170 //    printf("Debug %d %02d-%02d-%03d %02d:%02d:%02d\n", t.tm_wday, t2->tm_mday, t2->tm_mon, t2->tm_year, t2->tm_hour, t2->tm_min, t2->tm_sec);
01171 //    printf("Weekday %d\n", t2->tm_wday);
01172 
01173     return seconds;
01174 }
01175 
01176 uint8_t MCP79412::getWeekdayFromDate(uint8_t dayOfMonth, uint8_t month, uint8_t year)          // year 0-99
01177 {
01178     // setup time structure for Wed, 28 Oct 2009 11:35:37
01179     struct tm t;
01180     t.tm_sec  = 0;              // 0-59
01181     t.tm_min  = 0;              // 0-59
01182     t.tm_hour = 0;              // 0-23
01183     t.tm_mday = dayOfMonth;     // 1-31
01184     t.tm_mon  = month - 1;      // 0-11
01185     t.tm_year = year + 100;     // 100-199 year since 1900
01186 
01187 //    printf("Debug %d %02d:%02d:%02d %02d-%02d-%02d\n", t.tm_wday, t.tm_mday, t.tm_mon, t.tm_year, t.tm_hour, t.tm_min, t.tm_sec);
01188 
01189     // convert to timestamp and display (1256729737)
01190     time_t seconds = mktime(&t);
01191 //    printf("Time as seconds since January 1, 1970 = %d\n", seconds);
01192 
01193 //    char buffer[32];
01194 //    strftime(buffer, 32, "%a %d-%m-%Y %H:%M:%S\n", localtime(&seconds));
01195 //    printf("Time: %s", buffer);
01196 
01197     // Get weekday Sunday as 0 (0-6) for RTC
01198     struct tm *t2;
01199     t2 = localtime(&seconds);
01200 //    printf("Debug %d %02d-%02d-%03d %02d:%02d:%02d\n", t2->tm_wday, t2->tm_mday, t2->tm_mon, t2->tm_year, t2->tm_hour, t2->tm_min, t2->tm_sec);
01201 //    printf("Weekday %d\n", t2->tm_wday);
01202 
01203     return t2->tm_wday;
01204 }
01205 
01206 
01207 
01208 
01209 
01210 
01211 
01212 
01213 //double MCP79412::clamp(double v)
01214 //{
01215 //    const double t = v < 0.0f ? 0.0f : v;
01216 //    return t > 1.0f ? 1.0f : t;
01217 //}
01218 
01219 
01220 //bool MCP79412::checkTimeLost(void)
01221 //{
01222 ////    return (atoi(getFormatedDateTime("%Y")) <= 2015) ? true : false;
01223 //    return false;
01224 //}
01225 
01226 //
01227 ///*----------------------------------------------------------------------*
01228 // * Read the current time from the RTC and return it in a tmElements_t   *
01229 // * structure. Returns false if RTC not present (I2C I/O error).         *
01230 // *----------------------------------------------------------------------*/
01231 //boolean MCP79412RTC::read(tmElements_t &tm)
01232 //{
01233 //    i2cBeginTransmission(RTC_ADDR);
01234 //    i2cWrite((uint8_t)TIME_REG);
01235 //    if (i2cEndTransmission() != 0) {
01236 //        return false;
01237 //    }
01238 //    else {
01239 //        //request 7 uint8_ts (secs, min, hr, dow, date, mth, yr)
01240 //        i2cRequestFrom(RTC_ADDR, tmNbrFields);
01241 //        tm.Second = bcd2dec(i2cRead() & ~_BV(ST));
01242 //        tm.Minute = bcd2dec(i2cRead());
01243 //        tm.Hour = bcd2dec(i2cRead() & ~_BV(HR1224));    //assumes 24hr clock
01244 //        tm.Wday = i2cRead() & ~(_BV(OSCON) | _BV(VBAT) | _BV(VBATEN));    //mask off OSCON, VBAT, VBATEN bits
01245 //        tm.Day = bcd2dec(i2cRead());
01246 //        tm.Month = bcd2dec(i2cRead() & ~_BV(LP));       //mask off the leap year bit
01247 //        tm.Year = y2kYearToTm(bcd2dec(i2cRead()));
01248 //        return true;
01249 //    }
01250 //}
01251 //
01252 ///*----------------------------------------------------------------------*
01253 // * Set the RTC's time from a tmElements_t structure.                    *
01254 // *----------------------------------------------------------------------*/
01255 //void MCP79412RTC::write(tmElements_t &tm)
01256 //{
01257 //    i2cBeginTransmission(RTC_ADDR);
01258 //    i2cWrite((uint8_t)TIME_REG);
01259 //    i2cWrite((uint8_t)0x00);                     //stops the oscillator (Bit 7, ST == 0)
01260 //    i2cWrite(dec2bcd(tm.Minute));
01261 //    i2cWrite(dec2bcd(tm.Hour));                  //sets 24 hour format (Bit 6 == 0)
01262 //    i2cWrite(tm.Wday | _BV(VBATEN));             //enable battery backup operation
01263 //    i2cWrite(dec2bcd(tm.Day));
01264 //    i2cWrite(dec2bcd(tm.Month));
01265 //    i2cWrite(dec2bcd(tmYearToY2k(tm.Year)));
01266 //    i2cEndTransmission();
01267 //
01268 //    i2cBeginTransmission(RTC_ADDR);
01269 //    i2cWrite((uint8_t)TIME_REG);
01270 //    i2cWrite(dec2bcd(tm.Second) | _BV(ST));    //set the seconds and start the oscillator (Bit 7, ST == 1)
01271 //    i2cEndTransmission();
01272 //}
01273 //
01274 ///*----------------------------------------------------------------------*
01275 // * Write a single uint8_t to RTC RAM.                                      *
01276 // * Valid address range is 0x00 - 0x5F, no checking.                     *
01277 // *----------------------------------------------------------------------*/
01278 //void MCP79412RTC::ramWrite(uint8_t addr, uint8_t value)
01279 //{
01280 //    ramWrite(addr, &value, 1);
01281 //}
01282 //
01283 ///*----------------------------------------------------------------------*
01284 // * Write multiple uint8_ts to RTC RAM.                                     *
01285 // * Valid address range is 0x00 - 0x5F, no checking.                     *
01286 // * Number of uint8_ts (nuint8_ts) must be between 1 and 31 (Wire library      *
01287 // * limitation).                                                         *
01288 // *----------------------------------------------------------------------*/
01289 //void MCP79412RTC::ramWrite(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
01290 //{
01291 //    i2cBeginTransmission(RTC_ADDR);
01292 //    i2cWrite(addr);
01293 //    for (uint8_t i=0; i<nuint8_ts; i++) i2cWrite(values[i]);
01294 //    i2cEndTransmission();
01295 //}
01296 //
01297 ///*----------------------------------------------------------------------*
01298 // * Read a single uint8_t from RTC RAM.                                     *
01299 // * Valid address range is 0x00 - 0x5F, no checking.                     *
01300 // *----------------------------------------------------------------------*/
01301 //uint8_t MCP79412RTC::ramRead(uint8_t addr)
01302 //{
01303 //    uint8_t value;
01304 //
01305 //    ramRead(addr, &value, 1);
01306 //    return value;
01307 //}
01308 //
01309 ///*----------------------------------------------------------------------*
01310 // * Read multiple uint8_ts from RTC RAM.                                    *
01311 // * Valid address range is 0x00 - 0x5F, no checking.                     *
01312 // * Number of uint8_ts (nuint8_ts) must be between 1 and 32 (Wire library      *
01313 // * limitation).                                                         *
01314 // *----------------------------------------------------------------------*/
01315 //void MCP79412RTC::ramRead(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
01316 //{
01317 //    i2cBeginTransmission(RTC_ADDR);
01318 //    i2cWrite(addr);
01319 //    i2cEndTransmission();
01320 //    i2cRequestFrom( (uint8_t)RTC_ADDR, nuint8_ts );
01321 //    for (uint8_t i=0; i<nuint8_ts; i++) values[i] = i2cRead();
01322 //}
01323 //
01324 ///*----------------------------------------------------------------------*
01325 // * Write a single uint8_t to Static RAM.                                   *
01326 // * Address (addr) is constrained to the range (0, 63).                  *
01327 // *----------------------------------------------------------------------*/
01328 //void MCP79412RTC::sramWrite(uint8_t addr, uint8_t value)
01329 //{
01330 //    ramWrite( (addr & (SRAM_SIZE - 1) ) + SRAM_START_ADDR, &value, 1 );
01331 //}
01332 //
01333 ///*----------------------------------------------------------------------*
01334 // * Write multiple uint8_ts to Static RAM.                                  *
01335 // * Address (addr) is constrained to the range (0, 63).                  *
01336 // * Number of uint8_ts (nuint8_ts) must be between 1 and 31 (Wire library      *
01337 // * limitation).                                                         *
01338 // * Invalid values for nuint8_ts, or combinations of addr and nuint8_ts        *
01339 // * that would result in addressing past the last uint8_t of SRAM will      *
01340 // * result in no action.                                                 *
01341 // *----------------------------------------------------------------------*/
01342 //void MCP79412RTC::sramWrite(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
01343 //{
01344 //#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
01345 //    if (nuint8_ts >= 1 && (addr + nuint8_ts) <= SRAM_SIZE) {
01346 //#else
01347 //    if (nuint8_ts >= 1 && nuint8_ts <= (BUFFER_LENGTH - 1) && (addr + nuint8_ts) <= SRAM_SIZE) {
01348 //#endif
01349 //        ramWrite( (addr & (SRAM_SIZE - 1) ) + SRAM_START_ADDR, values, nuint8_ts );
01350 //    }
01351 //}
01352 //
01353 ///*----------------------------------------------------------------------*
01354 // * Read a single uint8_t from Static RAM.                                  *
01355 // * Address (addr) is constrained to the range (0, 63).                  *
01356 // *----------------------------------------------------------------------*/
01357 //uint8_t MCP79412RTC::sramRead(uint8_t addr)
01358 //{
01359 //    uint8_t value;
01360 //
01361 //    ramRead( (addr & (SRAM_SIZE - 1) ) + SRAM_START_ADDR, &value, 1 );
01362 //    return value;
01363 //}
01364 //
01365 ///*----------------------------------------------------------------------*
01366 // * Read multiple uint8_ts from Static RAM.                                 *
01367 // * Address (addr) is constrained to the range (0, 63).                  *
01368 // * Number of uint8_ts (nuint8_ts) must be between 1 and 32 (Wire library      *
01369 // * limitation).                                                         *
01370 // * Invalid values for nuint8_ts, or combinations of addr and               *
01371 // * nuint8_ts that would result in addressing past the last uint8_t of SRAM    *
01372 // * result in no action.                                                 *
01373 // *----------------------------------------------------------------------*/
01374 //void MCP79412RTC::sramRead(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
01375 //{
01376 //#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
01377 //    if (nuint8_ts >= 1 && (addr + nuint8_ts) <= SRAM_SIZE) {
01378 //#else
01379 //    if (nuint8_ts >= 1 && nuint8_ts <= BUFFER_LENGTH && (addr + nuint8_ts) <= SRAM_SIZE) {
01380 //#endif
01381 //        ramRead((addr & (SRAM_SIZE - 1) ) + SRAM_START_ADDR, values, nuint8_ts);
01382 //    }
01383 //}
01384 //
01385 ///*----------------------------------------------------------------------*
01386 // * Write a single uint8_t to EEPROM.                                       *
01387 // * Address (addr) is constrained to the range (0, 127).                 *
01388 // * Can't leverage page write function because a write can't start       *
01389 // * mid-page.                                                            *
01390 // *----------------------------------------------------------------------*/
01391 //void MCP79412RTC::eepromWrite(uint8_t addr, uint8_t value)
01392 //{
01393 //    i2cBeginTransmission(MCP79412_EEPROM_ADDR);
01394 //    i2cWrite( addr & (EEPROM_SIZE - 1) );
01395 //    i2cWrite(value);
01396 //    i2cEndTransmission();
01397 //    eepromWait();
01398 //}
01399 //
01400 ///*----------------------------------------------------------------------*
01401 // * Write a page (or less) to EEPROM. An EEPROM page is 8 uint8_ts.         *
01402 // * Address (addr) should be a page start address (0, 8, ..., 120), but  *
01403 // * is ruthlessly coerced into a valid value.                            *
01404 // * Number of uint8_ts (nuint8_ts) must be between 1 and 8, other values       *
01405 // * result in no action.                                                 *
01406 // *----------------------------------------------------------------------*/
01407 //void MCP79412RTC::eepromWrite(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
01408 //{
01409 //    if (nuint8_ts >= 1 && nuint8_ts <= EEPROM_PAGE_SIZE) {
01410 //        i2cBeginTransmission(MCP79412_EEPROM_ADDR);
01411 //        i2cWrite( addr & ~(EEPROM_PAGE_SIZE - 1) & (EEPROM_SIZE - 1) );
01412 //        for (uint8_t i=0; i<nuint8_ts; i++) i2cWrite(values[i]);
01413 //        i2cEndTransmission();
01414 //        eepromWait();
01415 //    }
01416 //}
01417 //
01418 ///*----------------------------------------------------------------------*
01419 // * Read a single uint8_t from EEPROM.                                      *
01420 // * Address (addr) is constrained to the range (0, 127).                  *
01421 // *----------------------------------------------------------------------*/
01422 //uint8_t MCP79412RTC::eepromRead(uint8_t addr)
01423 //{
01424 //    uint8_t value;
01425 //
01426 //    eepromRead( addr & (EEPROM_SIZE - 1), &value, 1 );
01427 //    return value;
01428 //}
01429 //
01430 ///*----------------------------------------------------------------------*
01431 // * Read multiple uint8_ts from EEPROM.                                     *
01432 // * Address (addr) is constrained to the range (0, 127).                 *
01433 // * Number of uint8_ts (nuint8_ts) must be between 1 and 32 (Wire library      *
01434 // * limitation).                                                         *
01435 // * Invalid values for addr or nuint8_ts, or combinations of addr and       *
01436 // * nuint8_ts that would result in addressing past the last uint8_t of EEPROM  *
01437 // * result in no action.                                                 *
01438 // *----------------------------------------------------------------------*/
01439 //void MCP79412RTC::eepromRead(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
01440 //{
01441 //#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
01442 //    if (nuint8_ts >= 1 && (addr + nuint8_ts) <= EEPROM_SIZE) {
01443 //#else
01444 //    if (nuint8_ts >= 1 && nuint8_ts <= BUFFER_LENGTH && (addr + nuint8_ts) <= EEPROM_SIZE) {
01445 //#endif
01446 //        i2cBeginTransmission(MCP79412_EEPROM_ADDR);
01447 //        i2cWrite( addr & (EEPROM_SIZE - 1) );
01448 //        i2cEndTransmission();
01449 //        i2cRequestFrom( (uint8_t)MCP79412_EEPROM_ADDR, nuint8_ts );
01450 //        for (uint8_t i=0; i<nuint8_ts; i++) values[i] = i2cRead();
01451 //    }
01452 //}
01453 //
01454 ///*----------------------------------------------------------------------*
01455 // * Wait for EEPROM write to complete.                                   *
01456 // *----------------------------------------------------------------------*/
01457 //uint8_t MCP79412RTC::eepromWait(void)
01458 //{
01459 //    uint8_t waitCount = 0;
01460 //    uint8_t txStatus;
01461 //
01462 //    do
01463 //    {
01464 //        ++waitCount;
01465 //        i2cBeginTransmission(MCP79412_EEPROM_ADDR);
01466 //        i2cWrite((uint8_t)0);
01467 //        txStatus = i2cEndTransmission();
01468 //
01469 //    } while (txStatus != 0);
01470 //
01471 //    return waitCount;
01472 //}
01473 //
01474 ///*----------------------------------------------------------------------*
01475 // * Read the calibration register.                                       *
01476 // * The calibration value is not a twos-complement number. The MSB is    *
01477 // * the sign bit, and the 7 LSBs are an unsigned number, so we convert   *
01478 // * it and return it to the caller as a regular twos-complement integer. *
01479 // *----------------------------------------------------------------------*/
01480 //int MCP79412RTC::calibRead(void)
01481 //{
01482 //    uint8_t val = ramRead(CALIB_REG);
01483 //
01484 //    if ( val & 0x80 ) return -(val & 0x7F);
01485 //    else return val;
01486 //}
01487 //
01488 ///*----------------------------------------------------------------------*
01489 // * Write the calibration register.                                      *
01490 // * Calibration value must be between -127 and 127, others result        *
01491 // * in no action. See note above on the format of the calibration value. *
01492 // *----------------------------------------------------------------------*/
01493 //void MCP79412RTC::calibWrite(int value)
01494 //{
01495 //    uint8_t calibVal;
01496 //
01497 //    if (value >= -127 && value <= 127) {
01498 //        calibVal = abs(value);
01499 //        if (value < 0) calibVal += 128;
01500 //        ramWrite(CALIB_REG, calibVal);
01501 //    }
01502 //}
01503 //
01504 ///*----------------------------------------------------------------------*
01505 // * Read the unique ID.                                                  *
01506 // * For the MCP79411 (EUI-48), the first two uint8_ts will contain 0xFF.    *
01507 // * Caller must provide an 8-uint8_t array to contain the results.          *
01508 // *----------------------------------------------------------------------*/
01509 //void MCP79412RTC::idRead(uint8_t *uniqueID)
01510 //{
01511 //    i2cBeginTransmission(MCP79412_EEPROM_ADDR);
01512 //    i2cWrite(UNIQUE_ID_ADDR);
01513 //    i2cEndTransmission();
01514 //    i2cRequestFrom( MCP79412_EEPROM_ADDR, UNIQUE_ID_SIZE );
01515 //    for (uint8_t i=0; i<UNIQUE_ID_SIZE; i++) uniqueID[i] = i2cRead();
01516 //}
01517 //
01518 ///*----------------------------------------------------------------------*
01519 // * Returns an EUI-64 ID. For an MCP79411, the EUI-48 ID is converted to *
01520 // * EUI-64. For an MCP79412, calling this function is equivalent to      *
01521 // * calling idRead(). For an MCP79412, if the RTC type is known, calling *
01522 // * idRead() will be a bit more efficient.                               *
01523 // * Caller must provide an 8-uint8_t array to contain the results.          *
01524 // *----------------------------------------------------------------------*/
01525 //void MCP79412RTC::getEUI64(uint8_t *uniqueID)
01526 //{
01527 //    uint8_t rtcID[8];
01528 //
01529 //    idRead(rtcID);
01530 //    if (rtcID[0] == 0xFF && rtcID[1] == 0xFF) {
01531 //        rtcID[0] = rtcID[2];
01532 //        rtcID[1] = rtcID[3];
01533 //        rtcID[2] = rtcID[4];
01534 //        rtcID[3] = 0xFF;
01535 //        rtcID[4] = 0xFE;
01536 //    }
01537 //    for (uint8_t i=0; i<UNIQUE_ID_SIZE; i++) uniqueID[i] = rtcID[i];
01538 //}
01539 //
01540 ///*----------------------------------------------------------------------*
01541 // * Check to see if a power failure has occurred. If so, returns TRUE    *
01542 // * as the function value, and returns the power down and power up       *
01543 // * timestamps. After returning the time stamps, the RTC's timestamp     *
01544 // * registers are cleared and the VBAT bit which indicates a power       *
01545 // * failure is reset.                                                    *
01546 // *                                                                      *
01547 // * Note that the power down and power up timestamp registers do not     *
01548 // * contain values for seconds or for the year. The returned time stamps *
01549 // * will therefore contain the current year from the RTC. However, there *
01550 // * is a chance that a power outage spans from one year to the next.     *
01551 // * If we find the power down timestamp to be later (larger) than the    *
01552 // * power up timestamp, we will assume this has happened, and well       *
01553 // * subtract one year from the power down timestamp.                     *
01554 // *                                                                      *
01555 // * Still, there is an assumption that the timestamps are being read     *
01556 // * in the same year as that when the power up occurred.                 *
01557 // *                                                                      *
01558 // * Finally, note that once the RTC records a power outage, it must be   *
01559 // * cleared before another will be recorded.                             *
01560 // *----------------------------------------------------------------------*/
01561 //boolean MCP79412RTC::powerFail(time_t *powerDown, time_t *powerUp)
01562 //{
01563 //    uint8_t day, yr;                   //copies of the RTC Day and Year registers
01564 //    tmElements_t dn, up;            //power down and power up times
01565 //
01566 //    ramRead(DAY_REG, &day, 1);
01567 //    ramRead(YEAR_REG, &yr, 1);
01568 //    yr = y2kYearToTm(bcd2dec(yr));
01569 //    if ( day & _BV(VBAT) ) {
01570 //        i2cBeginTransmission(RTC_ADDR);
01571 //        i2cWrite(PWRDWN_TS_REG);
01572 //        i2cEndTransmission();
01573 //
01574 //        i2cRequestFrom(RTC_ADDR, TIMESTAMP_SIZE);     //read both timestamp registers, 8 uint8_ts total
01575 //        dn.Second = 0;
01576 //        dn.Minute = bcd2dec(i2cRead());
01577 //        dn.Hour = bcd2dec(i2cRead() & ~_BV(HR1224));    //assumes 24hr clock
01578 //        dn.Day = bcd2dec(i2cRead());
01579 //        dn.Month = bcd2dec(i2cRead() & 0x1F);           //mask off the day, we don't need it
01580 //        dn.Year = yr;                                   //assume current year
01581 //        up.Second = 0;
01582 //        up.Minute = bcd2dec(i2cRead());
01583 //        up.Hour = bcd2dec(i2cRead() & ~_BV(HR1224));    //assumes 24hr clock
01584 //        up.Day = bcd2dec(i2cRead());
01585 //        up.Month = bcd2dec(i2cRead() & 0x1F);           //mask off the day, we don't need it
01586 //        up.Year = yr;                                   //assume current year
01587 //
01588 //        *powerDown = makeTime(dn);
01589 //        *powerUp = makeTime(up);
01590 //
01591 //        //clear the VBAT bit, which causes the RTC hardware to clear the timestamps too.
01592 //        //I suppose there is a risk here that the day has changed since we read it,
01593 //        //but the Day of Week is actually redundant data and the makeTime() function
01594 //        //does not use it. This could be an issue if someone is reading the RTC
01595 //        //registers directly, but as this library is meant to be used with the Time library,
01596 //        //and also because we don't provide a method to read the RTC clock/calendar
01597 //        //registers directly, we won't lose any sleep about it at this point unless
01598 //        //some issue is actually brought to our attention ;-)
01599 //        day &= ~_BV(VBAT);
01600 //        ramWrite(DAY_REG, &day , 1);
01601 //
01602 //        //adjust the powerDown timestamp if needed (see notes above)
01603 //        if (*powerDown > *powerUp) {
01604 //            --dn.Year;
01605 //            *powerDown = makeTime(dn);
01606 //        }
01607 //        return true;
01608 //    }
01609 //    else
01610 //        return false;
01611 //}
01612 //
01613 ///*----------------------------------------------------------------------*
01614 // * Enable or disable the square wave output.                            *
01615 // *----------------------------------------------------------------------*/
01616 //void MCP79412RTC::squareWave(uint8_t freq)
01617 //{
01618 //    uint8_t ctrlReg;
01619 //
01620 //    ramRead(CTRL_REG, &ctrlReg, 1);
01621 //    if (freq > 3) {
01622 //        ctrlReg &= ~_BV(SQWE);
01623 //    }
01624 //    else {
01625 //        ctrlReg = (ctrlReg & 0xF8) | _BV(SQWE) | freq;
01626 //    }
01627 //    ramWrite(CTRL_REG, &ctrlReg, 1);
01628 //}
01629 //
01630 ///*----------------------------------------------------------------------*
01631 // * Set an alarm time. Sets the alarm registers only, does not enable    *
01632 // * the alarm. See enableAlarm().                                        *
01633 // *----------------------------------------------------------------------*/
01634 //void MCP79412RTC::setAlarm(uint8_t alarmNumber, time_t alarmTime)
01635 //{
01636 //    tmElements_t tm;
01637 //    uint8_t day;        //need to preserve bits in the day (of week) register
01638 //
01639 //    alarmNumber &= 0x01;        //ensure a valid alarm number
01640 //    ramRead( ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG) , &day, 1);
01641 //    breakTime(alarmTime, tm);
01642 //    i2cBeginTransmission(RTC_ADDR);
01643 //    i2cWrite( ALM0_REG + alarmNumber * (ALM1_REG - ALM0_REG) );
01644 //    i2cWrite(dec2bcd(tm.Second));
01645 //    i2cWrite(dec2bcd(tm.Minute));
01646 //    i2cWrite(dec2bcd(tm.Hour));                  //sets 24 hour format (Bit 6 == 0)
01647 //    i2cWrite( (day & 0xF8) + tm.Wday );
01648 //    i2cWrite(dec2bcd(tm.Day));
01649 //    i2cWrite(dec2bcd(tm.Month));
01650 //    i2cEndTransmission();
01651 //}
01652 //
01653 ///*----------------------------------------------------------------------*
01654 // * Enable or disable an alarm, and set the trigger criteria,            *
01655 // * e.g. match only seconds, only minutes, entire time and date, etc.    *
01656 // *----------------------------------------------------------------------*/
01657 //void MCP79412RTC::enableAlarm(uint8_t alarmNumber, uint8_t alarmType)
01658 //{
01659 //    uint8_t day;                //alarm day register has config & flag bits
01660 //    uint8_t ctrl;               //control register has alarm enable bits
01661 //
01662 //    alarmNumber &= 0x01;        //ensure a valid alarm number
01663 //    ramRead(CTRL_REG, &ctrl, 1);
01664 //    if (alarmType < ALM_DISABLE) {
01665 //        ramRead(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
01666 //        day = ( day & 0x87 ) | alarmType << 4;  //reset interrupt flag, OR in the config bits
01667 //        ramWrite(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
01668 //        ctrl |= _BV(ALM0 + alarmNumber);        //enable the alarm
01669 //    }
01670 //    else {
01671 //        ctrl &= ~(_BV(ALM0 + alarmNumber));     //disable the alarm
01672 //    }
01673 //    ramWrite(CTRL_REG, &ctrl, 1);
01674 //}
01675 //
01676 ///*----------------------------------------------------------------------*
01677 // * Returns true or false depending on whether the given alarm has been  *
01678 // * triggered, and resets the alarm "interrupt" flag. This is not a real *
01679 // * interrupt, just a bit that's set when an alarm is triggered.         *
01680 // *----------------------------------------------------------------------*/
01681 //boolean MCP79412RTC::alarm(uint8_t alarmNumber)
01682 //{
01683 //    uint8_t day;                //alarm day register has config & flag bits
01684 //
01685 //    alarmNumber &= 0x01;        //ensure a valid alarm number
01686 //    ramRead( ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
01687 //    if (day & _BV(ALMIF)) {
01688 //        day &= ~_BV(ALMIF);     //turn off the alarm "interrupt" flag
01689 //        ramWrite( ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
01690 //        return true;
01691 //    }
01692 //    else
01693 //        return false;
01694 //}
01695 //
01696 ///*----------------------------------------------------------------------*
01697 // * Sets the logic level on the MFP when it's not being used as a        *
01698 // * square wave or alarm output. The default is HIGH.                    *
01699 // *----------------------------------------------------------------------*/
01700 //void MCP79412RTC::out(boolean level)
01701 //{
01702 //    uint8_t ctrlReg;
01703 //
01704 //    ramRead(CTRL_REG, &ctrlReg, 1);
01705 //    if (level)
01706 //        ctrlReg |= _BV(OUT);
01707 //    else
01708 //        ctrlReg &= ~_BV(OUT);
01709 //    ramWrite(CTRL_REG, &ctrlReg, 1);
01710 //}
01711 //
01712 ///*----------------------------------------------------------------------*
01713 // * Specifies the logic level on the Multi-Function Pin (MFP) when an    *
01714 // * alarm is triggered. The default is LOW. When both alarms are         *
01715 // * active, the two are ORed together to determine the level of the MFP. *
01716 // * With alarm polarity set to LOW (the default), this causes the MFP    *
01717 // * to go low only when BOTH alarms are triggered. With alarm polarity   *
01718 // * set to HIGH, the MFP will go high when EITHER alarm is triggered.    *
01719 // *                                                                      *
01720 // * Note that the state of the MFP is independent of the alarm           *
01721 // * "interrupt" flags, and the alarm() function will indicate when an    *
01722 // * alarm is triggered regardless of the polarity.                       *
01723 // *----------------------------------------------------------------------*/
01724 //void MCP79412RTC::alarmPolarity(boolean polarity)
01725 //{
01726 //    uint8_t alm0Day;
01727 //
01728 //    ramRead(ALM0_DAY, &alm0Day, 1);
01729 //    if (polarity)
01730 //        alm0Day |= _BV(OUT);
01731 //    else
01732 //        alm0Day &= ~_BV(OUT);
01733 //    ramWrite(ALM0_DAY, &alm0Day, 1);
01734 //}
01735 //
01736 ///*----------------------------------------------------------------------*
01737 // * Check to see if the RTC's oscillator is started (ST bit in seconds   *
01738 // * register). Returns true if started.                                  *
01739 // *----------------------------------------------------------------------*/
01740 //boolean MCP79412RTC::isRunning(void)
01741 //{
01742 //    i2cBeginTransmission(RTC_ADDR);
01743 //    i2cWrite((uint8_t)TIME_REG);
01744 //    i2cEndTransmission();
01745 //
01746 //    //request just the seconds register
01747 //    i2cRequestFrom(RTC_ADDR, 1);
01748 //    return i2cRead() & _BV(ST);
01749 //}
01750 //
01751 ///*----------------------------------------------------------------------*
01752 // * Set or clear the VBATEN bit. Setting the bit powers the clock and    *
01753 // * SRAM from the backup battery when Vcc falls. Note that setting the   *
01754 // * time via set() or write() sets the VBATEN bit.                       *
01755 // *----------------------------------------------------------------------*/
01756 //void MCP79412RTC::vbaten(boolean enable)
01757 //{
01758 //    uint8_t day;
01759 //
01760 //    ramRead(DAY_REG, &day, 1);
01761 //    if (enable)
01762 //        day |= _BV(VBATEN);
01763 //    else
01764 //        day &= ~_BV(VBATEN);
01765 //
01766 //    ramWrite(DAY_REG, &day, 1);
01767 //    return;
01768 //}
01769 
01770 ///*----------------------------------------------------------------------*
01771 // * Decimal-to-BCD conversion                                            *
01772 // *----------------------------------------------------------------------*/
01773 //uint8_t MCP79412RTC::dec2bcd(uint8_t n)
01774 //{
01775 //    return n + 6 * (n / 10);
01776 //}
01777 //
01778 ///*----------------------------------------------------------------------*
01779 // * BCD-to-Decimal conversion                                            *
01780 // *----------------------------------------------------------------------*/
01781 //uint8_t __attribute__ ((noinline)) MCP79412RTC::bcd2dec(uint8_t n)
01782 //{
01783 //    return n - 6 * (n >> 4);
01784 //}
01785 
01786 // BCD to decimal conversion
01787 int MCP79412::bcd2dec(int bcd)
01788 {
01789     return(((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F));
01790 }
01791 
01792 // decimal to BCD conversion
01793 int MCP79412::dec2bcd(int dec)
01794 {
01795     return((dec / 10) * 16 + (dec % 10));
01796 }
01797 
01798 // Convert normal decimal numbers to binary coded decimal:
01799 int MCP79412::decToBcd(int val)
01800 {
01801   return ( (val/10*16) + (val%10) );
01802 }
01803 
01804 // Convert binary coded decimal to normal decimal numbers:
01805 int MCP79412::bcdToDec(int val)
01806 {
01807   return ( (val/16*10) + (val%16) );
01808 }