#include "rtc.hpp" // the hardware rtc driver was made with the support of Wh1teRabbitHU's implementation bool rtcset; bool NTPupdated; ESP32Time rtc(0); bool rx_rtc_avail = false; inline int16_t readFromModule(byte address) { Wire.beginTransmission(RX8010SJ_ADDRESS); Wire.write(address); if (Wire.endTransmission() != 0) return -1; if (Wire.requestFrom(RX8010SJ_ADDRESS, 1) != 1) return -1; if (Wire.available()) return Wire.read(); return -1; } inline void writeToModule(byte address, byte data) { Wire.beginTransmission(RX8010SJ_ADDRESS); Wire.write(address); Wire.write(data); Wire.endTransmission(); } inline byte toBCD(byte val) { return ((val / 10) << 4) | (val % 10); } inline byte sumValueFromBinary(byte binary, byte length) { byte sum = 0; for (byte i = 0; i < length; i++) { byte value; if (i < 4 ) value = 1 << i; else value = 10 * (1 << (i - 4)); sum += ((binary >> i) & 1) == 1 ? value : 0; } return sum; } void sync_from_rx_rtc(int32_t offset = 0) { if(!rx_rtc_avail) return; struct tm timeinfo; memset(&timeinfo, 0, sizeof(timeinfo)); Wire.beginTransmission(RX8010SJ_ADDRESS); Wire.write(0x10); Wire.endTransmission(); if (Wire.requestFrom(RX8010SJ_ADDRESS, 7) == 7) { timeinfo.tm_sec = sumValueFromBinary(Wire.read(), 7); timeinfo.tm_min = sumValueFromBinary(Wire.read(), 7); timeinfo.tm_hour = sumValueFromBinary(Wire.read(), 6); auto dayOfWeekBin = Wire.read(); for (int i = 0; i < 7; i++) { if (dayOfWeekBin & (1u << i)) { timeinfo.tm_wday = i; break; } } timeinfo.tm_mday = sumValueFromBinary(Wire.read(), 6); timeinfo.tm_mon = sumValueFromBinary(Wire.read(), 5) - 1; timeinfo.tm_year = sumValueFromBinary(Wire.read(), 8) + 100; rtc.setTime(mktime(&timeinfo) + offset); } } bool init_rtc() { rtc.setTime(0); if(!rx_rtc_avail) return false; auto flagregister = readFromModule(0x1E); if(flagregister < 0) { rx_rtc_avail = false; return false; } if((flagregister >> 1) & 1) { while((flagregister >> 1) & 1) { writeToModule(0x1E, 0); // clear VLF flagregister = readFromModule(0x1E); } writeToModule(0x17, 216); // Reserved register writeToModule(0x1F, 64); // Control register, stop bit set Wire.beginTransmission(RX8010SJ_ADDRESS); Wire.write(0x31); Wire.write(8); // Reserved register Wire.write(0); // IRQ control register Wire.endTransmission(); Wire.beginTransmission(RX8010SJ_ADDRESS); Wire.write(0x10); Wire.write(0); Wire.write(0); Wire.write(toBCD(12)); Wire.write(1 << 2); Wire.write(toBCD(14)); Wire.write(1); Wire.write(toBCD(26)); Wire.endTransmission(); writeToModule(0x1F, 0); // Unset stop bit return true; } sync_from_rx_rtc(); return false; } void set_time(time_t time) { rtc.setTime(time); if(!rx_rtc_avail) return; struct tm* timeinfo = gmtime(&time); writeToModule(0x1F, 64); Wire.beginTransmission(RX8010SJ_ADDRESS); Wire.write(0x10); Wire.write(toBCD(timeinfo->tm_sec)); Wire.write(toBCD(timeinfo->tm_min)); Wire.write(toBCD(timeinfo->tm_hour)); Wire.write(1 << timeinfo->tm_wday); Wire.write(toBCD(timeinfo->tm_mday)); Wire.write(toBCD(timeinfo->tm_mon + 1)); Wire.write(toBCD((1900 + timeinfo->tm_year) % 100)); Wire.endTransmission(); writeToModule(0x1F, 0); }