23 #include "DS3232RTC.h" 
   24 #include "../I2C/I2CMaster.h" 
   25 #if defined(ARDUINO) && ARDUINO >= 100 
   60 #define DS3232_I2C_ADDRESS  0x68 
   63 #define DS3232_SECOND       0x00 
   64 #define DS3232_MINUTE       0x01 
   65 #define DS3232_HOUR         0x02 
   66 #define DS3232_DAY_OF_WEEK  0x03 
   67 #define DS3232_DATE         0x04 
   68 #define DS3232_MONTH        0x05 
   69 #define DS3232_YEAR         0x06 
   70 #define DS3232_ALARM1_SEC   0x07 
   71 #define DS3232_ALARM1_MIN   0x08 
   72 #define DS3232_ALARM1_HOUR  0x09 
   73 #define DS3232_ALARM1_DAY   0x0A 
   74 #define DS3232_ALARM2_MIN   0x0B 
   75 #define DS3232_ALARM2_HOUR  0x0C 
   76 #define DS3232_ALARM2_DAY   0x0D 
   77 #define DS3232_CONTROL      0x0E 
   78 #define DS3232_STATUS       0x0F 
   79 #define DS3232_AGING_OFFSET 0x10 
   80 #define DS3232_TEMP_MSB     0x11 
   81 #define DS3232_TEMP_LSB     0x12 
   82 #define DS3232_RESERVED     0x13 
   83 #define DS3232_NVRAM        0x14 
   86 #define DS3232_EOSC         0x80 
   87 #define DS3232_BBSQW        0x40 
   88 #define DS3232_CONV         0x20 
   89 #define DS3232_RS_1HZ       0x00 
   90 #define DS3232_RS_1024HZ    0x08 
   91 #define DS3232_RS_4096HZ    0x10 
   92 #define DS3232_RS_8192HZ    0x18 
   93 #define DS3232_INTCN        0x04 
   94 #define DS3232_A2IE         0x02 
   95 #define DS3232_A1IE         0x01 
   98 #define DS3232_OSF          0x80 
   99 #define DS3232_BB32KHZ      0x40 
  100 #define DS3232_CRATE_64     0x00 
  101 #define DS3232_CRATE_128    0x10 
  102 #define DS3232_CRATE_256    0x20 
  103 #define DS3232_CRATE_512    0x30 
  104 #define DS3232_EN32KHZ      0x08 
  105 #define DS3232_BSY          0x04 
  106 #define DS3232_A2F          0x02 
  107 #define DS3232_A1F          0x01 
  110 #define DS3232_ALARM_SIZE   3 
  111 #define DS3232_ALARMS       (256 - RTC::ALARM_COUNT * DS3232_ALARM_SIZE - 1) 
  112 #define DS3232_ALARM_MAGIC  255 
  128     , _oneHzPin(oneHzPin)
 
  131     , alarmInterrupts(false)
 
  135     _bus->
write(DS3232_CONTROL);
 
  136     if (_bus->
startRead(DS3232_I2C_ADDRESS, 1)) {
 
  137         uint8_t value = _bus->
read() & DS3232_CONV;
 
  139             value |= DS3232_BBSQW | DS3232_RS_1HZ;
 
  141         _bus->
write(DS3232_CONTROL);
 
  143         _bus->
write(DS3232_CRATE_64);
 
  151     if (oneHzPin != 255 && _isRealTime) {
 
  152         pinMode(oneHzPin, INPUT);
 
  153         digitalWrite(oneHzPin, HIGH);
 
  170     if (_oneHzPin == 255 || !_isRealTime)
 
  175     bool value = digitalRead(_oneHzPin);
 
  176     if (value && !prevOneHz) {
 
  185 inline uint8_t fromBCD(uint8_t value)
 
  187     return (value >> 4) * 10 + (value & 0x0F);
 
  190 inline uint8_t fromHourBCD(uint8_t value)
 
  192     if ((value & 0x40) != 0) {
 
  194         uint8_t result = ((value >> 4) & 0x01) * 10 + (value & 0x0F);
 
  195         if ((value & 0x20) != 0)
 
  196             return (result == 12) ? 12 : (result + 12);     
 
  198             return (result == 12) ? 0 : result;             
 
  201         return fromBCD(value);
 
  209         _bus->
write(DS3232_SECOND);
 
  210         if (_bus->
startRead(DS3232_I2C_ADDRESS, 3)) {
 
  213             value->
hour = fromHourBCD(_bus->
read());
 
  232     _bus->
write(DS3232_DATE);
 
  233     if (_bus->
startRead(DS3232_I2C_ADDRESS, 3)) {
 
  234         value->
day = fromBCD(_bus->
read());
 
  235         value->
month = fromBCD(_bus->
read() & 0x7F); 
 
  236         value->
year = fromBCD(_bus->
read()) + 2000;
 
  245 inline uint8_t toBCD(uint8_t value)
 
  247     return ((value / 10) << 4) + (value % 10);
 
  254         _bus->
write(DS3232_SECOND);
 
  268         _bus->
write(DS3232_DATE);
 
  282         _bus->
write(DS3232_ALARMS + alarmNum * DS3232_ALARM_SIZE);
 
  283         if (_bus->
startRead(DS3232_I2C_ADDRESS, 3)) {
 
  284             value->
hour = fromBCD(_bus->
read());
 
  303         _bus->
write(DS3232_ALARMS + alarmNum * DS3232_ALARM_SIZE);
 
  312             _bus->
write(DS3232_ALARM1_SEC);
 
  319                 updateAlarmInterrupts();
 
  320         } 
else if (alarmNum == 1) {
 
  322             _bus->
write(DS3232_ALARM2_MIN);
 
  328                 updateAlarmInterrupts();
 
  337     return DS3232_ALARMS - DS3232_NVRAM;
 
  343         return readRegister(DS3232_NVRAM + offset);
 
  351         writeRegister(DS3232_NVRAM + offset, value);
 
  359         return (((
int)(
signed char)readRegister(DS3232_TEMP_MSB)) << 2) |
 
  360                (readRegister(DS3232_TEMP_LSB) >> 6);
 
  382     if (_oneHzPin == 255 && _isRealTime) {
 
  383         updateAlarmInterrupts();
 
  384         alarmInterrupts = 
true;
 
  395     if (alarmInterrupts) {
 
  396         uint8_t value = readRegister(DS3232_CONTROL);
 
  397         value &= ~(DS3232_INTCN | DS3232_A2IE | DS3232_A1IE);
 
  398         writeRegister(DS3232_CONTROL, value);
 
  399         alarmInterrupts = 
false;
 
  420     uint8_t value = readRegister(DS3232_STATUS);
 
  422     if (value & DS3232_A1F) {
 
  423         if (value & DS3232_A2F)
 
  427     } 
else if (value & DS3232_A2F) {
 
  433         value &= ~(DS3232_A1F | DS3232_A2F);
 
  434         writeRegister(DS3232_STATUS, value);
 
  447         uint8_t value = readRegister(DS3232_STATUS);
 
  448         value |= DS3232_BB32KHZ | DS3232_EN32KHZ;
 
  449         writeRegister(DS3232_STATUS, value);
 
  461         uint8_t value = readRegister(DS3232_STATUS);
 
  462         value &= ~(DS3232_BB32KHZ | DS3232_EN32KHZ);
 
  463         writeRegister(DS3232_STATUS, value);
 
  467 void DS3232RTC::initAlarms()
 
  469     uint8_t value = readRegister(DS3232_ALARM_MAGIC);
 
  477         for (uint8_t index = 0; index < 
ALARM_COUNT; ++index)
 
  479         writeRegister(DS3232_ALARM_MAGIC, 0xB0 + ALARM_COUNT);
 
  484         _bus->
write(DS3232_NVRAM);
 
  485         for (uint8_t index = DS3232_NVRAM; index < DS3232_ALARMS; ++index)
 
  491 uint8_t DS3232RTC::readRegister(uint8_t reg)
 
  495     if (!_bus->
startRead(DS3232_I2C_ADDRESS, 1))
 
  500 bool DS3232RTC::writeRegister(uint8_t reg, uint8_t value)
 
  508 #define DS3232_ALARM1_FLAGS (DS3232_ALARMS + 2) 
  509 #define DS3232_ALARM2_FLAGS (DS3232_ALARMS + DS3232_ALARM_SIZE + 2) 
  511 void DS3232RTC::updateAlarmInterrupts()
 
  513     bool alarm1Enabled = ((readRegister(DS3232_ALARM1_FLAGS) & 0x01) != 0);
 
  514     bool alarm2Enabled = ((readRegister(DS3232_ALARM2_FLAGS) & 0x01) != 0);
 
  515     uint8_t value = readRegister(DS3232_CONTROL);
 
  516     value |= DS3232_INTCN;
 
  518         value |= DS3232_A1IE;
 
  520         value &= ~DS3232_A1IE;
 
  522         value |= DS3232_A2IE;
 
  524         value &= ~DS3232_A2IE;
 
  525     writeRegister(DS3232_CONTROL, value);
 
uint8_t month
Month of the year (1-12) 
virtual void writeTime(const RTCTime *value)
Updates the time in the realtime clock to match value. 
void enableAlarmInterrupts()
Enables the generation of interrupts for alarms 0 and 1. 
void disable32kHzOutput()
Disables the 32 kHz output on the DS3232 chip. 
void readTime(RTCTime *value)
Reads the current time from the realtime clock into value. 
int readTemperature()
Reads the value of the temperature sensor and returns the temperature in quarters of a degree celcius...
uint8_t minute
Minute within the hour (0-59) 
virtual void readAlarm(uint8_t alarmNum, RTCAlarm *value)
Reads the details of the alarm with index alarmNum into value. 
virtual void readDate(RTCDate *value)
Reads the current date from the realtime clock into value. 
int byteCount() const 
Returns the number of bytes of non-volatile memory that can be used for storage of arbitrary settings...
void readDate(RTCDate *value)
Reads the current date from the realtime clock into value. 
void enable32kHzOutput()
Enables the 32 kHz output on the DS3232 chip. 
virtual void write(uint8_t value)=0
Writes a single byte value on the I2C bus. 
void writeAlarm(uint8_t alarmNum, const RTCAlarm *value)
Updates the details of the alarm with index alarmNum from value. 
virtual void writeAlarm(uint8_t alarmNum, const RTCAlarm *value)
Updates the details of the alarm with index alarmNum from value. 
static const uint8_t ALARM_COUNT
Number of alarms that are supported by RTC::readAlarm() and RTC::writeAlarm(). 
virtual void writeDate(const RTCDate *value)
Updates the date in the realtime clock to match value. 
void disableAlarmInterrupts()
Disables the generation of interrupts for alarms 0 and 1. 
virtual bool startRead(unsigned int address, unsigned int count)=0
Starts a read operation for count bytes by sending the start condition and the I2C control byte...
uint8_t hour
Hour of the day for the alarm (0-23). 
static const int NO_TEMPERATURE
Value that is returned from readTemperature() if the realtime clock chip cannot determine the tempera...
uint8_t flags
Additional flags for the alarm. 
Stores date information from a realtime clock chip. 
void writeTime(const RTCTime *value)
Updates the time in the realtime clock to match value. 
uint8_t readByte(uint8_t offset)
Reads the byte at offset within the realtime clock's non-volatile memory. 
int firedAlarm()
Determines which of alarms 0 or 1 have fired since the last call. 
DS3232RTC(I2CMaster &bus, uint8_t oneHzPin=255)
Attaches to a realtime clock slave device on bus. 
virtual void startWrite(unsigned int address)
Starts a write operation by sending a start condition and the I2C control byte. 
virtual bool endWrite()=0
Ends the current write operation. 
unsigned int year
Year (4-digit) 
virtual void writeByte(uint8_t offset, uint8_t value)
Writes value to offset within the realtime clock's non-volatile memory. 
uint8_t minute
Minute of the hour for the alarm (0-59). 
bool hasUpdates()
Returns true if the realtime clock has updated since the last call to this function. 
virtual uint8_t readByte(uint8_t offset)
Reads the byte at offset within the realtime clock's non-volatile memory. 
Stores time information from a realtime clock chip. 
Abstract base class for I2C master implementations. 
void writeDate(const RTCDate *value)
Updates the date in the realtime clock to match value. 
Stores alarm information from a realtime clock chip. 
virtual uint8_t read()=0
Reads a single byte from the I2C bus. 
uint8_t hour
Hour of the day (0-23) 
uint8_t day
Day of the month (1-31) 
void readAlarm(uint8_t alarmNum, RTCAlarm *value)
Reads the details of the alarm with index alarmNum into value. 
uint8_t second
Second within the minute (0-59) 
void writeByte(uint8_t offset, uint8_t value)
Writes value to offset within the realtime clock's non-volatile memory. 
virtual void readTime(RTCTime *value)
Reads the current time from the realtime clock into value.