diff --git a/lib/Rtc_Pcf8563/Rtc_Pcf8563.cpp b/lib/Rtc_Pcf8563/Rtc_Pcf8563.cpp index 546b333..4338538 100644 --- a/lib/Rtc_Pcf8563/Rtc_Pcf8563.cpp +++ b/lib/Rtc_Pcf8563/Rtc_Pcf8563.cpp @@ -38,59 +38,59 @@ #include #include "Rtc_Pcf8563.h" -Rtc_Pcf8563::Rtc_Pcf8563(void) +Rtc_Pcf8563::Rtc_Pcf8563() { - Wire.begin(); - Rtcc_Addr = RTCC_R>>1; + Wire.begin(); + Rtcc_Addr = RTCC_R >> 1; } Rtc_Pcf8563::Rtc_Pcf8563(int sdaPin, int sdlPin) { - Wire.begin(sdaPin, sdlPin); - Rtcc_Addr = RTCC_R>>1; + Wire.begin(sdaPin, sdlPin); + Rtcc_Addr = RTCC_R >> 1; } /* Private internal functions, but useful to look at if you need a similar func. */ byte Rtc_Pcf8563::decToBcd(byte val) { - return ( (val/10*16) + (val%10) ); + return ((val / 10 * 16) + (val % 10)); } byte Rtc_Pcf8563::bcdToDec(byte val) { - return ( (val/16*10) + (val%16) ); + return ((val / 16 * 10) + (val % 16)); } void Rtc_Pcf8563::zeroClock() { - Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal - Wire.write((byte)0x0); // start address + Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal + Wire.write((byte)0x0); // start address - Wire.write((byte)0x0); //control/status1 - Wire.write((byte)0x0); //control/status2 - Wire.write((byte)0x00); //set seconds to 0 & VL to 0 - Wire.write((byte)0x00); //set minutes to 0 - Wire.write((byte)0x00); //set hour to 0 - Wire.write((byte)0x01); //set day to 1 - Wire.write((byte)0x00); //set weekday to 0 - Wire.write((byte)0x81); //set month to 1, century to 1900 - Wire.write((byte)0x00); //set year to 0 - Wire.write((byte)0x80); //minute alarm value reset to 00 - Wire.write((byte)0x80); //hour alarm value reset to 00 - Wire.write((byte)0x80); //day alarm value reset to 00 - Wire.write((byte)0x80); //weekday alarm value reset to 00 - Wire.write((byte)SQW_32KHZ); //set SQW to default, see: setSquareWave - Wire.write((byte)0x0); //timer off - Wire.endTransmission(); + Wire.write((byte)0x0); //control/status1 + Wire.write((byte)0x0); //control/status2 + Wire.write((byte)0x00); //set seconds to 0 & VL to 0 + Wire.write((byte)0x00); //set minutes to 0 + Wire.write((byte)0x00); //set hour to 0 + Wire.write((byte)0x01); //set day to 1 + Wire.write((byte)0x00); //set weekday to 0 + Wire.write((byte)0x81); //set month to 1, century to 1900 + Wire.write((byte)0x00); //set year to 0 + Wire.write((byte)0x80); //minute alarm value reset to 00 + Wire.write((byte)0x80); //hour alarm value reset to 00 + Wire.write((byte)0x80); //day alarm value reset to 00 + Wire.write((byte)0x80); //weekday alarm value reset to 00 + Wire.write((byte)SQW_32KHZ); //set SQW to default, see: setSquareWave + Wire.write((byte)0x0); //timer off + Wire.endTransmission(); } void Rtc_Pcf8563::clearStatus() { - Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal - Wire.write((byte)0x0); - Wire.write((byte)0x0); //control/status1 - Wire.write((byte)0x0); //control/status2 - Wire.endTransmission(); + Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal + Wire.write((byte)0x0); + Wire.write((byte)0x0); //control/status1 + Wire.write((byte)0x0); //control/status2 + Wire.endTransmission(); } /* @@ -98,91 +98,100 @@ void Rtc_Pcf8563::clearStatus() */ byte Rtc_Pcf8563::readStatus2() { - getDateTime(); - return getStatus2(); + getDateTime(); + return getStatus2(); } -void Rtc_Pcf8563::clearVoltLow(void) +void Rtc_Pcf8563::clearVoltLow() { - getDateTime(); - // Only clearing is possible on device (I tried) - setDateTime(getDay(), getWeekday(), getMonth(), - getCentury(), getYear(), getHour(), - getMinute(), getSecond()); + getDateTime(); + // Only clearing is possible on device (I tried) + setDateTime(getDay(), getWeekday(), getMonth(), + getCentury(), getYear(), getHour(), + getMinute(), getSecond()); } /* * Atomicly read all device registers in one operation */ -void Rtc_Pcf8563::getDateTime(void) +void Rtc_Pcf8563::getDateTime() { - /* Start at beginning, read entire memory in one go */ - Wire.beginTransmission(Rtcc_Addr); - Wire.write((byte)RTCC_STAT1_ADDR); - Wire.endTransmission(); + /* Start at beginning, read entire memory in one go */ + Wire.beginTransmission(Rtcc_Addr); + Wire.write((byte)RTCC_STAT1_ADDR); + Wire.endTransmission(); - /* As per data sheet, have to read everything all in one operation */ - uint8_t readBuffer[16] = {0}; - Wire.requestFrom(Rtcc_Addr, 16); - for (uint8_t i=0; i < 16; i++) - readBuffer[i] = Wire.read(); + /* As per data sheet, have to read everything all in one operation */ + uint8_t readBuffer[16] = {0}; + Wire.requestFrom(Rtcc_Addr, 16); + for (uint8_t i=0; i < 16; i++) { + readBuffer[i] = Wire.read(); + } - // status bytes - status1 = readBuffer[0]; - status2 = readBuffer[1]; + // status bytes + status1 = readBuffer[0]; + status2 = readBuffer[1]; - // time bytes - //0x7f = 0b01111111 - volt_low = readBuffer[2] & RTCC_VLSEC_MASK; //VL_Seconds - sec = bcdToDec(readBuffer[2] & ~RTCC_VLSEC_MASK); - minute = bcdToDec(readBuffer[3] & 0x7f); - //0x3f = 0b00111111 - hour = bcdToDec(readBuffer[4] & 0x3f); + // time bytes + //0x7f = 0b01111111 + volt_low = readBuffer[2] & RTCC_VLSEC_MASK; //VL_Seconds + sec = bcdToDec(readBuffer[2] & ~RTCC_VLSEC_MASK); + minute = bcdToDec(readBuffer[3] & 0x7f); + //0x3f = 0b00111111 + hour = bcdToDec(readBuffer[4] & 0x3f); - // date bytes - //0x3f = 0b00111111 - day = bcdToDec(readBuffer[5] & 0x3f); - //0x07 = 0b00000111 - weekday = bcdToDec(readBuffer[6] & 0x07); - //get raw month data byte and set month and century with it. - month = readBuffer[7]; - if (month & RTCC_CENTURY_MASK) - century = true; - else - century = false; - //0x1f = 0b00011111 - month = month & 0x1f; - month = bcdToDec(month); - year = bcdToDec(readBuffer[8]); + // date bytes + //0x3f = 0b00111111 + day = bcdToDec(readBuffer[5] & 0x3f); + //0x07 = 0b00000111 + weekday = bcdToDec(readBuffer[6] & 0x07); + //get raw month data byte and set month and century with it. + month = readBuffer[7]; + if (month & RTCC_CENTURY_MASK) { + century = true; + } else { + century = false; + } - // alarm bytes - alarm_minute = readBuffer[9]; - if(B10000000 & alarm_minute) - alarm_minute = RTCC_NO_ALARM; - else - alarm_minute = bcdToDec(alarm_minute & B01111111); - alarm_hour = readBuffer[10]; - if(B10000000 & alarm_hour) - alarm_hour = RTCC_NO_ALARM; - else - alarm_hour = bcdToDec(alarm_hour & B00111111); - alarm_day = readBuffer[11]; - if(B10000000 & alarm_day) - alarm_day = RTCC_NO_ALARM; - else - alarm_day = bcdToDec(alarm_day & B00111111); - alarm_weekday = readBuffer[12]; - if(B10000000 & alarm_weekday) - alarm_weekday = RTCC_NO_ALARM; - else - alarm_weekday = bcdToDec(alarm_weekday & B00000111); + //0x1f = 0b00011111 + month = month & 0x1f; + month = bcdToDec(month); + year = bcdToDec(readBuffer[8]); - // CLKOUT_control 0x03 = 0b00000011 - squareWave = readBuffer[13] & 0x03; + // alarm bytes + alarm_minute = readBuffer[9]; + if(B10000000 & alarm_minute) { + alarm_minute = RTCC_NO_ALARM; + } else { + alarm_minute = bcdToDec(alarm_minute & B01111111); + } - // timer bytes - timer_control = readBuffer[14] & 0x03; - timer_value = readBuffer[15]; // current value != set value when running + alarm_hour = readBuffer[10]; + if(B10000000 & alarm_hour) { + alarm_hour = RTCC_NO_ALARM; + } else { + alarm_hour = bcdToDec(alarm_hour & B00111111); + } + + alarm_day = readBuffer[11]; + if(B10000000 & alarm_day) { + alarm_day = RTCC_NO_ALARM; + } else { + alarm_day = bcdToDec(alarm_day & B00111111); + } + alarm_weekday = readBuffer[12]; + if(B10000000 & alarm_weekday) { + alarm_weekday = RTCC_NO_ALARM; + } else { + alarm_weekday = bcdToDec(alarm_weekday & B00000111); + } + + // CLKOUT_control 0x03 = 0b00000011 + squareWave = readBuffer[13] & 0x03; + + // timer bytes + timer_control = readBuffer[14] & 0x03; + timer_value = readBuffer[15]; // current value != set value when running } @@ -190,30 +199,32 @@ void Rtc_Pcf8563::setDateTime(byte day, byte weekday, byte month, bool century, byte year, byte hour, byte minute, byte sec) { - /* year val is 00 to 99, xx - with the highest bit of month = century - 0=20xx - 1=19xx - */ - month = decToBcd(month); - if (century) - month |= RTCC_CENTURY_MASK; - else - month &= ~RTCC_CENTURY_MASK; + /* year val is 00 to 99, xx + with the highest bit of month = century + 0=20xx + 1=19xx + */ + month = decToBcd(month); - /* As per data sheet, have to set everything all in one operation */ - Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal - Wire.write(RTCC_SEC_ADDR); // send addr low byte, req'd - Wire.write(decToBcd(sec) &~RTCC_VLSEC_MASK); //set sec, clear VL bit - Wire.write(decToBcd(minute)); //set minutes - Wire.write(decToBcd(hour)); //set hour - Wire.write(decToBcd(day)); //set day - Wire.write(decToBcd(weekday)); //set weekday - Wire.write(month); //set month, century to 1 - Wire.write(decToBcd(year)); //set year to 99 - Wire.endTransmission(); - // Keep values in-sync with device - getDateTime(); + if (century) { + month |= RTCC_CENTURY_MASK; + } else { + month &= ~RTCC_CENTURY_MASK; + } + + /* As per data sheet, have to set everything all in one operation */ + Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal + Wire.write(RTCC_SEC_ADDR); // send addr low byte, req'd + Wire.write(decToBcd(sec) &~RTCC_VLSEC_MASK); //set sec, clear VL bit + Wire.write(decToBcd(minute)); //set minutes + Wire.write(decToBcd(hour)); //set hour + Wire.write(decToBcd(day)); //set day + Wire.write(decToBcd(weekday)); //set weekday + Wire.write(month); //set month, century to 1 + Wire.write(decToBcd(year)); //set year to 99 + Wire.endTransmission(); + // Keep values in-sync with device + getDateTime(); } /** @@ -221,7 +232,7 @@ void Rtc_Pcf8563::setDateTime(byte day, byte weekday, byte month, */ void Rtc_Pcf8563::getAlarm() { - getDateTime(); + getDateTime(); } /* @@ -230,7 +241,7 @@ void Rtc_Pcf8563::getAlarm() */ bool Rtc_Pcf8563::alarmEnabled() { - return getStatus2() & RTCC_ALARM_AIE; + return getStatus2() & RTCC_ALARM_AIE; } /* @@ -239,7 +250,7 @@ bool Rtc_Pcf8563::alarmEnabled() */ bool Rtc_Pcf8563::alarmActive() { - return getStatus2() & RTCC_ALARM_AF; + return getStatus2() & RTCC_ALARM_AF; } /* enable alarm interrupt @@ -248,19 +259,19 @@ bool Rtc_Pcf8563::alarmActive() */ void Rtc_Pcf8563::enableAlarm() { - getDateTime(); // operate on current values - //set status2 AF val to zero - status2 &= ~RTCC_ALARM_AF; - //set TF to 1 masks it from changing, as per data-sheet - status2 |= RTCC_TIMER_TF; - //enable the interrupt - status2 |= RTCC_ALARM_AIE; + getDateTime(); // operate on current values + //set status2 AF val to zero + status2 &= ~RTCC_ALARM_AF; + //set TF to 1 masks it from changing, as per data-sheet + status2 |= RTCC_TIMER_TF; + //enable the interrupt + status2 |= RTCC_ALARM_AIE; - //enable the interrupt - Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal - Wire.write((byte)RTCC_STAT2_ADDR); - Wire.write((byte)status2); - Wire.endTransmission(); + //enable the interrupt + Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal + Wire.write((byte)RTCC_STAT2_ADDR); + Wire.write((byte)status2); + Wire.endTransmission(); } /* set the alarm values @@ -269,68 +280,68 @@ void Rtc_Pcf8563::enableAlarm() */ void Rtc_Pcf8563::setAlarm(byte min, byte hour, byte day, byte weekday) { - getDateTime(); // operate on current values - if (min <99) { - min = constrain(min, 0, 59); - min = decToBcd(min); - min &= ~RTCC_ALARM; - } else { - min = 0x0; min |= RTCC_ALARM; - } + getDateTime(); // operate on current values + if (min < 99) { + min = constrain(min, 0, 59); + min = decToBcd(min); + min &= ~RTCC_ALARM; + } else { + min = 0x0; min |= RTCC_ALARM; + } - if (hour <99) { - hour = constrain(hour, 0, 23); - hour = decToBcd(hour); - hour &= ~RTCC_ALARM; - } else { - hour = 0x0; hour |= RTCC_ALARM; - } + if (hour <99) { + hour = constrain(hour, 0, 23); + hour = decToBcd(hour); + hour &= ~RTCC_ALARM; + } else { + hour = 0x0; hour |= RTCC_ALARM; + } - if (day <99) { - day = constrain(day, 1, 31); - day = decToBcd(day); day &= ~RTCC_ALARM; - } else { - day = 0x0; day |= RTCC_ALARM; - } + if (day <99) { + day = constrain(day, 1, 31); + day = decToBcd(day); day &= ~RTCC_ALARM; + } else { + day = 0x0; day |= RTCC_ALARM; + } - if (weekday <99) { - weekday = constrain(weekday, 0, 6); - weekday = decToBcd(weekday); - weekday &= ~RTCC_ALARM; - } else { - weekday = 0x0; weekday |= RTCC_ALARM; - } + if (weekday <99) { + weekday = constrain(weekday, 0, 6); + weekday = decToBcd(weekday); + weekday &= ~RTCC_ALARM; + } else { + weekday = 0x0; weekday |= RTCC_ALARM; + } - alarm_hour = hour; - alarm_minute = min; - alarm_weekday = weekday; - alarm_day = day; + alarm_hour = hour; + alarm_minute = min; + alarm_weekday = weekday; + alarm_day = day; - // First set alarm values, then enable - Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal - Wire.write((byte)RTCC_ALRM_MIN_ADDR); - Wire.write((byte)alarm_minute); - Wire.write((byte)alarm_hour); - Wire.write((byte)alarm_day); - Wire.write((byte)alarm_weekday); - Wire.endTransmission(); + // First set alarm values, then enable + Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal + Wire.write((byte)RTCC_ALRM_MIN_ADDR); + Wire.write((byte)alarm_minute); + Wire.write((byte)alarm_hour); + Wire.write((byte)alarm_day); + Wire.write((byte)alarm_weekday); + Wire.endTransmission(); - Rtc_Pcf8563::enableAlarm(); + Rtc_Pcf8563::enableAlarm(); } void Rtc_Pcf8563::clearAlarm() { - //set status2 AF val to zero to reset alarm - status2 &= ~RTCC_ALARM_AF; - //set TF to 1 masks it from changing, as per data-sheet - status2 |= RTCC_TIMER_TF; - //turn off the interrupt - status2 &= ~RTCC_ALARM_AIE; + //set status2 AF val to zero to reset alarm + status2 &= ~RTCC_ALARM_AF; + //set TF to 1 masks it from changing, as per data-sheet + status2 |= RTCC_TIMER_TF; + //turn off the interrupt + status2 &= ~RTCC_ALARM_AIE; - Wire.beginTransmission(Rtcc_Addr); - Wire.write((byte)RTCC_STAT2_ADDR); - Wire.write((byte)status2); - Wire.endTransmission(); + Wire.beginTransmission(Rtcc_Addr); + Wire.write((byte)RTCC_STAT2_ADDR); + Wire.write((byte)status2); + Wire.endTransmission(); } /** @@ -338,127 +349,132 @@ void Rtc_Pcf8563::clearAlarm() */ void Rtc_Pcf8563::resetAlarm() { - //set status2 AF val to zero to reset alarm - status2 &= ~RTCC_ALARM_AF; - //set TF to 1 masks it from changing, as per data-sheet - status2 |= RTCC_TIMER_TF; + //set status2 AF val to zero to reset alarm + status2 &= ~RTCC_ALARM_AF; + //set TF to 1 masks it from changing, as per data-sheet + status2 |= RTCC_TIMER_TF; - Wire.beginTransmission(Rtcc_Addr); - Wire.write((byte)RTCC_STAT2_ADDR); - Wire.write((byte)status2); - Wire.endTransmission(); + Wire.beginTransmission(Rtcc_Addr); + Wire.write((byte)RTCC_STAT2_ADDR); + Wire.write((byte)status2); + Wire.endTransmission(); } // true if timer interrupt and control is enabled bool Rtc_Pcf8563::timerEnabled() { - if (getStatus2() & RTCC_TIMER_TIE) - if (timer_control & RTCC_TIMER_TE) - return true; - return false; + if (getStatus2() & RTCC_TIMER_TIE) { + if (timer_control & RTCC_TIMER_TE) { + return true; + } + } + + return false; } // true if timer is active bool Rtc_Pcf8563::timerActive() { - return getStatus2() & RTCC_TIMER_TF; + return getStatus2() & RTCC_TIMER_TF; } // enable timer and interrupt -void Rtc_Pcf8563::enableTimer(void) +void Rtc_Pcf8563::enableTimer() { - getDateTime(); - //set TE to 1 - timer_control |= RTCC_TIMER_TE; - //set status2 TF val to zero - status2 &= ~RTCC_TIMER_TF; - //set AF to 1 masks it from changing, as per data-sheet - status2 |= RTCC_ALARM_AF; - //enable the interrupt - status2 |= RTCC_TIMER_TIE; + getDateTime(); + //set TE to 1 + timer_control |= RTCC_TIMER_TE; + //set status2 TF val to zero + status2 &= ~RTCC_TIMER_TF; + //set AF to 1 masks it from changing, as per data-sheet + status2 |= RTCC_ALARM_AF; + //enable the interrupt + status2 |= RTCC_TIMER_TIE; - // Enable interrupt first, then enable timer - Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal - Wire.write((byte)RTCC_STAT2_ADDR); - Wire.write((byte)status2); - Wire.endTransmission(); + // Enable interrupt first, then enable timer + Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal + Wire.write((byte)RTCC_STAT2_ADDR); + Wire.write((byte)status2); + Wire.endTransmission(); - Wire.beginTransmission(Rtcc_Addr); - Wire.write((byte)RTCC_TIMER1_ADDR); - Wire.write((byte)timer_control); // Timer starts ticking now! - Wire.endTransmission(); + Wire.beginTransmission(Rtcc_Addr); + Wire.write((byte)RTCC_TIMER1_ADDR); + Wire.write((byte)timer_control); // Timer starts ticking now! + Wire.endTransmission(); } // set count-down value and frequency void Rtc_Pcf8563::setTimer(byte value, byte frequency, bool is_pulsed) { - getDateTime(); - if (is_pulsed) - status2 |= 0x01 << 4; - else - status2 &= ~(0x01 << 4); - timer_value = value; - // TE set to 1 in enableTimer(), leave 0 for now - timer_control |= (frequency & RTCC_TIMER_TD10); // use only last 2 bits + getDateTime(); + if (is_pulsed) { + status2 |= 0x01 << 4; + } else { + status2 &= ~(0x01 << 4); + } - Wire.beginTransmission(Rtcc_Addr); - Wire.write((byte)RTCC_TIMER1_ADDR); - Wire.write((byte)timer_control); - Wire.write((byte)timer_value); - Wire.endTransmission(); + timer_value = value; + // TE set to 1 in enableTimer(), leave 0 for now + timer_control |= (frequency & RTCC_TIMER_TD10); // use only last 2 bits - Wire.beginTransmission(Rtcc_Addr); - Wire.write((byte)RTCC_STAT2_ADDR); - Wire.write((byte)status2); - Wire.endTransmission(); + Wire.beginTransmission(Rtcc_Addr); + Wire.write((byte)RTCC_TIMER1_ADDR); + Wire.write((byte)timer_control); + Wire.write((byte)timer_value); + Wire.endTransmission(); - enableTimer(); + Wire.beginTransmission(Rtcc_Addr); + Wire.write((byte)RTCC_STAT2_ADDR); + Wire.write((byte)status2); + Wire.endTransmission(); + + enableTimer(); } // clear timer flag and interrupt -void Rtc_Pcf8563::clearTimer(void) +void Rtc_Pcf8563::clearTimer() { - getDateTime(); - //set status2 TF val to zero - status2 &= ~RTCC_TIMER_TF; - //set AF to 1 masks it from changing, as per data-sheet - status2 |= RTCC_ALARM_AF; - //turn off the interrupt - status2 &= ~RTCC_TIMER_TIE; - //turn off the timer - timer_control = 0; + getDateTime(); + //set status2 TF val to zero + status2 &= ~RTCC_TIMER_TF; + //set AF to 1 masks it from changing, as per data-sheet + status2 |= RTCC_ALARM_AF; + //turn off the interrupt + status2 &= ~RTCC_TIMER_TIE; + //turn off the timer + timer_control = 0; - // Stop timer first - Wire.beginTransmission(Rtcc_Addr); - Wire.write((byte)RTCC_TIMER1_ADDR); - Wire.write((byte)timer_control); - Wire.endTransmission(); + // Stop timer first + Wire.beginTransmission(Rtcc_Addr); + Wire.write((byte)RTCC_TIMER1_ADDR); + Wire.write((byte)timer_control); + Wire.endTransmission(); - // clear flag and interrupt - Wire.beginTransmission(Rtcc_Addr); - Wire.write((byte)RTCC_STAT2_ADDR); - Wire.write((byte)status2); - Wire.endTransmission(); + // clear flag and interrupt + Wire.beginTransmission(Rtcc_Addr); + Wire.write((byte)RTCC_STAT2_ADDR); + Wire.write((byte)status2); + Wire.endTransmission(); } // clear timer flag but leave interrupt unchanged */ -void Rtc_Pcf8563::resetTimer(void) +void Rtc_Pcf8563::resetTimer() { - getDateTime(); - //set status2 TF val to zero to reset timer - status2 &= ~RTCC_TIMER_TF; - //set AF to 1 masks it from changing, as per data-sheet - status2 |= RTCC_ALARM_AF; + getDateTime(); + //set status2 TF val to zero to reset timer + status2 &= ~RTCC_TIMER_TF; + //set AF to 1 masks it from changing, as per data-sheet + status2 |= RTCC_ALARM_AF; - Wire.beginTransmission(Rtcc_Addr); - Wire.write((byte)RTCC_STAT2_ADDR); - Wire.write((byte)status2); - Wire.endTransmission(); + Wire.beginTransmission(Rtcc_Addr); + Wire.write((byte)RTCC_STAT2_ADDR); + Wire.write((byte)status2); + Wire.endTransmission(); } /** @@ -466,41 +482,41 @@ void Rtc_Pcf8563::resetTimer(void) */ void Rtc_Pcf8563::setSquareWave(byte frequency) { - Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal - Wire.write((byte)RTCC_SQW_ADDR); - Wire.write((byte)frequency); - Wire.endTransmission(); + Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal + Wire.write((byte)RTCC_SQW_ADDR); + Wire.write((byte)frequency); + Wire.endTransmission(); } void Rtc_Pcf8563::clearSquareWave() { - Rtc_Pcf8563::setSquareWave(SQW_DISABLE); + Rtc_Pcf8563::setSquareWave(SQW_DISABLE); } const char *Rtc_Pcf8563::formatTime(byte style) { getTime(); switch (style) { - case RTCC_TIME_HM: - strOut[0] = '0' + (hour / 10); - strOut[1] = '0' + (hour % 10); - strOut[2] = ':'; - strOut[3] = '0' + (minute / 10); - strOut[4] = '0' + (minute % 10); - strOut[5] = '\0'; - break; - case RTCC_TIME_HMS: - default: - strOut[0] = '0' + (hour / 10); - strOut[1] = '0' + (hour % 10); - strOut[2] = ':'; - strOut[3] = '0' + (minute / 10); - strOut[4] = '0' + (minute % 10); - strOut[5] = ':'; - strOut[6] = '0' + (sec / 10); - strOut[7] = '0' + (sec % 10); - strOut[8] = '\0'; - break; + case RTCC_TIME_HM: + strOut[0] = '0' + (hour / 10); + strOut[1] = '0' + (hour % 10); + strOut[2] = ':'; + strOut[3] = '0' + (minute / 10); + strOut[4] = '0' + (minute % 10); + strOut[5] = '\0'; + break; + case RTCC_TIME_HMS: + default: + strOut[0] = '0' + (hour / 10); + strOut[1] = '0' + (hour % 10); + strOut[2] = ':'; + strOut[3] = '0' + (minute / 10); + strOut[4] = '0' + (minute % 10); + strOut[5] = ':'; + strOut[6] = '0' + (sec / 10); + strOut[7] = '0' + (sec % 10); + strOut[8] = '\0'; + break; } return strOut; } @@ -508,98 +524,97 @@ const char *Rtc_Pcf8563::formatTime(byte style) const char *Rtc_Pcf8563::formatDate(byte style) { - getDate(); - - switch (style) { - - case RTCC_DATE_ASIA: - //do the asian style, yyyy-mm-dd - if (century ){ - strDate[0] = '1'; - strDate[1] = '9'; - } - else { - strDate[0] = '2'; - strDate[1] = '0'; - } - strDate[2] = '0' + (year / 10 ); - strDate[3] = '0' + (year % 10); - strDate[4] = '-'; - strDate[5] = '0' + (month / 10); - strDate[6] = '0' + (month % 10); - strDate[7] = '-'; - strDate[8] = '0' + (day / 10); - strDate[9] = '0' + (day % 10); - strDate[10] = '\0'; - break; - case RTCC_DATE_US: - //the pitiful US style, mm/dd/yyyy - strDate[0] = '0' + (month / 10); - strDate[1] = '0' + (month % 10); - strDate[2] = '/'; - strDate[3] = '0' + (day / 10); - strDate[4] = '0' + (day % 10); - strDate[5] = '/'; - if (century){ - strDate[6] = '1'; - strDate[7] = '9'; - } - else { - strDate[6] = '2'; - strDate[7] = '0'; - } - strDate[8] = '0' + (year / 10 ); - strDate[9] = '0' + (year % 10); - strDate[10] = '\0'; - break; - case RTCC_DATE_WORLD: - default: - //do the world style, dd-mm-yyyy - strDate[0] = '0' + (day / 10); - strDate[1] = '0' + (day % 10); - strDate[2] = '-'; - strDate[3] = '0' + (month / 10); - strDate[4] = '0' + (month % 10); - strDate[5] = '-'; - - if (century){ - strDate[6] = '1'; - strDate[7] = '9'; - } - else { - strDate[6] = '2'; - strDate[7] = '0'; - } - strDate[8] = '0' + (year / 10 ); - strDate[9] = '0' + (year % 10); - strDate[10] = '\0'; - break; + getDate(); + switch (style) { + case RTCC_DATE_ISO8601: + if (century ) { + strDate[0] = '1'; + strDate[1] = '9'; + } else { + strDate[0] = '2'; + strDate[1] = '0'; } - return strDate; + + strDate[2] = '0' + (year / 10 ); + strDate[3] = '0' + (year % 10); + strDate[4] = '-'; + strDate[5] = '0' + (month / 10); + strDate[6] = '0' + (month % 10); + strDate[7] = '-'; + strDate[8] = '0' + (day / 10); + strDate[9] = '0' + (day % 10); + strDate[10] = '\0'; + break; + case RTCC_DATE_US: + // the utterly bonkers US style, mm/dd/yyyy + strDate[0] = '0' + (month / 10); + strDate[1] = '0' + (month % 10); + strDate[2] = '/'; + strDate[3] = '0' + (day / 10); + strDate[4] = '0' + (day % 10); + strDate[5] = '/'; + + if (century) { + strDate[6] = '1'; + strDate[7] = '9'; + } else { + strDate[6] = '2'; + strDate[7] = '0'; + } + + strDate[8] = '0' + (year / 10 ); + strDate[9] = '0' + (year % 10); + strDate[10] = '\0'; + break; + case RTCC_DATE_WORLD: + default: + //do the world style, dd-mm-yyyy + strDate[0] = '0' + (day / 10); + strDate[1] = '0' + (day % 10); + strDate[2] = '-'; + strDate[3] = '0' + (month / 10); + strDate[4] = '0' + (month % 10); + strDate[5] = '-'; + + if (century) { + strDate[6] = '1'; + strDate[7] = '9'; + } else { + strDate[6] = '2'; + strDate[7] = '0'; + } + + strDate[8] = '0' + (year / 10 ); + strDate[9] = '0' + (year % 10); + strDate[10] = '\0'; + break; + } + + return strDate; } void Rtc_Pcf8563::initClock() { - Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal - Wire.write((byte)0x0); // start address + Wire.beginTransmission(Rtcc_Addr); // Issue I2C start signal + Wire.write((byte)0x0); // start address - Wire.write((byte)0x0); //control/status1 - Wire.write((byte)0x0); //control/status2 - Wire.write((byte)0x81); //set seconds & VL - Wire.write((byte)0x01); //set minutes - Wire.write((byte)0x01); //set hour - Wire.write((byte)0x01); //set day - Wire.write((byte)0x01); //set weekday - Wire.write((byte)0x01); //set month, century to 1 - Wire.write((byte)0x01); //set year to 99 - Wire.write((byte)0x80); //minute alarm value reset to 00 - Wire.write((byte)0x80); //hour alarm value reset to 00 - Wire.write((byte)0x80); //day alarm value reset to 00 - Wire.write((byte)0x80); //weekday alarm value reset to 00 - Wire.write((byte)0x0); //set SQW, see: setSquareWave - Wire.write((byte)0x0); //timer off - Wire.endTransmission(); + Wire.write((byte)0x0); //control/status1 + Wire.write((byte)0x0); //control/status2 + Wire.write((byte)0x81); //set seconds & VL + Wire.write((byte)0x01); //set minutes + Wire.write((byte)0x01); //set hour + Wire.write((byte)0x01); //set day + Wire.write((byte)0x01); //set weekday + Wire.write((byte)0x01); //set month, century to 1 + Wire.write((byte)0x01); //set year to 99 + Wire.write((byte)0x80); //minute alarm value reset to 00 + Wire.write((byte)0x80); //hour alarm value reset to 00 + Wire.write((byte)0x80); //day alarm value reset to 00 + Wire.write((byte)0x80); //weekday alarm value reset to 00 + Wire.write((byte)0x0); //set SQW, see: setSquareWave + Wire.write((byte)0x0); //timer off + Wire.endTransmission(); } void Rtc_Pcf8563::setTime(byte hour, byte minute, byte sec) @@ -611,130 +626,190 @@ void Rtc_Pcf8563::setTime(byte hour, byte minute, byte sec) void Rtc_Pcf8563::setDate(byte day, byte weekday, byte month, bool century, byte year) { - getDateTime(); - setDateTime(day, weekday, month, century, year, - getHour(), getMinute(), getSecond()); + getDateTime(); + setDateTime(day, weekday, month, century, year, + getHour(), getMinute(), getSecond()); } void Rtc_Pcf8563::getDate() { - getDateTime(); + getDateTime(); } void Rtc_Pcf8563::getTime() { - getDateTime(); + getDateTime(); } -bool Rtc_Pcf8563::getVoltLow(void) +bool Rtc_Pcf8563::getVoltLow() { - return volt_low; + return volt_low; } -byte Rtc_Pcf8563::getSecond() { - return sec; +byte Rtc_Pcf8563::getSecond() +{ + return sec; } -byte Rtc_Pcf8563::getMinute() { - return minute; +byte Rtc_Pcf8563::getMinute() +{ + return minute; } -byte Rtc_Pcf8563::getHour() { - return hour; +byte Rtc_Pcf8563::getHour() +{ + return hour; } -byte Rtc_Pcf8563::getAlarmMinute() { - return alarm_minute; +byte Rtc_Pcf8563::getAlarmMinute() +{ + return alarm_minute; } -byte Rtc_Pcf8563::getAlarmHour() { - return alarm_hour; +byte Rtc_Pcf8563::getAlarmHour() +{ + return alarm_hour; } -byte Rtc_Pcf8563::getAlarmDay() { - return alarm_day; +byte Rtc_Pcf8563::getAlarmDay() +{ + return alarm_day; } -byte Rtc_Pcf8563::getAlarmWeekday() { - return alarm_weekday; +byte Rtc_Pcf8563::getAlarmWeekday() +{ + return alarm_weekday; } -byte Rtc_Pcf8563::getTimerControl() { - return timer_control; +byte Rtc_Pcf8563::getTimerControl() +{ + return timer_control; } -byte Rtc_Pcf8563::getTimerValue() { +byte Rtc_Pcf8563::getTimerValue() +{ // Impossible to freeze this value, it could // be changing during read. Multiple reads // required to check for consistency. uint8_t last_value; do { - last_value = timer_value; - getDateTime(); + last_value = timer_value; + getDateTime(); } while (timer_value != last_value); + return timer_value; } -byte Rtc_Pcf8563::getDay() { - return day; +byte Rtc_Pcf8563::getDay() +{ + return day; } -byte Rtc_Pcf8563::getMonth() { - return month; +byte Rtc_Pcf8563::getMonth() +{ + return month; } -byte Rtc_Pcf8563::getYear() { - return year; +byte Rtc_Pcf8563::getYear() +{ + return year; } -bool Rtc_Pcf8563::getCentury() { - return century; +bool Rtc_Pcf8563::getCentury() +{ + return century; } -byte Rtc_Pcf8563::getWeekday() { - return weekday; +byte Rtc_Pcf8563::getWeekday() +{ + return weekday; } -byte Rtc_Pcf8563::getStatus1() { - return status1; +byte Rtc_Pcf8563::getStatus1() +{ + return status1; } -byte Rtc_Pcf8563::getStatus2() { - return status2; +byte Rtc_Pcf8563::getStatus2() +{ + return status2; } -unsigned long Rtc_Pcf8563::getTimestamp(){ - getDateTime(); // update date and time - unsigned long timestamp = 0; +unsigned long Rtc_Pcf8563::getTimestamp() +{ + getDateTime(); // update date and time + unsigned long timestamp = 0; - // Convert years in days - timestamp = (year-epoch_year)*365; // convert years in days + // Convert years in days + timestamp = (year-epoch_year) * 365; // convert years in days - if((year-epoch_year)>1) // add a dy when it's a leap year - { - for(unsigned char i = epoch_year; i2&&isLeapYear(century, year)) timestamp++; // test for the year's febuary + if((year-epoch_year)>1) { // add a dy when it's a leap year + for(unsigned char i = epoch_year; i1) timestamp += months_days[month-2]; + if(month>2 && isLeapYear(century, year)) { + timestamp++; // test for the year's febuary + } - // add days - timestamp += (day-epoch_day); + // add months converted in days + if(month>1) timestamp += months_days[month-2]; - timestamp*= 86400; // convert days in seconds + // add days + timestamp += (day-epoch_day); - // convert time to second and add it to timestamp - unsigned long timeTemp = hour*60+ minute; - timeTemp *=60; - timeTemp += sec; + timestamp *= 86400; // convert days in seconds - timestamp += timeTemp; // add hours +minutes + seconds + // convert time to second and add it to timestamp + unsigned long timeTemp = hour*60+ minute; + timeTemp *= 60; + timeTemp += sec; - timestamp += EPOCH_TIMESTAMP; // add epoch reference + timestamp += timeTemp; // add hours +minutes + seconds - return timestamp; + timestamp += EPOCH_TIMESTAMP; // add epoch reference + + return timestamp; } + +uint64_t Rtc_Pcf8563::getTimestamp64() +{ + getDateTime(); // update date and time + uint64_t timestamp = 0; + + // Convert years in days + timestamp = (year - epoch_year) * 365; // convert years to days + + if((year - epoch_year) > 1) { // add a day when it's a leap year + for(unsigned char i = epoch_year; i 2 && isLeapYear(century, year)) { + timestamp++; // test for the year's febuary + } + + // add months converted in days + if(month > 1) { + timestamp += months_days[month-2]; + } + + // add days + timestamp += (day-epoch_day); + + timestamp *= 86400; // convert days in seconds + + // convert time to second and add it to timestamp + unsigned long timeTemp = hour * 60 + minute; + timeTemp *= 60; + timeTemp += sec; + + timestamp += timeTemp; // add hours +minutes + seconds + timestamp += EPOCH_TIMESTAMP; // add epoch reference + + return timestamp; +} \ No newline at end of file diff --git a/lib/Rtc_Pcf8563/Rtc_Pcf8563.h b/lib/Rtc_Pcf8563/Rtc_Pcf8563.h index 3096030..99a0870 100644 --- a/lib/Rtc_Pcf8563/Rtc_Pcf8563.h +++ b/lib/Rtc_Pcf8563/Rtc_Pcf8563.h @@ -102,7 +102,8 @@ /* date format flags */ #define RTCC_DATE_WORLD 0x01 -#define RTCC_DATE_ASIA 0x02 +#define RTCC_DATE_ISO8601 0x02 +#define RTCC_DATE_ASIA 0x02 // It's not "asian", it's ISO8601, that anybody with any sense uses #define RTCC_DATE_US 0x04 /* time format flags */ #define RTCC_TIME_HMS 0x01 @@ -198,6 +199,7 @@ class Rtc_Pcf8563 { byte getTimerValue(); unsigned long getTimestamp(); // return unix timestamp + uint64_t getTimestamp64(); // Fixed for 2038+ // Sets date/time to static fixed values, disable all alarms // use zeroClock() above to guarantee lowest possible values instead.