i2c locking for rtc & timesync streamlined

This commit is contained in:
Verkehrsrot 2019-07-29 14:43:37 +02:00
parent 3f3c58feeb
commit 11cfa27c76
6 changed files with 15 additions and 23 deletions

View File

@ -99,7 +99,6 @@ typedef struct {
enum sendprio_t { prio_low, prio_normal, prio_high }; enum sendprio_t { prio_low, prio_normal, prio_high };
enum timesource_t { _gps, _rtc, _lora, _unsynced }; enum timesource_t { _gps, _rtc, _lora, _unsynced };
enum mutexselect_t { no_mutex, do_mutex };
extern std::set<uint16_t, std::less<uint16_t>, Mallocator<uint16_t>> macs; extern std::set<uint16_t, std::less<uint16_t>, Mallocator<uint16_t>> macs;
extern std::array<uint64_t, 0xff>::iterator it; extern std::array<uint64_t, 0xff>::iterator it;

View File

@ -9,7 +9,7 @@
extern RtcDS3231<TwoWire> Rtc; // make RTC instance globally available extern RtcDS3231<TwoWire> Rtc; // make RTC instance globally available
uint8_t rtc_init(void); uint8_t rtc_init(void);
uint8_t set_rtctime(time_t t, mutexselect_t mutex); uint8_t set_rtctime(time_t t);
void sync_rtctime(void); void sync_rtctime(void);
time_t get_rtctime(void); time_t get_rtctime(void);
float get_rtctemp(void); float get_rtctemp(void);

View File

@ -507,15 +507,8 @@ void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime,
return; return;
} }
// begin of time critical section // mask application irq to ensure accurate timing
// lock I2C bus and application irq to ensure accurate timing
mask_user_IRQ(); mask_user_IRQ();
if (!I2C_MUTEX_LOCK()) {
ESP_LOGW(TAG, "[%0.3f] Timesync handshake error: i2c bus locking failed",
millis() / 1000.0);
goto finish; // failure
}
// Update userUTCTime, considering the difference between the GPS and UTC // Update userUTCTime, considering the difference between the GPS and UTC
// time, and the leap seconds until year 2019 // time, and the leap seconds until year 2019
@ -532,8 +525,7 @@ void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime,
setMyTime(*pUserUTCTime + requestDelaySec, 0); setMyTime(*pUserUTCTime + requestDelaySec, 0);
finish: finish:
// end of time critical section: release I2C bus and app irq // end of time critical section: release app irq lock
I2C_MUTEX_UNLOCK();
unmask_user_IRQ(); unmask_user_IRQ();
} // user_request_network_time_callback } // user_request_network_time_callback

View File

@ -46,21 +46,20 @@ uint8_t rtc_init(void) {
} // rtc_init() } // rtc_init()
uint8_t set_rtctime(time_t t, mutexselect_t mutex) { // t is sec epoch time uint8_t set_rtctime(time_t t) { // t is sec epoch time
if (!mutex || I2C_MUTEX_LOCK()) { if (I2C_MUTEX_LOCK()) {
#ifdef RTC_INT // sync rtc 1Hz pulse on top of second #ifdef RTC_INT // sync rtc 1Hz pulse on top of second
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone); // off Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone); // off
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock); // start Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock); // start
#endif #endif
Rtc.SetDateTime(RtcDateTime(t - SECS_YR_2000)); // epoch -> sec2000 Rtc.SetDateTime(RtcDateTime(t - SECS_YR_2000)); // epoch -> sec2000
if (mutex) I2C_MUTEX_UNLOCK();
I2C_MUTEX_UNLOCK();
ESP_LOGI(TAG, "RTC time synced"); ESP_LOGI(TAG, "RTC time synced");
return 1; // success return 1; // success
} else { } else {
ESP_LOGE(TAG, "RTC set time failure"); ESP_LOGE(TAG, "RTC set time failure");
return 0; return 0; // failure
} // failure }
} // set_rtctime() } // set_rtctime()
time_t get_rtctime(void) { time_t get_rtctime(void) {
@ -71,8 +70,11 @@ time_t get_rtctime(void) {
t = tt.Epoch32Time(); // sec2000 -> epoch t = tt.Epoch32Time(); // sec2000 -> epoch
} }
I2C_MUTEX_UNLOCK(); I2C_MUTEX_UNLOCK();
return timeIsValid(t);
} else {
ESP_LOGE(TAG, "RTC get time failure");
return 0; // failure
} }
return timeIsValid(t);
} // get_rtctime() } // get_rtctime()
float get_rtctemp(void) { float get_rtctemp(void) {

View File

@ -31,7 +31,7 @@ time_t timeProvider(void) {
t = fetch_gpsTime(gps_status); t = fetch_gpsTime(gps_status);
if (t) { if (t) {
#ifdef HAS_RTC #ifdef HAS_RTC
set_rtctime(t, do_mutex); // calibrate RTC set_rtctime(t); // 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

View File

@ -132,9 +132,8 @@ void process_timesync_req(void *taskparameter) {
finish: finish:
// end of time critical section: release app irq lock // end of time critical section: release app irq lock
unmask_user_IRQ();
timeSyncPending = false; timeSyncPending = false;
unmask_user_IRQ();
} // infinite while(1) } // infinite while(1)
} }
@ -223,7 +222,7 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) {
// set RTC time and calibrate RTC_INT pulse on top of second // set RTC time and calibrate RTC_INT pulse on top of second
#ifdef HAS_RTC #ifdef HAS_RTC
set_rtctime(time_to_set, no_mutex); set_rtctime(time_to_set);
#endif #endif
// sync pps timer to top of second // sync pps timer to top of second