timesync fixes

This commit is contained in:
Verkehrsrot 2019-03-24 16:20:39 +01:00
parent 57042e943c
commit 94766f2832
2 changed files with 27 additions and 22 deletions

View File

@ -20,8 +20,6 @@ HardwareSerial IF482(2); // use UART #2 (#1 may be in use for serial GPS)
Ticker timesyncer; Ticker timesyncer;
static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); } void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); }
time_t timeProvider(void) { time_t timeProvider(void) {
@ -32,7 +30,7 @@ time_t timeProvider(void) {
t = get_gpstime(); // fetch recent time from last NEMA record t = get_gpstime(); // fetch recent time from last NEMA record
if (t) { if (t) {
#ifdef HAS_RTC #ifdef HAS_RTC
set_rtctime(t); // calibrate RTC set_rtctime(t, do_mutex); // calibrate RTC
#endif #endif
timeSource = _gps; timeSource = _gps;
timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat
@ -121,7 +119,6 @@ void timepulse_start(void) {
// interrupt service routine triggered by either pps or esp32 hardware timer // interrupt service routine triggered by either pps or esp32 hardware timer
void IRAM_ATTR CLOCKIRQ(void) { void IRAM_ATTR CLOCKIRQ(void) {
portENTER_CRITICAL_ISR(&mux);
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
SyncToPPS(); // calibrates UTC systime and advances it +1, see microTime.h SyncToPPS(); // calibrates UTC systime and advances it +1, see microTime.h
@ -136,13 +133,12 @@ void IRAM_ATTR CLOCKIRQ(void) {
#endif #endif
#endif #endif
portEXIT_CRITICAL_ISR(&mux);
// yield only if we should // yield only if we should
if (xHigherPriorityTaskWoken) if (xHigherPriorityTaskWoken)
portYIELD_FROM_ISR(); portYIELD_FROM_ISR();
} }
// helper function to check plausibility of a time // helper function to check plausibility of a time
time_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 // is it a time in the past? we use compile date to guess
@ -208,6 +204,7 @@ void clock_init(void) {
assert(ClockTask); // has clock task started? assert(ClockTask); // has clock task started?
} // clock_init } // clock_init
void clock_loop(void *taskparameter) { // ClockTask void clock_loop(void *taskparameter) { // ClockTask
// caveat: don't use now() in this task, it will cause a race condition // caveat: don't use now() in this task, it will cause a race condition
@ -224,9 +221,8 @@ void clock_loop(void *taskparameter) { // ClockTask
uint8_t *DCFpulse; // pointer on array with DCF pulse bits uint8_t *DCFpulse; // pointer on array with DCF pulse bits
DCFpulse = DCF77_Frame(nextmin(t)); // load first DCF frame before start DCFpulse = DCF77_Frame(nextmin(t)); // load first DCF frame before start
#elif defined HAS_IF482 #elif defined HAS_IF482
static TickType_t txDelay = static TickType_t txDelay = pdMS_TO_TICKS(1000 - IF482_SYNC_FIXUP) -
pdMS_TO_TICKS(1000 - 2) - tx_Ticks(IF482_FRAME_SIZE, HAS_IF482); tx_Ticks(IF482_FRAME_SIZE, HAS_IF482);
// 2ms margin for processing time
#endif #endif
// output the next second's pulse after timepulse arrived // output the next second's pulse after timepulse arrived
@ -246,7 +242,8 @@ void clock_loop(void *taskparameter) { // ClockTask
last_printtime = t; last_printtime = t;
#ifdef HAS_LED1 // pps blink on secondary LED if we have one
#ifdef HAS_TWO_LED
if (led1_state) if (led1_state)
switch_LED1(LED_OFF); switch_LED1(LED_OFF);
else else

View File

@ -119,10 +119,10 @@ void process_timesync_req(void *taskparameter) {
time_offset_ms /= TIME_SYNC_SAMPLES; time_offset_ms /= TIME_SYNC_SAMPLES;
// calculate time offset with millisecond precision using time base // calculate time offset with millisecond precision using time base
// of LMIC os, since we use LMIC's ostime_t txEnd as tx timestamp // of LMIC os, since we use LMIC's ostime_t txEnd as tx timestamp.
time_offset_ms += milliseconds(osticks2ms(os_getTime()));
// apply calibration factor for processing time // apply calibration factor for processing time
time_offset_ms += milliseconds(TIME_SYNC_FIXUP); time_offset_ms +=
milliseconds(osticks2ms(os_getTime())) + milliseconds(TIME_SYNC_FIXUP);
// calculate absolute time in UTC epoch // calculate absolute time in UTC epoch
// convert to whole seconds, floor // convert to whole seconds, floor
@ -136,18 +136,26 @@ void process_timesync_req(void *taskparameter) {
// adjust system time // adjust system time
if (timeIsValid(time_to_set)) { if (timeIsValid(time_to_set)) {
// wait until top of second #ifdef HAS_RTC
vTaskDelay(pdMS_TO_TICKS(1000 - time_to_set_fraction_msec)); // get and lock access to i2c before we start time sync
if (I2C_MUTEX_LOCK()) {
#endif
// wait until top of second with 4ms precision
time_to_set++; // advance time 1 sec wait time time_to_set++; // advance time 1 sec wait time
vTaskDelay(pdMS_TO_TICKS(1000 - time_to_set_fraction_msec));
#ifdef HAS_RTC
// set RTC time and, if he have, calibrate RTC_INT pulse on top of second
set_rtctime(time_to_set, no_mutex);
I2C_MUTEX_UNLOCK();
} // release i2c bus access
#endif
#if (!defined GPS_INT && !defined RTC_INT) #if (!defined GPS_INT && !defined RTC_INT)
// sync esp32 hardware timer based pps to top of second // sync pps timer to top of second
timerRestart(ppsIRQ); // reset pps timer timerRestart(ppsIRQ); // reset pps timer
CLOCKIRQ(); // fire clock pps interrupt CLOCKIRQ(); // fire clock pps
#elif defined HAS_RTC
// calibrate RTC and RTC_INT pulse on top of second
set_rtctime(time_to_set);
#endif #endif
setTime(time_to_set); // set the time on top of second setTime(time_to_set); // set the time on top of second