timekeeper once again reworked and shortened
This commit is contained in:
parent
5fb4c7bec2
commit
5c191a269f
@ -41,9 +41,9 @@
|
||||
#define SCREEN_MODE (0x80)
|
||||
|
||||
// I2C bus access control
|
||||
#define I2C_MUTEX_LOCK() \
|
||||
xSemaphoreTake(I2Caccess, (3 * DISPLAYREFRESH_MS / portTICK_PERIOD_MS)) == \
|
||||
pdTRUE
|
||||
#define I2C_MUTEX_LOCK()
|
||||
xSemaphoreTake(I2Caccess,
|
||||
(3 * DISPLAYREFRESH_MS / portTICK_PERIOD_MS)) == pdTRUE
|
||||
#define I2C_MUTEX_UNLOCK() xSemaphoreGive(I2Caccess)
|
||||
|
||||
// Struct holding devices's runtime configuration
|
||||
@ -108,7 +108,8 @@ extern char display_line6[], display_line7[]; // screen buffers
|
||||
extern uint8_t volatile channel; // wifi channel rotation counter
|
||||
extern uint16_t volatile macs_total, macs_wifi, macs_ble,
|
||||
batt_voltage; // display values
|
||||
extern bool volatile TimePulseTick; // one-pulse-per-second flags set by GPS or RTC
|
||||
extern bool volatile TimePulseTick; // one-pulse-per-second flags set by GPS or
|
||||
// RTC
|
||||
extern hw_timer_t *sendCycle, *displaytimer, *clockCycle;
|
||||
extern SemaphoreHandle_t I2Caccess, TimePulse;
|
||||
extern TaskHandle_t irqHandlerTask, ClockTask;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <TinyGPS++.h> // library for parsing NMEA data
|
||||
#include <RtcDateTime.h>
|
||||
#include "timekeeper.h"
|
||||
|
||||
#ifdef GPS_I2C // Needed for reading from I2C Bus
|
||||
#include <Wire.h>
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _IF482_H
|
||||
|
||||
#include "globals.h"
|
||||
#include "timekeeper.h"
|
||||
|
||||
#define IF482_FRAME_SIZE (17)
|
||||
#define IF482_PULSE_LENGTH (1000)
|
||||
@ -10,7 +11,5 @@ extern HardwareSerial IF482;
|
||||
|
||||
void IF482_Pulse(time_t t);
|
||||
String IRAM_ATTR IF482_Frame(time_t tt);
|
||||
TickType_t tx_Ticks(unsigned long baud, uint32_t config, int8_t rxPin,
|
||||
int8_t txPins);
|
||||
|
||||
#endif
|
@ -20,12 +20,13 @@ void clock_init(void);
|
||||
void clock_loop(void *pvParameters);
|
||||
time_t time_sync(void);
|
||||
void timepulse_start(void);
|
||||
time_t syncTime(getExternalTime getTimeFunction, timesource_t const caller);
|
||||
uint8_t timepulse_init(void);
|
||||
uint8_t TimeIsValid(time_t const t);
|
||||
time_t TimeIsValid(time_t const t);
|
||||
time_t syncProvider_CB(void);
|
||||
time_t compiledUTC(void);
|
||||
time_t tmConvert(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh, uint8_t mm,
|
||||
uint8_t ss);
|
||||
TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config,
|
||||
int8_t rxPin, int8_t txPins);
|
||||
|
||||
#endif // _timekeeper_H
|
@ -75,22 +75,29 @@ void gps_read() {
|
||||
|
||||
// function to fetch current time from gps
|
||||
time_t get_gpstime(void) {
|
||||
|
||||
#define NMEA_FRAME_SIZE 80 // NEMA has a maxium of 80 bytes per record
|
||||
#define NMEA_BUFFER 50 // 50ms safety time regardless
|
||||
|
||||
time_t t = 0;
|
||||
|
||||
if ((gps.time.age() < 950) && (gps.time.isValid())) {
|
||||
// set timeout for reading recent time from GPS
|
||||
#ifdef GPS_SERIAL // serial GPS
|
||||
static const TickType_t txDelay =
|
||||
pdMS_TO_TICKS(1000 - NMEA_BUFFER - tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL));
|
||||
#else // I2C GPS
|
||||
static const TickType_t txDelay = 1000 - NMEA_BUFFER;
|
||||
#endif
|
||||
|
||||
if ((gps.time.age() < txDelay) && (gps.time.isValid())) {
|
||||
|
||||
ESP_LOGD(TAG, "GPS time age: %dms, is valid: %s", gps.time.age(),
|
||||
gps.time.isValid() ? "yes" : "no");
|
||||
|
||||
// use recent gps time
|
||||
t = tmConvert(gps.date.year(), gps.date.month(), gps.date.day(),
|
||||
gps.time.hour(), gps.time.minute(), gps.time.second());
|
||||
|
||||
// ESP_LOGD(TAG, "GPS time: %02d.%02d.%04d %02d:%02d:%02d", gps.date.day(),
|
||||
// gps.date.month(), gps.date.year(), gps.time.hour(),
|
||||
// gps.time.minute(), gps.time.second());
|
||||
}
|
||||
return t;
|
||||
return TimeIsValid(t);
|
||||
} // get_gpstime()
|
||||
|
||||
// GPS serial feed FreeRTos Task
|
||||
|
@ -90,7 +90,7 @@ HardwareSerial IF482(2); // use UART #2 (note: #1 may be in use for serial GPS)
|
||||
void IF482_Pulse(time_t t) {
|
||||
|
||||
static const TickType_t txDelay =
|
||||
pdMS_TO_TICKS(IF482_PULSE_LENGTH) - tx_Ticks(HAS_IF482);
|
||||
pdMS_TO_TICKS(IF482_PULSE_LENGTH - tx_Ticks(IF482_FRAME_SIZE, HAS_IF482));
|
||||
|
||||
TickType_t startTime = xTaskGetTickCount();
|
||||
|
||||
@ -124,17 +124,4 @@ String IRAM_ATTR IF482_Frame(time_t startTime) {
|
||||
return out;
|
||||
}
|
||||
|
||||
// calculate serial tx time from IF482 serial settings
|
||||
TickType_t tx_Ticks(unsigned long baud, uint32_t config, int8_t rxPin,
|
||||
int8_t txPins) {
|
||||
|
||||
uint32_t databits = ((config & 0x0c) >> 2) + 5;
|
||||
uint32_t stopbits = ((config & 0x20) >> 5) + 1;
|
||||
uint32_t txTime =
|
||||
(databits + stopbits + 2) * IF482_FRAME_SIZE * 1000.0 / baud;
|
||||
// +2 ms margin for the startbit and the clock's processing time
|
||||
|
||||
return pdMS_TO_TICKS(round(txTime));
|
||||
}
|
||||
|
||||
#endif // HAS_IF482
|
@ -474,6 +474,7 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
|
||||
// Update system time with time read from the network
|
||||
if (TimeIsValid(*pUserUTCTime)) {
|
||||
setTime(*pUserUTCTime);
|
||||
timeSource = _lora;
|
||||
ESP_LOGI(TAG, "Received recent time from LoRa");
|
||||
}
|
||||
else
|
||||
|
@ -67,7 +67,7 @@ time_t get_rtctime(void) {
|
||||
}
|
||||
I2C_MUTEX_UNLOCK();
|
||||
}
|
||||
return t;
|
||||
return TimeIsValid(t);
|
||||
} // get_rtctime()
|
||||
|
||||
float get_rtctemp(void) {
|
||||
|
@ -13,18 +13,26 @@ time_t time_sync() {
|
||||
|
||||
time_t t = 0;
|
||||
|
||||
#ifdef TIME_SYNC_INTERVAL
|
||||
|
||||
#ifdef HAS_GPS
|
||||
t = syncTime(get_gpstime, _gps);
|
||||
if (t)
|
||||
return t; // attempt sync with GPS time
|
||||
xSemaphoreTake(TimePulse, pdMS_TO_TICKS(1000)); // wait for pps
|
||||
ESP_LOGD(TAG, "micros = %d", micros());
|
||||
t = get_gpstime();
|
||||
if (t) {
|
||||
t++; // gps time concerns past second, so we add one second
|
||||
#ifdef HAS_RTC
|
||||
set_rtctime(t); // calibrate RTC
|
||||
#endif
|
||||
timeSource = _gps;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
// no GPS -> fallback to RTC time while trying lora sync
|
||||
#ifdef HAS_RTC
|
||||
t = syncTime(get_rtctime, _rtc); // sync with RTC time
|
||||
if (!t)
|
||||
t = get_rtctime();
|
||||
if (t)
|
||||
timeSource = _rtc;
|
||||
else
|
||||
ESP_LOGW(TAG, "no confident RTC time");
|
||||
#endif
|
||||
|
||||
@ -33,45 +41,18 @@ time_t time_sync() {
|
||||
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
|
||||
#endif
|
||||
|
||||
#endif // TIME_SYNC_INTERVAL
|
||||
exit:
|
||||
ESP_LOGD(TAG, "micros = %d", micros());
|
||||
if (t)
|
||||
ESP_LOGD(TAG, "Time was set by %c to %02d:%02d:%02d",
|
||||
timeSetSymbols[timeSource], hour(t), minute(t), second(t));
|
||||
else
|
||||
timeSource = _unsynced;
|
||||
|
||||
return t;
|
||||
|
||||
} // time_sync()
|
||||
|
||||
// sync time on start of next second from GPS or RTC
|
||||
time_t syncTime(getExternalTime getTimeFunction, timesource_t const caller) {
|
||||
|
||||
time_t t;
|
||||
TimeSourcePtr = getTimeFunction;
|
||||
if (!TimeSourcePtr)
|
||||
goto error;
|
||||
|
||||
xSemaphoreTake(TimePulse, pdMS_TO_TICKS(1000)); // wait for pps
|
||||
|
||||
t = TimeSourcePtr(); // get time from given timesource
|
||||
|
||||
if (TimeIsValid(t)) {
|
||||
if (caller == _gps) // gps time concerns past second
|
||||
t++;
|
||||
timeSource = caller;
|
||||
ESP_LOGD(TAG, "Time source %c set time to %02d:%02d:%02d",
|
||||
timeSetSymbols[timeSource], hour(t), minute(t), second(t));
|
||||
|
||||
#ifdef HAS_RTC
|
||||
if (caller != _rtc)
|
||||
set_rtctime(t);
|
||||
#endif
|
||||
|
||||
return t; // success
|
||||
}
|
||||
|
||||
error:
|
||||
ESP_LOGD(TAG, "Time source %c sync attempt failed", timeSetSymbols[caller]);
|
||||
timeSource = _unsynced;
|
||||
return 0; // failure
|
||||
|
||||
} // syncTime()
|
||||
|
||||
// helper function to setup a pulse per second for time synchronisation
|
||||
uint8_t timepulse_init() {
|
||||
|
||||
@ -136,11 +117,11 @@ void IRAM_ATTR CLOCKIRQ(void) {
|
||||
}
|
||||
|
||||
// helper function to check plausibility of a time
|
||||
uint8_t TimeIsValid(time_t const t) {
|
||||
time_t TimeIsValid(time_t const t) {
|
||||
// is it a time in the past? we use compile date to guess
|
||||
ESP_LOGD(TAG, "t=%d, tt=%d, valid: %s", t, compiledUTC(),
|
||||
(t >= compiledUTC()) ? "yes" : "no");
|
||||
return (t >= compiledUTC());
|
||||
return (t >= compiledUTC() ? t : 0);
|
||||
}
|
||||
|
||||
// helper function to convert compile time to UTC time
|
||||
@ -162,6 +143,18 @@ time_t tmConvert(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh, uint8_t mm,
|
||||
return makeTime(tm);
|
||||
}
|
||||
|
||||
// helper function to calculate serial transmit time
|
||||
TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config,
|
||||
int8_t rxPin, int8_t txPins) {
|
||||
|
||||
uint32_t databits = ((config & 0x0c) >> 2) + 5;
|
||||
uint32_t stopbits = ((config & 0x20) >> 5) + 1;
|
||||
uint32_t txTime = (databits + stopbits + 2) * framesize * 1000.0 / baud;
|
||||
// +1 ms margin for the startbit +1 ms for pending processing time
|
||||
|
||||
return round(txTime);
|
||||
}
|
||||
|
||||
#if defined HAS_IF482 || defined HAS_DCF77
|
||||
|
||||
#if defined HAS_DCF77 && defined HAS_IF482
|
||||
|
Loading…
Reference in New Issue
Block a user