/*
DS3231.cpp - Class file for the DS3231 Real-Time Clock
Version: 1.0.1
(c) 2014 Korneliusz Jarzebski
www.jarzebski.pl
This program is free software: you can redistribute it and/or modify
it under the terms of the version 3 GNU General Public License as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include
#include "DS3231.h"
const uint8_t daysArray [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 };
const uint8_t dowArray[] PROGMEM = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
bool DS3231::begin(void)
{
Wire.begin();
setBattery(true, false);
t.year = 2000;
t.month = 1;
t.day = 1;
t.hour = 0;
t.minute = 0;
t.second = 0;
t.dayOfWeek = 6;
t.unixtime = 946681200;
return true;
}
void DS3231::setDateTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second)
{
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(DS3231_REG_TIME);
#else
Wire.send(DS3231_REG_TIME);
#endif
#if ARDUINO >= 100
Wire.write(dec2bcd(second));
Wire.write(dec2bcd(minute));
Wire.write(dec2bcd(hour));
Wire.write(dec2bcd(dow(year, month, day)));
Wire.write(dec2bcd(day));
Wire.write(dec2bcd(month));
Wire.write(dec2bcd(year-2000));
#else
Wire.send(dec2bcd(second));
Wire.send(dec2bcd(minute));
Wire.send(dec2bcd(hour));
Wire.send(dec2bcd(dow(year, month, day)));
Wire.send(dec2bcd(day));
Wire.send(dec2bcd(month));
Wire.send(dec2bcd(year-2000));
#endif
#if ARDUINO >= 100
Wire.write(DS3231_REG_TIME);
#else
Wire.send(DS3231_REG_TIME);
#endif
Wire.endTransmission();
}
void DS3231::setDateTime(uint32_t t)
{
t -= 946681200;
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
second = t % 60;
t /= 60;
minute = t % 60;
t /= 60;
hour = t % 24;
uint16_t days = t / 24;
uint8_t leap;
for (year = 0; ; ++year)
{
leap = year % 4 == 0;
if (days < 365 + leap)
{
break;
}
days -= 365 + leap;
}
for (month = 1; ; ++month)
{
uint8_t daysPerMonth = pgm_read_byte(daysArray + month - 1);
if (leap && month == 2)
{
++daysPerMonth;
}
if (days < daysPerMonth)
{
break;
}
days -= daysPerMonth;
}
day = days + 1;
setDateTime(year+2000, month, day, hour, minute, second);
}
void DS3231::setDateTime(const char* date, const char* time)
{
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
year = conv2d(date + 9);
switch (date[0])
{
case 'J': month = date[1] == 'a' ? 1 : month = date[2] == 'n' ? 6 : 7; break;
case 'F': month = 2; break;
case 'A': month = date[2] == 'r' ? 4 : 8; break;
case 'M': month = date[2] == 'r' ? 3 : 5; break;
case 'S': month = 9; break;
case 'O': month = 10; break;
case 'N': month = 11; break;
case 'D': month = 12; break;
}
day = conv2d(date + 4);
hour = conv2d(time);
minute = conv2d(time + 3);
second = conv2d(time + 6);
setDateTime(year+2000, month, day, hour, minute, second);
}
char* DS3231::dateFormat(const char* dateFormat, RTCDateTime dt)
{
char buffer[255];
buffer[0] = 0;
char helper[11];
while (*dateFormat != '\0')
{
switch (dateFormat[0])
{
// Day decoder
case 'd':
sprintf(helper, "%02d", dt.day);
strcat(buffer, (const char *)helper);
break;
case 'j':
sprintf(helper, "%d", dt.day);
strcat(buffer, (const char *)helper);
break;
case 'l':
strcat(buffer, (const char *)strDayOfWeek(dt.dayOfWeek));
break;
case 'D':
strncat(buffer, strDayOfWeek(dt.dayOfWeek), 3);
break;
case 'N':
sprintf(helper, "%d", dt.dayOfWeek);
strcat(buffer, (const char *)helper);
break;
case 'w':
sprintf(helper, "%d", (dt.dayOfWeek + 7) % 7);
strcat(buffer, (const char *)helper);
break;
case 'z':
sprintf(helper, "%d", dayInYear(dt.year, dt.month, dt.day));
strcat(buffer, (const char *)helper);
break;
case 'S':
strcat(buffer, (const char *)strDaySufix(dt.day));
break;
// Month decoder
case 'm':
sprintf(helper, "%02d", dt.month);
strcat(buffer, (const char *)helper);
break;
case 'n':
sprintf(helper, "%d", dt.month);
strcat(buffer, (const char *)helper);
break;
case 'F':
strcat(buffer, (const char *)strMonth(dt.month));
break;
case 'M':
strncat(buffer, (const char *)strMonth(dt.month), 3);
break;
case 't':
sprintf(helper, "%d", daysInMonth(dt.year, dt.month));
strcat(buffer, (const char *)helper);
break;
// Year decoder
case 'Y':
sprintf(helper, "%d", dt.year);
strcat(buffer, (const char *)helper);
break;
case 'y': sprintf(helper, "%02d", dt.year-2000);
strcat(buffer, (const char *)helper);
break;
case 'L':
sprintf(helper, "%d", isLeapYear(dt.year));
strcat(buffer, (const char *)helper);
break;
// Hour decoder
case 'H':
sprintf(helper, "%02d", dt.hour);
strcat(buffer, (const char *)helper);
break;
case 'G':
sprintf(helper, "%d", dt.hour);
strcat(buffer, (const char *)helper);
break;
case 'h':
sprintf(helper, "%02d", hour12(dt.hour));
strcat(buffer, (const char *)helper);
break;
case 'g':
sprintf(helper, "%d", hour12(dt.hour));
strcat(buffer, (const char *)helper);
break;
case 'A':
strcat(buffer, (const char *)strAmPm(dt.hour, true));
break;
case 'a':
strcat(buffer, (const char *)strAmPm(dt.hour, false));
break;
// Minute decoder
case 'i':
sprintf(helper, "%02d", dt.minute);
strcat(buffer, (const char *)helper);
break;
// Second decoder
case 's':
sprintf(helper, "%02d", dt.second);
strcat(buffer, (const char *)helper);
break;
// Misc decoder
case 'U':
sprintf(helper, "%lu", dt.unixtime);
strcat(buffer, (const char *)helper);
break;
default:
strncat(buffer, dateFormat, 1);
break;
}
dateFormat++;
}
return buffer;
}
char* DS3231::dateFormat(const char* dateFormat, RTCAlarmTime dt)
{
char buffer[255];
buffer[0] = 0;
char helper[11];
while (*dateFormat != '\0')
{
switch (dateFormat[0])
{
// Day decoder
case 'd':
sprintf(helper, "%02d", dt.day);
strcat(buffer, (const char *)helper);
break;
case 'j':
sprintf(helper, "%d", dt.day);
strcat(buffer, (const char *)helper);
break;
case 'l':
strcat(buffer, (const char *)strDayOfWeek(dt.day));
break;
case 'D':
strncat(buffer, strDayOfWeek(dt.day), 3);
break;
case 'N':
sprintf(helper, "%d", dt.day);
strcat(buffer, (const char *)helper);
break;
case 'w':
sprintf(helper, "%d", (dt.day + 7) % 7);
strcat(buffer, (const char *)helper);
break;
case 'S':
strcat(buffer, (const char *)strDaySufix(dt.day));
break;
// Hour decoder
case 'H':
sprintf(helper, "%02d", dt.hour);
strcat(buffer, (const char *)helper);
break;
case 'G':
sprintf(helper, "%d", dt.hour);
strcat(buffer, (const char *)helper);
break;
case 'h':
sprintf(helper, "%02d", hour12(dt.hour));
strcat(buffer, (const char *)helper);
break;
case 'g':
sprintf(helper, "%d", hour12(dt.hour));
strcat(buffer, (const char *)helper);
break;
case 'A':
strcat(buffer, (const char *)strAmPm(dt.hour, true));
break;
case 'a':
strcat(buffer, (const char *)strAmPm(dt.hour, false));
break;
// Minute decoder
case 'i':
sprintf(helper, "%02d", dt.minute);
strcat(buffer, (const char *)helper);
break;
// Second decoder
case 's':
sprintf(helper, "%02d", dt.second);
strcat(buffer, (const char *)helper);
break;
default:
strncat(buffer, dateFormat, 1);
break;
}
dateFormat++;
}
return buffer;
}
RTCDateTime DS3231::getDateTime(void)
{
int values[7];
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(DS3231_REG_TIME);
#else
Wire.send(DS3231_REG_TIME);
#endif
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 7);
while(!Wire.available()) {};
for (int i = 6; i >= 0; i--)
{
#if ARDUINO >= 100
values[i] = bcd2dec(Wire.read());
#else
values[i] = bcd2dec(Wire.receive());
#endif
}
Wire.endTransmission();
t.year = values[0] + 2000;
t.month = values[1];
t.day = values[2];
t.dayOfWeek = values[3];
t.hour = values[4];
t.minute = values[5];
t.second = values[6];
t.unixtime = unixtime();
return t;
}
uint8_t DS3231::isReady(void)
{
return true;
}
void DS3231::enableOutput(bool enabled)
{
uint8_t value;
value = readRegister8(DS3231_REG_CONTROL);
value &= 0b11111011;
value |= (!enabled << 2);
writeRegister8(DS3231_REG_CONTROL, value);
}
void DS3231::setBattery(bool timeBattery, bool squareBattery)
{
uint8_t value;
value = readRegister8(DS3231_REG_CONTROL);
if (squareBattery)
{
value |= 0b01000000;
} else
{
value &= 0b10111111;
}
if (timeBattery)
{
value &= 0b01111011;
} else
{
value |= 0b10000000;
}
writeRegister8(DS3231_REG_CONTROL, value);
}
bool DS3231::isOutput(void)
{
uint8_t value;
value = readRegister8(DS3231_REG_CONTROL);
value &= 0b00000100;
value >>= 2;
return !value;
}
void DS3231::setOutput(DS3231_sqw_t mode)
{
uint8_t value;
value = readRegister8(DS3231_REG_CONTROL);
value &= 0b11100111;
value |= (mode << 3);
writeRegister8(DS3231_REG_CONTROL, value);
}
DS3231_sqw_t DS3231::getOutput(void)
{
uint8_t value;
value = readRegister8(DS3231_REG_CONTROL);
value &= 0b00011000;
value >>= 3;
return (DS3231_sqw_t)value;
}
void DS3231::enable32kHz(bool enabled)
{
uint8_t value;
value = readRegister8(DS3231_REG_STATUS);
value &= 0b11110111;
value |= (enabled << 3);
writeRegister8(DS3231_REG_STATUS, value);
}
bool DS3231::is32kHz(void)
{
uint8_t value;
value = readRegister8(DS3231_REG_STATUS);
value &= 0b00001000;
value >>= 3;
return value;
}
void DS3231::forceConversion(void)
{
uint8_t value;
value = readRegister8(DS3231_REG_CONTROL);
value |= 0b00100000;
writeRegister8(DS3231_REG_CONTROL, value);
do {} while ((readRegister8(DS3231_REG_CONTROL) & 0b00100000) != 0);
}
float DS3231::readTemperature(void)
{
uint8_t msb, lsb;
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(DS3231_REG_TEMPERATURE);
#else
Wire.send(DS3231_REG_TEMPERATURE);
#endif
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 2);
while(!Wire.available()) {};
#if ARDUINO >= 100
msb = Wire.read();
lsb = Wire.read();
#else
msb = Wire.receive();
lsb = Wire.receive();
#endif
return ((((short)msb << 8) | (short)lsb) >> 6) / 4.0f;
}
RTCAlarmTime DS3231::getAlarm1(void)
{
uint8_t values[4];
RTCAlarmTime a;
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(DS3231_REG_ALARM_1);
#else
Wire.send(DS3231_REG_ALARM_1);
#endif
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 4);
while(!Wire.available()) {};
for (int i = 3; i >= 0; i--)
{
#if ARDUINO >= 100
values[i] = bcd2dec(Wire.read() & 0b01111111);
#else
values[i] = bcd2dec(Wire.receive() & 0b01111111);
#endif
}
Wire.endTransmission();
a.day = values[0];
a.hour = values[1];
a.minute = values[2];
a.second = values[3];
return a;
}
DS3231_alarm1_t DS3231::getAlarmType1(void)
{
uint8_t values[4];
uint8_t mode = 0;
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(DS3231_REG_ALARM_1);
#else
Wire.send(DS3231_REG_ALARM_1);
#endif
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 4);
while(!Wire.available()) {};
for (int i = 3; i >= 0; i--)
{
#if ARDUINO >= 100
values[i] = bcd2dec(Wire.read());
#else
values[i] = bcd2dec(Wire.receive());
#endif
}
Wire.endTransmission();
mode |= ((values[3] & 0b01000000) >> 6);
mode |= ((values[2] & 0b01000000) >> 5);
mode |= ((values[1] & 0b01000000) >> 4);
mode |= ((values[0] & 0b01000000) >> 3);
mode |= ((values[0] & 0b00100000) >> 1);
return (DS3231_alarm1_t)mode;
}
void DS3231::setAlarm1(uint8_t dydw, uint8_t hour, uint8_t minute, uint8_t second, DS3231_alarm1_t mode, bool armed)
{
second = dec2bcd(second);
minute = dec2bcd(minute);
hour = dec2bcd(hour);
dydw = dec2bcd(dydw);
switch(mode)
{
case DS3231_EVERY_SECOND:
second |= 0b10000000;
minute |= 0b10000000;
hour |= 0b10000000;
dydw |= 0b10000000;
break;
case DS3231_MATCH_S:
second &= 0b01111111;
minute |= 0b10000000;
hour |= 0b10000000;
dydw |= 0b10000000;
break;
case DS3231_MATCH_M_S:
second &= 0b01111111;
minute &= 0b01111111;
hour |= 0b10000000;
dydw |= 0b10000000;
break;
case DS3231_MATCH_H_M_S:
second &= 0b01111111;
minute &= 0b01111111;
hour &= 0b01111111;
dydw |= 0b10000000;
break;
case DS3231_MATCH_DT_H_M_S:
second &= 0b01111111;
minute &= 0b01111111;
hour &= 0b01111111;
dydw &= 0b01111111;
break;
case DS3231_MATCH_DY_H_M_S:
second &= 0b01111111;
minute &= 0b01111111;
hour &= 0b01111111;
dydw &= 0b01111111;
dydw |= 0b01000000;
break;
}
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(DS3231_REG_ALARM_1);
Wire.write(second);
Wire.write(minute);
Wire.write(hour);
Wire.write(dydw);
#else
Wire.send(DS3231_REG_ALARM_1);
Wire.send(second);
Wire.send(minute);
Wire.send(hour);
Wire.send(dydw);
#endif
Wire.endTransmission();
armAlarm1(armed);
clearAlarm1();
}
bool DS3231::isAlarm1(bool clear)
{
uint8_t alarm;
alarm = readRegister8(DS3231_REG_STATUS);
alarm &= 0b00000001;
if (alarm && clear)
{
clearAlarm1();
}
return alarm;
}
void DS3231::armAlarm1(bool armed)
{
uint8_t value;
value = readRegister8(DS3231_REG_CONTROL);
if (armed)
{
value |= 0b00000001;
} else
{
value &= 0b11111110;
}
writeRegister8(DS3231_REG_CONTROL, value);
}
bool DS3231::isArmed1(void)
{
uint8_t value;
value = readRegister8(DS3231_REG_CONTROL);
value &= 0b00000001;
return value;
}
void DS3231::clearAlarm1(void)
{
uint8_t value;
value = readRegister8(DS3231_REG_STATUS);
value &= 0b11111110;
writeRegister8(DS3231_REG_STATUS, value);
}
RTCAlarmTime DS3231::getAlarm2(void)
{
uint8_t values[3];
RTCAlarmTime a;
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(DS3231_REG_ALARM_2);
#else
Wire.send(DS3231_REG_ALARM_2);
#endif
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 3);
while(!Wire.available()) {};
for (int i = 2; i >= 0; i--)
{
#if ARDUINO >= 100
values[i] = bcd2dec(Wire.read() & 0b01111111);
#else
values[i] = bcd2dec(Wire.receive() & 0b01111111);
#endif
}
Wire.endTransmission();
a.day = values[0];
a.hour = values[1];
a.minute = values[2];
a.second = 0;
return a;
}
DS3231_alarm2_t DS3231::getAlarmType2(void)
{
uint8_t values[3];
uint8_t mode = 0;
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(DS3231_REG_ALARM_2);
#else
Wire.send(DS3231_REG_ALARM_2);
#endif
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 3);
while(!Wire.available()) {};
for (int i = 2; i >= 0; i--)
{
#if ARDUINO >= 100
values[i] = bcd2dec(Wire.read());
#else
values[i] = bcd2dec(Wire.receive());
#endif
}
Wire.endTransmission();
mode |= ((values[2] & 0b01000000) >> 5);
mode |= ((values[1] & 0b01000000) >> 4);
mode |= ((values[0] & 0b01000000) >> 3);
mode |= ((values[0] & 0b00100000) >> 1);
return (DS3231_alarm2_t)mode;
}
void DS3231::setAlarm2(uint8_t dydw, uint8_t hour, uint8_t minute, DS3231_alarm2_t mode, bool armed)
{
minute = dec2bcd(minute);
hour = dec2bcd(hour);
dydw = dec2bcd(dydw);
switch(mode)
{
case DS3231_EVERY_MINUTE:
minute |= 0b10000000;
hour |= 0b10000000;
dydw |= 0b10000000;
break;
case DS3231_MATCH_M:
minute &= 0b01111111;
hour |= 0b10000000;
dydw |= 0b10000000;
break;
case DS3231_MATCH_H_M:
minute &= 0b01111111;
hour &= 0b01111111;
dydw |= 0b10000000;
break;
case DS3231_MATCH_DT_H_M:
minute &= 0b01111111;
hour &= 0b01111111;
dydw &= 0b01111111;
break;
case DS3231_MATCH_DY_H_M:
minute &= 0b01111111;
hour &= 0b01111111;
dydw &= 0b01111111;
dydw |= 0b01000000;
break;
}
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(DS3231_REG_ALARM_2);
Wire.write(minute);
Wire.write(hour);
Wire.write(dydw);
#else
Wire.send(DS3231_REG_ALARM_2);
Wire.send(minute);
Wire.send(hour);
Wire.send(dydw);
#endif
Wire.endTransmission();
armAlarm2(armed);
clearAlarm2();
}
void DS3231::armAlarm2(bool armed)
{
uint8_t value;
value = readRegister8(DS3231_REG_CONTROL);
if (armed)
{
value |= 0b00000010;
} else
{
value &= 0b11111101;
}
writeRegister8(DS3231_REG_CONTROL, value);
}
bool DS3231::isArmed2(void)
{
uint8_t value;
value = readRegister8(DS3231_REG_CONTROL);
value &= 0b00000010;
value >>= 1;
return value;
}
void DS3231::clearAlarm2(void)
{
uint8_t value;
value = readRegister8(DS3231_REG_STATUS);
value &= 0b11111101;
writeRegister8(DS3231_REG_STATUS, value);
}
bool DS3231::isAlarm2(bool clear)
{
uint8_t alarm;
alarm = readRegister8(DS3231_REG_STATUS);
alarm &= 0b00000010;
if (alarm && clear)
{
clearAlarm2();
}
return alarm;
}
uint8_t DS3231::bcd2dec(uint8_t bcd)
{
return ((bcd / 16) * 10) + (bcd % 16);
}
uint8_t DS3231::dec2bcd(uint8_t dec)
{
return ((dec / 10) * 16) + (dec % 10);
}
char *DS3231::strDayOfWeek(uint8_t dayOfWeek)
{
switch (dayOfWeek) {
case 1:
return "Monday";
break;
case 2:
return "Tuesday";
break;
case 3:
return "Wednesday";
break;
case 4:
return "Thursday";
break;
case 5:
return "Friday";
break;
case 6:
return "Saturday";
break;
case 7:
return "Sunday";
break;
default:
return "Unknown";
}
}
char *DS3231::strMonth(uint8_t month)
{
switch (month) {
case 1:
return "January";
break;
case 2:
return "February";
break;
case 3:
return "March";
break;
case 4:
return "April";
break;
case 5:
return "May";
break;
case 6:
return "June";
break;
case 7:
return "July";
break;
case 8:
return "August";
break;
case 9:
return "September";
break;
case 10:
return "October";
break;
case 11:
return "November";
break;
case 12:
return "December";
break;
default:
return "Unknown";
}
}
char *DS3231::strAmPm(uint8_t hour, bool uppercase)
{
if (hour < 12)
{
if (uppercase)
{
return "AM";
} else
{
return "am";
}
} else
{
if (uppercase)
{
return "PM";
} else
{
return "pm";
}
}
}
char *DS3231::strDaySufix(uint8_t day)
{
if (day % 10 == 1)
{
return "st";
} else
if (day % 10 == 2)
{
return "nd";
}
if (day % 10 == 3)
{
return "rd";
}
return "th";
}
uint8_t DS3231::hour12(uint8_t hour24)
{
if (hour24 == 0)
{
return 12;
}
if (hour24 > 12)
{
return (hour24 - 12);
}
return hour24;
}
long DS3231::time2long(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds)
{
return ((days * 24L + hours) * 60 + minutes) * 60 + seconds;
}
uint16_t DS3231::dayInYear(uint16_t year, uint8_t month, uint8_t day)
{
uint16_t fromDate;
uint16_t toDate;
fromDate = date2days(year, 1, 1);
toDate = date2days(year, month, day);
return (toDate - fromDate);
}
bool DS3231::isLeapYear(uint16_t year)
{
return (year % 4 == 0);
}
uint8_t DS3231::daysInMonth(uint16_t year, uint8_t month)
{
uint8_t days;
days = pgm_read_byte(daysArray + month - 1);
if ((month == 2) && isLeapYear(year))
{
++days;
}
return days;
}
uint16_t DS3231::date2days(uint16_t year, uint8_t month, uint8_t day)
{
year = year - 2000;
uint16_t days16 = day;
for (uint8_t i = 1; i < month; ++i)
{
days16 += pgm_read_byte(daysArray + i - 1);
}
if ((month == 2) && isLeapYear(year))
{
++days16;
}
return days16 + 365 * year + (year + 3) / 4 - 1;
}
uint32_t DS3231::unixtime(void)
{
uint32_t u;
u = time2long(date2days(t.year, t.month, t.day), t.hour, t.minute, t.second);
u += 946681200;
return u;
}
uint8_t DS3231::conv2d(const char* p)
{
uint8_t v = 0;
if ('0' <= *p && *p <= '9')
{
v = *p - '0';
}
return 10 * v + *++p - '0';
}
uint8_t DS3231::dow(uint16_t y, uint8_t m, uint8_t d)
{
uint8_t dow;
y -= m < 3;
dow = ((y + y/4 - y/100 + y/400 + pgm_read_byte(dowArray+(m-1)) + d) % 7);
if (dow == 0)
{
return 7;
}
return dow;
}
void DS3231::writeRegister8(uint8_t reg, uint8_t value)
{
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(reg);
Wire.write(value);
#else
Wire.send(reg);
Wire.send(value);
#endif
Wire.endTransmission();
}
uint8_t DS3231::readRegister8(uint8_t reg)
{
uint8_t value;
Wire.beginTransmission(DS3231_ADDRESS);
#if ARDUINO >= 100
Wire.write(reg);
#else
Wire.send(reg);
#endif
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 1);
while(!Wire.available()) {};
#if ARDUINO >= 100
value = Wire.read();
#else
value = Wire.receive();
#endif;
Wire.endTransmission();
return value;
}