21 return (b >> 4) * 10 + (b & 0x0F);
25 return (uint8_t)(((v / 10) << 4) | (v % 10));
29long days_from_civil(
int y,
int m,
int d)
32 long era = (y >= 0 ? y : y - 399) / 400;
33 unsigned yoe = (unsigned)(y - era * 400);
34 unsigned doy = (153u * (unsigned)(m + (m > 2 ? -3 : 9)) + 2u) / 5u + (unsigned)d - 1u;
35 unsigned doe = yoe * 365u + yoe / 4u - yoe / 100u + doy;
36 return era * 146097L + (long)doe - 719468L;
38void civil_from_days(
long z,
int *y,
int *m,
int *d)
41 long era = (z >= 0 ? z : z - 146096) / 146097;
42 unsigned doe = (unsigned)(z - era * 146097);
43 unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
44 long yy = (long)yoe + era * 400;
45 unsigned doy = doe - (365u * yoe + yoe / 4u - yoe / 100u);
46 unsigned mp = (5u * doy + 2u) / 153u;
47 *d = (int)(doy - (153u * mp + 2u) / 5u + 1u);
48 *m = (int)(mp < 10 ? mp + 3 : mp - 9);
49 *y = (int)(yy + (*m <= 2));
57 int sec = bcd2int(r[0] & 0x7F);
58 int min = bcd2int(r[1] & 0x7F);
62 int h12 = bcd2int(r[2] & 0x1F);
63 if (h12 < 1 || h12 > 12)
65 bool pm = (r[2] & 0x20) != 0;
66 hour = (h12 % 12) + (pm ? 12 : 0);
70 hour = bcd2int(r[2] & 0x3F);
72 int date = bcd2int(r[4] & 0x3F);
73 int month = bcd2int(r[5] & 0x1F);
74 int year = 2000 + bcd2int(r[6]);
75 if (sec > 59 || min > 59 || hour > 23 || date < 1 || date > 31 || month < 1 || month > 12)
78 int64_t t = (int64_t)days_from_civil(year, month, date) * 86400 + hour * 3600 + min * 60 + sec;
79 if (t < 0 || t > 0xFFFFFFFFLL)
87 long days = (long)(epoch / 86400u);
88 int rem = (int)(epoch % 86400u);
92 civil_from_days(days, &y, &m, &d);
93 r[0] = int2bcd(rem % 60);
94 r[1] = int2bcd((rem % 3600) / 60);
95 r[2] = int2bcd(rem / 3600);
96 r[3] = (uint8_t)((((days % 7) + 3) % 7) + 1);
99 r[6] = int2bcd(y - 2000);
120 Wire.write((uint8_t)0x00);
121 if (Wire.endTransmission() != 0)
127 r[i] = (uint8_t)Wire.read();
137 Wire.write((uint8_t)0x00);
140 return Wire.endTransmission() == 0;
User-facing configuration for DeterministicESPAsyncWebServer.
#define DETWS_RTC_I2C_ADDR
I2C address of the RTC (DS1307/DS3231 are fixed at 0x68).
The one owner of the shared I2C bus bring-up for the peripheral drivers.
void detws_i2c_begin()
Bring up the shared I2C bus on DETWS_I2C_SDA_PIN / DETWS_I2C_SCL_PIN (-1 = default).
I2C real-time-clock driver (DS1307 / DS3231) - a battery-backed time source.
uint32_t rtc_time_source()
A TimeSourceFn wrapper (returns rtc_read_epoch()) to register with detws_time_source_add().
#define RTC_REG_COUNT
Number of time registers read from the RTC (seconds..year).
uint32_t rtc_read_epoch()
Read the current time from the RTC over I2C.
bool rtc_set_epoch(uint32_t epoch)
Set the RTC to epoch over I2C.
bool rtc_regs_to_epoch(const uint8_t regs[RTC_REG_COUNT], uint32_t *epoch)
Convert the 7 raw RTC time registers (BCD: sec, min, hour, dow, date, month, year) to a Unix timestam...
void rtc_epoch_to_regs(uint32_t epoch, uint8_t regs[RTC_REG_COUNT])
Convert a Unix timestamp to the 7 RTC time registers (BCD, 24-hour). Pure - no I2C....
bool rtc_begin()
Initialize the I2C bus for the RTC.