commit
74fa91127c
@ -1,3 +1,5 @@
|
|||||||
|
#if (HAS_LORA)
|
||||||
|
|
||||||
#ifndef _LORAWAN_H
|
#ifndef _LORAWAN_H
|
||||||
#define _LORAWAN_H
|
#define _LORAWAN_H
|
||||||
|
|
||||||
@ -49,3 +51,5 @@ void showLoraKeys(void);
|
|||||||
#endif // VERBOSE
|
#endif // VERBOSE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // HAS_LORA
|
@ -10,6 +10,8 @@
|
|||||||
#include "dcf77.h"
|
#include "dcf77.h"
|
||||||
#include "esp_sntp.h"
|
#include "esp_sntp.h"
|
||||||
|
|
||||||
|
#define HAS_LORA_TIME ((HAS_LORA) && ((TIME_SYNC_LORASERVER) || (TIME_SYNC_LORAWAN)))
|
||||||
|
|
||||||
#define SECS_YR_2000 (946684800UL) // the time at the start of y2k
|
#define SECS_YR_2000 (946684800UL) // the time at the start of y2k
|
||||||
#define GPS_UTC_DIFF 315964800UL // seconds diff between gps and utc epoch
|
#define GPS_UTC_DIFF 315964800UL // seconds diff between gps and utc epoch
|
||||||
#define LEAP_SECS_SINCE_GPSEPOCH 18UL // state of 2021
|
#define LEAP_SECS_SINCE_GPSEPOCH 18UL // state of 2021
|
||||||
@ -32,7 +34,7 @@ void setTimeSyncIRQ(void);
|
|||||||
uint8_t timepulse_init(void);
|
uint8_t timepulse_init(void);
|
||||||
bool timeIsValid(time_t const t);
|
bool timeIsValid(time_t const t);
|
||||||
void calibrateTime(void);
|
void calibrateTime(void);
|
||||||
void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec,
|
bool IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec,
|
||||||
timesource_t mytimesource);
|
timesource_t mytimesource);
|
||||||
time_t compileTime(void);
|
time_t compileTime(void);
|
||||||
time_t mkgmtime(const struct tm *ptm);
|
time_t mkgmtime(const struct tm *ptm);
|
||||||
|
@ -95,7 +95,7 @@ void start_boot_menu(void) {
|
|||||||
|
|
||||||
// setup watchdog, based on esp32 timer2 interrupt
|
// setup watchdog, based on esp32 timer2 interrupt
|
||||||
wdTimer = timerBegin(0, 80, true); // timer 0, div 80, countup
|
wdTimer = timerBegin(0, 80, true); // timer 0, div 80, countup
|
||||||
timerAttachInterrupt(wdTimer, &watchdog, true); // callback for device reset
|
timerAttachInterrupt(wdTimer, &watchdog, false); // callback for device reset
|
||||||
timerAlarmWrite(wdTimer, BOOTDELAY * 1000000, false); // set time in us
|
timerAlarmWrite(wdTimer, BOOTDELAY * 1000000, false); // set time in us
|
||||||
timerAlarmEnable(wdTimer); // enable watchdog
|
timerAlarmEnable(wdTimer); // enable watchdog
|
||||||
|
|
||||||
|
@ -7,9 +7,12 @@ static const char TAG[] = __FILE__;
|
|||||||
|
|
||||||
SemaphoreHandle_t I2Caccess;
|
SemaphoreHandle_t I2Caccess;
|
||||||
|
|
||||||
void i2c_init(void) { Wire.begin(MY_DISPLAY_SDA, MY_DISPLAY_SCL, 100000); }
|
void i2c_init(void) {
|
||||||
|
Wire.setPins(MY_DISPLAY_SDA, MY_DISPLAY_SCL);
|
||||||
|
Wire.begin();
|
||||||
|
}
|
||||||
|
|
||||||
void i2c_deinit(void) { Wire.~TwoWire(); }
|
void i2c_deinit(void) { Wire.end(); }
|
||||||
|
|
||||||
void i2c_scan(void) {
|
void i2c_scan(void) {
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
// COUNTRY AND PROJECT SPECIFIC DEFINITIONS FOR LMIC STACK
|
// COUNTRY AND PROJECT SPECIFIC DEFINITIONS FOR LMIC STACK
|
||||||
|
|
||||||
|
// workaround for arduino-espressif32 v2.0.0 (see isse #714 @ MCCI_LMIC)
|
||||||
|
#define hal_init LMICHAL_init
|
||||||
|
|
||||||
// COUNTRY SETTINGS
|
// COUNTRY SETTINGS
|
||||||
// --> please check with you local regulations for ISM band frequency use!
|
// --> please check with you local regulations for ISM band frequency use!
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ void setup() {
|
|||||||
// https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
|
// https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
|
||||||
// prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 0, count up
|
// prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 0, count up
|
||||||
displayIRQ = timerBegin(0, 80, true);
|
displayIRQ = timerBegin(0, 80, true);
|
||||||
timerAttachInterrupt(displayIRQ, &DisplayIRQ, true);
|
timerAttachInterrupt(displayIRQ, &DisplayIRQ, false);
|
||||||
timerAlarmWrite(displayIRQ, DISPLAYREFRESH_MS * 1000, true);
|
timerAlarmWrite(displayIRQ, DISPLAYREFRESH_MS * 1000, true);
|
||||||
timerAlarmEnable(displayIRQ);
|
timerAlarmEnable(displayIRQ);
|
||||||
#endif
|
#endif
|
||||||
@ -460,7 +460,7 @@ void setup() {
|
|||||||
// https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
|
// https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
|
||||||
// prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 3, count up
|
// prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 3, count up
|
||||||
matrixDisplayIRQ = timerBegin(3, 80, true);
|
matrixDisplayIRQ = timerBegin(3, 80, true);
|
||||||
timerAttachInterrupt(matrixDisplayIRQ, &MatrixDisplayIRQ, true);
|
timerAttachInterrupt(matrixDisplayIRQ, &MatrixDisplayIRQ, false);
|
||||||
timerAlarmWrite(matrixDisplayIRQ, MATRIX_DISPLAY_SCAN_US, true);
|
timerAlarmWrite(matrixDisplayIRQ, MATRIX_DISPLAY_SCAN_US, true);
|
||||||
timerAlarmEnable(matrixDisplayIRQ);
|
timerAlarmEnable(matrixDisplayIRQ);
|
||||||
#endif
|
#endif
|
||||||
@ -480,14 +480,14 @@ void setup() {
|
|||||||
cyclicTimer.attach(HOMECYCLE, setCyclicIRQ);
|
cyclicTimer.attach(HOMECYCLE, setCyclicIRQ);
|
||||||
|
|
||||||
// only if we have a timesource we do timesync
|
// only if we have a timesource we do timesync
|
||||||
#if ((TIME_SYNC_LORAWAN) || (TIME_SYNC_LORASERVER) || (HAS_GPS) || (HAS_RTC))
|
#if ((HAS_LORA_TIME) || (HAS_GPS) || (HAS_RTC))
|
||||||
|
|
||||||
#if (defined HAS_IF482 || defined HAS_DCF77)
|
#if (defined HAS_IF482 || defined HAS_DCF77)
|
||||||
ESP_LOGI(TAG, "Starting Clock Controller...");
|
ESP_LOGI(TAG, "Starting Clock Controller...");
|
||||||
clock_init();
|
clock_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (TIME_SYNC_LORASERVER) || (TIME_SYNC_LORAWAN)
|
#if (HAS_LORA_TIME)
|
||||||
timesync_init(); // create loraserver time sync task
|
timesync_init(); // create loraserver time sync task
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -43,8 +43,14 @@ void AXP192_powerevent_IRQ(void) {
|
|||||||
ESP_LOGI(TAG, "Battery was removed.");
|
ESP_LOGI(TAG, "Battery was removed.");
|
||||||
if (pmu.isChargingIRQ())
|
if (pmu.isChargingIRQ())
|
||||||
ESP_LOGI(TAG, "Battery charging.");
|
ESP_LOGI(TAG, "Battery charging.");
|
||||||
if (pmu.isChargingDoneIRQ())
|
if (pmu.isChargingDoneIRQ()) {
|
||||||
ESP_LOGI(TAG, "Battery charging done.");
|
ESP_LOGI(TAG, "Battery charging done.");
|
||||||
|
#ifdef PMU_LED_RUN_MODE
|
||||||
|
pmu.setChgLEDMode(PMU_LED_RUN_MODE);
|
||||||
|
#else
|
||||||
|
pmu.setChgLEDMode(AXP20X_LED_LOW_LEVEL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
if (pmu.isBattTempLowIRQ())
|
if (pmu.isBattTempLowIRQ())
|
||||||
ESP_LOGI(TAG, "Battery high temperature.");
|
ESP_LOGI(TAG, "Battery high temperature.");
|
||||||
if (pmu.isBattTempHighIRQ())
|
if (pmu.isBattTempHighIRQ())
|
||||||
|
@ -1,13 +1,5 @@
|
|||||||
#include "timekeeper.h"
|
#include "timekeeper.h"
|
||||||
|
|
||||||
#if !(HAS_LORA)
|
|
||||||
#if (TIME_SYNC_LORASERVER)
|
|
||||||
#error TIME_SYNC_LORASERVER defined, but device has no LORA configured
|
|
||||||
#elif (TIME_SYNC_LORAWAN)
|
|
||||||
#error TIME_SYNC_LORAWAN defined, but device has no LORA configured
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (defined HAS_DCF77 && defined HAS_IF482)
|
#if (defined HAS_DCF77 && defined HAS_IF482)
|
||||||
#error You must define at most one of IF482 or DCF77!
|
#error You must define at most one of IF482 or DCF77!
|
||||||
#endif
|
#endif
|
||||||
@ -44,48 +36,38 @@ void calibrateTime(void) {
|
|||||||
time_t t = 0;
|
time_t t = 0;
|
||||||
uint16_t t_msec = 0;
|
uint16_t t_msec = 0;
|
||||||
|
|
||||||
// kick off asychronous lora timesync if we have
|
// kick off asynchronous lora timesync if we have
|
||||||
#if (HAS_LORA) && ((TIME_SYNC_LORASERVER) || (TIME_SYNC_LORAWAN))
|
#if (HAS_LORA_TIME)
|
||||||
timesync_request();
|
timesync_request();
|
||||||
#endif
|
if (timeSource == _lora) // did have lora time before?
|
||||||
|
|
||||||
// if no LORA timesource is available, or if we lost time, then fallback to
|
|
||||||
// local time source RTS or GPS
|
|
||||||
if (((!TIME_SYNC_LORASERVER) && (!TIME_SYNC_LORAWAN)) ||
|
|
||||||
(timeSource == _unsynced)) {
|
|
||||||
|
|
||||||
// has RTC -> fallback to RTC time
|
|
||||||
#ifdef HAS_RTC
|
|
||||||
t = get_rtctime(&t_msec);
|
|
||||||
// set time from RTC - method will check if time is valid
|
|
||||||
setMyTime((uint32_t)t, t_msec, _rtc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// no RTC -> fallback to GPS time
|
|
||||||
#if (HAS_GPS)
|
|
||||||
t = get_gpstime(&t_msec);
|
|
||||||
// set time from GPS - method will check if time is valid
|
|
||||||
setMyTime((uint32_t)t, t_msec, _gps);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // fallback
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
// no fallback time source available -> we can't set time
|
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// get GPS time, if we have
|
||||||
|
#if (HAS_GPS)
|
||||||
|
t = get_gpstime(&t_msec);
|
||||||
|
if (setMyTime((uint32_t)t, t_msec, _gps))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// fallback to RTC time, if we have
|
||||||
|
#ifdef HAS_RTC
|
||||||
|
t = get_rtctime(&t_msec);
|
||||||
|
if (setMyTime((uint32_t)t, t_msec, _rtc))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
} // calibrateTime()
|
} // calibrateTime()
|
||||||
|
|
||||||
// set system time (UTC), calibrate RTC and RTC_INT pps
|
// set system time (UTC), calibrate RTC and RTC_INT pps
|
||||||
void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec,
|
bool IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec,
|
||||||
timesource_t mytimesource) {
|
timesource_t mytimesource) {
|
||||||
|
|
||||||
struct timeval tv = {0};
|
struct timeval tv = {0};
|
||||||
|
|
||||||
// called with invalid timesource?
|
// called with invalid timesource?
|
||||||
if (mytimesource == _unsynced)
|
if (mytimesource == _unsynced)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
// increment t_sec if t_msec > 1000
|
// increment t_sec if t_msec > 1000
|
||||||
time_t time_to_set = (time_t)(t_sec + t_msec / 1000);
|
time_t time_to_set = (time_t)(t_sec + t_msec / 1000);
|
||||||
@ -126,13 +108,17 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec,
|
|||||||
timesyncer.attach(TIME_SYNC_INTERVAL * 60, setTimeSyncIRQ);
|
timesyncer.attach(TIME_SYNC_INTERVAL * 60, setTimeSyncIRQ);
|
||||||
ESP_LOGD(TAG, "[%0.3f] Timesync finished, time was set | timesource=%d",
|
ESP_LOGD(TAG, "[%0.3f] Timesync finished, time was set | timesource=%d",
|
||||||
_seconds(), mytimesource);
|
_seconds(), mytimesource);
|
||||||
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, setTimeSyncIRQ);
|
timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, setTimeSyncIRQ);
|
||||||
ESP_LOGV(TAG,
|
ESP_LOGV(TAG,
|
||||||
"[%0.3f] Failed to synchronise time from source %c | unix sec "
|
"[%0.3f] Failed to synchronise time from source %c | unix sec "
|
||||||
"obtained from source: %d | unix sec at program compilation: %d",
|
"obtained from source: %d | unix sec at program compilation: %d",
|
||||||
_seconds(), timeSetSymbols[mytimesource], time_to_set,
|
_seconds(), timeSetSymbols[mytimesource], time_to_set,
|
||||||
compileTime());
|
compileTime());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +158,7 @@ uint8_t timepulse_init() {
|
|||||||
// use ESP32 hardware timer as time base for calendar time
|
// use ESP32 hardware timer as time base for calendar time
|
||||||
ppsIRQ = timerBegin(1, 8000, true); // set 80 MHz prescaler to 1/10000 sec
|
ppsIRQ = timerBegin(1, 8000, true); // set 80 MHz prescaler to 1/10000 sec
|
||||||
timerAlarmWrite(ppsIRQ, 10000, true); // 1000ms
|
timerAlarmWrite(ppsIRQ, 10000, true); // 1000ms
|
||||||
timerAttachInterrupt(ppsIRQ, &CLOCKIRQ, true);
|
timerAttachInterrupt(ppsIRQ, &CLOCKIRQ, false);
|
||||||
timerAlarmEnable(ppsIRQ);
|
timerAlarmEnable(ppsIRQ);
|
||||||
ESP_LOGI(TAG, "Timepulse: internal (ESP32 hardware timer)");
|
ESP_LOGI(TAG, "Timepulse: internal (ESP32 hardware timer)");
|
||||||
return 1; // success
|
return 1; // success
|
||||||
|
@ -13,6 +13,8 @@ accept this.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if (HAS_LORA)
|
||||||
|
|
||||||
#if (TIME_SYNC_LORASERVER) && (TIME_SYNC_LORAWAN)
|
#if (TIME_SYNC_LORASERVER) && (TIME_SYNC_LORAWAN)
|
||||||
#error Duplicate timesync method selected. You must select either LORASERVER or LORAWAN timesync.
|
#error Duplicate timesync method selected. You must select either LORASERVER or LORAWAN timesync.
|
||||||
#endif
|
#endif
|
||||||
@ -173,7 +175,7 @@ void timesync_store(uint32_t timestamp, timesync_t timestamp_type) {
|
|||||||
// callback function to receive time answer from network or answer
|
// callback function to receive time answer from network or answer
|
||||||
void IRAM_ATTR timesync_serverAnswer(void *pUserData, int flag) {
|
void IRAM_ATTR timesync_serverAnswer(void *pUserData, int flag) {
|
||||||
|
|
||||||
#if (TIME_SYNC_LORASERVER) || (TIME_SYNC_LORAWAN)
|
#if (HAS_LORA_TIME)
|
||||||
|
|
||||||
// if no timesync handshake is pending then exit
|
// if no timesync handshake is pending then exit
|
||||||
if (!timeSyncPending)
|
if (!timeSyncPending)
|
||||||
@ -277,5 +279,7 @@ Exit:
|
|||||||
xTaskNotify(timeSyncProcTask, (rc ? rcv_seqNo : TIME_SYNC_END_FLAG),
|
xTaskNotify(timeSyncProcTask, (rc ? rcv_seqNo : TIME_SYNC_END_FLAG),
|
||||||
eSetBits);
|
eSetBits);
|
||||||
|
|
||||||
#endif // (TIME_SYNC_LORASERVER) || (TIME_SYNC_LORAWAN)
|
#endif // (HAS_LORA_TIME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // HAS_LORA
|
Loading…
Reference in New Issue
Block a user