timekeeper fixes (still experimental)

This commit is contained in:
Klaus K Wilting committed 2019-02-27 00:52:27 +01:00
1 parent 55e0c73c77
commit 7e4a360bb7
16 files changed
+106 -98

No files matched your search

+5 -1
View File
@@ -5,7 +5,7 @@
#include "cyclic.h"
// Local logging tag
static const char TAG[] = "main";
static const char TAG[] = __FILE__;
// do all housekeeping
void doHousekeeping() {
@@ -17,8 +17,12 @@ void doHousekeeping() {
if (cfg.runmode == 1)
do_reset();
#ifdef HAS_SPI
spi_housekeeping();
#endif
#ifdef HAS_LORA
lora_housekeeping();
#endif
// task storage debugging //
ESP_LOGD(TAG, "IRQhandler %d bytes left | Taskstate = %d",
+1 -1
View File
@@ -14,7 +14,7 @@ https://github.com/udoklein/dcf77
#include "dcf77.h"
// Local logging tag
static const char TAG[] = "main";
static const char TAG[] = __FILE__;
// triggered by second timepulse to ticker out DCF signal
void DCF77_Pulse(time_t t, uint8_t const *DCFpulse) {
-1
View File
@@ -46,7 +46,6 @@ const char *printmonth[] = {"xxx", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
uint8_t DisplayState = 0;
timesource_t timeSource = _unsynced;
// helper function, prints a hex key on display
void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) {
+15 -12
View File
@@ -3,7 +3,7 @@
#include "globals.h"
// Local logging tag
static const char TAG[] = "main";
static const char TAG[] = __FILE__;
TinyGPSPlus gps;
gpsStatus_t gps_status;
@@ -11,6 +11,10 @@ TaskHandle_t GpsTask;
#ifdef GPS_SERIAL
HardwareSerial GPS_Serial(1); // use UART #1
TickType_t const gpsDelay_ticks = pdMS_TO_TICKS(1000 - NMEA_BUFFERTIME) -
tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL);
#else
TickType_t const gpsDelay_ticks = pdMS_TO_TICKS(1000 - NMEA_BUFFERTIME);
#endif
// initialize and configure GPS
@@ -23,6 +27,13 @@ int gps_init(void) {
return 0;
}
// set timeout for reading recent time from GPS
#ifdef GPS_SERIAL // serial GPS
#else // I2C GPS
#endif
#if defined GPS_SERIAL
GPS_Serial.begin(GPS_SERIAL);
ESP_LOGI(TAG, "Using serial GPS");
@@ -76,20 +87,12 @@ 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
// set time to wait for arrive next recent NMEA time record
static const uint32_t gpsDelay_ms = gpsDelay_ticks / portTICK_PERIOD_MS;
time_t t = 0;
// 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())) {
if ((gps.time.age() < gpsDelay_ms) && (gps.time.isValid())) {
ESP_LOGD(TAG, "GPS time age: %dms, is valid: %s", gps.time.age(),
gps.time.isValid() ? "yes" : "no");
+5 -5
View File
@@ -82,19 +82,19 @@ not evaluated by model BU-190
#include "if482.h"
// Local logging tag
static const char TAG[] = "main";
static const char TAG[] = __FILE__;
HardwareSerial IF482(2); // use UART #2 (note: #1 may be in use for serial GPS)
// triggered by timepulse to ticker out DCF signal
// triggered by timepulse to send IF482 signal
void IF482_Pulse(time_t t) {
static const TickType_t txDelay =
pdMS_TO_TICKS(IF482_PULSE_LENGTH - tx_Ticks(IF482_FRAME_SIZE, HAS_IF482));
TickType_t startTime = xTaskGetTickCount();
vTaskDelayUntil(&startTime, txDelay); // wait until moment to fire
//TickType_t startTime = xTaskGetTickCount();
//vTaskDelayUntil(&startTime, txDelay); // wait until moment to fire
vTaskDelay(txDelay); // wait until moment to fire
IF482.print(IF482_Frame(t + 1)); // note: if482 telegram for *next* second
}
+8 -7
View File
@@ -1,7 +1,7 @@
#include "irqhandler.h"
// Local logging tag
static const char TAG[] = "main";
static const char TAG[] = __FILE__;
// irq handler task, handles all our application level interrupts
void irqHandler(void *pvParameters) {
@@ -12,11 +12,10 @@ void irqHandler(void *pvParameters) {
// task remains in blocked state until it is notified by an irq
for (;;) {
xTaskNotifyWait(
0x00, // Don't clear any bits on entry
ULONG_MAX, // Clear all bits on exit
&InterruptStatus, // Receives the notification value
portMAX_DELAY); // wait forever
xTaskNotifyWait(0x00, // Don't clear any bits on entry
ULONG_MAX, // Clear all bits on exit
&InterruptStatus, // Receives the notification value
portMAX_DELAY); // wait forever
// button pressed?
#ifdef HAS_BUTTON
@@ -31,8 +30,10 @@ void irqHandler(void *pvParameters) {
#endif
// are cyclic tasks due?
if (InterruptStatus & CYCLIC_IRQ)
if (InterruptStatus & CYCLIC_IRQ) {
doHousekeeping();
timeSync();
}
// is time to send the payload?
if (InterruptStatus & SENDCOUNTER_IRQ)
+16 -23
View File
@@ -358,12 +358,7 @@ void lora_send(osjob_t *job) {
lora_send);
}
#endif // HAS_LORA
esp_err_t lora_stack_init() {
#ifndef HAS_LORA
return ESP_OK; // continue main program
#else
assert(SEND_QUEUE_SIZE);
LoraSendQueue = xQueueCreate(SEND_QUEUE_SIZE, sizeof(MessageBuffer_t));
if (LoraSendQueue == 0) {
@@ -401,12 +396,10 @@ esp_err_t lora_stack_init() {
}
return ESP_OK; // continue main program
#endif // HAS_LORA
}
void lora_enqueuedata(MessageBuffer_t *message, sendprio_t prio) {
// enqueue message in LORA send queue
#ifdef HAS_LORA
BaseType_t ret;
switch (prio) {
case prio_high:
@@ -423,27 +416,26 @@ void lora_enqueuedata(MessageBuffer_t *message, sendprio_t prio) {
} else {
ESP_LOGW(TAG, "LORA sendqueue is full");
}
#endif
}
void lora_queuereset(void) {
#ifdef HAS_LORA
xQueueReset(LoraSendQueue);
#endif
}
void lora_queuereset(void) { xQueueReset(LoraSendQueue); }
void lora_housekeeping(void) {
#ifdef HAS_LORA
// ESP_LOGD(TAG, "loraloop %d bytes left",
// uxTaskGetStackHighWaterMark(LoraTask));
#endif
// ESP_LOGD(TAG, "loraloop %d bytes left",
// uxTaskGetStackHighWaterMark(LoraTask));
}
void user_request_network_time_callback(void *pVoidUserUTCTime,
int flagSuccess) {
#ifdef HAS_LORA
// Explicit conversion from void* to uint32_t* to avoid compiler errors
time_t *pUserUTCTime = (time_t *)pVoidUserUTCTime;
// A struct that will be populated by LMIC_getNetworkTimeReference.
// It contains the following fields:
// - tLocal: the value returned by os_GetTime() when the time
// request was sent to the gateway, and
// - tNetwork: the seconds between the GPS epoch and the time
// the gateway received the time request
lmic_time_reference_t lmicTimeReference;
if (flagSuccess != 1) {
@@ -473,11 +465,12 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
// Update system time with time read from the network
if (TimeIsValid(*pUserUTCTime)) {
setTime(*pUserUTCTime);
xSemaphoreTake(TimePulse, pdMS_TO_TICKS(1000)); // wait for pps
setTime(*pUserUTCTime + 1);
timeSource = _lora;
ESP_LOGI(TAG, "Received recent time from LoRa");
}
else
} else
ESP_LOGI(TAG, "Invalid time received from LoRa");
#endif // HAS_LORA
} // user_request_network_time_callback
} // user_request_network_time_callback
#endif // HAS_LORA
+6 -8
View File
@@ -52,7 +52,7 @@ ESP32 hardware irq timers
RTC hardware timer (if present)
================================
triggers IF482 clock signal
triggers pps 1 sec impulse
*/
@@ -72,6 +72,7 @@ TaskHandle_t irqHandlerTask, ClockTask;
SemaphoreHandle_t I2Caccess, TimePulse;
bool volatile TimePulseTick = false;
time_t userUTCTime = 0;
timesource_t timeSource = _unsynced;
// container holding unique MAC address hashes with Memory Alloctor using PSRAM,
// if present
@@ -86,7 +87,7 @@ TimeChangeRule mySTD = STANDARD_TIME;
Timezone myTZ(myDST, mySTD);
// local Tag for logging
static const char TAG[] = "main";
static const char TAG[] = __FILE__;
void setup() {
@@ -283,14 +284,14 @@ void setup() {
// initialize LoRa
#ifdef HAS_LORA
strcat_P(features, " LORA");
#endif
assert(lora_stack_init() == ESP_OK);
#endif
// initialize SPI
#ifdef HAS_SPI
strcat_P(features, " SPI");
#endif
assert(spi_init() == ESP_OK);
#endif
#ifdef VENDORFILTER
strcat_P(features, " OUIFLT");
@@ -361,10 +362,7 @@ void setup() {
ESP_LOGI(TAG, "Starting Timekeeper...");
assert(timepulse_init()); // setup timepulse
timepulse_start();
#ifdef TIME_SYNC_INTERVAL
setSyncInterval(TIME_SYNC_INTERVAL * 60); // controls timeStatus() via Time.h
setSyncProvider(time_sync); // is called by Time.h
#endif
timeSync();
// start wifi in monitor mode and start channel rotation timer
ESP_LOGI(TAG, "Starting Wifi...");
+1 -1
View File
@@ -1,7 +1,7 @@
#include "rtctime.h"
// Local logging tag
static const char TAG[] = "main";
static const char TAG[] = __FILE__;
#ifdef HAS_RTC // we have hardware RTC
+33 -28
View File
@@ -1,57 +1,64 @@
#include "timekeeper.h"
// Local logging tag
static const char TAG[] = "main";
static const char TAG[] = __FILE__;
// symbol to display current time source
const char timeSetSymbols[] = {'G', 'R', 'L', '?'};
getExternalTime TimeSourcePtr; // pointer to time source function
time_t time_sync() {
// check synchonization of systime, called by cyclic.cpp
// syncs systime from external time source and sets/reads RTC, called by
// cyclic.cpp
void timeSync(void) {
time_t t = 0;
#ifdef HAS_GPS
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
// do we have a valid GPS time?
if (get_gpstime()) { // then let's sync GPS time on top of second
xSemaphoreTake(TimePulse, pdMS_TO_TICKS(1000)); // wait for pps
vTaskDelay(gpsDelay_ticks);
t = get_gpstime(); // fetch time from recent NEMA record
if (t) {
t++; // gps time concerns past second, so we add one
xSemaphoreTake(TimePulse, pdMS_TO_TICKS(1000)); // wait for pps
setTime(t);
#ifdef HAS_RTC
set_rtctime(t); // calibrate RTC
set_rtctime(t); // calibrate RTC
#endif
timeSource = _gps;
goto exit;
}
timeSource = _gps;
goto exit;
}
}
#endif
// no GPS -> fallback to RTC time while trying lora sync
#ifdef HAS_RTC
t = get_rtctime();
if (t)
timeSource = _rtc;
else
ESP_LOGW(TAG, "no confident RTC time");
t = get_rtctime();
if (t) {
setTime(t);
timeSource = _rtc;
} else
ESP_LOGW(TAG, "no confident RTC time");
#endif
// try lora sync if we have
#if defined HAS_LORA && defined TIME_SYNC_LORA
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
#endif
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;
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;
} // time_sync()
} // timeSync()
// helper function to setup a pulse per second for time synchronisation
uint8_t timepulse_init() {
@@ -119,8 +126,6 @@ void IRAM_ATTR CLOCKIRQ(void) {
// helper function to check plausibility of a time
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() ? t : 0);
}