x

Dependents:   20180621_FT813

Committer:
JackB
Date:
Mon Jul 23 12:24:33 2018 +0000
Revision:
0:04311b121ac4
MCP79412

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JackB 0:04311b121ac4 1 #include "MCP79412.h"
JackB 0:04311b121ac4 2
JackB 0:04311b121ac4 3 MCP79412::MCP79412(PinName sda, PinName scl) : _i2c(sda, scl)
JackB 0:04311b121ac4 4 {
JackB 0:04311b121ac4 5 _address_RTC = MCP79412_RTC_ADDR << 1;
JackB 0:04311b121ac4 6 squareWave(SQWAVE_1_HZ);
JackB 0:04311b121ac4 7 // setTimeZone(1);
JackB 0:04311b121ac4 8 // dayLightSaving = true;
JackB 0:04311b121ac4 9 setI2Cfrequency(400000);
JackB 0:04311b121ac4 10 }
JackB 0:04311b121ac4 11
JackB 0:04311b121ac4 12 void MCP79412::setI2Cfrequency(int freq)
JackB 0:04311b121ac4 13 {
JackB 0:04311b121ac4 14 _i2c.frequency(freq);
JackB 0:04311b121ac4 15 }
JackB 0:04311b121ac4 16
JackB 0:04311b121ac4 17 // get a uint8_t containing just the requested bits
JackB 0:04311b121ac4 18 // pass the register address to read, a mask to apply to the register and
JackB 0:04311b121ac4 19 // an uint* for the output
JackB 0:04311b121ac4 20 // you can test this value directly as true/false for specific bit mask
JackB 0:04311b121ac4 21 // of use a mask of 0xff to just return the whole register uint8_t
JackB 0:04311b121ac4 22 // returns true to indicate success
JackB 0:04311b121ac4 23 /** Get flag
JackB 0:04311b121ac4 24 * @param reg : register address
JackB 0:04311b121ac4 25 * @param mask : flag mask
JackB 0:04311b121ac4 26 * @return The register content
JackB 0:04311b121ac4 27 */
JackB 0:04311b121ac4 28 bool MCP79412::getFlag(char reg, char mask, char *flag)
JackB 0:04311b121ac4 29 {
JackB 0:04311b121ac4 30 char buf[1];
JackB 0:04311b121ac4 31 buf[0] = reg;
JackB 0:04311b121ac4 32 int w = _i2c.write(_address_RTC, buf, 1);
JackB 0:04311b121ac4 33 int r = _i2c.read(_address_RTC, buf, 1);
JackB 0:04311b121ac4 34 _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 35 // return only requested flag
JackB 0:04311b121ac4 36 *flag = (buf[0] & mask);
JackB 0:04311b121ac4 37 return flag == 0 ? false : true;
JackB 0:04311b121ac4 38 }
JackB 0:04311b121ac4 39
JackB 0:04311b121ac4 40 // set/clear bits in a uint8_t register, or replace the uint8_t altogether
JackB 0:04311b121ac4 41 // pass the register address to modify, a uint8_t to replace the existing
JackB 0:04311b121ac4 42 // value with or containing the bits to set/clear and one of
JackB 0:04311b121ac4 43 // MCP79412_SET/MCP79412_CLEAR/MCP79412_REPLACE
JackB 0:04311b121ac4 44 // returns true to indicate success
JackB 0:04311b121ac4 45 /** Set flag
JackB 0:04311b121ac4 46 * @param reg : register address
JackB 0:04311b121ac4 47 * @param bits : bits to set or reset
JackB 0:04311b121ac4 48 * @param mode : MCP79412_REPLACE, MCP79412_SET, MCP79412_CLEAR
JackB 0:04311b121ac4 49 * @return none
JackB 0:04311b121ac4 50 */
JackB 0:04311b121ac4 51 void MCP79412::setFlag(char reg, char bits, char mode)
JackB 0:04311b121ac4 52 {
JackB 0:04311b121ac4 53 char buf[2];
JackB 0:04311b121ac4 54 buf[0] = reg;
JackB 0:04311b121ac4 55 // get status register
JackB 0:04311b121ac4 56 int w = _i2c.write(_address_RTC, buf, 1);
JackB 0:04311b121ac4 57 int r = _i2c.read(_address_RTC, buf+1, 1);
JackB 0:04311b121ac4 58 // clear the flag
JackB 0:04311b121ac4 59 if (mode == MCP79412_REPLACE)
JackB 0:04311b121ac4 60 buf[1] = bits;
JackB 0:04311b121ac4 61 else if (mode == MCP79412_SET)
JackB 0:04311b121ac4 62 buf[1] |= bits;
JackB 0:04311b121ac4 63 else
JackB 0:04311b121ac4 64 buf[1] &= ~bits;
JackB 0:04311b121ac4 65 int w2 = _i2c.write(_address_RTC, buf, 2);
JackB 0:04311b121ac4 66 _error = ((w != 0) || (r != 0) || (w2 != 0));
JackB 0:04311b121ac4 67 }
JackB 0:04311b121ac4 68
JackB 0:04311b121ac4 69 // read a register
JackB 0:04311b121ac4 70 int MCP79412::readRegister(char reg)
JackB 0:04311b121ac4 71 {
JackB 0:04311b121ac4 72 // int w = _i2c.write(_address_RTC, &reg, 1);
JackB 0:04311b121ac4 73 // char rtn;
JackB 0:04311b121ac4 74 // int r = _i2c.read(_address_RTC, &rtn, 1);
JackB 0:04311b121ac4 75 // _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 76 // return rtn;
JackB 0:04311b121ac4 77
JackB 0:04311b121ac4 78 char buf[1];
JackB 0:04311b121ac4 79 buf[0] = reg;
JackB 0:04311b121ac4 80 int w = _i2c.write(_address_RTC, buf, 1);
JackB 0:04311b121ac4 81 int r = _i2c.read(_address_RTC, buf, 1);
JackB 0:04311b121ac4 82 _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 83 return(buf[0]);
JackB 0:04311b121ac4 84 }
JackB 0:04311b121ac4 85
JackB 0:04311b121ac4 86 // read registers
JackB 0:04311b121ac4 87 void MCP79412::readRegisters(char reg, char *outbuf, char length)
JackB 0:04311b121ac4 88 {
JackB 0:04311b121ac4 89 char buf[1];
JackB 0:04311b121ac4 90 buf[0] = reg;
JackB 0:04311b121ac4 91 int w = _i2c.write(_address_RTC, buf, 1);
JackB 0:04311b121ac4 92 int r = _i2c.read(_address_RTC, outbuf, length);
JackB 0:04311b121ac4 93 _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 94 }
JackB 0:04311b121ac4 95
JackB 0:04311b121ac4 96 // write a register
JackB 0:04311b121ac4 97 void MCP79412::writeRegister(int reg, char uint8_t)
JackB 0:04311b121ac4 98 {
JackB 0:04311b121ac4 99 char buf[2];
JackB 0:04311b121ac4 100 buf[0] = reg;
JackB 0:04311b121ac4 101 buf[1] = uint8_t;
JackB 0:04311b121ac4 102 int w = _i2c.write(_address_RTC, buf, 2);
JackB 0:04311b121ac4 103 _error = (w != 0);
JackB 0:04311b121ac4 104 }
JackB 0:04311b121ac4 105
JackB 0:04311b121ac4 106 // write registers
JackB 0:04311b121ac4 107 void MCP79412::writeRegisters(int reg, char *inbuf, char length)
JackB 0:04311b121ac4 108 {
JackB 0:04311b121ac4 109 char buf[32];
JackB 0:04311b121ac4 110 buf[0] = reg;
JackB 0:04311b121ac4 111 for (int i = 1; i <= length; i++) {
JackB 0:04311b121ac4 112 buf[i] = inbuf[i-1];
JackB 0:04311b121ac4 113 }
JackB 0:04311b121ac4 114 int w = _i2c.write(_address_RTC, buf, length+1);
JackB 0:04311b121ac4 115 _error = (w != 0);
JackB 0:04311b121ac4 116 }
JackB 0:04311b121ac4 117
JackB 0:04311b121ac4 118
JackB 0:04311b121ac4 119 // Function to read the mac address from the eeprom
JackB 0:04311b121ac4 120 void MCP79412::getMacAddress(char *mac_address)
JackB 0:04311b121ac4 121 {
JackB 0:04311b121ac4 122 char buf[1];
JackB 0:04311b121ac4 123 buf[0] = MAC_LOCATION;
JackB 0:04311b121ac4 124 int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 1);
JackB 0:04311b121ac4 125 int r = _i2c.read(MCP79412_EEPROM_ADDR, mac_address, 6);
JackB 0:04311b121ac4 126 _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 127 }
JackB 0:04311b121ac4 128
JackB 0:04311b121ac4 129 // Unlock the unique id area and write in the mac address
JackB 0:04311b121ac4 130 void MCP79412::writeMacAddress(char *mac_address)
JackB 0:04311b121ac4 131 {
JackB 0:04311b121ac4 132 char buf[7];
JackB 0:04311b121ac4 133 unlockUniqueID();
JackB 0:04311b121ac4 134 buf[0] = MAC_LOCATION;
JackB 0:04311b121ac4 135 for (int i = 1; i <= 6; i++) {
JackB 0:04311b121ac4 136 buf[i] = mac_address[i-1];
JackB 0:04311b121ac4 137 }
JackB 0:04311b121ac4 138 int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 7);
JackB 0:04311b121ac4 139
JackB 0:04311b121ac4 140 _error = (w != 0);
JackB 0:04311b121ac4 141 }
JackB 0:04311b121ac4 142
JackB 0:04311b121ac4 143 // Unlock the unique id area ready for writing
JackB 0:04311b121ac4 144 void MCP79412::unlockUniqueID()
JackB 0:04311b121ac4 145 {
JackB 0:04311b121ac4 146 // Write 0x55 to the memory location 0x09
JackB 0:04311b121ac4 147 char buf[2];
JackB 0:04311b121ac4 148 buf[0] = UNLOCK_ID_REG;
JackB 0:04311b121ac4 149 buf[1] = UNLOCK_ID_CODE1;
JackB 0:04311b121ac4 150 int w1 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
JackB 0:04311b121ac4 151
JackB 0:04311b121ac4 152 // Write 0xAA to the memory location 0x09
JackB 0:04311b121ac4 153 buf[0] = UNLOCK_ID_REG;
JackB 0:04311b121ac4 154 buf[1] = UNLOCK_ID_CODE2;
JackB 0:04311b121ac4 155 int w2 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
JackB 0:04311b121ac4 156
JackB 0:04311b121ac4 157 _error = ((w1 != 0) || (w2 != 0));
JackB 0:04311b121ac4 158 }
JackB 0:04311b121ac4 159
JackB 0:04311b121ac4 160 // Set the date/time, set to 24hr and enable the clock
JackB 0:04311b121ac4 161 // (assumes you're passing in valid numbers)
JackB 0:04311b121ac4 162 void MCP79412::setRtcDateTime(
JackB 0:04311b121ac4 163 uint8_t second, // 0-59
JackB 0:04311b121ac4 164 uint8_t minute, // 0-59
JackB 0:04311b121ac4 165 uint8_t hour, // 1-23
JackB 0:04311b121ac4 166 uint8_t dayOfWeek, // 1-7
JackB 0:04311b121ac4 167 uint8_t dayOfMonth, // 1-31
JackB 0:04311b121ac4 168 uint8_t month, // 1-12
JackB 0:04311b121ac4 169 uint8_t year) // 0-99
JackB 0:04311b121ac4 170 {
JackB 0:04311b121ac4 171 char buf[8];
JackB 0:04311b121ac4 172 buf[0] = RTC_LOCATION;
JackB 0:04311b121ac4 173 buf[1] = decToBcd(second) & 0x7f; // set seconds and disable clock (01111111, Bit 7, ST = 0)
JackB 0:04311b121ac4 174 buf[2] = decToBcd(minute) & 0x7f; // set minutes (01111111)
JackB 0:04311b121ac4 175 buf[3] = decToBcd(hour) & 0x3f; // set hours and to 24hr format (00111111, Bit 6 = 0)
JackB 0:04311b121ac4 176 buf[4] = _BV(VBATEN) | (decToBcd(dayOfWeek) & 0x07); // set the day and enable battery backup (00000111)|(00001000, Bit 3 = 1)
JackB 0:04311b121ac4 177 buf[5] = decToBcd(dayOfMonth) & 0x3f; // set the date in month (00111111)
JackB 0:04311b121ac4 178 buf[6] = decToBcd(month) & 0x1f; // set the month (00011111)
JackB 0:04311b121ac4 179 buf[7] = decToBcd(year); // set the year (11111111)
JackB 0:04311b121ac4 180 int w1 = _i2c.write(MCP79412_RTC_ADDR, buf, 8);
JackB 0:04311b121ac4 181
JackB 0:04311b121ac4 182 // Start Clock:
JackB 0:04311b121ac4 183 buf[0] = RTC_LOCATION;
JackB 0:04311b121ac4 184 buf[1] = _BV(ST) | decToBcd(second); // set seconds and enable clock (10000000)
JackB 0:04311b121ac4 185 int w2 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
JackB 0:04311b121ac4 186
JackB 0:04311b121ac4 187 _error = ((w1 != 0) || (w2 != 0));
JackB 0:04311b121ac4 188 }
JackB 0:04311b121ac4 189
JackB 0:04311b121ac4 190 // Get the date/time
JackB 0:04311b121ac4 191 void MCP79412::getRtcDateTime(
JackB 0:04311b121ac4 192 uint8_t *second,
JackB 0:04311b121ac4 193 uint8_t *minute,
JackB 0:04311b121ac4 194 uint8_t *hour,
JackB 0:04311b121ac4 195 uint8_t *dayOfWeek,
JackB 0:04311b121ac4 196 uint8_t *dayOfMonth,
JackB 0:04311b121ac4 197 uint8_t *month,
JackB 0:04311b121ac4 198 uint8_t *year)
JackB 0:04311b121ac4 199 {
JackB 0:04311b121ac4 200 char buf[8];
JackB 0:04311b121ac4 201
JackB 0:04311b121ac4 202 buf[0] = RTC_LOCATION;
JackB 0:04311b121ac4 203 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 204 int r = _i2c.read(MCP79412_RTC_ADDR, buf, 7);
JackB 0:04311b121ac4 205
JackB 0:04311b121ac4 206 _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 207
JackB 0:04311b121ac4 208 // A few of these need masks because certain bits are control bits
JackB 0:04311b121ac4 209 *second = bcdToDec(buf[0] & 0x7f); // 01111111 0-59
JackB 0:04311b121ac4 210 *minute = bcdToDec(buf[1] & 0x7f); // 01111111 0-59
JackB 0:04311b121ac4 211 *hour = bcdToDec(buf[2] & 0x3f); // 00111111 1-23
JackB 0:04311b121ac4 212 *dayOfWeek = bcdToDec(buf[3] & 0x07); // 00000111 1-7
JackB 0:04311b121ac4 213 *dayOfMonth = bcdToDec(buf[4] & 0x3f); // 00111111 1-31
JackB 0:04311b121ac4 214 *month = bcdToDec(buf[5] & 0x1f); // 00011111 1-12
JackB 0:04311b121ac4 215 *year = bcdToDec(buf[6]); // 11111111 0-99
JackB 0:04311b121ac4 216 }
JackB 0:04311b121ac4 217
JackB 0:04311b121ac4 218 bool MCP79412::checkTimeLost(void)
JackB 0:04311b121ac4 219 {
JackB 0:04311b121ac4 220 char buf[8];
JackB 0:04311b121ac4 221 uint8_t second, minute, hour, dayOfWeek, dayOfMonth, month, year;
JackB 0:04311b121ac4 222 buf[0] = RTC_LOCATION;
JackB 0:04311b121ac4 223 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 224 int r = _i2c.read(MCP79412_RTC_ADDR, buf, 7);
JackB 0:04311b121ac4 225
JackB 0:04311b121ac4 226 _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 227
JackB 0:04311b121ac4 228 // A few of these need masks because certain bits are control bits
JackB 0:04311b121ac4 229 second = bcdToDec(buf[0] & 0x7f); // 01111111 0-59
JackB 0:04311b121ac4 230 minute = bcdToDec(buf[1] & 0x7f); // 01111111 0-59
JackB 0:04311b121ac4 231 hour = bcdToDec(buf[2] & 0x3f); // 00111111 1-23
JackB 0:04311b121ac4 232 dayOfWeek = bcdToDec(buf[3] & 0x07); // 00000111 1-7
JackB 0:04311b121ac4 233 dayOfMonth = bcdToDec(buf[4] & 0x3f); // 00111111 1-31
JackB 0:04311b121ac4 234 month = bcdToDec(buf[5] & 0x1f); // 00011111 1-12
JackB 0:04311b121ac4 235 year = bcdToDec(buf[6]); // 11111111 0-99
JackB 0:04311b121ac4 236 return (year <= 15) ? true : false;
JackB 0:04311b121ac4 237 }
JackB 0:04311b121ac4 238
JackB 0:04311b121ac4 239 // Enable the clock without changing the date/time
JackB 0:04311b121ac4 240 void MCP79412::enableClock()
JackB 0:04311b121ac4 241 {
JackB 0:04311b121ac4 242 // Get the current seconds value as the enable/disable bit is in the same
JackB 0:04311b121ac4 243 // byte of memory as the seconds value:
JackB 0:04311b121ac4 244 char buf[2];
JackB 0:04311b121ac4 245 buf[0] = RTC_LOCATION;
JackB 0:04311b121ac4 246 int w1 = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 247 int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 248
JackB 0:04311b121ac4 249 int second = bcdToDec(buf[0] & 0x7f); // 01111111
JackB 0:04311b121ac4 250
JackB 0:04311b121ac4 251 // Start Clock:
JackB 0:04311b121ac4 252 buf[0] = RTC_LOCATION;
JackB 0:04311b121ac4 253 buf[1] = _BV(ST) | decToBcd(second); // set seconds and enable clock (10000000, Bit 7, ST = 1)
JackB 0:04311b121ac4 254 int w2 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
JackB 0:04311b121ac4 255
JackB 0:04311b121ac4 256 _error = ((w1 != 0) || (r != 0) || (w2 != 0));
JackB 0:04311b121ac4 257 }
JackB 0:04311b121ac4 258
JackB 0:04311b121ac4 259 // Disable the clock without changing the date/time
JackB 0:04311b121ac4 260 void MCP79412::disableClock()
JackB 0:04311b121ac4 261 {
JackB 0:04311b121ac4 262 // Get the current seconds value as the enable/disable bit is in the same
JackB 0:04311b121ac4 263 // uint8_t of memory as the seconds value:
JackB 0:04311b121ac4 264 char buf[2];
JackB 0:04311b121ac4 265 buf[0] = RTC_LOCATION;
JackB 0:04311b121ac4 266 int w1 = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 267 int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 268
JackB 0:04311b121ac4 269 int second = bcdToDec(buf[0] & 0x7f); // 01111111
JackB 0:04311b121ac4 270
JackB 0:04311b121ac4 271 // Stop Clock:
JackB 0:04311b121ac4 272 buf[0] = RTC_LOCATION;
JackB 0:04311b121ac4 273 buf[1] = decToBcd(second); // set seconds and disable clock (01111111, Bit 7, ST = 0)
JackB 0:04311b121ac4 274 int w2 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
JackB 0:04311b121ac4 275
JackB 0:04311b121ac4 276 _error = ((w1 != 0) || (r != 0) || (w2 != 0));
JackB 0:04311b121ac4 277 }
JackB 0:04311b121ac4 278
JackB 0:04311b121ac4 279 // Enable the battery
JackB 0:04311b121ac4 280 void MCP79412::enableBattery()
JackB 0:04311b121ac4 281 {
JackB 0:04311b121ac4 282 // Get the current day value as the enable/disable bit is in the same
JackB 0:04311b121ac4 283 // uint8_t of memory as the seconds value:
JackB 0:04311b121ac4 284 char buf[2];
JackB 0:04311b121ac4 285 buf[0] = DAY_REG;
JackB 0:04311b121ac4 286 int w1 = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 287 int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 288
JackB 0:04311b121ac4 289 int day = bcdToDec(buf[0] & 0x07); // 00000111
JackB 0:04311b121ac4 290
JackB 0:04311b121ac4 291 // Start Clock:
JackB 0:04311b121ac4 292 buf[0] = DAY_REG;
JackB 0:04311b121ac4 293 buf[1] = _BV(VBATEN) | decToBcd(day); // set day and enable battery (00001000)
JackB 0:04311b121ac4 294 int w2 = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
JackB 0:04311b121ac4 295
JackB 0:04311b121ac4 296 _error = ((w1 != 0) || (r != 0) || (w2 != 0));
JackB 0:04311b121ac4 297 }
JackB 0:04311b121ac4 298
JackB 0:04311b121ac4 299
JackB 0:04311b121ac4 300 // Write a single byte of data to RAM
JackB 0:04311b121ac4 301 void MCP79412::writeRamByte(uint8_t location, uint8_t data)
JackB 0:04311b121ac4 302 {
JackB 0:04311b121ac4 303 writeRamBytes(location, &data, 1);
JackB 0:04311b121ac4 304 // char buf[2];
JackB 0:04311b121ac4 305 // if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
JackB 0:04311b121ac4 306 // {
JackB 0:04311b121ac4 307 // buf[0] = location;
JackB 0:04311b121ac4 308 // buf[1] = data;
JackB 0:04311b121ac4 309 // int w = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
JackB 0:04311b121ac4 310 // _error = (w != 0);
JackB 0:04311b121ac4 311 // }
JackB 0:04311b121ac4 312 }
JackB 0:04311b121ac4 313
JackB 0:04311b121ac4 314 // Write multiple bytes of data to RAM
JackB 0:04311b121ac4 315 uint8_t MCP79412::writeRamBytes(uint8_t location, uint8_t *data, uint8_t length)
JackB 0:04311b121ac4 316 {
JackB 0:04311b121ac4 317 uint8_t bytesWritten = 0;
JackB 0:04311b121ac4 318 char buf[1];
JackB 0:04311b121ac4 319 buf[0] = location;
JackB 0:04311b121ac4 320 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 321 _error = (w != 0);
JackB 0:04311b121ac4 322 for (uint8_t i = 0; i < length; i++) {
JackB 0:04311b121ac4 323 buf[0] = data[i];
JackB 0:04311b121ac4 324 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1); // Returns 0 on success (ack), non-0 on failure (nack)
JackB 0:04311b121ac4 325 bytesWritten++;
JackB 0:04311b121ac4 326 if (_error == false) {
JackB 0:04311b121ac4 327 _error = (w != 0);
JackB 0:04311b121ac4 328 }
JackB 0:04311b121ac4 329 }
JackB 0:04311b121ac4 330 return bytesWritten;
JackB 0:04311b121ac4 331 }
JackB 0:04311b121ac4 332
JackB 0:04311b121ac4 333 // Read a single byte of data from RAM
JackB 0:04311b121ac4 334 uint8_t MCP79412::readRamByte(uint8_t location)
JackB 0:04311b121ac4 335 {
JackB 0:04311b121ac4 336 uint8_t data;
JackB 0:04311b121ac4 337 readRamBytes(location, &data, 1);
JackB 0:04311b121ac4 338 return data;
JackB 0:04311b121ac4 339 // char buf[2];
JackB 0:04311b121ac4 340 // if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
JackB 0:04311b121ac4 341 // {
JackB 0:04311b121ac4 342 // buf[0] = location;
JackB 0:04311b121ac4 343 // int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 344 // int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 345 //
JackB 0:04311b121ac4 346 // _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 347 //
JackB 0:04311b121ac4 348 // return buf[0];
JackB 0:04311b121ac4 349 // }
JackB 0:04311b121ac4 350 // return 0;
JackB 0:04311b121ac4 351 }
JackB 0:04311b121ac4 352
JackB 0:04311b121ac4 353 // Read multiple bytes of data from RAM
JackB 0:04311b121ac4 354 uint8_t MCP79412::readRamBytes(uint8_t location, uint8_t *data, uint8_t length)
JackB 0:04311b121ac4 355 {
JackB 0:04311b121ac4 356 uint8_t bytesRead = 0;
JackB 0:04311b121ac4 357 char buf[1];
JackB 0:04311b121ac4 358 buf[0] = location;
JackB 0:04311b121ac4 359 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 360 _error = (w != 0);
JackB 0:04311b121ac4 361 for (uint8_t i = 0; i < length; i++) {
JackB 0:04311b121ac4 362 int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 363 bytesRead++;
JackB 0:04311b121ac4 364 data[i] = buf[0];
JackB 0:04311b121ac4 365 if (_error == false) {
JackB 0:04311b121ac4 366 _error = (r != 0);
JackB 0:04311b121ac4 367 }
JackB 0:04311b121ac4 368 }
JackB 0:04311b121ac4 369 return bytesRead;
JackB 0:04311b121ac4 370 }
JackB 0:04311b121ac4 371
JackB 0:04311b121ac4 372 // 64 Bytes SRAM, Battery Backed
JackB 0:04311b121ac4 373 // Write a single byte of data to SRAM
JackB 0:04311b121ac4 374 void MCP79412::writeSramByte(uint8_t location, uint8_t data)
JackB 0:04311b121ac4 375 {
JackB 0:04311b121ac4 376 writeSramBytes(location, &data, 1);
JackB 0:04311b121ac4 377 // char buf[2];
JackB 0:04311b121ac4 378 // if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
JackB 0:04311b121ac4 379 // {
JackB 0:04311b121ac4 380 // buf[0] = location;
JackB 0:04311b121ac4 381 // buf[1] = data;
JackB 0:04311b121ac4 382 // int w = _i2c.write(MCP79412_RTC_ADDR, buf, 2);
JackB 0:04311b121ac4 383 // _error = (w != 0);
JackB 0:04311b121ac4 384 // }
JackB 0:04311b121ac4 385 }
JackB 0:04311b121ac4 386
JackB 0:04311b121ac4 387 // 64 Bytes SRAM, Battery Backed
JackB 0:04311b121ac4 388 // Write multiple bytes of data to SRAM
JackB 0:04311b121ac4 389 uint8_t MCP79412::writeSramBytes(uint8_t location, uint8_t *data, uint8_t length)
JackB 0:04311b121ac4 390 {
JackB 0:04311b121ac4 391 uint8_t bytesWritten = 0;
JackB 0:04311b121ac4 392 char buf[1];
JackB 0:04311b121ac4 393 buf[0] = location;
JackB 0:04311b121ac4 394 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 395 _error = (w != 0);
JackB 0:04311b121ac4 396 for (uint8_t i = 0; i < length; i++) {
JackB 0:04311b121ac4 397 if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
JackB 0:04311b121ac4 398 {
JackB 0:04311b121ac4 399 buf[0] = data[i];
JackB 0:04311b121ac4 400 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1); // Returns 0 on success (ack), non-0 on failure (nack)
JackB 0:04311b121ac4 401 bytesWritten++;
JackB 0:04311b121ac4 402 if (_error == false) {
JackB 0:04311b121ac4 403 _error = (w != 0);
JackB 0:04311b121ac4 404 }
JackB 0:04311b121ac4 405 }
JackB 0:04311b121ac4 406 location++;
JackB 0:04311b121ac4 407 }
JackB 0:04311b121ac4 408 return bytesWritten;
JackB 0:04311b121ac4 409 }
JackB 0:04311b121ac4 410
JackB 0:04311b121ac4 411 // 64 Bytes SRAM, Battery Backed
JackB 0:04311b121ac4 412 // Read a single byte of data from SRAM
JackB 0:04311b121ac4 413 uint8_t MCP79412::readSramByte(uint8_t location)
JackB 0:04311b121ac4 414 {
JackB 0:04311b121ac4 415 uint8_t data;
JackB 0:04311b121ac4 416 readSramBytes(location, &data, 1);
JackB 0:04311b121ac4 417 return data;
JackB 0:04311b121ac4 418 // char buf[2];
JackB 0:04311b121ac4 419 // if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
JackB 0:04311b121ac4 420 // {
JackB 0:04311b121ac4 421 // buf[0] = location;
JackB 0:04311b121ac4 422 // int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 423 // int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 424 //
JackB 0:04311b121ac4 425 // _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 426 //
JackB 0:04311b121ac4 427 // return buf[0];
JackB 0:04311b121ac4 428 // }
JackB 0:04311b121ac4 429 // return 0;
JackB 0:04311b121ac4 430 }
JackB 0:04311b121ac4 431
JackB 0:04311b121ac4 432 // 64 Bytes SRAM, Battery Backed
JackB 0:04311b121ac4 433 // Read multiple bytes of data from SRAM
JackB 0:04311b121ac4 434 uint8_t MCP79412::readSramBytes(uint8_t location, uint8_t *data, uint8_t length)
JackB 0:04311b121ac4 435 {
JackB 0:04311b121ac4 436 uint8_t bytesRead = 0;
JackB 0:04311b121ac4 437 char buf[1];
JackB 0:04311b121ac4 438 buf[0] = location;
JackB 0:04311b121ac4 439 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 440 _error = (w != 0);
JackB 0:04311b121ac4 441 for (uint8_t i = 0; i < length; i++) {
JackB 0:04311b121ac4 442 if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
JackB 0:04311b121ac4 443 {
JackB 0:04311b121ac4 444 int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 445 bytesRead++;
JackB 0:04311b121ac4 446 data[i] = buf[0];
JackB 0:04311b121ac4 447 if (_error == false) {
JackB 0:04311b121ac4 448 _error = (r != 0);
JackB 0:04311b121ac4 449 }
JackB 0:04311b121ac4 450 }
JackB 0:04311b121ac4 451 location++;
JackB 0:04311b121ac4 452 }
JackB 0:04311b121ac4 453 return bytesRead;
JackB 0:04311b121ac4 454 }
JackB 0:04311b121ac4 455
JackB 0:04311b121ac4 456 // 128 Bytes EEPROM
JackB 0:04311b121ac4 457 // Write a single byte of data to EEPROM
JackB 0:04311b121ac4 458 void MCP79412::writeEepromByte(uint8_t location, uint8_t data)
JackB 0:04311b121ac4 459 {
JackB 0:04311b121ac4 460 writeEepromBytes(location, &data, 1);
JackB 0:04311b121ac4 461 // char buf[2];
JackB 0:04311b121ac4 462 // unlockUniqueID();
JackB 0:04311b121ac4 463 // buf[0] = location & (EEPROM_SIZE - 1);
JackB 0:04311b121ac4 464 // buf[1] = data;
JackB 0:04311b121ac4 465 // int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 2);
JackB 0:04311b121ac4 466 // _error = (w != 0);
JackB 0:04311b121ac4 467 }
JackB 0:04311b121ac4 468
JackB 0:04311b121ac4 469 // 128 Bytes EEPROM
JackB 0:04311b121ac4 470 // Unlock the unique id area and write multiple of bytes to EEPROM
JackB 0:04311b121ac4 471 uint8_t MCP79412::writeEepromBytes(uint8_t location, uint8_t *data, uint8_t length)
JackB 0:04311b121ac4 472 {
JackB 0:04311b121ac4 473 uint8_t bytesWritten = 0;
JackB 0:04311b121ac4 474 char buf[1];
JackB 0:04311b121ac4 475 unlockUniqueID();
JackB 0:04311b121ac4 476 buf[0] = location & (EEPROM_SIZE - 1); // location & 0x7f
JackB 0:04311b121ac4 477 int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 1);
JackB 0:04311b121ac4 478 _error = (w != 0);
JackB 0:04311b121ac4 479 for (uint8_t i = 0; i < length; i++) {
JackB 0:04311b121ac4 480 if (location < EEPROM_SIZE)
JackB 0:04311b121ac4 481 {
JackB 0:04311b121ac4 482 buf[0] = data[i];
JackB 0:04311b121ac4 483 int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 1); // Returns 0 on success (ack), non-0 on failure (nack)
JackB 0:04311b121ac4 484 bytesWritten++;
JackB 0:04311b121ac4 485 if (_error == false) {
JackB 0:04311b121ac4 486 _error = (w != 0);
JackB 0:04311b121ac4 487 }
JackB 0:04311b121ac4 488 }
JackB 0:04311b121ac4 489 location++;
JackB 0:04311b121ac4 490 }
JackB 0:04311b121ac4 491 return bytesWritten;
JackB 0:04311b121ac4 492 }
JackB 0:04311b121ac4 493
JackB 0:04311b121ac4 494 // 128 Bytes EEPROM
JackB 0:04311b121ac4 495 // Read a single byte of data from EEPROM
JackB 0:04311b121ac4 496 uint8_t MCP79412::readEepromByte(uint8_t location)
JackB 0:04311b121ac4 497 {
JackB 0:04311b121ac4 498 uint8_t data;
JackB 0:04311b121ac4 499 readEepromBytes(location, &data, 1);
JackB 0:04311b121ac4 500 return data;
JackB 0:04311b121ac4 501 // char buf[2];
JackB 0:04311b121ac4 502 // if ((location >= SRAM_START_ADDR) && (location <= SRAM_END_ADDR))
JackB 0:04311b121ac4 503 // {
JackB 0:04311b121ac4 504 // buf[0] = location;
JackB 0:04311b121ac4 505 // int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 506 // int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 507 //
JackB 0:04311b121ac4 508 // _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 509 //
JackB 0:04311b121ac4 510 // return buf[0];
JackB 0:04311b121ac4 511 // }
JackB 0:04311b121ac4 512 // return 0;
JackB 0:04311b121ac4 513 }
JackB 0:04311b121ac4 514
JackB 0:04311b121ac4 515 // 128 Bytes EEPROM
JackB 0:04311b121ac4 516 // Read multiple bytes of data from EEPROM
JackB 0:04311b121ac4 517 uint8_t MCP79412::readEepromBytes(uint8_t location, uint8_t *data, uint8_t length)
JackB 0:04311b121ac4 518 {
JackB 0:04311b121ac4 519 uint8_t bytesRead = 0;
JackB 0:04311b121ac4 520 char buf[1];
JackB 0:04311b121ac4 521 buf[0] = location & (EEPROM_SIZE - 1); // location & 0x7f
JackB 0:04311b121ac4 522 int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 1);
JackB 0:04311b121ac4 523 _error = (w != 0);
JackB 0:04311b121ac4 524 for (uint8_t i = 0; i < length; i++) {
JackB 0:04311b121ac4 525 if (location < EEPROM_SIZE)
JackB 0:04311b121ac4 526 {
JackB 0:04311b121ac4 527 int r = _i2c.read(MCP79412_EEPROM_ADDR, buf, 1);
JackB 0:04311b121ac4 528 bytesRead++;
JackB 0:04311b121ac4 529 data[i] = buf[0];
JackB 0:04311b121ac4 530 if (_error == false) {
JackB 0:04311b121ac4 531 _error = (r != 0);
JackB 0:04311b121ac4 532 }
JackB 0:04311b121ac4 533 }
JackB 0:04311b121ac4 534 location++;
JackB 0:04311b121ac4 535 }
JackB 0:04311b121ac4 536 return bytesRead;
JackB 0:04311b121ac4 537 }
JackB 0:04311b121ac4 538
JackB 0:04311b121ac4 539 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 540 * Read the calibration register. *
JackB 0:04311b121ac4 541 * The calibration value is not a twos-complement number. The MSB is *
JackB 0:04311b121ac4 542 * the sign bit, and the 7 LSBs are an unsigned number, so we convert *
JackB 0:04311b121ac4 543 * it and return it to the caller as a regular twos-complement integer. *
JackB 0:04311b121ac4 544 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 545 int MCP79412::calibRead(void)
JackB 0:04311b121ac4 546 {
JackB 0:04311b121ac4 547 uint8_t val = readRamByte(CALIB_REG);
JackB 0:04311b121ac4 548
JackB 0:04311b121ac4 549 if ( val & 0x80 ) {
JackB 0:04311b121ac4 550 return -(val & 0x7F);
JackB 0:04311b121ac4 551 }
JackB 0:04311b121ac4 552 return val;
JackB 0:04311b121ac4 553 }
JackB 0:04311b121ac4 554
JackB 0:04311b121ac4 555 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 556 * Write the calibration register. *
JackB 0:04311b121ac4 557 * Calibration value must be between -127 and 127, others result *
JackB 0:04311b121ac4 558 * in no action. See note above on the format of the calibration value. *
JackB 0:04311b121ac4 559 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 560 void MCP79412::calibWrite(int value)
JackB 0:04311b121ac4 561 {
JackB 0:04311b121ac4 562 uint8_t calibVal;
JackB 0:04311b121ac4 563
JackB 0:04311b121ac4 564 if (value >= -127 && value <= 127) {
JackB 0:04311b121ac4 565 calibVal = abs(value);
JackB 0:04311b121ac4 566 if (value < 0) {
JackB 0:04311b121ac4 567 calibVal += 128;
JackB 0:04311b121ac4 568 }
JackB 0:04311b121ac4 569 writeRamByte(CALIB_REG, calibVal);
JackB 0:04311b121ac4 570 }
JackB 0:04311b121ac4 571 }
JackB 0:04311b121ac4 572
JackB 0:04311b121ac4 573 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 574 * Read the unique ID. *
JackB 0:04311b121ac4 575 * User or factory programmable, Protected area *
JackB 0:04311b121ac4 576 * For the MCP79411 (EUI-48), the first two bytes will contain 0xFF. *
JackB 0:04311b121ac4 577 * Caller must provide an 8-byte array to contain the results. *
JackB 0:04311b121ac4 578 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 579 void MCP79412::readUniqueId(char *uniqueID)
JackB 0:04311b121ac4 580 {
JackB 0:04311b121ac4 581 char buf[1];
JackB 0:04311b121ac4 582 buf[0] = UNIQUE_ID_ADDR;
JackB 0:04311b121ac4 583 int w = _i2c.write(MCP79412_EEPROM_ADDR, buf, 1);
JackB 0:04311b121ac4 584 int r = _i2c.read(MCP79412_EEPROM_ADDR, uniqueID, UNIQUE_ID_SIZE);
JackB 0:04311b121ac4 585 _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 586 }
JackB 0:04311b121ac4 587
JackB 0:04311b121ac4 588 /*----------------------------------------------------------------------------*
JackB 0:04311b121ac4 589 * Returns an EUI-64 ID. For an MCP79411, the EUI-48 ID is converted to *
JackB 0:04311b121ac4 590 * EUI-64. For an MCP79412, calling this function is equivalent to *
JackB 0:04311b121ac4 591 * calling readUniqueId(). For an MCP79412, if the RTC type is known, calling *
JackB 0:04311b121ac4 592 * readUniqueId() will be a bit more efficient. *
JackB 0:04311b121ac4 593 * Caller must provide an 8-byte array to contain the results. *
JackB 0:04311b121ac4 594 *----------------------------------------------------------------------------*/
JackB 0:04311b121ac4 595 void MCP79412::getEUI64(char *uniqueID)
JackB 0:04311b121ac4 596 {
JackB 0:04311b121ac4 597 char rtcID[8];
JackB 0:04311b121ac4 598
JackB 0:04311b121ac4 599 readUniqueId(rtcID);
JackB 0:04311b121ac4 600 if ((rtcID[0] == 0xFF) && (rtcID[1] == 0xFF)) {
JackB 0:04311b121ac4 601 rtcID[0] = rtcID[2];
JackB 0:04311b121ac4 602 rtcID[1] = rtcID[3];
JackB 0:04311b121ac4 603 rtcID[2] = rtcID[4];
JackB 0:04311b121ac4 604 rtcID[3] = 0xFF;
JackB 0:04311b121ac4 605 rtcID[4] = 0xFE;
JackB 0:04311b121ac4 606 }
JackB 0:04311b121ac4 607 for (uint8_t i = 0; i < UNIQUE_ID_SIZE; i++) {
JackB 0:04311b121ac4 608 uniqueID[i] = rtcID[i];
JackB 0:04311b121ac4 609 }
JackB 0:04311b121ac4 610 }
JackB 0:04311b121ac4 611
JackB 0:04311b121ac4 612 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 613 * Check to see if a power failure has occurred. If so, returns TRUE *
JackB 0:04311b121ac4 614 * as the function value, and returns the power down and power up *
JackB 0:04311b121ac4 615 * timestamps. After returning the time stamps, the RTC's timestamp *
JackB 0:04311b121ac4 616 * registers are cleared and the VBAT bit which indicates a power *
JackB 0:04311b121ac4 617 * failure is reset. *
JackB 0:04311b121ac4 618 * *
JackB 0:04311b121ac4 619 * Note that the power down and power up timestamp registers do not *
JackB 0:04311b121ac4 620 * contain values for seconds or for the year. The returned time stamps *
JackB 0:04311b121ac4 621 * will therefore contain the current year from the RTC. However, there *
JackB 0:04311b121ac4 622 * is a chance that a power outage spans from one year to the next. *
JackB 0:04311b121ac4 623 * If we find the power down timestamp to be later (larger) than the *
JackB 0:04311b121ac4 624 * power up timestamp, we will assume this has happened, and well *
JackB 0:04311b121ac4 625 * subtract one year from the power down timestamp. *
JackB 0:04311b121ac4 626 * *
JackB 0:04311b121ac4 627 * Still, there is an assumption that the timestamps are being read *
JackB 0:04311b121ac4 628 * in the same year as that when the power up occurred. *
JackB 0:04311b121ac4 629 * *
JackB 0:04311b121ac4 630 * Finally, note that once the RTC records a power outage, it must be *
JackB 0:04311b121ac4 631 * cleared before another will be recorded. *
JackB 0:04311b121ac4 632 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 633 bool MCP79412::powerFail(time_t *powerDown, time_t *powerUp)
JackB 0:04311b121ac4 634 {
JackB 0:04311b121ac4 635 uint8_t day, yr; //copies of the RTC Day and Year registers
JackB 0:04311b121ac4 636 struct tm dn, up; //power down and power up times
JackB 0:04311b121ac4 637 char buf[8];
JackB 0:04311b121ac4 638
JackB 0:04311b121ac4 639 readRamBytes(DAY_REG, &day, 1);
JackB 0:04311b121ac4 640 readRamBytes(YEAR_REG, &yr, 1);
JackB 0:04311b121ac4 641 yr = y2kYearToTm(bcdToDec(yr));
JackB 0:04311b121ac4 642 if ( day & _BV(VBAT) ) {
JackB 0:04311b121ac4 643 buf[0] = PWRDWN_TS_REG;
JackB 0:04311b121ac4 644 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 645
JackB 0:04311b121ac4 646 int r = _i2c.read(MCP79412_RTC_ADDR, buf, 8); //read both timestamp registers, 8 bytes total
JackB 0:04311b121ac4 647 dn.tm_sec = 0;
JackB 0:04311b121ac4 648 dn.tm_min = bcdToDec(buf[0]);
JackB 0:04311b121ac4 649 dn.tm_hour = bcdToDec(buf[1] & ~_BV(HR1224)); //assumes 24hr clock
JackB 0:04311b121ac4 650 dn.tm_mday = bcdToDec(buf[2]);
JackB 0:04311b121ac4 651 dn.tm_mon = bcdToDec(buf[3] & 0x1F); //mask off the day, we don't need it
JackB 0:04311b121ac4 652 dn.tm_year = yr; //assume current year
JackB 0:04311b121ac4 653 up.tm_sec = 0;
JackB 0:04311b121ac4 654 up.tm_min = bcdToDec(buf[4]);
JackB 0:04311b121ac4 655 up.tm_hour = bcdToDec(buf[5] & ~_BV(HR1224)); //assumes 24hr clock
JackB 0:04311b121ac4 656 up.tm_mday = bcdToDec(buf[6]);
JackB 0:04311b121ac4 657 up.tm_mon = bcdToDec(buf[7] & 0x1F); //mask off the day, we don't need it
JackB 0:04311b121ac4 658 up.tm_year = yr; //assume current year
JackB 0:04311b121ac4 659
JackB 0:04311b121ac4 660 *powerDown = mktime(&dn);
JackB 0:04311b121ac4 661 *powerUp = mktime(&up);
JackB 0:04311b121ac4 662
JackB 0:04311b121ac4 663 //clear the VBAT bit, which causes the RTC hardware to clear the timestamps too.
JackB 0:04311b121ac4 664 //I suppose there is a risk here that the day has changed since we read it,
JackB 0:04311b121ac4 665 //but the Day of Week is actually redundant data and the makeTime() function
JackB 0:04311b121ac4 666 //does not use it. This could be an issue if someone is reading the RTC
JackB 0:04311b121ac4 667 //registers directly, but as this library is meant to be used with the Time library,
JackB 0:04311b121ac4 668 //and also because we don't provide a method to read the RTC clock/calendar
JackB 0:04311b121ac4 669 //registers directly, we won't lose any sleep about it at this point unless
JackB 0:04311b121ac4 670 //some issue is actually brought to our attention ;-)
JackB 0:04311b121ac4 671 day &= ~_BV(VBAT);
JackB 0:04311b121ac4 672 writeRamBytes(DAY_REG, &day , 1);
JackB 0:04311b121ac4 673
JackB 0:04311b121ac4 674 //adjust the powerDown timestamp if needed (see notes above)
JackB 0:04311b121ac4 675 if (*powerDown > *powerUp) {
JackB 0:04311b121ac4 676 --dn.tm_year;
JackB 0:04311b121ac4 677 *powerDown = mktime(&dn);
JackB 0:04311b121ac4 678 }
JackB 0:04311b121ac4 679 return true;
JackB 0:04311b121ac4 680 }
JackB 0:04311b121ac4 681 return false;
JackB 0:04311b121ac4 682 }
JackB 0:04311b121ac4 683
JackB 0:04311b121ac4 684 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 685 * Enable or disable the square wave output. *
JackB 0:04311b121ac4 686 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 687 void MCP79412::squareWave(Sqwave freq)
JackB 0:04311b121ac4 688 {
JackB 0:04311b121ac4 689 uint8_t ctrlReg;
JackB 0:04311b121ac4 690
JackB 0:04311b121ac4 691 readRamBytes(CTRL_REG, &ctrlReg, 1);
JackB 0:04311b121ac4 692 if (freq > 3) {
JackB 0:04311b121ac4 693 ctrlReg &= ~_BV(SQWE);
JackB 0:04311b121ac4 694 }
JackB 0:04311b121ac4 695 else {
JackB 0:04311b121ac4 696 ctrlReg = (ctrlReg & 0xF8) | _BV(SQWE) | freq;
JackB 0:04311b121ac4 697 }
JackB 0:04311b121ac4 698 writeRamByte(CTRL_REG, ctrlReg);
JackB 0:04311b121ac4 699 }
JackB 0:04311b121ac4 700
JackB 0:04311b121ac4 701 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 702 * Set an alarm time. Sets the alarm registers only, does not enable *
JackB 0:04311b121ac4 703 * the alarm. See enableAlarm(). *
JackB 0:04311b121ac4 704 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 705 void MCP79412::setAlarm(uint8_t alarmNumber, time_t alarmTime)
JackB 0:04311b121ac4 706 {
JackB 0:04311b121ac4 707 struct tm *t;
JackB 0:04311b121ac4 708 uint8_t day; // Need to preserve bits in the day (of week) register
JackB 0:04311b121ac4 709
JackB 0:04311b121ac4 710 alarmNumber &= 0x01; // Ensure a valid alarm number
JackB 0:04311b121ac4 711 readRamBytes(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG) , &day, 1);
JackB 0:04311b121ac4 712 t = localtime(&alarmTime); // Put the time_t into the tm structure
JackB 0:04311b121ac4 713
JackB 0:04311b121ac4 714 char buf[7];
JackB 0:04311b121ac4 715 buf[0] = ALM0_REG + alarmNumber * (ALM1_REG - ALM0_REG);
JackB 0:04311b121ac4 716 buf[1] = dec2bcd(t->tm_sec);
JackB 0:04311b121ac4 717 buf[2] = dec2bcd(t->tm_min);
JackB 0:04311b121ac4 718 buf[3] = dec2bcd(t->tm_hour); // Sets 24 hour format (Bit 6 == 0)
JackB 0:04311b121ac4 719 buf[4] = (day & 0xF8) + t->tm_wday;
JackB 0:04311b121ac4 720 buf[5] = dec2bcd(t->tm_mday);
JackB 0:04311b121ac4 721 buf[6] = dec2bcd(t->tm_mon);
JackB 0:04311b121ac4 722 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 7);
JackB 0:04311b121ac4 723 _error = (w != 0);
JackB 0:04311b121ac4 724 }
JackB 0:04311b121ac4 725
JackB 0:04311b121ac4 726 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 727 * Enable or disable an alarm, and set the trigger criteria, *
JackB 0:04311b121ac4 728 * e.g. match only seconds, only minutes, entire time and date, etc. *
JackB 0:04311b121ac4 729 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 730 void MCP79412::enableAlarm(uint8_t alarmNumber, uint8_t alarmType)
JackB 0:04311b121ac4 731 {
JackB 0:04311b121ac4 732 uint8_t day; //alarm day register has config & flag bits
JackB 0:04311b121ac4 733 uint8_t ctrl; //control register has alarm enable bits
JackB 0:04311b121ac4 734
JackB 0:04311b121ac4 735 alarmNumber &= 0x01; //ensure a valid alarm number
JackB 0:04311b121ac4 736 readRamBytes(CTRL_REG, &ctrl, 1);
JackB 0:04311b121ac4 737 if (alarmType < ALM_DISABLE) {
JackB 0:04311b121ac4 738 readRamBytes(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
JackB 0:04311b121ac4 739 day = ( day & 0x87 ) | alarmType << 4; //reset interrupt flag, OR in the config bits
JackB 0:04311b121ac4 740 writeRamByte(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), day);
JackB 0:04311b121ac4 741 ctrl |= _BV(ALM0 + alarmNumber); //enable the alarm
JackB 0:04311b121ac4 742 }
JackB 0:04311b121ac4 743 else {
JackB 0:04311b121ac4 744 ctrl &= ~(_BV(ALM0 + alarmNumber)); //disable the alarm
JackB 0:04311b121ac4 745 }
JackB 0:04311b121ac4 746 writeRamByte(CTRL_REG, ctrl);
JackB 0:04311b121ac4 747 }
JackB 0:04311b121ac4 748
JackB 0:04311b121ac4 749 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 750 * Returns true or false depending on whether the given alarm has been *
JackB 0:04311b121ac4 751 * triggered, and resets the alarm "interrupt" flag. This is not a real *
JackB 0:04311b121ac4 752 * interrupt, just a bit that's set when an alarm is triggered. *
JackB 0:04311b121ac4 753 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 754 bool MCP79412::alarm(uint8_t alarmNumber)
JackB 0:04311b121ac4 755 {
JackB 0:04311b121ac4 756 uint8_t day; //alarm day register has config & flag bits
JackB 0:04311b121ac4 757
JackB 0:04311b121ac4 758 alarmNumber &= 0x01; //ensure a valid alarm number
JackB 0:04311b121ac4 759 readRamBytes( ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
JackB 0:04311b121ac4 760 if (day & _BV(ALMIF)) {
JackB 0:04311b121ac4 761 day &= ~_BV(ALMIF); //turn off the alarm "interrupt" flag
JackB 0:04311b121ac4 762 writeRamByte(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), day);
JackB 0:04311b121ac4 763 return true;
JackB 0:04311b121ac4 764 }
JackB 0:04311b121ac4 765 return false;
JackB 0:04311b121ac4 766 }
JackB 0:04311b121ac4 767
JackB 0:04311b121ac4 768 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 769 * Sets the logic level on the MFP when it's not being used as a *
JackB 0:04311b121ac4 770 * square wave or alarm output. The default is HIGH. *
JackB 0:04311b121ac4 771 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 772 void MCP79412::out(bool level)
JackB 0:04311b121ac4 773 {
JackB 0:04311b121ac4 774 uint8_t ctrlReg;
JackB 0:04311b121ac4 775
JackB 0:04311b121ac4 776 readRamBytes(CTRL_REG, &ctrlReg, 1);
JackB 0:04311b121ac4 777 if (level)
JackB 0:04311b121ac4 778 ctrlReg |= _BV(OUT);
JackB 0:04311b121ac4 779 else
JackB 0:04311b121ac4 780 ctrlReg &= ~_BV(OUT);
JackB 0:04311b121ac4 781 writeRamByte(CTRL_REG, ctrlReg);
JackB 0:04311b121ac4 782 }
JackB 0:04311b121ac4 783
JackB 0:04311b121ac4 784 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 785 * Specifies the logic level on the Multi-Function Pin (MFP) when an *
JackB 0:04311b121ac4 786 * alarm is triggered. The default is LOW. When both alarms are *
JackB 0:04311b121ac4 787 * active, the two are ORed together to determine the level of the MFP. *
JackB 0:04311b121ac4 788 * With alarm polarity set to LOW (the default), this causes the MFP *
JackB 0:04311b121ac4 789 * to go low only when BOTH alarms are triggered. With alarm polarity *
JackB 0:04311b121ac4 790 * set to HIGH, the MFP will go high when EITHER alarm is triggered. *
JackB 0:04311b121ac4 791 * *
JackB 0:04311b121ac4 792 * Note that the state of the MFP is independent of the alarm *
JackB 0:04311b121ac4 793 * "interrupt" flags, and the alarm() function will indicate when an *
JackB 0:04311b121ac4 794 * alarm is triggered regardless of the polarity. *
JackB 0:04311b121ac4 795 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 796 void MCP79412::alarmPolarity(bool polarity)
JackB 0:04311b121ac4 797 {
JackB 0:04311b121ac4 798 uint8_t alm0Day;
JackB 0:04311b121ac4 799
JackB 0:04311b121ac4 800 readRamBytes(ALM0_DAY, &alm0Day, 1);
JackB 0:04311b121ac4 801 if (polarity)
JackB 0:04311b121ac4 802 alm0Day |= _BV(OUT);
JackB 0:04311b121ac4 803 else
JackB 0:04311b121ac4 804 alm0Day &= ~_BV(OUT);
JackB 0:04311b121ac4 805 writeRamByte(ALM0_DAY, alm0Day);
JackB 0:04311b121ac4 806 }
JackB 0:04311b121ac4 807
JackB 0:04311b121ac4 808 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 809 * Check to see if the RTC's oscillator is started (ST bit in seconds *
JackB 0:04311b121ac4 810 * register). Returns true if started. *
JackB 0:04311b121ac4 811 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 812 bool MCP79412::isRunning(void)
JackB 0:04311b121ac4 813 {
JackB 0:04311b121ac4 814 char buf[1];
JackB 0:04311b121ac4 815 buf[0] = (uint8_t)TIME_REG;
JackB 0:04311b121ac4 816 int w = _i2c.write(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 817 int r = _i2c.read(MCP79412_RTC_ADDR, buf, 1);
JackB 0:04311b121ac4 818 _error = ((w != 0) || (r != 0));
JackB 0:04311b121ac4 819 return buf[0] & _BV(ST);
JackB 0:04311b121ac4 820 }
JackB 0:04311b121ac4 821
JackB 0:04311b121ac4 822 /*----------------------------------------------------------------------*
JackB 0:04311b121ac4 823 * Set or clear the VBATEN bit. Setting the bit powers the clock and *
JackB 0:04311b121ac4 824 * SRAM from the backup battery when Vcc falls. Note that setting the *
JackB 0:04311b121ac4 825 * time via set() or write() sets the VBATEN bit. *
JackB 0:04311b121ac4 826 *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 827 void MCP79412::vbaten(bool enable)
JackB 0:04311b121ac4 828 {
JackB 0:04311b121ac4 829 uint8_t day;
JackB 0:04311b121ac4 830
JackB 0:04311b121ac4 831 readRamBytes(DAY_REG, &day, 1);
JackB 0:04311b121ac4 832 if (enable)
JackB 0:04311b121ac4 833 day |= _BV(VBATEN);
JackB 0:04311b121ac4 834 else
JackB 0:04311b121ac4 835 day &= ~_BV(VBATEN);
JackB 0:04311b121ac4 836
JackB 0:04311b121ac4 837 writeRamByte(DAY_REG, day);
JackB 0:04311b121ac4 838 return;
JackB 0:04311b121ac4 839 }
JackB 0:04311b121ac4 840
JackB 0:04311b121ac4 841
JackB 0:04311b121ac4 842
JackB 0:04311b121ac4 843 //bool MCP79412::getSummerTime(void)
JackB 0:04311b121ac4 844 //{
JackB 0:04311b121ac4 845 // getDateTime(&t);
JackB 0:04311b121ac4 846 //
JackB 0:04311b121ac4 847 // time_t secondsEpoch = mktime(&t); // seconds since the Epoch
JackB 0:04311b121ac4 848 // t = *localtime(&secondsEpoch);
JackB 0:04311b121ac4 849 // strftime(buffer, 32, "%j", localtime(&secondsEpoch));
JackB 0:04311b121ac4 850 // int dayOfYearC = atoi(buffer);
JackB 0:04311b121ac4 851 //
JackB 0:04311b121ac4 852 // strftime(buffer, 32, "%Y", localtime(&secondsEpoch));
JackB 0:04311b121ac4 853 // int year = atoi(buffer);
JackB 0:04311b121ac4 854 //
JackB 0:04311b121ac4 855 // int index = (year - 2011) * 5;
JackB 0:04311b121ac4 856 // if (index < 0)
JackB 0:04311b121ac4 857 // index = 0;
JackB 0:04311b121ac4 858 // if (index > 440) // (2099 - 2011) * 5 = 440
JackB 0:04311b121ac4 859 // index = 440;
JackB 0:04311b121ac4 860 //
JackB 0:04311b121ac4 861 // int monthS = atoi(SummerTime[index+1]);
JackB 0:04311b121ac4 862 // int dayS = atoi(SummerTime[index+2]);
JackB 0:04311b121ac4 863 //
JackB 0:04311b121ac4 864 // t.tm_mon = monthS - 1; // adjust for tm structure required values
JackB 0:04311b121ac4 865 // t.tm_mday = dayS;
JackB 0:04311b121ac4 866 // secondsEpoch = mktime(&t); // seconds since the Epoch
JackB 0:04311b121ac4 867 // t = *localtime(&secondsEpoch);
JackB 0:04311b121ac4 868 // strftime(buffer, 32, "%j", localtime(&secondsEpoch));
JackB 0:04311b121ac4 869 // int dayOfYearS = atoi(buffer);
JackB 0:04311b121ac4 870 //
JackB 0:04311b121ac4 871 // int monthE = atoi(SummerTime[index+3]);
JackB 0:04311b121ac4 872 // int dayE = atoi(SummerTime[index+4]);
JackB 0:04311b121ac4 873 //
JackB 0:04311b121ac4 874 // t.tm_mon = monthE - 1; // adjust for tm structure required values
JackB 0:04311b121ac4 875 // t.tm_mday = dayE;
JackB 0:04311b121ac4 876 // secondsEpoch = mktime(&t); // seconds since the Epoch
JackB 0:04311b121ac4 877 // t = *localtime(&secondsEpoch);
JackB 0:04311b121ac4 878 // strftime(buffer, 32, "%j", localtime(&secondsEpoch));
JackB 0:04311b121ac4 879 // int dayOfYearE = atoi(buffer);
JackB 0:04311b121ac4 880 //
JackB 0:04311b121ac4 881 // return ((dayOfYearC >= dayOfYearS) && (dayOfYearC < dayOfYearE)) ? true : false;
JackB 0:04311b121ac4 882 //}
JackB 0:04311b121ac4 883 //
JackB 0:04311b121ac4 884 //int MCP79412::dayOfYearC(void)
JackB 0:04311b121ac4 885 //{
JackB 0:04311b121ac4 886 // getDateTime(&t);
JackB 0:04311b121ac4 887 //
JackB 0:04311b121ac4 888 // time_t secondsEpoch = mktime(&t); // seconds since the Epoch
JackB 0:04311b121ac4 889 // strftime(buffer, 32, "%j", localtime(&secondsEpoch));
JackB 0:04311b121ac4 890 // return atoi(buffer);
JackB 0:04311b121ac4 891 //}
JackB 0:04311b121ac4 892 //
JackB 0:04311b121ac4 893 //char * MCP79412::getSunRise(void)
JackB 0:04311b121ac4 894 //{
JackB 0:04311b121ac4 895 // return (char*) SunRise[dayOfYearC()];
JackB 0:04311b121ac4 896 //}
JackB 0:04311b121ac4 897 //
JackB 0:04311b121ac4 898 //char * MCP79412::getSunSet(void)
JackB 0:04311b121ac4 899 //{
JackB 0:04311b121ac4 900 // return (char*) SunSet[dayOfYearC()];
JackB 0:04311b121ac4 901 //}
JackB 0:04311b121ac4 902 //
JackB 0:04311b121ac4 903 //char * MCP79412::getDayLength(void)
JackB 0:04311b121ac4 904 //{
JackB 0:04311b121ac4 905 // return (char*) DayLength[dayOfYearC()];
JackB 0:04311b121ac4 906 //}
JackB 0:04311b121ac4 907 //
JackB 0:04311b121ac4 908 //int MCP79412::getSunRiseMinute(void)
JackB 0:04311b121ac4 909 //{
JackB 0:04311b121ac4 910 // int doy = dayOfYearC();
JackB 0:04311b121ac4 911 // int h = atoi(substr((char*)SunRise[doy], 0, 2));
JackB 0:04311b121ac4 912 // int m = atoi(substr((char*)SunRise[doy], 3, 2));
JackB 0:04311b121ac4 913 // return h * 60 + m;
JackB 0:04311b121ac4 914 //}
JackB 0:04311b121ac4 915 //
JackB 0:04311b121ac4 916 //int MCP79412::getSunSetMinute(void)
JackB 0:04311b121ac4 917 //{
JackB 0:04311b121ac4 918 // int doy = dayOfYearC();
JackB 0:04311b121ac4 919 // int h = atoi(substr((char*)SunSet[doy], 0, 2));
JackB 0:04311b121ac4 920 // int m = atoi(substr((char*)SunSet[doy], 3, 2));
JackB 0:04311b121ac4 921 // return h * 60 + m;
JackB 0:04311b121ac4 922 //}
JackB 0:04311b121ac4 923 //
JackB 0:04311b121ac4 924 //bool MCP79412::checkSunRise(void)
JackB 0:04311b121ac4 925 //{
JackB 0:04311b121ac4 926 // int dayOfWeek, mday, month, year, hours, minutes, seconds;
JackB 0:04311b121ac4 927 // readDateTime(&dayOfWeek, &mday, &month, &year, &hours, &minutes, &seconds);
JackB 0:04311b121ac4 928 //
JackB 0:04311b121ac4 929 // int absMinute = hours * 60 + minutes;
JackB 0:04311b121ac4 930 // int SunRiseMinute = getSunRiseMinute();
JackB 0:04311b121ac4 931 // int SunSetMinute = getSunSetMinute();
JackB 0:04311b121ac4 932 //
JackB 0:04311b121ac4 933 // return ((absMinute >= SunRiseMinute) && (absMinute < SunSetMinute)) ? true : false;
JackB 0:04311b121ac4 934 //}
JackB 0:04311b121ac4 935
JackB 0:04311b121ac4 936
JackB 0:04311b121ac4 937 void MCP79412::substr(char *s, char *d, int pos, int len)
JackB 0:04311b121ac4 938 {
JackB 0:04311b121ac4 939 char *t;
JackB 0:04311b121ac4 940 s = s+pos;
JackB 0:04311b121ac4 941 t = s+len;
JackB 0:04311b121ac4 942 while (s != t) {
JackB 0:04311b121ac4 943 *d=*s;
JackB 0:04311b121ac4 944 s++;
JackB 0:04311b121ac4 945 d++;
JackB 0:04311b121ac4 946 }
JackB 0:04311b121ac4 947 *d='\0';
JackB 0:04311b121ac4 948 }
JackB 0:04311b121ac4 949
JackB 0:04311b121ac4 950 char * MCP79412::substr(char *s, int pos, int len)
JackB 0:04311b121ac4 951 {
JackB 0:04311b121ac4 952 char *t;
JackB 0:04311b121ac4 953 char *d;
JackB 0:04311b121ac4 954 d = buffer;
JackB 0:04311b121ac4 955 s = s+pos;
JackB 0:04311b121ac4 956 t = s+len;
JackB 0:04311b121ac4 957 while (s != t) {
JackB 0:04311b121ac4 958 *d=*s;
JackB 0:04311b121ac4 959 s++;
JackB 0:04311b121ac4 960 d++;
JackB 0:04311b121ac4 961 }
JackB 0:04311b121ac4 962 *d='\0';
JackB 0:04311b121ac4 963 return buffer;
JackB 0:04311b121ac4 964 }
JackB 0:04311b121ac4 965
JackB 0:04311b121ac4 966
JackB 0:04311b121ac4 967
JackB 0:04311b121ac4 968
JackB 0:04311b121ac4 969 struct tm MCP79412::setSystemDateTime(
JackB 0:04311b121ac4 970 uint8_t second, // 0-59
JackB 0:04311b121ac4 971 uint8_t minute, // 0-59
JackB 0:04311b121ac4 972 uint8_t hour, // 1-23
JackB 0:04311b121ac4 973 uint8_t dayOfMonth, // 1-31
JackB 0:04311b121ac4 974 uint8_t month, // 1-12
JackB 0:04311b121ac4 975 uint8_t year) // 0-99
JackB 0:04311b121ac4 976 {
JackB 0:04311b121ac4 977 uint8_t dayOfWeek = 1; // Will be determined
JackB 0:04311b121ac4 978 // Convert to unix time structure
JackB 0:04311b121ac4 979 t->tm_sec = second; // 0-59
JackB 0:04311b121ac4 980 t->tm_min = minute; // 0-59
JackB 0:04311b121ac4 981 t->tm_hour = hour; // 0-23
JackB 0:04311b121ac4 982 t->tm_wday = dayOfWeek - 1; // 0-6 (0 = Sunday)
JackB 0:04311b121ac4 983 t->tm_mday = dayOfMonth; // 1-31
JackB 0:04311b121ac4 984 t->tm_mon = month - 1; // 0-11
JackB 0:04311b121ac4 985 t->tm_year = year + 100; // 100-199 year since 1900
JackB 0:04311b121ac4 986 t->tm_isdst = 0;
JackB 0:04311b121ac4 987
JackB 0:04311b121ac4 988 // 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);
JackB 0:04311b121ac4 989
JackB 0:04311b121ac4 990 secondsEpoch = mktime(t); // seconds since the Epoch
JackB 0:04311b121ac4 991 set_time(secondsEpoch);
JackB 0:04311b121ac4 992
JackB 0:04311b121ac4 993 // Get weekday 0-6, Sunday as 0 for RTC
JackB 0:04311b121ac4 994 t = localtime(&secondsEpoch);
JackB 0:04311b121ac4 995 // 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);
JackB 0:04311b121ac4 996 return *t;
JackB 0:04311b121ac4 997 }
JackB 0:04311b121ac4 998
JackB 0:04311b121ac4 999 void MCP79412::getSystemDateTime(
JackB 0:04311b121ac4 1000 uint8_t *second, // 0-59
JackB 0:04311b121ac4 1001 uint8_t *minute, // 0-59
JackB 0:04311b121ac4 1002 uint8_t *hour, // 0-23
JackB 0:04311b121ac4 1003 uint8_t *dayOfWeek, // 1-7 (1 = Sunday)
JackB 0:04311b121ac4 1004 uint8_t *dayOfMonth, // 1-31
JackB 0:04311b121ac4 1005 uint8_t *month, // 1-12
JackB 0:04311b121ac4 1006 uint8_t *year) // 0-99 year since 2000
JackB 0:04311b121ac4 1007 {
JackB 0:04311b121ac4 1008 // struct tm *t;
JackB 0:04311b121ac4 1009 // time_t secondsEpoch;
JackB 0:04311b121ac4 1010
JackB 0:04311b121ac4 1011 // Get system DateTime
JackB 0:04311b121ac4 1012 secondsEpoch = time(NULL);
JackB 0:04311b121ac4 1013 t = localtime(&secondsEpoch);
JackB 0:04311b121ac4 1014
JackB 0:04311b121ac4 1015 // time/date data
JackB 0:04311b121ac4 1016 *second = (t->tm_sec); // 0-59
JackB 0:04311b121ac4 1017 *minute = (t->tm_min); // 0-59
JackB 0:04311b121ac4 1018 *hour = (t->tm_hour); // 0-23
JackB 0:04311b121ac4 1019 *dayOfWeek = (t->tm_wday + 1); // 1-7 (1 = Sunday)
JackB 0:04311b121ac4 1020 *dayOfMonth = (t->tm_mday); // 1-31
JackB 0:04311b121ac4 1021 *month = (t->tm_mon + 1); // 1-12
JackB 0:04311b121ac4 1022 *year = (t->tm_year - 100); // 0-99 year since 2000
JackB 0:04311b121ac4 1023 }
JackB 0:04311b121ac4 1024
JackB 0:04311b121ac4 1025 void MCP79412::setRtcToSystemDateTime(void)
JackB 0:04311b121ac4 1026 {
JackB 0:04311b121ac4 1027 // Get system DateTime
JackB 0:04311b121ac4 1028 secondsEpoch = time(NULL);
JackB 0:04311b121ac4 1029 t = localtime(&secondsEpoch);
JackB 0:04311b121ac4 1030
JackB 0:04311b121ac4 1031 // Convert from unix time structure
JackB 0:04311b121ac4 1032 uint8_t second = (t->tm_sec); // 0-59
JackB 0:04311b121ac4 1033 uint8_t minute = (t->tm_min); // 0-59
JackB 0:04311b121ac4 1034 uint8_t hour = (t->tm_hour); // 0-23
JackB 0:04311b121ac4 1035 uint8_t dayOfWeek = (t->tm_wday + 1); // 1-7 (1 = Sunday)
JackB 0:04311b121ac4 1036 uint8_t dayOfMonth = (t->tm_mday); // 1-31
JackB 0:04311b121ac4 1037 uint8_t month = (t->tm_mon + 1); // 1-12
JackB 0:04311b121ac4 1038 uint8_t year = (t->tm_year - 100); // 0-99 year since 2000
JackB 0:04311b121ac4 1039
JackB 0:04311b121ac4 1040 // Set RTC DateTime
JackB 0:04311b121ac4 1041 setRtcDateTime(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
JackB 0:04311b121ac4 1042 }
JackB 0:04311b121ac4 1043
JackB 0:04311b121ac4 1044 void MCP79412::setSystemToRtcDateTime(void)
JackB 0:04311b121ac4 1045 {
JackB 0:04311b121ac4 1046 // Get RTC DateTime
JackB 0:04311b121ac4 1047 getRtcDateTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
JackB 0:04311b121ac4 1048
JackB 0:04311b121ac4 1049 // Convert to unix time structure
JackB 0:04311b121ac4 1050 t->tm_sec = second; // 0-59
JackB 0:04311b121ac4 1051 t->tm_min = minute; // 0-59
JackB 0:04311b121ac4 1052 t->tm_hour = hour; // 0-23
JackB 0:04311b121ac4 1053 t->tm_wday = dayOfWeek - 1; // 0-6 (0 = Sunday)
JackB 0:04311b121ac4 1054 t->tm_mday = dayOfMonth; // 1-31
JackB 0:04311b121ac4 1055 t->tm_mon = month - 1; // 0-11
JackB 0:04311b121ac4 1056 t->tm_year = year + 100; // 100-199 year since 1900
JackB 0:04311b121ac4 1057 t->tm_isdst = 0;
JackB 0:04311b121ac4 1058
JackB 0:04311b121ac4 1059 // Set system DateTime
JackB 0:04311b121ac4 1060 secondsEpoch = mktime(t); // seconds since the Epoch
JackB 0:04311b121ac4 1061 set_time(secondsEpoch);
JackB 0:04311b121ac4 1062 }
JackB 0:04311b121ac4 1063
JackB 0:04311b121ac4 1064 void MCP79412::setRtcFromTm(struct tm *t)
JackB 0:04311b121ac4 1065 {
JackB 0:04311b121ac4 1066 // // Get system DateTime
JackB 0:04311b121ac4 1067 // secondsEpoch = time(NULL);
JackB 0:04311b121ac4 1068 // t = localtime(&secondsEpoch);
JackB 0:04311b121ac4 1069
JackB 0:04311b121ac4 1070 // Convert from unix time structure
JackB 0:04311b121ac4 1071 uint8_t second = (t->tm_sec); // 0-59
JackB 0:04311b121ac4 1072 uint8_t minute = (t->tm_min); // 0-59
JackB 0:04311b121ac4 1073 uint8_t hour = (t->tm_hour); // 0-23
JackB 0:04311b121ac4 1074 uint8_t dayOfWeek = (t->tm_wday + 1); // 1-7 (1 = Sunday)
JackB 0:04311b121ac4 1075 uint8_t dayOfMonth = (t->tm_mday); // 1-31
JackB 0:04311b121ac4 1076 uint8_t month = (t->tm_mon + 1); // 1-12
JackB 0:04311b121ac4 1077 uint8_t year = (t->tm_year - 100); // 0-99 year since 2000
JackB 0:04311b121ac4 1078
JackB 0:04311b121ac4 1079 // printf("setRtcFromTm %d %02d-%02d-%03d %02d:%02d:%02d\n", dayOfWeek, dayOfMonth, month, year, hour, minute, second);
JackB 0:04311b121ac4 1080
JackB 0:04311b121ac4 1081 // Set RTC DateTime
JackB 0:04311b121ac4 1082 setRtcDateTime(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
JackB 0:04311b121ac4 1083 }
JackB 0:04311b121ac4 1084
JackB 0:04311b121ac4 1085 struct tm MCP79412::getTmFromRtc(void)
JackB 0:04311b121ac4 1086 {
JackB 0:04311b121ac4 1087 // Get RTC DateTime
JackB 0:04311b121ac4 1088 getRtcDateTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
JackB 0:04311b121ac4 1089
JackB 0:04311b121ac4 1090 // Convert to unix time structure
JackB 0:04311b121ac4 1091 t->tm_sec = second; // 0-59
JackB 0:04311b121ac4 1092 t->tm_min = minute; // 0-59
JackB 0:04311b121ac4 1093 t->tm_hour = hour; // 0-23
JackB 0:04311b121ac4 1094 t->tm_wday = dayOfWeek - 1; // 0-6 (0 = Sunday)
JackB 0:04311b121ac4 1095 t->tm_mday = dayOfMonth; // 1-31
JackB 0:04311b121ac4 1096 t->tm_mon = month - 1; // 0-11
JackB 0:04311b121ac4 1097 t->tm_year = year + 100; // 100-199 year since 1900
JackB 0:04311b121ac4 1098 t->tm_isdst = 0;
JackB 0:04311b121ac4 1099
JackB 0:04311b121ac4 1100 return *t;
JackB 0:04311b121ac4 1101 // // Set system DateTime
JackB 0:04311b121ac4 1102 // secondsEpoch = mktime(t); // seconds since the Epoch
JackB 0:04311b121ac4 1103 // set_time(secondsEpoch);
JackB 0:04311b121ac4 1104 }
JackB 0:04311b121ac4 1105
JackB 0:04311b121ac4 1106 time_t MCP79412::getSecondsEpoch(void)
JackB 0:04311b121ac4 1107 {
JackB 0:04311b121ac4 1108 secondsEpoch = time(NULL);
JackB 0:04311b121ac4 1109 return secondsEpoch;
JackB 0:04311b121ac4 1110 }
JackB 0:04311b121ac4 1111
JackB 0:04311b121ac4 1112 void MCP79412::setSecondsEpoch(time_t t)
JackB 0:04311b121ac4 1113 {
JackB 0:04311b121ac4 1114 secondsEpoch = t;
JackB 0:04311b121ac4 1115 set_time(secondsEpoch);
JackB 0:04311b121ac4 1116 }
JackB 0:04311b121ac4 1117
JackB 0:04311b121ac4 1118 void MCP79412::getRtcDateTimeAsTm(void)
JackB 0:04311b121ac4 1119 {
JackB 0:04311b121ac4 1120 // Get RTC DateTime
JackB 0:04311b121ac4 1121 getRtcDateTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
JackB 0:04311b121ac4 1122
JackB 0:04311b121ac4 1123 // Convert to unix time structure
JackB 0:04311b121ac4 1124 t->tm_sec = second; // 0-59
JackB 0:04311b121ac4 1125 t->tm_min = minute; // 0-59
JackB 0:04311b121ac4 1126 t->tm_hour = hour; // 0-23
JackB 0:04311b121ac4 1127 t->tm_wday = dayOfWeek - 1; // 0-6 (0 = Sunday)
JackB 0:04311b121ac4 1128 t->tm_mday = dayOfMonth; // 1-31
JackB 0:04311b121ac4 1129 t->tm_mon = month - 1; // 0-11
JackB 0:04311b121ac4 1130 t->tm_year = year + 100; // 100-199 year since 1900
JackB 0:04311b121ac4 1131 t->tm_isdst = 0;
JackB 0:04311b121ac4 1132
JackB 0:04311b121ac4 1133 // Set system DateTime
JackB 0:04311b121ac4 1134 secondsEpoch = mktime(t); // seconds since the Epoch
JackB 0:04311b121ac4 1135 // time_t t = time(secondsEpoch);
JackB 0:04311b121ac4 1136
JackB 0:04311b121ac4 1137 // set_time(secondsEpoch);
JackB 0:04311b121ac4 1138 }
JackB 0:04311b121ac4 1139
JackB 0:04311b121ac4 1140 time_t MCP79412::convertDateTimeToTimestamp(
JackB 0:04311b121ac4 1141 uint8_t second, // 0-59
JackB 0:04311b121ac4 1142 uint8_t minute, // 0-59
JackB 0:04311b121ac4 1143 uint8_t hour, // 0-23
JackB 0:04311b121ac4 1144 uint8_t dayOfMonth, // 1-31
JackB 0:04311b121ac4 1145 uint8_t month, // 1-12
JackB 0:04311b121ac4 1146 uint8_t year) // 0-99 year since 2000
JackB 0:04311b121ac4 1147 {
JackB 0:04311b121ac4 1148 // setup time structure for Wed, 28 Oct 2009 11:35:37
JackB 0:04311b121ac4 1149 struct tm t;
JackB 0:04311b121ac4 1150 t.tm_sec = second; // 0-59
JackB 0:04311b121ac4 1151 t.tm_min = minute; // 0-59
JackB 0:04311b121ac4 1152 t.tm_hour = hour; // 0-23
JackB 0:04311b121ac4 1153 t.tm_mday = dayOfMonth; // 1-31
JackB 0:04311b121ac4 1154 t.tm_mon = month - 1; // 0-11
JackB 0:04311b121ac4 1155 t.tm_year = year + 100; // 100-199 year since 1900
JackB 0:04311b121ac4 1156
JackB 0:04311b121ac4 1157 // 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);
JackB 0:04311b121ac4 1158
JackB 0:04311b121ac4 1159 // convert to timestamp and display (1256729737)
JackB 0:04311b121ac4 1160 time_t seconds = mktime(&t);
JackB 0:04311b121ac4 1161 // printf("Time as seconds since January 1, 1970 = %d\n", seconds);
JackB 0:04311b121ac4 1162
JackB 0:04311b121ac4 1163 // char buffer[32];
JackB 0:04311b121ac4 1164 // strftime(buffer, 32, "%a %d-%m-%Y %H:%M:%S\n", localtime(&seconds));
JackB 0:04311b121ac4 1165 // printf("Time: %s", buffer);
JackB 0:04311b121ac4 1166
JackB 0:04311b121ac4 1167 // Get weekday Sunday as 0 (0-6) for RTC
JackB 0:04311b121ac4 1168 struct tm *t2;
JackB 0:04311b121ac4 1169 t2 = localtime(&seconds);
JackB 0:04311b121ac4 1170 // 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);
JackB 0:04311b121ac4 1171 // printf("Weekday %d\n", t2->tm_wday);
JackB 0:04311b121ac4 1172
JackB 0:04311b121ac4 1173 return seconds;
JackB 0:04311b121ac4 1174 }
JackB 0:04311b121ac4 1175
JackB 0:04311b121ac4 1176 uint8_t MCP79412::getWeekdayFromDate(uint8_t dayOfMonth, uint8_t month, uint8_t year) // year 0-99
JackB 0:04311b121ac4 1177 {
JackB 0:04311b121ac4 1178 // setup time structure for Wed, 28 Oct 2009 11:35:37
JackB 0:04311b121ac4 1179 struct tm t;
JackB 0:04311b121ac4 1180 t.tm_sec = 0; // 0-59
JackB 0:04311b121ac4 1181 t.tm_min = 0; // 0-59
JackB 0:04311b121ac4 1182 t.tm_hour = 0; // 0-23
JackB 0:04311b121ac4 1183 t.tm_mday = dayOfMonth; // 1-31
JackB 0:04311b121ac4 1184 t.tm_mon = month - 1; // 0-11
JackB 0:04311b121ac4 1185 t.tm_year = year + 100; // 100-199 year since 1900
JackB 0:04311b121ac4 1186
JackB 0:04311b121ac4 1187 // 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);
JackB 0:04311b121ac4 1188
JackB 0:04311b121ac4 1189 // convert to timestamp and display (1256729737)
JackB 0:04311b121ac4 1190 time_t seconds = mktime(&t);
JackB 0:04311b121ac4 1191 // printf("Time as seconds since January 1, 1970 = %d\n", seconds);
JackB 0:04311b121ac4 1192
JackB 0:04311b121ac4 1193 // char buffer[32];
JackB 0:04311b121ac4 1194 // strftime(buffer, 32, "%a %d-%m-%Y %H:%M:%S\n", localtime(&seconds));
JackB 0:04311b121ac4 1195 // printf("Time: %s", buffer);
JackB 0:04311b121ac4 1196
JackB 0:04311b121ac4 1197 // Get weekday Sunday as 0 (0-6) for RTC
JackB 0:04311b121ac4 1198 struct tm *t2;
JackB 0:04311b121ac4 1199 t2 = localtime(&seconds);
JackB 0:04311b121ac4 1200 // 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);
JackB 0:04311b121ac4 1201 // printf("Weekday %d\n", t2->tm_wday);
JackB 0:04311b121ac4 1202
JackB 0:04311b121ac4 1203 return t2->tm_wday;
JackB 0:04311b121ac4 1204 }
JackB 0:04311b121ac4 1205
JackB 0:04311b121ac4 1206
JackB 0:04311b121ac4 1207
JackB 0:04311b121ac4 1208
JackB 0:04311b121ac4 1209
JackB 0:04311b121ac4 1210
JackB 0:04311b121ac4 1211
JackB 0:04311b121ac4 1212
JackB 0:04311b121ac4 1213 //double MCP79412::clamp(double v)
JackB 0:04311b121ac4 1214 //{
JackB 0:04311b121ac4 1215 // const double t = v < 0.0f ? 0.0f : v;
JackB 0:04311b121ac4 1216 // return t > 1.0f ? 1.0f : t;
JackB 0:04311b121ac4 1217 //}
JackB 0:04311b121ac4 1218
JackB 0:04311b121ac4 1219
JackB 0:04311b121ac4 1220 //bool MCP79412::checkTimeLost(void)
JackB 0:04311b121ac4 1221 //{
JackB 0:04311b121ac4 1222 //// return (atoi(getFormatedDateTime("%Y")) <= 2015) ? true : false;
JackB 0:04311b121ac4 1223 // return false;
JackB 0:04311b121ac4 1224 //}
JackB 0:04311b121ac4 1225
JackB 0:04311b121ac4 1226 //
JackB 0:04311b121ac4 1227 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1228 // * Read the current time from the RTC and return it in a tmElements_t *
JackB 0:04311b121ac4 1229 // * structure. Returns false if RTC not present (I2C I/O error). *
JackB 0:04311b121ac4 1230 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1231 //boolean MCP79412RTC::read(tmElements_t &tm)
JackB 0:04311b121ac4 1232 //{
JackB 0:04311b121ac4 1233 // i2cBeginTransmission(RTC_ADDR);
JackB 0:04311b121ac4 1234 // i2cWrite((uint8_t)TIME_REG);
JackB 0:04311b121ac4 1235 // if (i2cEndTransmission() != 0) {
JackB 0:04311b121ac4 1236 // return false;
JackB 0:04311b121ac4 1237 // }
JackB 0:04311b121ac4 1238 // else {
JackB 0:04311b121ac4 1239 // //request 7 uint8_ts (secs, min, hr, dow, date, mth, yr)
JackB 0:04311b121ac4 1240 // i2cRequestFrom(RTC_ADDR, tmNbrFields);
JackB 0:04311b121ac4 1241 // tm.Second = bcd2dec(i2cRead() & ~_BV(ST));
JackB 0:04311b121ac4 1242 // tm.Minute = bcd2dec(i2cRead());
JackB 0:04311b121ac4 1243 // tm.Hour = bcd2dec(i2cRead() & ~_BV(HR1224)); //assumes 24hr clock
JackB 0:04311b121ac4 1244 // tm.Wday = i2cRead() & ~(_BV(OSCON) | _BV(VBAT) | _BV(VBATEN)); //mask off OSCON, VBAT, VBATEN bits
JackB 0:04311b121ac4 1245 // tm.Day = bcd2dec(i2cRead());
JackB 0:04311b121ac4 1246 // tm.Month = bcd2dec(i2cRead() & ~_BV(LP)); //mask off the leap year bit
JackB 0:04311b121ac4 1247 // tm.Year = y2kYearToTm(bcd2dec(i2cRead()));
JackB 0:04311b121ac4 1248 // return true;
JackB 0:04311b121ac4 1249 // }
JackB 0:04311b121ac4 1250 //}
JackB 0:04311b121ac4 1251 //
JackB 0:04311b121ac4 1252 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1253 // * Set the RTC's time from a tmElements_t structure. *
JackB 0:04311b121ac4 1254 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1255 //void MCP79412RTC::write(tmElements_t &tm)
JackB 0:04311b121ac4 1256 //{
JackB 0:04311b121ac4 1257 // i2cBeginTransmission(RTC_ADDR);
JackB 0:04311b121ac4 1258 // i2cWrite((uint8_t)TIME_REG);
JackB 0:04311b121ac4 1259 // i2cWrite((uint8_t)0x00); //stops the oscillator (Bit 7, ST == 0)
JackB 0:04311b121ac4 1260 // i2cWrite(dec2bcd(tm.Minute));
JackB 0:04311b121ac4 1261 // i2cWrite(dec2bcd(tm.Hour)); //sets 24 hour format (Bit 6 == 0)
JackB 0:04311b121ac4 1262 // i2cWrite(tm.Wday | _BV(VBATEN)); //enable battery backup operation
JackB 0:04311b121ac4 1263 // i2cWrite(dec2bcd(tm.Day));
JackB 0:04311b121ac4 1264 // i2cWrite(dec2bcd(tm.Month));
JackB 0:04311b121ac4 1265 // i2cWrite(dec2bcd(tmYearToY2k(tm.Year)));
JackB 0:04311b121ac4 1266 // i2cEndTransmission();
JackB 0:04311b121ac4 1267 //
JackB 0:04311b121ac4 1268 // i2cBeginTransmission(RTC_ADDR);
JackB 0:04311b121ac4 1269 // i2cWrite((uint8_t)TIME_REG);
JackB 0:04311b121ac4 1270 // i2cWrite(dec2bcd(tm.Second) | _BV(ST)); //set the seconds and start the oscillator (Bit 7, ST == 1)
JackB 0:04311b121ac4 1271 // i2cEndTransmission();
JackB 0:04311b121ac4 1272 //}
JackB 0:04311b121ac4 1273 //
JackB 0:04311b121ac4 1274 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1275 // * Write a single uint8_t to RTC RAM. *
JackB 0:04311b121ac4 1276 // * Valid address range is 0x00 - 0x5F, no checking. *
JackB 0:04311b121ac4 1277 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1278 //void MCP79412RTC::ramWrite(uint8_t addr, uint8_t value)
JackB 0:04311b121ac4 1279 //{
JackB 0:04311b121ac4 1280 // ramWrite(addr, &value, 1);
JackB 0:04311b121ac4 1281 //}
JackB 0:04311b121ac4 1282 //
JackB 0:04311b121ac4 1283 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1284 // * Write multiple uint8_ts to RTC RAM. *
JackB 0:04311b121ac4 1285 // * Valid address range is 0x00 - 0x5F, no checking. *
JackB 0:04311b121ac4 1286 // * Number of uint8_ts (nuint8_ts) must be between 1 and 31 (Wire library *
JackB 0:04311b121ac4 1287 // * limitation). *
JackB 0:04311b121ac4 1288 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1289 //void MCP79412RTC::ramWrite(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
JackB 0:04311b121ac4 1290 //{
JackB 0:04311b121ac4 1291 // i2cBeginTransmission(RTC_ADDR);
JackB 0:04311b121ac4 1292 // i2cWrite(addr);
JackB 0:04311b121ac4 1293 // for (uint8_t i=0; i<nuint8_ts; i++) i2cWrite(values[i]);
JackB 0:04311b121ac4 1294 // i2cEndTransmission();
JackB 0:04311b121ac4 1295 //}
JackB 0:04311b121ac4 1296 //
JackB 0:04311b121ac4 1297 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1298 // * Read a single uint8_t from RTC RAM. *
JackB 0:04311b121ac4 1299 // * Valid address range is 0x00 - 0x5F, no checking. *
JackB 0:04311b121ac4 1300 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1301 //uint8_t MCP79412RTC::ramRead(uint8_t addr)
JackB 0:04311b121ac4 1302 //{
JackB 0:04311b121ac4 1303 // uint8_t value;
JackB 0:04311b121ac4 1304 //
JackB 0:04311b121ac4 1305 // ramRead(addr, &value, 1);
JackB 0:04311b121ac4 1306 // return value;
JackB 0:04311b121ac4 1307 //}
JackB 0:04311b121ac4 1308 //
JackB 0:04311b121ac4 1309 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1310 // * Read multiple uint8_ts from RTC RAM. *
JackB 0:04311b121ac4 1311 // * Valid address range is 0x00 - 0x5F, no checking. *
JackB 0:04311b121ac4 1312 // * Number of uint8_ts (nuint8_ts) must be between 1 and 32 (Wire library *
JackB 0:04311b121ac4 1313 // * limitation). *
JackB 0:04311b121ac4 1314 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1315 //void MCP79412RTC::ramRead(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
JackB 0:04311b121ac4 1316 //{
JackB 0:04311b121ac4 1317 // i2cBeginTransmission(RTC_ADDR);
JackB 0:04311b121ac4 1318 // i2cWrite(addr);
JackB 0:04311b121ac4 1319 // i2cEndTransmission();
JackB 0:04311b121ac4 1320 // i2cRequestFrom( (uint8_t)RTC_ADDR, nuint8_ts );
JackB 0:04311b121ac4 1321 // for (uint8_t i=0; i<nuint8_ts; i++) values[i] = i2cRead();
JackB 0:04311b121ac4 1322 //}
JackB 0:04311b121ac4 1323 //
JackB 0:04311b121ac4 1324 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1325 // * Write a single uint8_t to Static RAM. *
JackB 0:04311b121ac4 1326 // * Address (addr) is constrained to the range (0, 63). *
JackB 0:04311b121ac4 1327 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1328 //void MCP79412RTC::sramWrite(uint8_t addr, uint8_t value)
JackB 0:04311b121ac4 1329 //{
JackB 0:04311b121ac4 1330 // ramWrite( (addr & (SRAM_SIZE - 1) ) + SRAM_START_ADDR, &value, 1 );
JackB 0:04311b121ac4 1331 //}
JackB 0:04311b121ac4 1332 //
JackB 0:04311b121ac4 1333 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1334 // * Write multiple uint8_ts to Static RAM. *
JackB 0:04311b121ac4 1335 // * Address (addr) is constrained to the range (0, 63). *
JackB 0:04311b121ac4 1336 // * Number of uint8_ts (nuint8_ts) must be between 1 and 31 (Wire library *
JackB 0:04311b121ac4 1337 // * limitation). *
JackB 0:04311b121ac4 1338 // * Invalid values for nuint8_ts, or combinations of addr and nuint8_ts *
JackB 0:04311b121ac4 1339 // * that would result in addressing past the last uint8_t of SRAM will *
JackB 0:04311b121ac4 1340 // * result in no action. *
JackB 0:04311b121ac4 1341 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1342 //void MCP79412RTC::sramWrite(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
JackB 0:04311b121ac4 1343 //{
JackB 0:04311b121ac4 1344 //#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
JackB 0:04311b121ac4 1345 // if (nuint8_ts >= 1 && (addr + nuint8_ts) <= SRAM_SIZE) {
JackB 0:04311b121ac4 1346 //#else
JackB 0:04311b121ac4 1347 // if (nuint8_ts >= 1 && nuint8_ts <= (BUFFER_LENGTH - 1) && (addr + nuint8_ts) <= SRAM_SIZE) {
JackB 0:04311b121ac4 1348 //#endif
JackB 0:04311b121ac4 1349 // ramWrite( (addr & (SRAM_SIZE - 1) ) + SRAM_START_ADDR, values, nuint8_ts );
JackB 0:04311b121ac4 1350 // }
JackB 0:04311b121ac4 1351 //}
JackB 0:04311b121ac4 1352 //
JackB 0:04311b121ac4 1353 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1354 // * Read a single uint8_t from Static RAM. *
JackB 0:04311b121ac4 1355 // * Address (addr) is constrained to the range (0, 63). *
JackB 0:04311b121ac4 1356 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1357 //uint8_t MCP79412RTC::sramRead(uint8_t addr)
JackB 0:04311b121ac4 1358 //{
JackB 0:04311b121ac4 1359 // uint8_t value;
JackB 0:04311b121ac4 1360 //
JackB 0:04311b121ac4 1361 // ramRead( (addr & (SRAM_SIZE - 1) ) + SRAM_START_ADDR, &value, 1 );
JackB 0:04311b121ac4 1362 // return value;
JackB 0:04311b121ac4 1363 //}
JackB 0:04311b121ac4 1364 //
JackB 0:04311b121ac4 1365 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1366 // * Read multiple uint8_ts from Static RAM. *
JackB 0:04311b121ac4 1367 // * Address (addr) is constrained to the range (0, 63). *
JackB 0:04311b121ac4 1368 // * Number of uint8_ts (nuint8_ts) must be between 1 and 32 (Wire library *
JackB 0:04311b121ac4 1369 // * limitation). *
JackB 0:04311b121ac4 1370 // * Invalid values for nuint8_ts, or combinations of addr and *
JackB 0:04311b121ac4 1371 // * nuint8_ts that would result in addressing past the last uint8_t of SRAM *
JackB 0:04311b121ac4 1372 // * result in no action. *
JackB 0:04311b121ac4 1373 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1374 //void MCP79412RTC::sramRead(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
JackB 0:04311b121ac4 1375 //{
JackB 0:04311b121ac4 1376 //#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
JackB 0:04311b121ac4 1377 // if (nuint8_ts >= 1 && (addr + nuint8_ts) <= SRAM_SIZE) {
JackB 0:04311b121ac4 1378 //#else
JackB 0:04311b121ac4 1379 // if (nuint8_ts >= 1 && nuint8_ts <= BUFFER_LENGTH && (addr + nuint8_ts) <= SRAM_SIZE) {
JackB 0:04311b121ac4 1380 //#endif
JackB 0:04311b121ac4 1381 // ramRead((addr & (SRAM_SIZE - 1) ) + SRAM_START_ADDR, values, nuint8_ts);
JackB 0:04311b121ac4 1382 // }
JackB 0:04311b121ac4 1383 //}
JackB 0:04311b121ac4 1384 //
JackB 0:04311b121ac4 1385 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1386 // * Write a single uint8_t to EEPROM. *
JackB 0:04311b121ac4 1387 // * Address (addr) is constrained to the range (0, 127). *
JackB 0:04311b121ac4 1388 // * Can't leverage page write function because a write can't start *
JackB 0:04311b121ac4 1389 // * mid-page. *
JackB 0:04311b121ac4 1390 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1391 //void MCP79412RTC::eepromWrite(uint8_t addr, uint8_t value)
JackB 0:04311b121ac4 1392 //{
JackB 0:04311b121ac4 1393 // i2cBeginTransmission(MCP79412_EEPROM_ADDR);
JackB 0:04311b121ac4 1394 // i2cWrite( addr & (EEPROM_SIZE - 1) );
JackB 0:04311b121ac4 1395 // i2cWrite(value);
JackB 0:04311b121ac4 1396 // i2cEndTransmission();
JackB 0:04311b121ac4 1397 // eepromWait();
JackB 0:04311b121ac4 1398 //}
JackB 0:04311b121ac4 1399 //
JackB 0:04311b121ac4 1400 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1401 // * Write a page (or less) to EEPROM. An EEPROM page is 8 uint8_ts. *
JackB 0:04311b121ac4 1402 // * Address (addr) should be a page start address (0, 8, ..., 120), but *
JackB 0:04311b121ac4 1403 // * is ruthlessly coerced into a valid value. *
JackB 0:04311b121ac4 1404 // * Number of uint8_ts (nuint8_ts) must be between 1 and 8, other values *
JackB 0:04311b121ac4 1405 // * result in no action. *
JackB 0:04311b121ac4 1406 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1407 //void MCP79412RTC::eepromWrite(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
JackB 0:04311b121ac4 1408 //{
JackB 0:04311b121ac4 1409 // if (nuint8_ts >= 1 && nuint8_ts <= EEPROM_PAGE_SIZE) {
JackB 0:04311b121ac4 1410 // i2cBeginTransmission(MCP79412_EEPROM_ADDR);
JackB 0:04311b121ac4 1411 // i2cWrite( addr & ~(EEPROM_PAGE_SIZE - 1) & (EEPROM_SIZE - 1) );
JackB 0:04311b121ac4 1412 // for (uint8_t i=0; i<nuint8_ts; i++) i2cWrite(values[i]);
JackB 0:04311b121ac4 1413 // i2cEndTransmission();
JackB 0:04311b121ac4 1414 // eepromWait();
JackB 0:04311b121ac4 1415 // }
JackB 0:04311b121ac4 1416 //}
JackB 0:04311b121ac4 1417 //
JackB 0:04311b121ac4 1418 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1419 // * Read a single uint8_t from EEPROM. *
JackB 0:04311b121ac4 1420 // * Address (addr) is constrained to the range (0, 127). *
JackB 0:04311b121ac4 1421 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1422 //uint8_t MCP79412RTC::eepromRead(uint8_t addr)
JackB 0:04311b121ac4 1423 //{
JackB 0:04311b121ac4 1424 // uint8_t value;
JackB 0:04311b121ac4 1425 //
JackB 0:04311b121ac4 1426 // eepromRead( addr & (EEPROM_SIZE - 1), &value, 1 );
JackB 0:04311b121ac4 1427 // return value;
JackB 0:04311b121ac4 1428 //}
JackB 0:04311b121ac4 1429 //
JackB 0:04311b121ac4 1430 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1431 // * Read multiple uint8_ts from EEPROM. *
JackB 0:04311b121ac4 1432 // * Address (addr) is constrained to the range (0, 127). *
JackB 0:04311b121ac4 1433 // * Number of uint8_ts (nuint8_ts) must be between 1 and 32 (Wire library *
JackB 0:04311b121ac4 1434 // * limitation). *
JackB 0:04311b121ac4 1435 // * Invalid values for addr or nuint8_ts, or combinations of addr and *
JackB 0:04311b121ac4 1436 // * nuint8_ts that would result in addressing past the last uint8_t of EEPROM *
JackB 0:04311b121ac4 1437 // * result in no action. *
JackB 0:04311b121ac4 1438 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1439 //void MCP79412RTC::eepromRead(uint8_t addr, uint8_t *values, uint8_t nuint8_ts)
JackB 0:04311b121ac4 1440 //{
JackB 0:04311b121ac4 1441 //#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
JackB 0:04311b121ac4 1442 // if (nuint8_ts >= 1 && (addr + nuint8_ts) <= EEPROM_SIZE) {
JackB 0:04311b121ac4 1443 //#else
JackB 0:04311b121ac4 1444 // if (nuint8_ts >= 1 && nuint8_ts <= BUFFER_LENGTH && (addr + nuint8_ts) <= EEPROM_SIZE) {
JackB 0:04311b121ac4 1445 //#endif
JackB 0:04311b121ac4 1446 // i2cBeginTransmission(MCP79412_EEPROM_ADDR);
JackB 0:04311b121ac4 1447 // i2cWrite( addr & (EEPROM_SIZE - 1) );
JackB 0:04311b121ac4 1448 // i2cEndTransmission();
JackB 0:04311b121ac4 1449 // i2cRequestFrom( (uint8_t)MCP79412_EEPROM_ADDR, nuint8_ts );
JackB 0:04311b121ac4 1450 // for (uint8_t i=0; i<nuint8_ts; i++) values[i] = i2cRead();
JackB 0:04311b121ac4 1451 // }
JackB 0:04311b121ac4 1452 //}
JackB 0:04311b121ac4 1453 //
JackB 0:04311b121ac4 1454 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1455 // * Wait for EEPROM write to complete. *
JackB 0:04311b121ac4 1456 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1457 //uint8_t MCP79412RTC::eepromWait(void)
JackB 0:04311b121ac4 1458 //{
JackB 0:04311b121ac4 1459 // uint8_t waitCount = 0;
JackB 0:04311b121ac4 1460 // uint8_t txStatus;
JackB 0:04311b121ac4 1461 //
JackB 0:04311b121ac4 1462 // do
JackB 0:04311b121ac4 1463 // {
JackB 0:04311b121ac4 1464 // ++waitCount;
JackB 0:04311b121ac4 1465 // i2cBeginTransmission(MCP79412_EEPROM_ADDR);
JackB 0:04311b121ac4 1466 // i2cWrite((uint8_t)0);
JackB 0:04311b121ac4 1467 // txStatus = i2cEndTransmission();
JackB 0:04311b121ac4 1468 //
JackB 0:04311b121ac4 1469 // } while (txStatus != 0);
JackB 0:04311b121ac4 1470 //
JackB 0:04311b121ac4 1471 // return waitCount;
JackB 0:04311b121ac4 1472 //}
JackB 0:04311b121ac4 1473 //
JackB 0:04311b121ac4 1474 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1475 // * Read the calibration register. *
JackB 0:04311b121ac4 1476 // * The calibration value is not a twos-complement number. The MSB is *
JackB 0:04311b121ac4 1477 // * the sign bit, and the 7 LSBs are an unsigned number, so we convert *
JackB 0:04311b121ac4 1478 // * it and return it to the caller as a regular twos-complement integer. *
JackB 0:04311b121ac4 1479 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1480 //int MCP79412RTC::calibRead(void)
JackB 0:04311b121ac4 1481 //{
JackB 0:04311b121ac4 1482 // uint8_t val = ramRead(CALIB_REG);
JackB 0:04311b121ac4 1483 //
JackB 0:04311b121ac4 1484 // if ( val & 0x80 ) return -(val & 0x7F);
JackB 0:04311b121ac4 1485 // else return val;
JackB 0:04311b121ac4 1486 //}
JackB 0:04311b121ac4 1487 //
JackB 0:04311b121ac4 1488 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1489 // * Write the calibration register. *
JackB 0:04311b121ac4 1490 // * Calibration value must be between -127 and 127, others result *
JackB 0:04311b121ac4 1491 // * in no action. See note above on the format of the calibration value. *
JackB 0:04311b121ac4 1492 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1493 //void MCP79412RTC::calibWrite(int value)
JackB 0:04311b121ac4 1494 //{
JackB 0:04311b121ac4 1495 // uint8_t calibVal;
JackB 0:04311b121ac4 1496 //
JackB 0:04311b121ac4 1497 // if (value >= -127 && value <= 127) {
JackB 0:04311b121ac4 1498 // calibVal = abs(value);
JackB 0:04311b121ac4 1499 // if (value < 0) calibVal += 128;
JackB 0:04311b121ac4 1500 // ramWrite(CALIB_REG, calibVal);
JackB 0:04311b121ac4 1501 // }
JackB 0:04311b121ac4 1502 //}
JackB 0:04311b121ac4 1503 //
JackB 0:04311b121ac4 1504 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1505 // * Read the unique ID. *
JackB 0:04311b121ac4 1506 // * For the MCP79411 (EUI-48), the first two uint8_ts will contain 0xFF. *
JackB 0:04311b121ac4 1507 // * Caller must provide an 8-uint8_t array to contain the results. *
JackB 0:04311b121ac4 1508 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1509 //void MCP79412RTC::idRead(uint8_t *uniqueID)
JackB 0:04311b121ac4 1510 //{
JackB 0:04311b121ac4 1511 // i2cBeginTransmission(MCP79412_EEPROM_ADDR);
JackB 0:04311b121ac4 1512 // i2cWrite(UNIQUE_ID_ADDR);
JackB 0:04311b121ac4 1513 // i2cEndTransmission();
JackB 0:04311b121ac4 1514 // i2cRequestFrom( MCP79412_EEPROM_ADDR, UNIQUE_ID_SIZE );
JackB 0:04311b121ac4 1515 // for (uint8_t i=0; i<UNIQUE_ID_SIZE; i++) uniqueID[i] = i2cRead();
JackB 0:04311b121ac4 1516 //}
JackB 0:04311b121ac4 1517 //
JackB 0:04311b121ac4 1518 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1519 // * Returns an EUI-64 ID. For an MCP79411, the EUI-48 ID is converted to *
JackB 0:04311b121ac4 1520 // * EUI-64. For an MCP79412, calling this function is equivalent to *
JackB 0:04311b121ac4 1521 // * calling idRead(). For an MCP79412, if the RTC type is known, calling *
JackB 0:04311b121ac4 1522 // * idRead() will be a bit more efficient. *
JackB 0:04311b121ac4 1523 // * Caller must provide an 8-uint8_t array to contain the results. *
JackB 0:04311b121ac4 1524 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1525 //void MCP79412RTC::getEUI64(uint8_t *uniqueID)
JackB 0:04311b121ac4 1526 //{
JackB 0:04311b121ac4 1527 // uint8_t rtcID[8];
JackB 0:04311b121ac4 1528 //
JackB 0:04311b121ac4 1529 // idRead(rtcID);
JackB 0:04311b121ac4 1530 // if (rtcID[0] == 0xFF && rtcID[1] == 0xFF) {
JackB 0:04311b121ac4 1531 // rtcID[0] = rtcID[2];
JackB 0:04311b121ac4 1532 // rtcID[1] = rtcID[3];
JackB 0:04311b121ac4 1533 // rtcID[2] = rtcID[4];
JackB 0:04311b121ac4 1534 // rtcID[3] = 0xFF;
JackB 0:04311b121ac4 1535 // rtcID[4] = 0xFE;
JackB 0:04311b121ac4 1536 // }
JackB 0:04311b121ac4 1537 // for (uint8_t i=0; i<UNIQUE_ID_SIZE; i++) uniqueID[i] = rtcID[i];
JackB 0:04311b121ac4 1538 //}
JackB 0:04311b121ac4 1539 //
JackB 0:04311b121ac4 1540 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1541 // * Check to see if a power failure has occurred. If so, returns TRUE *
JackB 0:04311b121ac4 1542 // * as the function value, and returns the power down and power up *
JackB 0:04311b121ac4 1543 // * timestamps. After returning the time stamps, the RTC's timestamp *
JackB 0:04311b121ac4 1544 // * registers are cleared and the VBAT bit which indicates a power *
JackB 0:04311b121ac4 1545 // * failure is reset. *
JackB 0:04311b121ac4 1546 // * *
JackB 0:04311b121ac4 1547 // * Note that the power down and power up timestamp registers do not *
JackB 0:04311b121ac4 1548 // * contain values for seconds or for the year. The returned time stamps *
JackB 0:04311b121ac4 1549 // * will therefore contain the current year from the RTC. However, there *
JackB 0:04311b121ac4 1550 // * is a chance that a power outage spans from one year to the next. *
JackB 0:04311b121ac4 1551 // * If we find the power down timestamp to be later (larger) than the *
JackB 0:04311b121ac4 1552 // * power up timestamp, we will assume this has happened, and well *
JackB 0:04311b121ac4 1553 // * subtract one year from the power down timestamp. *
JackB 0:04311b121ac4 1554 // * *
JackB 0:04311b121ac4 1555 // * Still, there is an assumption that the timestamps are being read *
JackB 0:04311b121ac4 1556 // * in the same year as that when the power up occurred. *
JackB 0:04311b121ac4 1557 // * *
JackB 0:04311b121ac4 1558 // * Finally, note that once the RTC records a power outage, it must be *
JackB 0:04311b121ac4 1559 // * cleared before another will be recorded. *
JackB 0:04311b121ac4 1560 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1561 //boolean MCP79412RTC::powerFail(time_t *powerDown, time_t *powerUp)
JackB 0:04311b121ac4 1562 //{
JackB 0:04311b121ac4 1563 // uint8_t day, yr; //copies of the RTC Day and Year registers
JackB 0:04311b121ac4 1564 // tmElements_t dn, up; //power down and power up times
JackB 0:04311b121ac4 1565 //
JackB 0:04311b121ac4 1566 // ramRead(DAY_REG, &day, 1);
JackB 0:04311b121ac4 1567 // ramRead(YEAR_REG, &yr, 1);
JackB 0:04311b121ac4 1568 // yr = y2kYearToTm(bcd2dec(yr));
JackB 0:04311b121ac4 1569 // if ( day & _BV(VBAT) ) {
JackB 0:04311b121ac4 1570 // i2cBeginTransmission(RTC_ADDR);
JackB 0:04311b121ac4 1571 // i2cWrite(PWRDWN_TS_REG);
JackB 0:04311b121ac4 1572 // i2cEndTransmission();
JackB 0:04311b121ac4 1573 //
JackB 0:04311b121ac4 1574 // i2cRequestFrom(RTC_ADDR, TIMESTAMP_SIZE); //read both timestamp registers, 8 uint8_ts total
JackB 0:04311b121ac4 1575 // dn.Second = 0;
JackB 0:04311b121ac4 1576 // dn.Minute = bcd2dec(i2cRead());
JackB 0:04311b121ac4 1577 // dn.Hour = bcd2dec(i2cRead() & ~_BV(HR1224)); //assumes 24hr clock
JackB 0:04311b121ac4 1578 // dn.Day = bcd2dec(i2cRead());
JackB 0:04311b121ac4 1579 // dn.Month = bcd2dec(i2cRead() & 0x1F); //mask off the day, we don't need it
JackB 0:04311b121ac4 1580 // dn.Year = yr; //assume current year
JackB 0:04311b121ac4 1581 // up.Second = 0;
JackB 0:04311b121ac4 1582 // up.Minute = bcd2dec(i2cRead());
JackB 0:04311b121ac4 1583 // up.Hour = bcd2dec(i2cRead() & ~_BV(HR1224)); //assumes 24hr clock
JackB 0:04311b121ac4 1584 // up.Day = bcd2dec(i2cRead());
JackB 0:04311b121ac4 1585 // up.Month = bcd2dec(i2cRead() & 0x1F); //mask off the day, we don't need it
JackB 0:04311b121ac4 1586 // up.Year = yr; //assume current year
JackB 0:04311b121ac4 1587 //
JackB 0:04311b121ac4 1588 // *powerDown = makeTime(dn);
JackB 0:04311b121ac4 1589 // *powerUp = makeTime(up);
JackB 0:04311b121ac4 1590 //
JackB 0:04311b121ac4 1591 // //clear the VBAT bit, which causes the RTC hardware to clear the timestamps too.
JackB 0:04311b121ac4 1592 // //I suppose there is a risk here that the day has changed since we read it,
JackB 0:04311b121ac4 1593 // //but the Day of Week is actually redundant data and the makeTime() function
JackB 0:04311b121ac4 1594 // //does not use it. This could be an issue if someone is reading the RTC
JackB 0:04311b121ac4 1595 // //registers directly, but as this library is meant to be used with the Time library,
JackB 0:04311b121ac4 1596 // //and also because we don't provide a method to read the RTC clock/calendar
JackB 0:04311b121ac4 1597 // //registers directly, we won't lose any sleep about it at this point unless
JackB 0:04311b121ac4 1598 // //some issue is actually brought to our attention ;-)
JackB 0:04311b121ac4 1599 // day &= ~_BV(VBAT);
JackB 0:04311b121ac4 1600 // ramWrite(DAY_REG, &day , 1);
JackB 0:04311b121ac4 1601 //
JackB 0:04311b121ac4 1602 // //adjust the powerDown timestamp if needed (see notes above)
JackB 0:04311b121ac4 1603 // if (*powerDown > *powerUp) {
JackB 0:04311b121ac4 1604 // --dn.Year;
JackB 0:04311b121ac4 1605 // *powerDown = makeTime(dn);
JackB 0:04311b121ac4 1606 // }
JackB 0:04311b121ac4 1607 // return true;
JackB 0:04311b121ac4 1608 // }
JackB 0:04311b121ac4 1609 // else
JackB 0:04311b121ac4 1610 // return false;
JackB 0:04311b121ac4 1611 //}
JackB 0:04311b121ac4 1612 //
JackB 0:04311b121ac4 1613 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1614 // * Enable or disable the square wave output. *
JackB 0:04311b121ac4 1615 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1616 //void MCP79412RTC::squareWave(uint8_t freq)
JackB 0:04311b121ac4 1617 //{
JackB 0:04311b121ac4 1618 // uint8_t ctrlReg;
JackB 0:04311b121ac4 1619 //
JackB 0:04311b121ac4 1620 // ramRead(CTRL_REG, &ctrlReg, 1);
JackB 0:04311b121ac4 1621 // if (freq > 3) {
JackB 0:04311b121ac4 1622 // ctrlReg &= ~_BV(SQWE);
JackB 0:04311b121ac4 1623 // }
JackB 0:04311b121ac4 1624 // else {
JackB 0:04311b121ac4 1625 // ctrlReg = (ctrlReg & 0xF8) | _BV(SQWE) | freq;
JackB 0:04311b121ac4 1626 // }
JackB 0:04311b121ac4 1627 // ramWrite(CTRL_REG, &ctrlReg, 1);
JackB 0:04311b121ac4 1628 //}
JackB 0:04311b121ac4 1629 //
JackB 0:04311b121ac4 1630 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1631 // * Set an alarm time. Sets the alarm registers only, does not enable *
JackB 0:04311b121ac4 1632 // * the alarm. See enableAlarm(). *
JackB 0:04311b121ac4 1633 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1634 //void MCP79412RTC::setAlarm(uint8_t alarmNumber, time_t alarmTime)
JackB 0:04311b121ac4 1635 //{
JackB 0:04311b121ac4 1636 // tmElements_t tm;
JackB 0:04311b121ac4 1637 // uint8_t day; //need to preserve bits in the day (of week) register
JackB 0:04311b121ac4 1638 //
JackB 0:04311b121ac4 1639 // alarmNumber &= 0x01; //ensure a valid alarm number
JackB 0:04311b121ac4 1640 // ramRead( ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG) , &day, 1);
JackB 0:04311b121ac4 1641 // breakTime(alarmTime, tm);
JackB 0:04311b121ac4 1642 // i2cBeginTransmission(RTC_ADDR);
JackB 0:04311b121ac4 1643 // i2cWrite( ALM0_REG + alarmNumber * (ALM1_REG - ALM0_REG) );
JackB 0:04311b121ac4 1644 // i2cWrite(dec2bcd(tm.Second));
JackB 0:04311b121ac4 1645 // i2cWrite(dec2bcd(tm.Minute));
JackB 0:04311b121ac4 1646 // i2cWrite(dec2bcd(tm.Hour)); //sets 24 hour format (Bit 6 == 0)
JackB 0:04311b121ac4 1647 // i2cWrite( (day & 0xF8) + tm.Wday );
JackB 0:04311b121ac4 1648 // i2cWrite(dec2bcd(tm.Day));
JackB 0:04311b121ac4 1649 // i2cWrite(dec2bcd(tm.Month));
JackB 0:04311b121ac4 1650 // i2cEndTransmission();
JackB 0:04311b121ac4 1651 //}
JackB 0:04311b121ac4 1652 //
JackB 0:04311b121ac4 1653 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1654 // * Enable or disable an alarm, and set the trigger criteria, *
JackB 0:04311b121ac4 1655 // * e.g. match only seconds, only minutes, entire time and date, etc. *
JackB 0:04311b121ac4 1656 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1657 //void MCP79412RTC::enableAlarm(uint8_t alarmNumber, uint8_t alarmType)
JackB 0:04311b121ac4 1658 //{
JackB 0:04311b121ac4 1659 // uint8_t day; //alarm day register has config & flag bits
JackB 0:04311b121ac4 1660 // uint8_t ctrl; //control register has alarm enable bits
JackB 0:04311b121ac4 1661 //
JackB 0:04311b121ac4 1662 // alarmNumber &= 0x01; //ensure a valid alarm number
JackB 0:04311b121ac4 1663 // ramRead(CTRL_REG, &ctrl, 1);
JackB 0:04311b121ac4 1664 // if (alarmType < ALM_DISABLE) {
JackB 0:04311b121ac4 1665 // ramRead(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
JackB 0:04311b121ac4 1666 // day = ( day & 0x87 ) | alarmType << 4; //reset interrupt flag, OR in the config bits
JackB 0:04311b121ac4 1667 // ramWrite(ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
JackB 0:04311b121ac4 1668 // ctrl |= _BV(ALM0 + alarmNumber); //enable the alarm
JackB 0:04311b121ac4 1669 // }
JackB 0:04311b121ac4 1670 // else {
JackB 0:04311b121ac4 1671 // ctrl &= ~(_BV(ALM0 + alarmNumber)); //disable the alarm
JackB 0:04311b121ac4 1672 // }
JackB 0:04311b121ac4 1673 // ramWrite(CTRL_REG, &ctrl, 1);
JackB 0:04311b121ac4 1674 //}
JackB 0:04311b121ac4 1675 //
JackB 0:04311b121ac4 1676 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1677 // * Returns true or false depending on whether the given alarm has been *
JackB 0:04311b121ac4 1678 // * triggered, and resets the alarm "interrupt" flag. This is not a real *
JackB 0:04311b121ac4 1679 // * interrupt, just a bit that's set when an alarm is triggered. *
JackB 0:04311b121ac4 1680 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1681 //boolean MCP79412RTC::alarm(uint8_t alarmNumber)
JackB 0:04311b121ac4 1682 //{
JackB 0:04311b121ac4 1683 // uint8_t day; //alarm day register has config & flag bits
JackB 0:04311b121ac4 1684 //
JackB 0:04311b121ac4 1685 // alarmNumber &= 0x01; //ensure a valid alarm number
JackB 0:04311b121ac4 1686 // ramRead( ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
JackB 0:04311b121ac4 1687 // if (day & _BV(ALMIF)) {
JackB 0:04311b121ac4 1688 // day &= ~_BV(ALMIF); //turn off the alarm "interrupt" flag
JackB 0:04311b121ac4 1689 // ramWrite( ALM0_DAY + alarmNumber * (ALM1_REG - ALM0_REG), &day, 1);
JackB 0:04311b121ac4 1690 // return true;
JackB 0:04311b121ac4 1691 // }
JackB 0:04311b121ac4 1692 // else
JackB 0:04311b121ac4 1693 // return false;
JackB 0:04311b121ac4 1694 //}
JackB 0:04311b121ac4 1695 //
JackB 0:04311b121ac4 1696 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1697 // * Sets the logic level on the MFP when it's not being used as a *
JackB 0:04311b121ac4 1698 // * square wave or alarm output. The default is HIGH. *
JackB 0:04311b121ac4 1699 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1700 //void MCP79412RTC::out(boolean level)
JackB 0:04311b121ac4 1701 //{
JackB 0:04311b121ac4 1702 // uint8_t ctrlReg;
JackB 0:04311b121ac4 1703 //
JackB 0:04311b121ac4 1704 // ramRead(CTRL_REG, &ctrlReg, 1);
JackB 0:04311b121ac4 1705 // if (level)
JackB 0:04311b121ac4 1706 // ctrlReg |= _BV(OUT);
JackB 0:04311b121ac4 1707 // else
JackB 0:04311b121ac4 1708 // ctrlReg &= ~_BV(OUT);
JackB 0:04311b121ac4 1709 // ramWrite(CTRL_REG, &ctrlReg, 1);
JackB 0:04311b121ac4 1710 //}
JackB 0:04311b121ac4 1711 //
JackB 0:04311b121ac4 1712 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1713 // * Specifies the logic level on the Multi-Function Pin (MFP) when an *
JackB 0:04311b121ac4 1714 // * alarm is triggered. The default is LOW. When both alarms are *
JackB 0:04311b121ac4 1715 // * active, the two are ORed together to determine the level of the MFP. *
JackB 0:04311b121ac4 1716 // * With alarm polarity set to LOW (the default), this causes the MFP *
JackB 0:04311b121ac4 1717 // * to go low only when BOTH alarms are triggered. With alarm polarity *
JackB 0:04311b121ac4 1718 // * set to HIGH, the MFP will go high when EITHER alarm is triggered. *
JackB 0:04311b121ac4 1719 // * *
JackB 0:04311b121ac4 1720 // * Note that the state of the MFP is independent of the alarm *
JackB 0:04311b121ac4 1721 // * "interrupt" flags, and the alarm() function will indicate when an *
JackB 0:04311b121ac4 1722 // * alarm is triggered regardless of the polarity. *
JackB 0:04311b121ac4 1723 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1724 //void MCP79412RTC::alarmPolarity(boolean polarity)
JackB 0:04311b121ac4 1725 //{
JackB 0:04311b121ac4 1726 // uint8_t alm0Day;
JackB 0:04311b121ac4 1727 //
JackB 0:04311b121ac4 1728 // ramRead(ALM0_DAY, &alm0Day, 1);
JackB 0:04311b121ac4 1729 // if (polarity)
JackB 0:04311b121ac4 1730 // alm0Day |= _BV(OUT);
JackB 0:04311b121ac4 1731 // else
JackB 0:04311b121ac4 1732 // alm0Day &= ~_BV(OUT);
JackB 0:04311b121ac4 1733 // ramWrite(ALM0_DAY, &alm0Day, 1);
JackB 0:04311b121ac4 1734 //}
JackB 0:04311b121ac4 1735 //
JackB 0:04311b121ac4 1736 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1737 // * Check to see if the RTC's oscillator is started (ST bit in seconds *
JackB 0:04311b121ac4 1738 // * register). Returns true if started. *
JackB 0:04311b121ac4 1739 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1740 //boolean MCP79412RTC::isRunning(void)
JackB 0:04311b121ac4 1741 //{
JackB 0:04311b121ac4 1742 // i2cBeginTransmission(RTC_ADDR);
JackB 0:04311b121ac4 1743 // i2cWrite((uint8_t)TIME_REG);
JackB 0:04311b121ac4 1744 // i2cEndTransmission();
JackB 0:04311b121ac4 1745 //
JackB 0:04311b121ac4 1746 // //request just the seconds register
JackB 0:04311b121ac4 1747 // i2cRequestFrom(RTC_ADDR, 1);
JackB 0:04311b121ac4 1748 // return i2cRead() & _BV(ST);
JackB 0:04311b121ac4 1749 //}
JackB 0:04311b121ac4 1750 //
JackB 0:04311b121ac4 1751 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1752 // * Set or clear the VBATEN bit. Setting the bit powers the clock and *
JackB 0:04311b121ac4 1753 // * SRAM from the backup battery when Vcc falls. Note that setting the *
JackB 0:04311b121ac4 1754 // * time via set() or write() sets the VBATEN bit. *
JackB 0:04311b121ac4 1755 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1756 //void MCP79412RTC::vbaten(boolean enable)
JackB 0:04311b121ac4 1757 //{
JackB 0:04311b121ac4 1758 // uint8_t day;
JackB 0:04311b121ac4 1759 //
JackB 0:04311b121ac4 1760 // ramRead(DAY_REG, &day, 1);
JackB 0:04311b121ac4 1761 // if (enable)
JackB 0:04311b121ac4 1762 // day |= _BV(VBATEN);
JackB 0:04311b121ac4 1763 // else
JackB 0:04311b121ac4 1764 // day &= ~_BV(VBATEN);
JackB 0:04311b121ac4 1765 //
JackB 0:04311b121ac4 1766 // ramWrite(DAY_REG, &day, 1);
JackB 0:04311b121ac4 1767 // return;
JackB 0:04311b121ac4 1768 //}
JackB 0:04311b121ac4 1769
JackB 0:04311b121ac4 1770 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1771 // * Decimal-to-BCD conversion *
JackB 0:04311b121ac4 1772 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1773 //uint8_t MCP79412RTC::dec2bcd(uint8_t n)
JackB 0:04311b121ac4 1774 //{
JackB 0:04311b121ac4 1775 // return n + 6 * (n / 10);
JackB 0:04311b121ac4 1776 //}
JackB 0:04311b121ac4 1777 //
JackB 0:04311b121ac4 1778 ///*----------------------------------------------------------------------*
JackB 0:04311b121ac4 1779 // * BCD-to-Decimal conversion *
JackB 0:04311b121ac4 1780 // *----------------------------------------------------------------------*/
JackB 0:04311b121ac4 1781 //uint8_t __attribute__ ((noinline)) MCP79412RTC::bcd2dec(uint8_t n)
JackB 0:04311b121ac4 1782 //{
JackB 0:04311b121ac4 1783 // return n - 6 * (n >> 4);
JackB 0:04311b121ac4 1784 //}
JackB 0:04311b121ac4 1785
JackB 0:04311b121ac4 1786 // BCD to decimal conversion
JackB 0:04311b121ac4 1787 int MCP79412::bcd2dec(int bcd)
JackB 0:04311b121ac4 1788 {
JackB 0:04311b121ac4 1789 return(((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F));
JackB 0:04311b121ac4 1790 }
JackB 0:04311b121ac4 1791
JackB 0:04311b121ac4 1792 // decimal to BCD conversion
JackB 0:04311b121ac4 1793 int MCP79412::dec2bcd(int dec)
JackB 0:04311b121ac4 1794 {
JackB 0:04311b121ac4 1795 return((dec / 10) * 16 + (dec % 10));
JackB 0:04311b121ac4 1796 }
JackB 0:04311b121ac4 1797
JackB 0:04311b121ac4 1798 // Convert normal decimal numbers to binary coded decimal:
JackB 0:04311b121ac4 1799 int MCP79412::decToBcd(int val)
JackB 0:04311b121ac4 1800 {
JackB 0:04311b121ac4 1801 return ( (val/10*16) + (val%10) );
JackB 0:04311b121ac4 1802 }
JackB 0:04311b121ac4 1803
JackB 0:04311b121ac4 1804 // Convert binary coded decimal to normal decimal numbers:
JackB 0:04311b121ac4 1805 int MCP79412::bcdToDec(int val)
JackB 0:04311b121ac4 1806 {
JackB 0:04311b121ac4 1807 return ( (val/16*10) + (val%16) );
JackB 0:04311b121ac4 1808 }