diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7dffb04 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 FACTS Engineering, LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..25d6865 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# PCF8563 RTC Arduino Library + +Arduino library for the P1AM-200 PCF8563 RTC chip. + +Use the Arduino Library Manager to install. + +## Example +Here is a simple example which shows the capabilities of the library +```cpp +#include + +void setup(){ + Serial.begin(9600); + while(!Serial){ + ; + } + Serial.println(PCF8563_RTC.getEpoch()); //Print RTC's epoch time +} + +void loop(){ +} +``` diff --git a/examples/CheckLowVoltageBit/CheckLowVoltageBit.ino b/examples/CheckLowVoltageBit/CheckLowVoltageBit.ino new file mode 100644 index 0000000..7dd95e9 --- /dev/null +++ b/examples/CheckLowVoltageBit/CheckLowVoltageBit.ino @@ -0,0 +1,42 @@ +/* + Example: CheckLowVoltageBit + + This example checks the voltage low bit of the RTC. + The voltage low bit in the RTC is set when the RTC voltage falls below the low voltage threshold + (0.9V). + The current Unix time stamp is measured as seconds since January 1st, 1970 and can be + found here. https://www.unixtimestamp.com/index.php + + This example will check the low voltage bit of the PCF8563 RTC. In the case that the low voltage + bit is set the time is invalid. Otherwise the saved time will be displayed. + + Written by FACTS Engineering + Copyright (c) 2023 FACTS Engineering, LLC + Licensed under the MIT license. +*/ + +#include + + +void setup(){ // the setup routine runs once: + + Serial.begin(9600); //start serial monitor connection for display + while(!Serial){ //wait for connection to serial monitor + ; + } + + bool checkVolt = PCF8563_RTC.lowVolt(); + Serial.print("Is saved time valid? "); + if(PCF8563_RTC.lowVolt()){ + Serial.println("No. "); + } + else{ + Serial.print("Yes: "); + Serial.println(PCF8563_RTC.getEpoch()); //get saved time + } + delay(1000); //delay 1 second +} + + +void loop(){ // the loop routine runs over and over again forever +} diff --git a/examples/NTPserver/NTPserver.ino b/examples/NTPserver/NTPserver.ino new file mode 100644 index 0000000..809e5c3 --- /dev/null +++ b/examples/NTPserver/NTPserver.ino @@ -0,0 +1,128 @@ +/* + Example: NTPServer + + This example gets the current time from an NTP server (time.nist.gov). + The RTC is set to the Unix time stamp read from the server. + + The current Unix time stamp is measured as seconds since January 1st, 1970 and can be + found here. https://www.unixtimestamp.com/index.php + + This example uses and ethernet shield. + + created 4 Sep 2010 + by Michael Margolis + modified 9 Apr 2012 + by Tom Igoe + + Modified by FACTS Engineering +*/ + +#include +#include + +uint8_t mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; + +IPAddress ip(192, 168, 6, 177); +IPAddress myDns(192, 168, 0, 1); + +const char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server +const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message +byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets + +EthernetUDP Udp; +void setup(){ // the setup routine runs once: + + Serial.begin(9600); //start serial monitor connection for display + while(!Serial){ //wait for connection to serial monitor + ; + } + + Ethernet.init(5); // MKR ETH shield + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Ethernet.begin(mac, ip, myDns); + } + else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + + Udp.begin(8888); + // give the Ethernet shield a second to initialize: + delay(1000); + setTime(); +} + +unsigned int current_time = 0; + +void loop(){ // the loop routine runs over and over again forever: + current_time = PCF8563_RTC.getEpoch(); + Serial.println(current_time); + Serial.println(); + + delay(5000); //delay 5 seconds +} + +// send an NTP request to the time server at the given address +void sendNTPpacket(const char * address) { + // set all bytes in the buffer to 0 + memset(packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + packetBuffer[0] = 0b11100011; // LI, Version, Mode + packetBuffer[1] = 0; // Stratum, or type of clock + packetBuffer[2] = 6; // Polling Interval + packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + packetBuffer[12] = 49; + packetBuffer[13] = 0x4E; + packetBuffer[14] = 49; + packetBuffer[15] = 52; + + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + Udp.beginPacket(address, 123); // NTP requests are to port 123 + Udp.write(packetBuffer, NTP_PACKET_SIZE); + Udp.endPacket(); +} + +void setTime() { + sendNTPpacket(timeServer); // send an NTP packet to a time server + + // wait to see if a reply is available + delay(1000); + if (Udp.parsePacket()) { + // We've received a packet, read the data from it + Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer + + // the timestamp starts at byte 40 of the received packet and is four bytes, + // or two words, long. First, extract the two words: + unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); + unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); + // combine the four bytes (two words) into a long integer + // this is NTP time (seconds since Jan 1 1900): + unsigned long secsSince1900 = highWord << 16 | lowWord; + + // now convert NTP time into everyday time: + // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: + const unsigned long seventyYears = 2208988800UL; + // subtract seventy years: + unsigned long epoch = secsSince1900 - seventyYears; + // print Unix time: + PCF8563_RTC.setEpoch(epoch); + delay(1000); //delay 1 second + } +} diff --git a/examples/SetEpoch/SetEpoch.ino b/examples/SetEpoch/SetEpoch.ino new file mode 100644 index 0000000..8c91285 --- /dev/null +++ b/examples/SetEpoch/SetEpoch.ino @@ -0,0 +1,37 @@ +/* + Example: SetEpochUnix + + This example shows how to set the RTC to a given date and time using char arrays. + The current Unix time stamp is measured as seconds since January 1st, 1970 and can be + found here. https://www.unixtimestamp.com/index.php + + This example will set the time to 8:00am Janurary 1st, 2021 and read the date and time from + the RTC every 5 seconds. This Unix time stamp is 1609488000. + + Written by FACTS Engineering + Copyright (c) 2023 FACTS Engineering, LLC + Licensed under the MIT license. +*/ + +#include + +void setup(){ // the setup routine runs once: + + Serial.begin(9600); //start serial monitor connection for display + while(!Serial){ //wait for connection to serial monitor + ; + } + + PCF8563_RTC.setEpoch("Jan 01 2021 Fri", "08:00:00"); //set time to 8:00am Janurary 1st, 2021 + delay(1000); //delay 1 second +} + +unsigned int current_time = 0; + +void loop(){ // the loop routine runs over and over again forever: + current_time = PCF8563_RTC.getEpoch(); //get current time from PCF8563 RTC + Serial.println(current_time); //print time + Serial.println(); + + delay(5000); //delay 5 seconds +} diff --git a/examples/SetEpochUnix/SetEpochUnix.ino b/examples/SetEpochUnix/SetEpochUnix.ino new file mode 100644 index 0000000..9c96eab --- /dev/null +++ b/examples/SetEpochUnix/SetEpochUnix.ino @@ -0,0 +1,37 @@ +/* + Example: SetEpochUnix + + This example shows how to set the RTC to a Unix time stamp. + The current Unix time stamp is measured as seconds since January 1st, 1970 and can be + found here. https://www.unixtimestamp.com/index.php + + This example will set the time to 8:00am Janurary 1st, 2021 and read the date and time from + the RTC every 5 seconds.This Unix time stamp is 1609488000. + + Written by FACTS Engineering + Copyright (c) 2023 FACTS Engineering, LLC + Licensed under the MIT license. +*/ + +#include + +void setup(){ // the setup routine runs once: + + Serial.begin(9600); //start serial monitor connection for display + while(!Serial){ //wait for connection to serial monitor + ; + } + + PCF8563_RTC.setEpoch(1609488000); //set time to 8:00am Janurary 1st, 2021 + delay(1000); //delay 1 second +} + +unsigned int current_time = 0; + +void loop(){ // the loop routine runs over and over again forever: + current_time = PCF8563_RTC.getEpoch(); //get current time from PCF8563 RTC + Serial.println(current_time); //print time + Serial.println(); + + delay(5000); //delay 5 seconds +} diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..c43b9a3 --- /dev/null +++ b/keywords.txt @@ -0,0 +1,23 @@ +####################################### +# Syntax Coloring Map For RTC +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +PCF8563 KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +getEpoch KEYWORD2 +setEpoch KEYWORD2 +startClock KEYWORD2 +stopClock KEYWORD2 +lowVolt KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..551c519 --- /dev/null +++ b/library.properties @@ -0,0 +1,9 @@ +name=PCF8563_RTC +version=1.0.0 +author=FACTS Engineering +maintainer=FACTS Engineering +sentence=A library that interfaces with the PCF8563 RTC. +paragraph= +category=Timing +url=https://github.com/facts-engineering/PCF8563_RTC +architectures=samd diff --git a/src/PCF8563.cpp b/src/PCF8563.cpp new file mode 100644 index 0000000..13450b6 --- /dev/null +++ b/src/PCF8563.cpp @@ -0,0 +1,414 @@ +/* +MIT License + +Copyright (c) 2023 FACTS Engineering, LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include + +PCF8563Class::PCF8563Class(TwoWire &wirePort){ + rtc_port = &wirePort; +} +PCF8563Class PCF8563_RTC; + + + +/******************************************************************************* +Description: Sets the RTC to the provided Unix time stamp + +Parameters: -unix time stamp + +Returns: -none +*******************************************************************************/ + + void PCF8563Class::setEpoch(time_t epoch) + { + struct tm * ptm; //storage UTC time + uint8_t century = 0; + uint8_t temp = 0; + uint8_t month = 0; + + if(initialized == false){ + initialize(); + } + + ptm = gmtime(&epoch); + + if(ptm->tm_year < 70 || ptm->tm_year > 199){ + Serial.println("Invalid start year. "); + return; + } + + if(ptm->tm_year >= 100){ + temp = ptm->tm_year % 100; + century = 1; + } + else{ + temp = ptm->tm_year % 100; + century = 0; + } + + month = dec2bcd(ptm->tm_mon, century); + + stopClock(); + rtc_port->beginTransmission(PCF8563_ADDR_W); + rtc_port->write(0x02); // Second Register + rtc_port->write(dec2bcd(ptm->tm_sec) & 0x7F); + rtc_port->write(dec2bcd(ptm->tm_min) & 0x7F); + rtc_port->write(dec2bcd(ptm->tm_hour) & 0x3F); + rtc_port->write(dec2bcd(ptm->tm_mday) & 0x3F); + rtc_port->write(dec2bcd(ptm->tm_wday) & 0x03); + rtc_port->write(month); + rtc_port->write(dec2bcd(temp)); + rtc_port->endTransmission(); + startClock(); + } + +/******************************************************************************* +Description: Sets the RTC to the provided english time and date string provided + +Parameters: -Date and time in the following format + Example date and time: "Jan 13 2021 Wed", "07:27:45" + +Returns: -none +*******************************************************************************/ + void PCF8563Class::setEpoch(char* date, char* time) + { + uint8_t day, month, hour, minute, second, weekday, century; + uint16_t year; + + if(initialized == false){ + initialize(); + } + + switch (date[0]) { + case 'J': + if(date[1] == 'a'){ + month = 0; //set month to Jan + break; + } + else{ + if(date[2] == 'n'){ + month = 5; //set month to June + break; + } + else{ + month = 6; //set month to July + break; + } + } + case 'F': + month = 1; + break; + case 'A': + if(date[2] == 'r'){ + month = 3; + break; + } + else { + month = 7; + break; + } + case 'M': + if(date[2] == 'r'){ + month = 2; + break; + } + else{ + month = 4; + break; + } + case 'S': + month = 8; + break; + case 'O': + month = 9; + break; + case 'N': + month = 10; + break; + case 'D': + month = 11; + break; + } + + switch (date[12]) { + case 'M': + weekday = 1; + break; + case 'T': + if(date[13] == 'u'){ + weekday = 2; + break; + } + else{ + weekday = 4; + break; + } + case 'W': + weekday = 3; + break; + case 'F': + weekday = 5; + break; + case 'S': + if(date[13] == 'a'){ + weekday = 6; + break; + } + else{ + weekday = 0; + break; + } + } + + second = atoi(time + 6); + minute = atoi(time + 3); + hour = atoi(time); + day = atoi(date + 4); + year = atoi(date + 7); + if(year < 1970 || year > 2099){ + Serial.println("Invalid start year. "); + return; + } + + if(year >= 2000){ + year = year % 100; + century = 1; + } + else{ + year = year % 100; + century = 0; + } + + stopClock(); + rtc_port->beginTransmission(PCF8563_ADDR_W); + rtc_port->write(0x02); // Second Register + rtc_port->write(dec2bcd(second) & 0x7F); + rtc_port->write(dec2bcd(minute) & 0x7F); + rtc_port->write(dec2bcd(hour) & 0x3F); + rtc_port->write(dec2bcd(day) & 0x3F); + rtc_port->write(dec2bcd(weekday) & 0x03); + rtc_port->write(dec2bcd(month, century)); + rtc_port->write(dec2bcd(year)); + rtc_port->endTransmission(); + startClock(); + } + +/******************************************************************************* +Description: Reads epoch from RTC and formats it into Unix time stamp + +Parameters: -None + +Returns: -Current Unix time stamp +*******************************************************************************/ + time_t PCF8563Class::getEpoch() + { + uint8_t second; + uint8_t minute; + uint8_t hour; + uint8_t day; + uint8_t week; + uint8_t month; + uint16_t year; + uint8_t century; + + if(initialized == false){ + initialize(); + } + + rtc_port->beginTransmission(PCF8563_ADDR_W); + rtc_port->write(0x02); + rtc_port->endTransmission(); + rtc_port->requestFrom(PCF8563_ADDR_R, 7); + second = bcd2dec(rtc_port->read() & 0x7F); + minute = bcd2dec(rtc_port->read() & 0x7F); + hour = bcd2dec(rtc_port->read() & 0x3F); + day = bcd2dec(rtc_port->read() & 0x3F); + week = bcd2dec(rtc_port->read() & 0x07); + month = rtc_port->read() & 0x9F; + year = bcd2dec(rtc_port->read() & 0xFF); + rtc_port->endTransmission(); + + century = (month & 0x80) >> 7; + month = bcd2dec(month & 0x1F); + + time_t epoch; + struct tm epoch_tm; + + epoch_tm.tm_sec = second; + epoch_tm.tm_min = minute; + epoch_tm.tm_hour = hour; + epoch_tm.tm_wday = week; + epoch_tm.tm_mday = day; + epoch_tm.tm_mon = month - 1; + epoch_tm.tm_year = year + (100 * (century)); + + epoch = mktime (&epoch_tm); + + return (epoch); + } + +/******************************************************************************* +Description: Clears the RTC stop bit so the RTC will operate. + +Parameters: -None + +Returns: -None +*******************************************************************************/ + + void PCF8563Class::startClock(void) + { + uint8_t data; + + if(initialized == false){ + initialize(); + } + + rtc_port->beginTransmission(PCF8563_ADDR_W); + rtc_port->write(0x00); + rtc_port->endTransmission(); + + rtc_port->requestFrom(PCF8563_ADDR_R, 1); + data = rtc_port->read(); + + bitClear(data, 5); + + rtc_port->beginTransmission(PCF8563_ADDR_W); + rtc_port->write(0x00); + rtc_port->write(data); + rtc_port->endTransmission(); + } + +/******************************************************************************* +Description: Sets the RTC stop bit so the RTC will not count. + +Parameters: -None + +Returns: -None +*******************************************************************************/ + + void PCF8563Class::stopClock(void) + { + uint8_t data; + + if(initialized == false){ + initialize(); + } + + rtc_port->beginTransmission(PCF8563_ADDR_W); + rtc_port->write(0x00); + rtc_port->endTransmission(); + + rtc_port->requestFrom(PCF8563_ADDR_R, 1); + data = rtc_port->read(); + + bitSet(data, 5); + + rtc_port->beginTransmission(PCF8563_ADDR_W); + rtc_port->write(0x00); + rtc_port->write(data); + rtc_port->endTransmission(); + } + +/******************************************************************************* +Description: Checks low voltage bit on PCF8563. Indicates if power has fallen + below the threshold and time is no longer valid. + +Parameters: -None + +Returns: -Boolean True if low voltage is detected. + Boolean False if voltage is fine. +*******************************************************************************/ + + bool PCF8563Class::lowVolt(void) + { + uint8_t data; + + if(initialized == false){ + initialize(); + } + + rtc_port->beginTransmission(PCF8563_ADDR_W); + rtc_port->write(0x02); + rtc_port->endTransmission(); + + rtc_port->requestFrom(PCF8563_ADDR_R, 1); + data = rtc_port->read(); + + if(bitRead(data, 7) == 1) + { + return true; + } + return false; + } + +/******************************************************************************* +Description: Private functions to convert from BCD to Binary and vice versa. + Initialize starts i2c communication for the PCF8563 RTC. +*******************************************************************************/ + + void PCF8563Class::initialize (void) + { + INTERNAL_EEPROM_PORT.begin(); + initialized = true; + } + + uint8_t PCF8563Class::dec2bcd(uint8_t inVal){ + uint8_t bcdVal = 0; + uint8_t loByte = 0; + uint8_t hiByte = 0; + + loByte = inVal % 10; + hiByte = inVal / 10; + + bcdVal = (hiByte << 4) | loByte; + return bcdVal; + } + + uint8_t PCF8563Class::dec2bcd(uint8_t inVal, uint8_t century){ + uint8_t bcdVal = 0; + uint8_t loByte = 0; + uint8_t hiByte = 0; + + loByte = (inVal % 10) + 1; + hiByte = inVal / 10; + + bcdVal = (hiByte << 4) | loByte; + + bcdVal = bcdVal | (century << 7); + bcdVal = bcdVal & 0x9F; + + return bcdVal; + } + + uint8_t PCF8563Class::bcd2dec(uint8_t inVal){ + uint8_t decVal = 0; + uint8_t loByte = 0; + uint8_t hiByte = 0; + + loByte = inVal & 0x0F; + hiByte = (inVal & 0xF0) >> 4; + + decVal = ((hiByte * 10) + loByte); + + return decVal; + } diff --git a/src/PCF8563.h b/src/PCF8563.h new file mode 100644 index 0000000..c65bd67 --- /dev/null +++ b/src/PCF8563.h @@ -0,0 +1,68 @@ +/* +MIT License + +Copyright (c) 2023 FACTS Engineering, LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef PCF8563_H +#define PCF8563_H + +#include "Arduino.h" + + #include + #include + #include + + #define PCF8563_ADDR_R 0x51 + #define PCF8563_ADDR_W 0x51 + + #ifndef INTERNAL_RTC_PORT + #define INTERNAL_RTC_PORT Wire //Assume using standard I2C port and external device + #endif + + class PCF8563Class + { + public: + PCF8563Class(TwoWire &wirePort = INTERNAL_RTC_PORT); + + TwoWire *rtc_port; + + /* Epoch Functions */ + time_t getEpoch(); + void setEpoch(time_t epoch); + void setEpoch(char* date, char* time); + + void startClock(); + void stopClock(); + + bool lowVolt(); + + private: + bool initialized = false; + void initialize(); + + uint8_t dec2bcd(uint8_t inVal); + uint8_t dec2bcd(uint8_t inVal, uint8_t century); + uint8_t bcd2dec(uint8_t inVal); + }; + +extern PCF8563Class PCF8563_RTC; +#endif