diff --git a/src/main.cpp b/src/main.cpp index 3971ee57..e38178d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,7 +17,7 @@ Copyright 2018 Klaus Wilting See the License for the specific language governing permissions and limitations under the License. -NOTICE: +NOTE: Parts of the source files in this repository are made available under different licenses. Refer to LICENSE.txt file in repository for more details. @@ -31,8 +31,8 @@ ledloop 0 3 blinks LEDs spiloop 0 2 reads/writes data on spi interface IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer -timesync_req 1 4 processes realtime time sync requests -clockloop 1 3 generates realtime telegrams for external clock +clockloop 1 4 generates realtime telegrams for external clock +timesync_req 1 3 processes realtime time sync requests irqhandler 1 2 display, timesync, etc. tasks triggered by timer gpsloop 1 2 reads data from GPS via serial or i2c bmeloop 1 1 reads data from BME sensor via i2c @@ -44,6 +44,9 @@ Low priority numbers denote low priority tasks. Tasks using i2c bus all must have same priority, because using mutex semaphore (irqhandler, bmeloop) +NOTE: Changing any timings will have impact on time accuracy of whole code. +So don't do it if you do not own a digital oscilloscope. + // ESP32 hardware timers ------------------------------------------------------------------------------- 0 displayIRQ -> display refresh -> 40ms (DISPLAYREFRESH_MS) diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 8077693b..f4ee65e6 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -196,7 +196,7 @@ void clock_init(void) { "clockloop", // name of task 2048, // stack size of task (void *)&userUTCTime, // start time as task parameter - 3, // priority of the task + 4, // priority of the task &ClockTask, // task handle 1); // CPU core @@ -213,7 +213,6 @@ void clock_loop(void *taskparameter) { // ClockTask static bool led1_state = false; uint32_t printtime; time_t t = *((time_t *)taskparameter), last_printtime = 0; // UTC time seconds - TickType_t startTime; #ifdef HAS_DCF77 uint8_t *DCFpulse; // pointer on array with DCF pulse bits @@ -229,8 +228,6 @@ void clock_loop(void *taskparameter) { // ClockTask xTaskNotifyWait(0x00, ULONG_MAX, &printtime, portMAX_DELAY); // wait for timepulse - startTime = xTaskGetTickCount(); - t = time_t(printtime); // UTC time seconds // no confident or no recent time -> suppress clock output @@ -251,7 +248,7 @@ void clock_loop(void *taskparameter) { // ClockTask #if defined HAS_IF482 - 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 #elif defined HAS_DCF77 diff --git a/src/timesync.cpp b/src/timesync.cpp index 6440f34c..4b7176bb 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -54,7 +54,7 @@ void process_timesync_req(void *taskparameter) { while (1) { - // clear timestamp array before next sync run + // reset all timestamps before next sync run time_offset_ms = myClock_msecTick::zero(); for (uint8_t i = 0; i < TIME_SYNC_SAMPLES; i++) time_sync_tx[i] = time_sync_rx[i] = myClock_timepoint(); @@ -69,21 +69,22 @@ void process_timesync_req(void *taskparameter) { payload.addByte(time_sync_seqNo); SendPayload(TIMEPORT, prio_high); - // process answer, wait for notification from recv_timesync_ans() + // wait for notification from recv_timesync_ans() if ((xTaskNotifyWait(0x00, ULONG_MAX, &seq_no, pdMS_TO_TICKS(TIME_SYNC_TIMEOUT * 1000)) == pdFALSE) || (seq_no != time_sync_seqNo)) goto error; // no valid sequence received before timeout - else { // calculate time diff from collected timestamps + // process answer + else { k = seq_no % TIME_SYNC_SAMPLES; - // cumulate timepoint diffs + // calculate time diff from collected timestamps time_offset_ms += time_point_cast(time_sync_rx[k]) - time_point_cast(time_sync_tx[k]); - // wrap around seqNo keeping it in time port range + // wrap around seqNo, keeping it in time port range time_sync_seqNo = (time_sync_seqNo < TIMEANSWERPORT_MAX) ? time_sync_seqNo + 1 : TIMEANSWERPORT_MIN; @@ -100,18 +101,18 @@ void process_timesync_req(void *taskparameter) { // LMIC_sendAlive(); } } - } // end for() collect timestamp samples + } // end of for loop to collect timestamp samples - // begin of time critical section: lock I2C bus to ensure accurate timing + // begin of time critical section: lock app irq's and I2C bus if (!mask_user_IRQ()) goto error; // failure - // average time offset from collected diffs + // average time offset over all collected diffs time_offset_ms /= TIME_SYNC_SAMPLES; // calculate time offset with millisecond precision using LMIC's time base, // since we use LMIC's ostime_t txEnd as tx timestamp. - // Finally apply calibration const for processing time. + // Also apply calibration const to compensate processing time. time_offset_ms += milliseconds(osticks2ms(os_getTime())) + milliseconds(TIME_SYNC_FIXUP); @@ -123,7 +124,7 @@ void process_timesync_req(void *taskparameter) { setMyTime(time_to_set, time_to_set_fraction_msec); - // end of time critical section: release I2C bus + // end of time critical section: release I2C bus and re-enable app irq's unmask_user_IRQ(); goto finish; @@ -187,7 +188,7 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) { // construct the timepoint when message was seen on gateway time_sync_rx[k] += seconds(timestamp_sec) + milliseconds(timestamp_msec); - // guess timepoint is recent if newer than code compile date + // we guess timepoint is recent if it newer than code compile date if (timeIsValid(myClock::to_time_t(time_sync_rx[k]))) { ESP_LOGD(TAG, "[%0.3f] Timesync request #%d rcvd at %d.%03d", millis() / 1000.0, k, timestamp_sec, timestamp_msec); @@ -246,7 +247,7 @@ void timesync_init() { "timesync_req", // name of task 2048, // stack size of task (void *)1, // task parameter - 4, // priority of the task + 3, // priority of the task &timeSyncReqTask, // task handle 1); // CPU core }