-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRTCDS1307.cpp
More file actions
125 lines (105 loc) · 3.59 KB
/
RTCDS1307.cpp
File metadata and controls
125 lines (105 loc) · 3.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "RTCDS1307.h"
RTCDS1307::RTCDS1307(uint8_t address): _address(address) {};
bool RTCDS1307::begin() {
Wire.begin();
Wire.beginTransmission(_address);
return !Wire.endTransmission(1);
}
uint8_t RTCDS1307::bcd(uint8_t val) {
return val + (6 * (val / 10));
}
uint8_t RTCDS1307::decimal(uint8_t val) {
return val - (6 * (val >> 4));
}
bool RTCDS1307::getDate(uint8_t &Y, uint8_t &M, uint8_t &D, uint8_t &WD) {
if (read(RTCDS1307_DATE, 4)) {
WD = _buffer[0];
D = decimal(_buffer[1]);
M = decimal(_buffer[2]);
Y = decimal(_buffer[3]);
return true;
}
}
bool RTCDS1307::getMode() {
read(RTCDS1307_MODE, 1);
return _buffer[0] >> 6 & 1;
}
bool RTCDS1307::getTime(uint8_t &h, uint8_t &m, uint8_t &s) {
bool period;
return getTime(h, m, s, period);
}
bool RTCDS1307::getTime(uint8_t &h, uint8_t &m, uint8_t &s, bool &period) {
if (read(RTCDS1307_TIME, 3)) {
s = decimal(_buffer[0]);
m = decimal(_buffer[1]);
h = decimal(_buffer[2] & ((_buffer[2] >> 6 & 1) ? 0x1F : 0x3F));
period = (_buffer[2] >> 6 & 1) & (_buffer[2] >> 5 & 1);
return true;
}
}
bool RTCDS1307::isLeapYear(uint16_t Y) {
return !((Y % 4) * (!(Y % 100) + (Y % 400)));
}
bool RTCDS1307::read(uint8_t address, uint8_t length) {
_buffer = (uint8_t *) realloc(_buffer, length);
if (write(address, 0)) {
Wire.requestFrom(_address, length);
while (Wire.available() < length);
for (uint8_t i = 0; i < length; i++) _buffer[i] = uint8_t(Wire.read());
return true;
}
}
bool RTCDS1307::read(uint8_t address, uint8_t *&buffer, uint8_t length) {
if (read(RTCDS1307_RAM | address, length)) {
buffer = (uint8_t *) realloc(_buffer, length);
memcpy(buffer, _buffer, length);
return true;
}
}
bool RTCDS1307::setControl(bool output, bool square, uint8_t frequency) {
_buffer[0] = output << 7 | square << 4 | frequency & 0xFF;
return write(RTCDS1307_CONTROL, 1);
}
bool RTCDS1307::setDate(uint8_t Y, uint8_t M, uint8_t D) {
_buffer[0] = wday(Y, M, D);
_buffer[1] = bcd(D);
_buffer[2] = bcd(M);
_buffer[3] = bcd(Y);
return write(RTCDS1307_DATE, 4);
}
bool RTCDS1307::setMode(bool state) {
if (read(RTCDS1307_MODE, 1) && (state ^ (_buffer[0] >> 6 & 1))) {
bool period = (_buffer[0] >> 5 & 1);
_buffer[0] = decimal(_buffer[0] & ((_buffer[0] >> 6 & 1) ? 0x1F : 0x3F));
if (state) {
period = (_buffer[0] > 11);
_buffer[0] = (_buffer[0] % 12) + (!(_buffer[0] % 12) * 12);
} else {
_buffer[0] = (_buffer[0] % 12) + (period * 12);
}
_buffer[0] = bcd(_buffer[0]) | state << 6 | (state & period) << 5;
return write(RTCDS1307_MODE, 1);
}
}
bool RTCDS1307::setTime(uint8_t h, uint8_t m, uint8_t s, bool mode, bool period) {
_buffer[0] = bcd(s);
_buffer[1] = bcd(m);
_buffer[2] = bcd(h) | mode << 6 | (mode & period) << 5;
return write(RTCDS1307_TIME, 3);
}
uint8_t RTCDS1307::wday(uint16_t Y, uint8_t M, uint8_t D) {
uint8_t n[12] = {31, 28 + isLeapYear(Y), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
Y = (D + (((Y - 1) * 365UL) + ((Y - 1) / 4) - ((Y - 1) / 100) + ((Y - 1) / 400))) % 7;
while (M > 1) Y += n[--M - 1];
return (Y % 7) + 1;
}
bool RTCDS1307::write(uint8_t address, uint8_t length) {
Wire.beginTransmission(_address);
Wire.write(address);
for (uint8_t i = 0; i < length; i++) Wire.write(_buffer[i]);
return !Wire.endTransmission(1);
}
bool RTCDS1307::write(uint8_t address, uint8_t *buffer, uint8_t length) {
memcpy(_buffer, buffer, length);
return write(RTCDS1307_RAM | address, length);
}