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.