From 3dfc437a1520fac74613666b4f2e4944487782f0 Mon Sep 17 00:00:00 2001 From: g7uhn Date: Sat, 6 Feb 2021 16:12:33 +0000 Subject: [PATCH] added SparkFun DS1307 lib to repo --- .../LICENSE.md | 57 ++ .../README.md | 46 ++ .../DS1307_RTC_Demo/DS1307_RTC_Demo.ino | 104 ++++ .../keywords.txt | 61 +++ .../library.properties | 10 + .../src/SparkFunDS1307RTC.cpp | 499 ++++++++++++++++++ .../src/SparkFunDS1307RTC.h | 179 +++++++ 7 files changed, 956 insertions(+) create mode 100644 Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/LICENSE.md create mode 100644 Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/README.md create mode 100644 Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/examples/DS1307_RTC_Demo/DS1307_RTC_Demo.ino create mode 100644 Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/keywords.txt create mode 100644 Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/library.properties create mode 100644 Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/src/SparkFunDS1307RTC.cpp create mode 100644 Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/src/SparkFunDS1307RTC.h diff --git a/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/LICENSE.md b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/LICENSE.md new file mode 100644 index 0000000..f5cfad0 --- /dev/null +++ b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/LICENSE.md @@ -0,0 +1,57 @@ +SparkFun License Information +============================ + +SparkFun uses two different licenses for our files - one for hardware and one for code. + +Hardware +--------- + +**SparkFun hardware is released under [Creative Commons Share-alike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/).** + +Note: This is a human-readable summary of (and not a substitute for) the [license](http://creativecommons.org/licenses/by-sa/4.0/legalcode). + +You are free to: + +Share — copy and redistribute the material in any medium or format +Adapt — remix, transform, and build upon the material +for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. +ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. +No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. +Notices: + +You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material. + + +Code +-------- + +**SparkFun code, firmware, and software is released under the [MIT License](http://opensource.org/licenses/MIT).** + +The MIT License (MIT) + +Copyright (c) 2016 SparkFun Electronics, Inc. + +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/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/README.md b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/README.md new file mode 100644 index 0000000..7c23833 --- /dev/null +++ b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/README.md @@ -0,0 +1,46 @@ +SparkFun Real Time Clock Module (DS1307) Arduino Library +======================================== + +[![SparkFun Real Time Clock Module](https://cdn.sparkfun.com//assets/parts/9/4/5/4/12708-01.jpg)](https://www.sparkfun.com/products/12708) + +[*SparkFun Real Time Clock Module (BOB-12708)*](https://www.sparkfun.com/products/12708) + +Arduino library for the I2C-based DS1307 real time clock (RTC). Allows you to set and read the time and date, and configure the SQW output pin. + +Repository Contents +------------------- + +* **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE. +* **/src** - Source files for the library (.cpp, .h). +* **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE. +* **library.properties** - General library properties for the Arduino package manager. + +Documentation +-------------- + +* **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library. +* **[Product Repository](https://github.com/sparkfun/RTC-Module/tree/v1.4)** - Main repository (including hardware files) for the Real Time Clock Module. +* **[Hookup Guide](https://learn.sparkfun.com/tutorials/real-time-clock-module-hookup-guide)** - Basic hookup guide for the Real Time Clock Module. + +Products that use this Library +--------------------------------- + +* [SparkFun Real Time Clock Module (BOB-12708)](https://www.sparkfun.com/products/12708)- Basic breakout for the DS1307, including pull-up resistors and a coin cell battery holder. + +Version History +--------------- + +* [V_1.0.0](https://github.com/sparkfun/SparkFun_DS1307_RTC_Arduino_Library/tree/V_1.0.0) - Initial library release + +License Information +------------------- + +This product is _**open source**_! + +Please review the LICENSE.md file for license information. + +If you have any questions or concerns on licensing, please contact techsupport@sparkfun.com. + +Distributed as-is; no warranty is given. + +- Your friends at SparkFun. \ No newline at end of file diff --git a/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/examples/DS1307_RTC_Demo/DS1307_RTC_Demo.ino b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/examples/DS1307_RTC_Demo/DS1307_RTC_Demo.ino new file mode 100644 index 0000000..5e66f8f --- /dev/null +++ b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/examples/DS1307_RTC_Demo/DS1307_RTC_Demo.ino @@ -0,0 +1,104 @@ +/****************************************************************************** +DS1307_RTC_Demo.ino +Jim Lindblom @ SparkFun Electronics +original creation date: October 2, 2016 +https://github.com/sparkfun/SparkFun_DS1307_RTC_Arduino_Library + +Configures, sets, and reads from the DS1307 real-time clock (RTC). + +Resources: +Wire.h - Arduino I2C Library + +Development environment specifics: +Arduino 1.6.8 +SparkFun RedBoard +SparkFun Real Time Clock Module (v14) +******************************************************************************/ +#include +#include + +// Comment out the line below if you want month printed before date. +// E.g. October 31, 2016: 10/31/16 vs. 31/10/16 +#define PRINT_USA_DATE + +#define SQW_INPUT_PIN 2 // Input pin to read SQW +#define SQW_OUTPUT_PIN 13 // LED to indicate SQW's state + +void setup() +{ + // Use the serial monitor to view time/date output + Serial.begin(9600); + pinMode(SQW_INPUT_PIN, INPUT_PULLUP); + pinMode(SQW_OUTPUT_PIN, OUTPUT); + digitalWrite(SQW_OUTPUT_PIN, digitalRead(SQW_INPUT_PIN)); + + rtc.begin(); // Call rtc.begin() to initialize the library + // (Optional) Sets the SQW output to a 1Hz square wave. + // (Pull-up resistor is required to use the SQW pin.) + rtc.writeSQW(SQW_SQUARE_1); + + // Now set the time... + // You can use the autoTime() function to set the RTC's clock and + // date to the compiliers predefined time. (It'll be a few seconds + // behind, but close!) + rtc.autoTime(); + // Or you can use the rtc.setTime(s, m, h, day, date, month, year) + // function to explicitly set the time: + // e.g. 7:32:16 | Monday October 31, 2016: + // rtc.setTime(16, 32, 7, 2, 31, 10, 16); // Uncomment to manually set time + // rtc.set12Hour(); // Use rtc.set12Hour to set to 12-hour mode +} + +void loop() +{ + static int8_t lastSecond = -1; + + // Call rtc.update() to update all rtc.seconds(), rtc.minutes(), + // etc. return functions. + rtc.update(); + + if (rtc.second() != lastSecond) // If the second has changed + { + printTime(); // Print the new time + + lastSecond = rtc.second(); // Update lastSecond value + } + + // Read the state of the SQW pin and show it on the + // pin 13 LED. (It should blink at 1Hz.) + digitalWrite(SQW_OUTPUT_PIN, digitalRead(SQW_INPUT_PIN)); +} + +void printTime() +{ + Serial.print(String(rtc.hour()) + ":"); // Print hour + if (rtc.minute() < 10) + Serial.print('0'); // Print leading '0' for minute + Serial.print(String(rtc.minute()) + ":"); // Print minute + if (rtc.second() < 10) + Serial.print('0'); // Print leading '0' for second + Serial.print(String(rtc.second())); // Print second + + if (rtc.is12Hour()) // If we're in 12-hour mode + { + // Use rtc.pm() to read the AM/PM state of the hour + if (rtc.pm()) Serial.print(" PM"); // Returns true if PM + else Serial.print(" AM"); + } + + Serial.print(" | "); + + // Few options for printing the day, pick one: + Serial.print(rtc.dayStr()); // Print day string + //Serial.print(rtc.dayC()); // Print day character + //Serial.print(rtc.day()); // Print day integer (1-7, Sun-Sat) + Serial.print(" - "); +#ifdef PRINT_USA_DATE + Serial.print(String(rtc.month()) + "/" + // Print month + String(rtc.date()) + "/"); // Print date +#else + Serial.print(String(rtc.date()) + "/" + // (or) print date + String(rtc.month()) + "/"); // Print month +#endif + Serial.println(String(rtc.year())); // Print year +} diff --git a/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/keywords.txt b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/keywords.txt new file mode 100644 index 0000000..4c5cabf --- /dev/null +++ b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/keywords.txt @@ -0,0 +1,61 @@ +####################################### +# Syntax Coloring Map +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +rtc KEYWORD1 +SparkFunDS1307RTC KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +setTime KEYWORD2 +autoTime KEYWORD2 +setSecond KEYWORD2 +setMinute KEYWORD2 +setHour KEYWORD2 +setDay KEYWORD2 +setDate KEYWORD2 +setMonth KEYWORD2 +setYear KEYWORD2 +update KEYWORD2 +second KEYWORD2 +minute KEYWORD2 +hour KEYWORD2 +day KEYWORD2 +dayChar KEYWORD2 +dayStr KEYWORD2 +date KEYWORD2 +month KEYWORD2 +year KEYWORD2 +getSecond KEYWORD2 +getMinute KEYWORD2 +getHour KEYWORD2 +getDay KEYWORD2 +getDate KEYWORD2 +getMonth KEYWORD2 +getYear KEYWORD2 +is12Hour KEYWORD2 +pm KEYWORD2 +writeSQW KEYWORD2 +enable KEYWORD2 +disable KEYWORD2 +set12Hour KEYWORD2 +set24Hour KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +AM LITERAL1 +PM LITERAL1 +SQW_SQUARE_1 LITERAL1 +SQW_SQUARE_4K LITERAL1 +SQW_SQUARE_8K LITERAL1 +SQW_SQUARE_32K LITERAL1 +SQW_LOW LITERAL1 +SQW_HIGH LITERAL1 \ No newline at end of file diff --git a/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/library.properties b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/library.properties new file mode 100644 index 0000000..3f88f90 --- /dev/null +++ b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/library.properties @@ -0,0 +1,10 @@ +name=SparkFun DS1307 Real-Time Clock (RTC) +version=1.0.1 +author=SparkFun Electronics +maintainer=SparkFun Electronics +sentence=The DS1307 is an I2C-based real-time clock (RTC). +paragraph=This library allows you to set and read the DS1307 RTC. +category=Sensors +url=https://github.com/sparkfun/SparkFun_DS1307_RTC_Arduino_Library +architectures=* +includes=Wire.h, SparkFunDS1307RTC.h \ No newline at end of file diff --git a/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/src/SparkFunDS1307RTC.cpp b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/src/SparkFunDS1307RTC.cpp new file mode 100644 index 0000000..678e659 --- /dev/null +++ b/Arduino/lib/SparkFun_DS1307_RTC_Arduino_Library-master/src/SparkFunDS1307RTC.cpp @@ -0,0 +1,499 @@ +/****************************************************************************** +SparkFunDS1307RTC.cpp +Jim Lindblom @ SparkFun Electronics +original creation date: October 2, 2016 +https://github.com/sparkfun/SparkFun_DS1307_RTC_Arduino_Library + +Implementation of DS1307 real time clock functions + +Resources: +Wire.h - Arduino I2C Library + +Development environment specifics: +Arduino 1.6.8 +SparkFun RedBoard +SparkFun Real Time Clock Module (v14) +******************************************************************************/ + +#include "SparkFunDS1307RTC.h" + +// Parse the __DATE__ predefined macro to generate date defaults: +// __Date__ Format: MMM DD YYYY (First D may be a space if <10) +// +#define BUILD_MONTH_JAN ((__DATE__[0] == 'J') && (__DATE__[1] == 'a')) ? 1 : 0 +#define BUILD_MONTH_FEB (__DATE__[0] == 'F') ? 2 : 0 +#define BUILD_MONTH_MAR ((__DATE__[0] == 'M') && (__DATE__[1] == 'a') && (__DATE__[2] == 'r')) ? 3 : 0 +#define BUILD_MONTH_APR ((__DATE__[0] == 'A') && (__DATE__[1] == 'p')) ? 4 : 0 +#define BUILD_MONTH_MAY ((__DATE__[0] == 'M') && (__DATE__[1] == 'a') && (__DATE__[2] == 'y')) ? 5 : 0 +#define BUILD_MONTH_JUN ((__DATE__[0] == 'J') && (__DATE__[1] == 'u') && (__DATE__[2] == 'n')) ? 6 : 0 +#define BUILD_MONTH_JUL ((__DATE__[0] == 'J') && (__DATE__[1] == 'u') && (__DATE__[2] == 'l')) ? 7 : 0 +#define BUILD_MONTH_AUG ((__DATE__[0] == 'A') && (__DATE__[1] == 'u')) ? 8 : 0 +#define BUILD_MONTH_SEP (__DATE__[0] == 'S') ? 9 : 0 +#define BUILD_MONTH_OCT (__DATE__[0] == 'O') ? 10 : 0 +#define BUILD_MONTH_NOV (__DATE__[0] == 'N') ? 11 : 0 +#define BUILD_MONTH_DEC (__DATE__[0] == 'D') ? 12 : 0 +#define BUILD_MONTH BUILD_MONTH_JAN | BUILD_MONTH_FEB | BUILD_MONTH_MAR | \ + BUILD_MONTH_APR | BUILD_MONTH_MAY | BUILD_MONTH_JUN | \ + BUILD_MONTH_JUL | BUILD_MONTH_AUG | BUILD_MONTH_SEP | \ + BUILD_MONTH_OCT | BUILD_MONTH_NOV | BUILD_MONTH_DEC +// +#define BUILD_DATE_0 ((__DATE__[4] == ' ') ? 0 : (__DATE__[4] - 0x30)) +#define BUILD_DATE_1 (__DATE__[5] - 0x30) +#define BUILD_DATE ((BUILD_DATE_0 * 10) + BUILD_DATE_1) +// +#define BUILD_YEAR (((__DATE__[7] - 0x30) * 1000) + ((__DATE__[8] - 0x30) * 100) + \ + ((__DATE__[9] - 0x30) * 10) + ((__DATE__[10] - 0x30) * 1)) + +// Parse the __TIME__ predefined macro to generate time defaults: +// __TIME__ Format: HH:MM:SS (First number of each is padded by 0 if <10) +// +#define BUILD_HOUR_0 ((__TIME__[0] == ' ') ? 0 : (__TIME__[0] - 0x30)) +#define BUILD_HOUR_1 (__TIME__[1] - 0x30) +#define BUILD_HOUR ((BUILD_HOUR_0 * 10) + BUILD_HOUR_1) +// +#define BUILD_MINUTE_0 ((__TIME__[3] == ' ') ? 0 : (__TIME__[3] - 0x30)) +#define BUILD_MINUTE_1 (__TIME__[4] - 0x30) +#define BUILD_MINUTE ((BUILD_MINUTE_0 * 10) + BUILD_MINUTE_1) +// +#define BUILD_SECOND_0 ((__TIME__[6] == ' ') ? 0 : (__TIME__[6] - 0x30)) +#define BUILD_SECOND_1 (__TIME__[7] - 0x30) +#define BUILD_SECOND ((BUILD_SECOND_0 * 10) + BUILD_SECOND_1) + +// Constructor -- Initialize class variables to 0 +DS1307::DS1307() +{ + for (int i=0; i= 13) + _time[TIME_HOURS] -= 12; + } + DECtoBCD(_time[TIME_HOURS]); + _time[TIME_HOURS] |= pmBit; + _time[TIME_HOURS] |= TWELVE_HOUR_MODE; + } + else + { + DECtoBCD(_time[TIME_HOURS]); + } + + _time[TIME_MONTH] = DECtoBCD(BUILD_MONTH); + _time[TIME_DATE] = DECtoBCD(BUILD_DATE); + _time[TIME_YEAR] = DECtoBCD(BUILD_YEAR - 2000); //! Not Y2K (or Y2.1K)-proof :\ + + // Calculate weekday (from here: http://stackoverflow.com/a/21235587) + // 0 = Sunday, 6 = Saturday + int d = BUILD_DATE; + int m = BUILD_MONTH; + int y = BUILD_YEAR; + int weekday = (d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7 + 1; + _time[TIME_DAY] = DECtoBCD(weekday); + + setTime(_time, TIME_ARRAY_LENGTH); +} + +// update -- Read all time/date registers and update the _time array +bool DS1307::update(void) +{ + uint8_t rtcReads[7]; + + if (i2cReadBytes(DS1307_RTC_ADDRESS, DS1307_REGISTER_SECONDS, rtcReads, 7)) + { + for (int i=0; i= 1) && (d <= 7)) + { + uint8_t _d = DECtoBCD(d); + return i2cWriteByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_DAY, _d); + } + + return false; +} + +// setDate -- set the date register of the DS1307 +bool DS1307::setDate(uint8_t d) +{ + if (d <= 31) + { + uint8_t _d = DECtoBCD(d); + return i2cWriteByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_DATE, _d); + } + + return false; +} + +// setMonth -- set the month register of the DS1307 +bool DS1307::setMonth(uint8_t mo) +{ + if ((mo >= 1) && (mo <= 12)) + { + uint8_t _mo = DECtoBCD(mo); + return i2cWriteByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_MONTH, _mo); + } + + return false; +} + +// setYear -- set the year register of the DS1307 +bool DS1307::setYear(uint8_t y) +{ + if (y <= 99) + { + uint8_t _y = DECtoBCD(y); + return i2cWriteByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_YEAR, _y); + } + + return false; +} + +// set12Hour -- set (or not) to 12-hour mode) | enable12 defaults to true +bool DS1307::set12Hour(bool enable12) +{ + if (enable12) + set24Hour(false); + else + set24Hour(true); +} + +// set24Hour -- set (or not) to 24-hour mode) | enable24 defaults to true +bool DS1307::set24Hour(bool enable24) +{ + uint8_t hourRegister = i2cReadByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_HOURS); + + bool hour12 = hourRegister & TWELVE_HOUR_MODE; + if ((hour12 && !enable24) || (!hour12 && enable24)) + return true; + + uint8_t oldHour = hourRegister & 0x1F; // Mask out am/pm and 12-hour mode + oldHour = BCDtoDEC(oldHour); // Convert to decimal + uint8_t newHour = oldHour; + + if (enable24) + { + bool hourPM = hourRegister & TWELVE_HOUR_PM; + if ((hourPM) && (oldHour >= 1)) newHour += 12; + else if (!(hourPM) && (oldHour == 12)) newHour = 0; + newHour = DECtoBCD(newHour); + } + else + { + if (oldHour == 0) + newHour = 12; + else if (oldHour >= 13) + newHour -= 12; + + newHour = DECtoBCD(newHour); + newHour |= TWELVE_HOUR_MODE; // Set bit 6 to set 12-hour mode + if (oldHour >= 12) + newHour |= TWELVE_HOUR_PM; // Set PM bit if necessary + } + + return i2cWriteByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_HOURS, newHour); +} + +// is12Hour -- check if the DS1307 is in 12-hour mode +bool DS1307::is12Hour(void) +{ + uint8_t hourRegister = i2cReadByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_HOURS); + + return hourRegister & TWELVE_HOUR_MODE; +} + +// pm -- Check if 12-hour state is AM or PM +bool DS1307::pm(void) // Read bit 5 in hour byte +{ + uint8_t hourRegister = i2cReadByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_HOURS); + + return hourRegister & TWELVE_HOUR_PM; +} + +// enable -- enable the DS1307's oscillator +void DS1307::enable(void) // Write 0 to CH bit +{ + uint8_t secondRegister = i2cReadByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_SECONDS); + + secondRegister &= ~(1<<7); + + i2cWriteByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_SECONDS, secondRegister); +} + +// disable -- disable the DS1307's oscillator +void DS1307::disable(void) // Write 1 to CH bit +{ + uint8_t secondRegister = i2cReadByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_SECONDS); + + secondRegister |= (1<<7); + + i2cWriteByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_SECONDS, secondRegister); +} + +// writeSQW -- Set the SQW pin high or low +void DS1307::writeSQW(uint8_t high) +{ + if (high) + writeSQW(SQW_HIGH); + else + writeSQW(SQW_LOW); +} + +// writeSQW -- Set the SQW pin high, low, or to one of the square wave frequencies +void DS1307::writeSQW(sqw_rate value) +{ + uint8_t controlRegister = 0; + if (value == SQW_HIGH) + { + controlRegister |= CONTROL_BIT_OUT; + } + else if (value == SQW_LOW) + { + // Do nothing, just leave 0 + } + else + { + controlRegister |= CONTROL_BIT_SQWE; + controlRegister |= value; + } + + i2cWriteByte(DS1307_RTC_ADDRESS, DS1307_REGISTER_CONTROL, controlRegister); +} + +// BCDtoDEC -- convert binary-coded decimal (BCD) to decimal +uint8_t DS1307::BCDtoDEC(uint8_t val) +{ + return ( ( val / 0x10) * 10 ) + ( val % 0x10 ); +} + +// BCDtoDEC -- convert decimal to binary-coded decimal (BCD) +uint8_t DS1307::DECtoBCD(uint8_t val) +{ + return ( ( val / 10 ) * 0x10 ) + ( val % 10 ); +} + +// i2cWriteBytes -- write a set number of bytes to an i2c device, incrementing from a register +bool DS1307::i2cWriteBytes(uint8_t deviceAddress, ds1307_registers reg, uint8_t * values, uint8_t len) +{ + Wire.beginTransmission(deviceAddress); + Wire.write(reg); + for (int i=0; i +#include + +#define DS1307_RTC_ADDRESS 0x68 // DS1307 only has one I2C address - 0x68 + +#define TWELVE_HOUR_MODE (1<<6) // 12/24-hour Mode bit in Hour register +#define TWELVE_HOUR_PM (1<<5) // am/pm bit in hour register + +#define AM 0 +#define PM 1 + +#define CONTROL_BIT_RS0 (1<<0) // RS0 bit in control register +#define CONTROL_BIT_RS1 (1<<1) // RS1 bit in control register +#define CONTROL_BIT_SQWE (1<<4) // Square wave enable bit in control register +#define CONTROL_BIT_OUT (1<<7) // SQW Output value in control register + +#define TIME_ARRAY_LENGTH 7 // Total number of writable values in device +enum time_order { + TIME_SECONDS, // 0 + TIME_MINUTES, // 1 + TIME_HOURS, // 2 + TIME_DAY, // 3 + TIME_DATE, // 4 + TIME_MONTH, // 5 + TIME_YEAR, // 6 +}; + +// sqw_rate -- enum for possible SQW pin output settings +enum sqw_rate { + SQW_SQUARE_1, + SQW_SQUARE_4K, + SQW_SQUARE_8K, + SQW_SQUARE_32K, + SQW_LOW, + SQW_HIGH +}; + +// ds1307_register -- Definition of DS1307 registers +enum ds1307_registers { + DS1307_REGISTER_SECONDS, // 0x00 + DS1307_REGISTER_MINUTES, // 0x01 + DS1307_REGISTER_HOURS, // 0x02 + DS1307_REGISTER_DAY, // 0x03 + DS1307_REGISTER_DATE, // 0x04 + DS1307_REGISTER_MONTH, // 0x05 + DS1307_REGISTER_YEAR, // 0x06 + DS1307_REGISTER_CONTROL // 0x07 +}; + +// Base register for complete time/date readings +#define DS1307_REGISTER_BASE DS1307_REGISTER_SECONDS + +// dayIntToStr -- convert day integer to the string +static const char *dayIntToStr[7] { + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" +}; + +// dayIntToChar -- convert day integer to character +static const char dayIntToChar[7] = {'U', 'M', 'T', 'W', 'R', 'F', 'S'}; + +class DS1307 +{ +public: + + //////////////////// + // Initialization // + //////////////////// + // Constructor -- Initialize class variables to 0 + DS1307(); + // Begin -- Initialize I2C interface + void begin(void); + + /////////////////////// + // Setting the Clock // + /////////////////////// + // setTime -- Set time and date/day registers of DS1307 + bool setTime(uint8_t sec, uint8_t min, uint8_t hour, + uint8_t day, uint8_t date, uint8_t month, uint8_t year); + // setTime -- Set time and date/day registers of DS1307 (using data array) + bool setTime(uint8_t * time, uint8_t len); + // autoTime -- Set time with compiler time/date + bool autoTime(); + + // To set specific values of the clock, use the set____ functions: + bool setSecond(uint8_t s); + bool setMinute(uint8_t m); + bool setHour(uint8_t h); + bool setDay(uint8_t d); + bool setDate(uint8_t d); + bool setMonth(uint8_t mo); + bool setYear(uint8_t y); + + /////////////////////// + // Reading the Clock // + /////////////////////// + // update -- Read all time/date registers and update the _time array + bool update(void); + // update should be performed before any of the following. It will update + // all values at one time. + inline uint8_t second(void) { return BCDtoDEC(_time[TIME_SECONDS]); }; + inline uint8_t minute(void) { return BCDtoDEC(_time[TIME_MINUTES]); }; + inline uint8_t hour(void) { return BCDtoDEC(_time[TIME_HOURS]); }; + inline uint8_t day(void) { return BCDtoDEC(_time[TIME_DAY]); }; + inline const char dayChar(void) { return dayIntToChar[BCDtoDEC(_time[TIME_DAY]) - 1]; }; + inline const char * dayStr(void) { return dayIntToStr[BCDtoDEC(_time[TIME_DAY]) - 1]; }; + inline uint8_t date(void) { return BCDtoDEC(_time[TIME_DATE]); }; + inline uint8_t month(void) { return BCDtoDEC(_time[TIME_MONTH]); }; + inline uint8_t year(void) { return BCDtoDEC(_time[TIME_YEAR]); }; + + // To read a single value at a time, use the get___ functions: + uint8_t getSecond(void); + uint8_t getMinute(void); + uint8_t getHour(void); + uint8_t getDay(void); + uint8_t getDate(void); + uint8_t getMonth(void); + uint8_t getYear(void); + + // is12Hour -- check if the DS1307 is in 12-hour mode | returns true if 12-hour mode + bool is12Hour(void); + // pm -- Check if 12-hour state is AM or PM | returns true if PM + bool pm(void); + + /////////////////////////////// + // SQW Pin Control Functions // + /////////////////////////////// + void writeSQW(uint8_t high); // Write SQW pin high or low + void writeSQW(sqw_rate value); // Write SQW pin high, low, or to a set rate + + ///////////////////////////// + // Misc. Control Functions // + ///////////////////////////// + void enable(void); // Enable the oscillator + void disable(void); // Disable the oscillator (no counting!) + + bool set12Hour(bool enable12 = true); // Enable/disable 12-hour mode + bool set24Hour(bool enable24 = true); // Enable/disable 24-hour mode + +private: + uint8_t _time[TIME_ARRAY_LENGTH]; + bool _pm; + + uint8_t BCDtoDEC(uint8_t val); + uint8_t DECtoBCD(uint8_t val); + + bool i2cWriteBytes(uint8_t deviceAddress, ds1307_registers reg, uint8_t * values, uint8_t len); + bool i2cWriteByte(uint8_t deviceAddress, ds1307_registers reg, uint8_t value); + uint8_t i2cReadByte(uint8_t deviceAddress, ds1307_registers reg); + bool i2cReadBytes(uint8_t deviceAddress, ds1307_registers reg, uint8_t * dest, uint8_t len); +}; + +extern DS1307 rtc; + +#endif // SPARKFUNDS1307RTC_H \ No newline at end of file