add support for hardware rtc, not sure if this version won't crash
This commit is contained in:
@@ -55,6 +55,11 @@ void NTPupdate() {
|
||||
|
||||
if (currentTime) {
|
||||
rtc.setTime(currentTime);
|
||||
if(rx_rtc_avail) {
|
||||
RX8010SJ::DateTime rx_currenttime = RX8010SJ::DateTime();
|
||||
timeToDateTime(currentTime, &rx_currenttime);
|
||||
rx_rtc.writeDateTime(rx_currenttime);
|
||||
}
|
||||
rtcset = true;
|
||||
NTPupdated = true;
|
||||
radio.rds.ctupdate = false;
|
||||
|
||||
+14
-10
@@ -2,7 +2,7 @@
|
||||
#include <map>
|
||||
#include <Arduino.h>
|
||||
#include <TimeLib.h>
|
||||
#include "SPIFFS.h"
|
||||
#include <SPIFFS.h>
|
||||
#include "constants.h"
|
||||
#include "utils.h"
|
||||
|
||||
@@ -1212,11 +1212,12 @@ void TEF6686::readRDS(byte showrdserrors) {
|
||||
|
||||
case RDS_GROUP_4A: {
|
||||
if (!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold && rds.ctupdate && (rds.PICTlock == pi || rds.PICTlock == 0)) {
|
||||
uint32_t mjd = (rds.rdsB & 0x03) << 15 | ((rds.rdsC >> 1) & 0x7FFF);;
|
||||
auto rtc_time = rtc.getEpoch();
|
||||
uint32_t mjd = (rds.rdsB & 0x03) << 15 | ((rds.rdsC >> 1) & 0x7FFF);
|
||||
uint16_t hour, minute, day = 5, month = 1, year = 2026;
|
||||
int32_t timeoffset;
|
||||
|
||||
long J = mjd + 2400001 + 68569;
|
||||
long J = mjd + 2400001 + 68569;
|
||||
long C = 4 * J / 146097;
|
||||
J = J - (146097 * C + 3) / 4;
|
||||
long Y = 4000 * (J + 1) / 1461001;
|
||||
@@ -1247,20 +1248,23 @@ void TEF6686::readRDS(byte showrdserrors) {
|
||||
tm.tm_isdst = -1;
|
||||
time_t rdstime = mktime(&tm);
|
||||
|
||||
if (lastrdstime == 0) {
|
||||
lastrdstime = rdstime;
|
||||
lasttimeoffset = timeoffset;
|
||||
}
|
||||
if ((rdstime == lastrdstime + 60 && timeoffset == lasttimeoffset) || showrdserrors != 0) {
|
||||
if (((rdstime == lastrdstime + 60 && timeoffset == lasttimeoffset) || (lastrdstime == 0 && lasttimeoffset == 0)) || showrdserrors != 0) {
|
||||
rds.hasCT = true;
|
||||
rds.time = rdstime;
|
||||
rds.offset = timeoffset;
|
||||
rtcset = true;
|
||||
|
||||
time_t rds_utc_time = rdstime + timeoffset;
|
||||
rds.clock_correction = rtc_time - rds_utc_time;
|
||||
|
||||
if (!NTPupdated) {
|
||||
rtc.setTime(rds_utc_time);
|
||||
sync_to_rx_rtc();
|
||||
}
|
||||
} else rds.hasCT = false;
|
||||
lastrdstime = rdstime;
|
||||
lasttimeoffset = timeoffset;
|
||||
}
|
||||
} break;
|
||||
|
||||
case RDS_GROUP_10A: {
|
||||
if (!rdsCerrorThreshold && !rdsDerrorThreshold) {
|
||||
uint8_t segment = bitRead(rds.rdsB, 0);
|
||||
|
||||
@@ -51,7 +51,7 @@ const unsigned char tuner_init_tab55000[] PROGMEM = {
|
||||
};
|
||||
|
||||
bool Tuner_WriteBuffer(unsigned char *buf, uint16_t len) {
|
||||
Wire.beginTransmission(0x64);
|
||||
Wire.beginTransmission(TEF668X_ADDRESS);
|
||||
for (uint16_t i = 0; i < len; i++) Wire.write(buf[i]);
|
||||
uint8_t r = Wire.endTransmission();
|
||||
if (!Data_Accelerator) delay(2);
|
||||
@@ -59,7 +59,7 @@ bool Tuner_WriteBuffer(unsigned char *buf, uint16_t len) {
|
||||
}
|
||||
|
||||
bool Tuner_ReadBuffer(unsigned char *buf, uint16_t len) {
|
||||
Wire.requestFrom(0x64, len);
|
||||
Wire.requestFrom(TEF668X_ADDRESS, len);
|
||||
if (Wire.available() == len) {
|
||||
for (uint16_t i = 0; i < len; i++) buf[i] = Wire.read();
|
||||
return true;
|
||||
@@ -92,7 +92,7 @@ bool Tuner_Table_Write(const unsigned char *tab) {
|
||||
}
|
||||
|
||||
void Tuner_Reset(void) {
|
||||
Wire.beginTransmission(0x64);
|
||||
Wire.beginTransmission(TEF668X_ADDRESS);
|
||||
Wire.write(0x1e);
|
||||
Wire.write(0x5a);
|
||||
Wire.write(0x01);
|
||||
@@ -104,13 +104,13 @@ void Tuner_Reset(void) {
|
||||
void Tuner_Patch(byte TEF) {
|
||||
Tuner_Reset();
|
||||
delay(100);
|
||||
Wire.beginTransmission(0x64);
|
||||
Wire.beginTransmission(TEF668X_ADDRESS);
|
||||
Wire.write(0x1c);
|
||||
Wire.write(0x00);
|
||||
Wire.write(0x00);
|
||||
Wire.endTransmission();
|
||||
delay(100);
|
||||
Wire.beginTransmission(0x64);
|
||||
Wire.beginTransmission(TEF668X_ADDRESS);
|
||||
Wire.write(0x1c);
|
||||
Wire.write(0x00);
|
||||
Wire.write(0x74);
|
||||
@@ -123,13 +123,13 @@ void Tuner_Patch(byte TEF) {
|
||||
Tuner_Patch_Load(pPatchBytes205, PatchSize205);
|
||||
break;
|
||||
}
|
||||
Wire.beginTransmission(0x64);
|
||||
Wire.beginTransmission(TEF668X_ADDRESS);
|
||||
Wire.write(0x1c);
|
||||
Wire.write(0x00);
|
||||
Wire.write(0x00);
|
||||
Wire.endTransmission();
|
||||
delay(100);
|
||||
Wire.beginTransmission(0x64);
|
||||
Wire.beginTransmission(TEF668X_ADDRESS);
|
||||
Wire.write(0x1c);
|
||||
Wire.write(0x00);
|
||||
Wire.write(0x75);
|
||||
@@ -142,7 +142,7 @@ void Tuner_Patch(byte TEF) {
|
||||
Tuner_Patch_Load(pLutBytes205, LutSize205);
|
||||
break;
|
||||
}
|
||||
Wire.beginTransmission(0x64);
|
||||
Wire.beginTransmission(TEF668X_ADDRESS);
|
||||
Wire.write(0x1c);
|
||||
Wire.write(0x00);
|
||||
Wire.write(0x00);
|
||||
|
||||
+3
-5
@@ -720,7 +720,6 @@ void XDRGTKRoutine() {
|
||||
if (scandxmode) cancelDXScan();
|
||||
if (!XDRScan) BWsetRecall = BWset;
|
||||
XDRScan = true;
|
||||
Data_Accelerator = true;
|
||||
|
||||
switch (buff[1]) {
|
||||
case 'a': scanner_start = (atoi(buff + 2) + 5) / 10; break;
|
||||
@@ -748,9 +747,8 @@ void XDRGTKRoutine() {
|
||||
}
|
||||
doBW();
|
||||
break;
|
||||
case 'w':
|
||||
unsigned int bwtemp;
|
||||
bwtemp = atoi(buff + 2);
|
||||
case 'w': {
|
||||
unsigned int bwtemp = atoi(buff + 2);
|
||||
switch (bwtemp) {
|
||||
case 0: BWset = 0; break;
|
||||
case 56000: BWset = 1; break;
|
||||
@@ -772,6 +770,7 @@ void XDRGTKRoutine() {
|
||||
}
|
||||
doBW();
|
||||
break;
|
||||
}
|
||||
|
||||
case '\0':
|
||||
radio.setMute();
|
||||
@@ -808,7 +807,6 @@ void XDRGTKRoutine() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
Data_Accelerator = false;
|
||||
break;
|
||||
} case 'W': {
|
||||
unsigned int bwtemp = atoi(buff + 1);
|
||||
|
||||
+1
-4
@@ -25,14 +25,12 @@ bool memorystore;
|
||||
bool memreset, memtune;
|
||||
bool menu, menuopen;
|
||||
bool mwstepsize;
|
||||
bool NTPupdated;
|
||||
bool optenc;
|
||||
bool rdsflagreset;
|
||||
bool rdsreset;
|
||||
bool rdsstatscreen;
|
||||
bool RDSSPYTCP, RDSSPYUSB;
|
||||
bool rotaryaccelerate = true;
|
||||
bool rtcset;
|
||||
bool scandxmode;
|
||||
bool scanholdflag;
|
||||
bool scanholdonsignal;
|
||||
@@ -332,7 +330,6 @@ const size_t language_entrynumber = sizeof(myLanguage[0]) / sizeof(myLanguage[0]
|
||||
|
||||
mem presets[EE_PRESETS_CNT];
|
||||
TEF6686 radio;
|
||||
ESP32Time rtc(0);
|
||||
|
||||
// FrequencySprite.createSprite(200, 50);
|
||||
// RDSSprite.createSprite(165, 19);
|
||||
@@ -345,10 +342,10 @@ ESP32Time rtc(0);
|
||||
TFT_eSprite FrequencySprite = TFT_eSprite(&tft);
|
||||
TFT_eSprite RDSSprite = TFT_eSprite(&tft);
|
||||
TFT_eSprite PTYSprite = TFT_eSprite(&tft);
|
||||
TFT_eSprite SignalSprite = TFT_eSprite(&tft);
|
||||
TFT_eSprite SquelchSprite = TFT_eSprite(&tft);
|
||||
TFT_eSprite FullLineSprite = TFT_eSprite(&tft);
|
||||
TFT_eSprite OneBigLineSprite = TFT_eSprite(&tft);
|
||||
TFT_eSprite SignalSprite = TFT_eSprite(&tft);
|
||||
TFT_eSprite PSSprite = TFT_eSprite(&tft);
|
||||
|
||||
WiFiConnect wc;
|
||||
|
||||
+2
-12
@@ -3081,11 +3081,8 @@ void BuildDisplay() {
|
||||
tft.drawBitmap(68, 5, RDSLogo, 35, 22, GreyoutColor);
|
||||
tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor);
|
||||
|
||||
if (!StereoToggle) {
|
||||
tft.drawBitmap(38, 5, Mono, 22, 22, SecondaryColor);
|
||||
} else {
|
||||
tft.drawBitmap(32, 5, Stereo, 32, 22, GreyoutColor);
|
||||
}
|
||||
if (!StereoToggle) tft.drawBitmap(38, 5, Mono, 22, 22, SecondaryColor);
|
||||
else tft.drawBitmap(32, 5, Stereo, 32, 22, GreyoutColor);
|
||||
|
||||
if (autosquelch) showAutoSquelch(1);
|
||||
|
||||
@@ -3822,13 +3819,6 @@ void MenuUpDown(bool dir) {
|
||||
}
|
||||
}
|
||||
|
||||
if (ConverterSet >= 200) {
|
||||
Wire.beginTransmission(0x12);
|
||||
Wire.write(ConverterSet >> 8);
|
||||
Wire.write(ConverterSet & (0xFF));
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
OneBigLineSprite.setTextDatum(TL_DATUM);
|
||||
OneBigLineSprite.setTextColor(ActiveColor, ActiveColorSmooth, false);
|
||||
OneBigLineSprite.drawString("MHz", 155, 0);
|
||||
|
||||
+49
-3
@@ -841,10 +841,10 @@ int GetNum() {
|
||||
int cnt = 0;
|
||||
unsigned int num;
|
||||
|
||||
Wire.beginTransmission(0x20);
|
||||
Wire.beginTransmission(XL9555_ADDRESS);
|
||||
Wire.write(0x00);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(0x20, 2);
|
||||
Wire.requestFrom(XL9555_ADDRESS, 2);
|
||||
|
||||
if (Wire.available() == 2) {
|
||||
keypadtimer = millis();
|
||||
@@ -1146,6 +1146,52 @@ void setup() {
|
||||
gpio_set_drive_capability((gpio_num_t) 23, GPIO_DRIVE_CAP_0);
|
||||
|
||||
setupmode = true;
|
||||
|
||||
Tuner_I2C_Init();
|
||||
Serial.begin(115200);
|
||||
byte error, address;
|
||||
for (address = 1; address < 127; address++) { // I2C addresses 0x01–0x7F
|
||||
Wire.beginTransmission(address);
|
||||
error = Wire.endTransmission();
|
||||
|
||||
if (error == 0) {
|
||||
Serial.print("I2C device found at 0x");
|
||||
if (address < 16) Serial.print("0");
|
||||
Serial.print(address, HEX);
|
||||
if(address == RX8010SJ_ADDRESS) {
|
||||
Serial.print(" RTC");
|
||||
rx_rtc_avail = true;
|
||||
}
|
||||
Serial.println(" !");
|
||||
} else if (error == 4) {
|
||||
Serial.print("Unknown error at 0x");
|
||||
if (address < 16) Serial.print("0");
|
||||
Serial.println(address, HEX);
|
||||
}
|
||||
}
|
||||
Serial.flush();
|
||||
Serial.end();
|
||||
|
||||
rtc.setTime(0);
|
||||
if(rx_rtc_avail) {
|
||||
RX8010SJ::DateTime defaulttime = RX8010SJ::DateTime();
|
||||
defaulttime.second = 21;
|
||||
defaulttime.minute = 45;
|
||||
defaulttime.hour = 11;
|
||||
defaulttime.dayOfWeek = 6;
|
||||
defaulttime.dayOfMonth = 11;
|
||||
defaulttime.month = 1;
|
||||
defaulttime.year = 26;
|
||||
bool reset = rx_rtc.initModule(); // initModule, not initAdapter, adapter also reinits wire
|
||||
if(reset) {
|
||||
Serial.println("RTC reset with defaults");
|
||||
rx_rtc.writeDateTime(defaulttime);
|
||||
} else {
|
||||
rtcset = true;
|
||||
sync_from_rx_rtc();
|
||||
}
|
||||
}
|
||||
|
||||
EEPROM.begin(EE_TOTAL_CNT);
|
||||
loadData();
|
||||
|
||||
@@ -1417,7 +1463,7 @@ void setup() {
|
||||
}
|
||||
tftPrint(ACENTER, "Patch: v" + String(TEF), 160, 202, ActiveColor, ActiveColorSmooth, 28);
|
||||
|
||||
Wire.beginTransmission(0x20);
|
||||
Wire.beginTransmission(XL9555_ADDRESS);
|
||||
Wire.write(0x06);
|
||||
Wire.write(0xFF);
|
||||
Wire.write(0xFF);
|
||||
|
||||
+11
-19
@@ -514,50 +514,42 @@ void showPS() {
|
||||
void showCT() {
|
||||
char timeStr[16];
|
||||
char dateStr[9];
|
||||
time_t t;
|
||||
|
||||
if (radio.rds.hasCT && !dropout && !NTPupdated) t = radio.rds.time + radio.rds.offset;
|
||||
else {
|
||||
t = rtc.getEpoch() + (NTPupdated ? 0 : radio.rds.offset);
|
||||
|
||||
// Update RDS time during dropout
|
||||
if (dropout) radio.rds.time = static_cast<time_t>(rtc.getEpoch());
|
||||
}
|
||||
time_t t = rtc.getEpoch() + (NTPupdated ? 0 : radio.rds.offset);
|
||||
|
||||
if (NTPupdated) {
|
||||
t += NTPoffset * 3600; // Convert offset from hours to seconds
|
||||
if (autoDST && isDST(t)) t += 3600;
|
||||
}
|
||||
|
||||
auto localtm = localtime(&t);
|
||||
|
||||
if (clockampm) { // USA region: 12-hour AM/PM format
|
||||
int hour = localtime(&t)->tm_hour;
|
||||
int hour = localtm->tm_hour;
|
||||
|
||||
if (hour < 1 || hour > 12) {
|
||||
if (hour == 0) hour = 12;
|
||||
else if (hour > 12) hour -= 12;
|
||||
}
|
||||
|
||||
String ampm = (localtime(&t)->tm_hour >= 12) ? "PM" : "AM";
|
||||
snprintf(timeStr, sizeof(timeStr), "%d:%02d %s", hour, localtime(&t)->tm_min, ampm.c_str());
|
||||
String ampm = (localtm->tm_hour >= 12) ? "PM" : "AM";
|
||||
snprintf(timeStr, sizeof(timeStr), "%d:%02d %s", hour, localtm->tm_min, ampm.c_str());
|
||||
} else {
|
||||
int hour = localtime(&t)->tm_hour;
|
||||
int hour = localtm->tm_hour;
|
||||
if (hour < 0 || hour > 23) hour = 0;
|
||||
|
||||
snprintf(timeStr, sizeof(timeStr), "%02d:%02d", hour, localtime(&t)->tm_min);
|
||||
snprintf(timeStr, sizeof(timeStr), "%02d:%02d", hour, localtm->tm_min);
|
||||
|
||||
}
|
||||
|
||||
rds_clock = String(timeStr);
|
||||
|
||||
if (clockampm) strftime(dateStr, sizeof(dateStr), "%m-%d-%y", localtime(&t));
|
||||
else strftime(dateStr, sizeof(dateStr), "%d-%m-%y", localtime(&t));
|
||||
if (clockampm) strftime(dateStr, sizeof(dateStr), "%m-%d-%y", localtm);
|
||||
else strftime(dateStr, sizeof(dateStr), "%d-%m-%y", localtm);
|
||||
rds_date = String(dateStr);
|
||||
|
||||
if (!screenmute && showclock && (rds_clock != rds_clockold || rds_date != rds_dateold || radio.rds.hasCT.changed(0))) {
|
||||
|
||||
if ((radio.rds.hasCT && RDSstatus) || NTPupdated) {
|
||||
rtcset = true;
|
||||
if (!NTPupdated) rtc.setTime(radio.rds.time);
|
||||
|
||||
tftReplace(ACENTER, rds_clockold, rds_clock, 134, 1, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
||||
tftReplace(ACENTER, rds_dateold, rds_date, 134, 15, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
||||
} else { // Handle dropout scenarios
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
#include "rtc.hpp"
|
||||
|
||||
bool rtcset;
|
||||
bool NTPupdated;
|
||||
|
||||
ESP32Time rtc(0);
|
||||
bool rx_rtc_avail = false;
|
||||
RX8010SJ::Adapter rx_rtc = RX8010SJ::Adapter(RX8010SJ_ADDRESS);
|
||||
|
||||
void timeToDateTime(time_t t, struct RX8010SJ::DateTime* dateTime) {
|
||||
struct tm* timeinfo = gmtime(&t);
|
||||
dateTime->second = timeinfo->tm_sec;
|
||||
dateTime->minute = timeinfo->tm_min;
|
||||
dateTime->hour = timeinfo->tm_hour;
|
||||
dateTime->dayOfWeek = (timeinfo->tm_wday + 6) % 7;
|
||||
dateTime->dayOfMonth = timeinfo->tm_mday;
|
||||
dateTime->month = timeinfo->tm_mon + 1; // tm_mon is 0-11, convert to 1-12
|
||||
dateTime->year = (timeinfo->tm_year + 1900) % 100; // Get last 2 digits
|
||||
}
|
||||
|
||||
time_t timegm(struct tm *tm) {
|
||||
// https://linux.die.net/man/3/timegm
|
||||
time_t ret;
|
||||
char *tz;
|
||||
|
||||
tz = getenv("TZ");
|
||||
setenv("TZ", "", 1);
|
||||
tzset();
|
||||
ret = mktime(tm);
|
||||
if (tz) setenv("TZ", tz, 1);
|
||||
else unsetenv("TZ");
|
||||
tzset();
|
||||
return ret;
|
||||
}
|
||||
|
||||
time_t dateTimeToTime(const struct RX8010SJ::DateTime* dateTime) {
|
||||
struct tm timeinfo;
|
||||
timeinfo.tm_sec = dateTime->second;
|
||||
timeinfo.tm_min = dateTime->minute;
|
||||
timeinfo.tm_hour = dateTime->hour;
|
||||
timeinfo.tm_mday = dateTime->dayOfMonth;
|
||||
timeinfo.tm_mon = dateTime->month - 1;
|
||||
timeinfo.tm_year = dateTime->year + 100;
|
||||
timeinfo.tm_isdst = 0;
|
||||
return timegm(&timeinfo);
|
||||
}
|
||||
|
||||
void sync_to_rx_rtc(int32_t offset) {
|
||||
if(!rx_rtc_avail) return;
|
||||
RX8010SJ::DateTime rx_currenttime = RX8010SJ::DateTime();
|
||||
timeToDateTime(rtc.getEpoch() + offset, &rx_currenttime);
|
||||
rx_rtc.writeDateTime(rx_currenttime);
|
||||
}
|
||||
void sync_from_rx_rtc(int32_t offset) {
|
||||
if(!rx_rtc_avail) return;
|
||||
RX8010SJ::DateTime dateTime = rx_rtc.readDateTime();
|
||||
rtc.setTime(dateTimeToTime(&dateTime) + offset);
|
||||
}
|
||||
Reference in New Issue
Block a user