x
Embed:
(wiki syntax)
Show/hide line numbers
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, ®, 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 }
Generated on Sun Jul 17 2022 08:32:31 by 1.7.2