timemanager fixes
This commit is contained in:
		
							parent
							
								
									3d26f737be
								
							
						
					
					
						commit
						0c1c95d868
					
				@ -115,7 +115,6 @@ extern TaskHandle_t irqHandlerTask, ClockTask;
 | 
				
			|||||||
extern TimerHandle_t WifiChanTimer;
 | 
					extern TimerHandle_t WifiChanTimer;
 | 
				
			||||||
extern Timezone myTZ;
 | 
					extern Timezone myTZ;
 | 
				
			||||||
extern time_t LastSyncTime;
 | 
					extern time_t LastSyncTime;
 | 
				
			||||||
extern RtcDateTime compiled;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// application includes
 | 
					// application includes
 | 
				
			||||||
#include "led.h"
 | 
					#include "led.h"
 | 
				
			||||||
 | 
				
			|||||||
@ -13,14 +13,18 @@
 | 
				
			|||||||
#include "dcf77.h"
 | 
					#include "dcf77.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					time_t tmConvert_t(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh,
 | 
				
			||||||
 | 
					                   uint8_t mm, uint8_t ss);
 | 
				
			||||||
void clock_init(void);
 | 
					void clock_init(void);
 | 
				
			||||||
void clock_loop(void *pvParameters);
 | 
					void clock_loop(void *pvParameters);
 | 
				
			||||||
void time_sync(void);
 | 
					void time_sync(void);
 | 
				
			||||||
bool wait_for_pulse(void);
 | 
					int wait_for_pulse(void);
 | 
				
			||||||
int syncTime(time_t);
 | 
					int syncTime(time_t);
 | 
				
			||||||
int syncTime(uint32_t t);
 | 
					int syncTime(uint32_t t);
 | 
				
			||||||
void IRAM_ATTR CLOCKIRQ(void);
 | 
					void IRAM_ATTR CLOCKIRQ(void);
 | 
				
			||||||
int timepulse_init(void);
 | 
					int timepulse_init(void);
 | 
				
			||||||
void timepulse_start(void);
 | 
					void timepulse_start(void);
 | 
				
			||||||
 | 
					int TimeIsValid(time_t t);
 | 
				
			||||||
 | 
					time_t compiledUTC(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // _timemanager_H
 | 
					#endif // _timemanager_H
 | 
				
			||||||
@ -7,7 +7,7 @@
 | 
				
			|||||||
// Local logging tag
 | 
					// Local logging tag
 | 
				
			||||||
static const char TAG[] = "main";
 | 
					static const char TAG[] = "main";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
time_t userUTCTime; // Seconds since the UTC epoch
 | 
					time_t userUTCTime; // Seconds since the UTC in seconds GPS time starting 1.1.2000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// do all housekeeping
 | 
					// do all housekeeping
 | 
				
			||||||
void doHousekeeping() {
 | 
					void doHousekeeping() {
 | 
				
			||||||
 | 
				
			|||||||
@ -134,8 +134,7 @@ void init_display(const char *Productname, const char *Version) {
 | 
				
			|||||||
    u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%d", cfg.rssilimit);
 | 
					    u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%d", cfg.rssilimit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
					    I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
				
			||||||
  }
 | 
					  }                     // mutex
 | 
				
			||||||
 | 
					 | 
				
			||||||
} // init_display
 | 
					} // init_display
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void refreshtheDisplay() {
 | 
					void refreshtheDisplay() {
 | 
				
			||||||
@ -155,8 +154,10 @@ void refreshtheDisplay() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // if display is switched off we don't refresh it to relax cpu
 | 
					    // if display is switched off we don't refresh it to relax cpu
 | 
				
			||||||
    if (!DisplayState)
 | 
					    if (!DisplayState) {
 | 
				
			||||||
 | 
					      I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // update counter (lines 0-1)
 | 
					    // update counter (lines 0-1)
 | 
				
			||||||
    snprintf(
 | 
					    snprintf(
 | 
				
			||||||
@ -226,12 +227,11 @@ void refreshtheDisplay() {
 | 
				
			|||||||
    u8x8.printf("%-16s", display_line6);
 | 
					    u8x8.printf("%-16s", display_line6);
 | 
				
			||||||
#else // we want a systime display instead LoRa status
 | 
					#else // we want a systime display instead LoRa status
 | 
				
			||||||
    t = myTZ.toLocal(now());
 | 
					    t = myTZ.toLocal(now());
 | 
				
			||||||
    timePulse = (timeStatus() == timeSet) ? timePulseSymbol : timeNoPulseSymbol;
 | 
					    timePulse = TimeIsSynced ? timePulseSymbol : timeNoPulseSymbol;
 | 
				
			||||||
    timeState = TimePulseTick ? timeSync : ' ';
 | 
					    timeState = TimePulseTick ? timePulse : ' ';
 | 
				
			||||||
    TimePulseTick = false;
 | 
					    TimePulseTick = false;
 | 
				
			||||||
    u8x8.printf("%02d:%02d%c%02d%c %2d.%3s", hour(t), minute(t),
 | 
					    u8x8.printf("%02d:%02d:%02d%c %2d.%3s", hour(t), minute(t), second(t),
 | 
				
			||||||
                TimeIsSynced ? ':' : '.', second(t), timeState, day(t),
 | 
					                timeState, day(t), printmonth[month(t)]);
 | 
				
			||||||
                printmonth[month(t)]);
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // update LMiC event display (line 7)
 | 
					    // update LMiC event display (line 7)
 | 
				
			||||||
@ -250,8 +250,7 @@ void refreshtheDisplay() {
 | 
				
			|||||||
#endif // HAS_LORA
 | 
					#endif // HAS_LORA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
					    I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
				
			||||||
  }
 | 
					  }                     // mutex
 | 
				
			||||||
 | 
					 | 
				
			||||||
} // refreshDisplay()
 | 
					} // refreshDisplay()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // HAS_DISPLAY
 | 
					#endif // HAS_DISPLAY
 | 
				
			||||||
@ -73,19 +73,6 @@ void gps_read() {
 | 
				
			|||||||
           gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix());
 | 
					           gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// helper function to convert gps date/time into time_t
 | 
					 | 
				
			||||||
time_t tmConvert_t(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh,
 | 
					 | 
				
			||||||
                   uint8_t mm, uint8_t ss) {
 | 
					 | 
				
			||||||
  tmElements_t tm;
 | 
					 | 
				
			||||||
  tm.Year = YYYY - 1970; // note year argument is offset from 1970 in time.h
 | 
					 | 
				
			||||||
  tm.Month = MM;
 | 
					 | 
				
			||||||
  tm.Day = DD;
 | 
					 | 
				
			||||||
  tm.Hour = hh;
 | 
					 | 
				
			||||||
  tm.Minute = mm;
 | 
					 | 
				
			||||||
  tm.Second = ss;
 | 
					 | 
				
			||||||
  return makeTime(tm);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// function to fetch current time from gps
 | 
					// function to fetch current time from gps
 | 
				
			||||||
time_t get_gpstime(void) {
 | 
					time_t get_gpstime(void) {
 | 
				
			||||||
  // !! never call now() or delay in this function, this would break this
 | 
					  // !! never call now() or delay in this function, this would break this
 | 
				
			||||||
@ -93,8 +80,10 @@ time_t get_gpstime(void) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  time_t t = 0;
 | 
					  time_t t = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((gps.time.age() < 900) && (gps.time.isValid()) &&
 | 
					  if ((gps.time.age() < 950) && (gps.time.isValid())) {
 | 
				
			||||||
      (gps.date.year() >= compiled.Year())) {
 | 
					
 | 
				
			||||||
 | 
					    ESP_LOGD(TAG, "GPS time age: %dms, is valid: %s", gps.time.age(),
 | 
				
			||||||
 | 
					             gps.time.isValid() ? "yes" : "no");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // use recent gps time
 | 
					    // use recent gps time
 | 
				
			||||||
    t = tmConvert_t(gps.date.year(), gps.date.month(), gps.date.day(),
 | 
					    t = tmConvert_t(gps.date.year(), gps.date.month(), gps.date.day(),
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@
 | 
				
			|||||||
//#define LMIC_USE_INTERRUPTS
 | 
					//#define LMIC_USE_INTERRUPTS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//time sync via LoRaWAN network, is not yet supported by TTN (LoRaWAN spec v1.0.3)
 | 
					//time sync via LoRaWAN network, is not yet supported by TTN (LoRaWAN spec v1.0.3)
 | 
				
			||||||
//#define LMIC_ENABLE_DeviceTimeReq 1
 | 
					#define LMIC_ENABLE_DeviceTimeReq 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 16 μs per tick
 | 
					// 16 μs per tick
 | 
				
			||||||
// LMIC requires ticks to be 15.5μs - 100 μs long
 | 
					// LMIC requires ticks to be 15.5μs - 100 μs long
 | 
				
			||||||
 | 
				
			|||||||
@ -459,7 +459,8 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Update userUTCTime, considering the difference between the GPS and UTC
 | 
					  // Update userUTCTime, considering the difference between the GPS and UTC
 | 
				
			||||||
  // epoch, and the leap seconds
 | 
					  // time, and the leap seconds
 | 
				
			||||||
 | 
					  // !!! DANGER !!! This code will expire in the year when next leap second happenes
 | 
				
			||||||
  *pUserUTCTime = lmicTimeReference.tNetwork + 315964800;
 | 
					  *pUserUTCTime = lmicTimeReference.tNetwork + 315964800;
 | 
				
			||||||
  // Current time, in ticks
 | 
					  // Current time, in ticks
 | 
				
			||||||
  ostime_t ticksNow = os_getTime();
 | 
					  ostime_t ticksNow = os_getTime();
 | 
				
			||||||
@ -474,7 +475,7 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
 | 
				
			|||||||
  if (syncTime(*pUserUTCTime)) { // do we have a valid time?
 | 
					  if (syncTime(*pUserUTCTime)) { // do we have a valid time?
 | 
				
			||||||
#ifdef HAS_RTC
 | 
					#ifdef HAS_RTC
 | 
				
			||||||
    if (TimeIsSynced)
 | 
					    if (TimeIsSynced)
 | 
				
			||||||
      set_rtctime(now()); // epoch time
 | 
					      set_rtctime(now()); // UTC time
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    LastSyncTime = now(); // remember time of this sync event
 | 
					    LastSyncTime = now(); // remember time of this sync event
 | 
				
			||||||
    ESP_LOGI(TAG, "LORA has set the system time");
 | 
					    ESP_LOGI(TAG, "LORA has set the system time");
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,8 @@ uint8_t volatile channel = 0;              // channel rotation counter
 | 
				
			|||||||
uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0,
 | 
					uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0,
 | 
				
			||||||
                  batt_voltage = 0; // globals for display
 | 
					                  batt_voltage = 0; // globals for display
 | 
				
			||||||
 | 
					
 | 
				
			||||||
hw_timer_t *sendCycle = NULL, *homeCycle = NULL, *clockCycle = NULL, *displaytimer = NULL;
 | 
					hw_timer_t *sendCycle = NULL, *homeCycle = NULL, *clockCycle = NULL,
 | 
				
			||||||
 | 
					           *displaytimer = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TaskHandle_t irqHandlerTask, ClockTask;
 | 
					TaskHandle_t irqHandlerTask, ClockTask;
 | 
				
			||||||
SemaphoreHandle_t I2Caccess, TimePulse;
 | 
					SemaphoreHandle_t I2Caccess, TimePulse;
 | 
				
			||||||
@ -73,8 +74,6 @@ bool volatile TimePulseTick = false;
 | 
				
			|||||||
bool TimeIsSynced = false;
 | 
					bool TimeIsSynced = false;
 | 
				
			||||||
time_t LastSyncTime = 0;
 | 
					time_t LastSyncTime = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// container holding unique MAC address hashes with Memory Alloctor using PSRAM,
 | 
					// container holding unique MAC address hashes with Memory Alloctor using PSRAM,
 | 
				
			||||||
// if present
 | 
					// if present
 | 
				
			||||||
std::set<uint16_t, std::less<uint16_t>, Mallocator<uint16_t>> macs;
 | 
					std::set<uint16_t, std::less<uint16_t>, Mallocator<uint16_t>> macs;
 | 
				
			||||||
@ -82,7 +81,7 @@ std::set<uint16_t, std::less<uint16_t>, Mallocator<uint16_t>> macs;
 | 
				
			|||||||
// initialize payload encoder
 | 
					// initialize payload encoder
 | 
				
			||||||
PayloadConvert payload(PAYLOAD_BUFFER_SIZE);
 | 
					PayloadConvert payload(PAYLOAD_BUFFER_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// set Time Zone, fetch user setting from paxcounter.conf
 | 
					// set Time Zone for user setting from paxcounter.conf
 | 
				
			||||||
TimeChangeRule myDST = DAYLIGHT_TIME;
 | 
					TimeChangeRule myDST = DAYLIGHT_TIME;
 | 
				
			||||||
TimeChangeRule mySTD = STANDARD_TIME;
 | 
					TimeChangeRule mySTD = STANDARD_TIME;
 | 
				
			||||||
Timezone myTZ(myDST, mySTD);
 | 
					Timezone myTZ(myDST, mySTD);
 | 
				
			||||||
@ -97,7 +96,7 @@ void setup() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  char features[100] = "";
 | 
					  char features[100] = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // create some semaphores for syncing / mutexing tasks
 | 
					    // create some semaphores for syncing / mutexing tasks
 | 
				
			||||||
  I2Caccess = xSemaphoreCreateMutex(); // for access management of i2c bus
 | 
					  I2Caccess = xSemaphoreCreateMutex(); // for access management of i2c bus
 | 
				
			||||||
  if (I2Caccess)
 | 
					  if (I2Caccess)
 | 
				
			||||||
    xSemaphoreGive(I2Caccess); // Flag the i2c bus available for use
 | 
					    xSemaphoreGive(I2Caccess); // Flag the i2c bus available for use
 | 
				
			||||||
 | 
				
			|||||||
@ -10,63 +10,52 @@ RtcDS3231<TwoWire> Rtc(Wire); // RTC hardware i2c interface
 | 
				
			|||||||
// initialize RTC
 | 
					// initialize RTC
 | 
				
			||||||
int rtc_init(void) {
 | 
					int rtc_init(void) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // return = 0 -> error / return = 1 -> success
 | 
					  if (I2C_MUTEX_LOCK()) { // block i2c bus access
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // block i2c bus access
 | 
					 | 
				
			||||||
  if (I2C_MUTEX_LOCK()) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Wire.begin(HAS_RTC);
 | 
					    Wire.begin(HAS_RTC);
 | 
				
			||||||
    Rtc.Begin();
 | 
					    Rtc.Begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!Rtc.IsDateTimeValid()) {
 | 
					    // configure RTC chip
 | 
				
			||||||
      ESP_LOGW(TAG,
 | 
					    Rtc.Enable32kHzPin(false);
 | 
				
			||||||
               "RTC has no valid RTC date/time, setting to compilation date");
 | 
					    Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
 | 
				
			||||||
      Rtc.SetDateTime(compiled);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!Rtc.GetIsRunning()) {
 | 
					    if (!Rtc.GetIsRunning()) {
 | 
				
			||||||
      ESP_LOGI(TAG, "RTC not running, starting now");
 | 
					      ESP_LOGI(TAG, "RTC not running, starting now");
 | 
				
			||||||
      Rtc.SetIsRunning(true);
 | 
					      Rtc.SetIsRunning(true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RtcDateTime now = Rtc.GetDateTime();
 | 
					    RtcDateTime tt = Rtc.GetDateTime();
 | 
				
			||||||
 | 
					    time_t t = tt.Epoch32Time(); // sec2000 -> epoch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (now < compiled) {
 | 
					    if (!Rtc.IsDateTimeValid() || !TimeIsValid(t)) {
 | 
				
			||||||
      ESP_LOGI(TAG, "RTC date/time is older than compilation date, updating");
 | 
					      ESP_LOGW(TAG, "RTC has no recent time, setting to compilation date");
 | 
				
			||||||
      Rtc.SetDateTime(compiled);
 | 
					      Rtc.SetDateTime(
 | 
				
			||||||
 | 
					          RtcDateTime(compiledUTC() - SECS_YR_2000)); // epoch -> sec2000
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // configure RTC chip
 | 
					    I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
				
			||||||
    Rtc.Enable32kHzPin(false);
 | 
					    ESP_LOGI(TAG, "RTC initialized");
 | 
				
			||||||
    Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
 | 
					    return 1; // success
 | 
				
			||||||
 | 
					 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    ESP_LOGE(TAG, "I2c bus busy - RTC initialization error");
 | 
					    ESP_LOGE(TAG, "RTC initialization error, I2C bus busy");
 | 
				
			||||||
    goto error;
 | 
					    return 0; // failure
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
					 | 
				
			||||||
  ESP_LOGI(TAG, "RTC initialized");
 | 
					 | 
				
			||||||
  return 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
error:
 | 
					 | 
				
			||||||
  I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
					 | 
				
			||||||
  return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // rtc_init()
 | 
					} // rtc_init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int set_rtctime(time_t t) { // t is seconds epoch time starting 1.1.1970
 | 
					int set_rtctime(time_t t) { // t is UTC in seconds epoch time
 | 
				
			||||||
  if (I2C_MUTEX_LOCK()) {
 | 
					  if (I2C_MUTEX_LOCK()) {
 | 
				
			||||||
    Rtc.SetDateTime(RtcDateTime(t));
 | 
					    Rtc.SetDateTime(RtcDateTime(t - SECS_YR_2000)); // epoch -> sec2000
 | 
				
			||||||
    I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
					    I2C_MUTEX_UNLOCK();
 | 
				
			||||||
    ESP_LOGI(TAG, "RTC time synced");
 | 
					    ESP_LOGI(TAG, "RTC time synced");
 | 
				
			||||||
    return 1; // success
 | 
					    return 1; // success
 | 
				
			||||||
  }
 | 
					  } else {
 | 
				
			||||||
  ESP_LOGE(TAG, "RTC set time failure");
 | 
					    ESP_LOGE(TAG, "RTC set time failure");
 | 
				
			||||||
  return 0; // failure
 | 
					    return 0;
 | 
				
			||||||
 | 
					  } // failure
 | 
				
			||||||
} // set_rtctime()
 | 
					} // set_rtctime()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int set_rtctime(uint32_t t) { // t is epoch seconds starting 1.1.1970
 | 
					int set_rtctime(uint32_t t) { // t is UTC in seconds epoch time
 | 
				
			||||||
  return set_rtctime(static_cast<time_t>(t));
 | 
					  return set_rtctime(static_cast<time_t>(t));
 | 
				
			||||||
  // set_rtctime()
 | 
					  // set_rtctime()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -74,25 +63,23 @@ int set_rtctime(uint32_t t) { // t is epoch seconds starting 1.1.1970
 | 
				
			|||||||
time_t get_rtctime(void) {
 | 
					time_t get_rtctime(void) {
 | 
				
			||||||
  // !! never call now() or delay in this function, this would break this
 | 
					  // !! never call now() or delay in this function, this would break this
 | 
				
			||||||
  // function to be used as SyncProvider for Time.h
 | 
					  // function to be used as SyncProvider for Time.h
 | 
				
			||||||
  time_t t = 0; // 0 effects calling SyncProvider() to not set time
 | 
					  time_t t = 0;
 | 
				
			||||||
  // block i2c bus access
 | 
					 | 
				
			||||||
  if (I2C_MUTEX_LOCK()) {
 | 
					  if (I2C_MUTEX_LOCK()) {
 | 
				
			||||||
    if (Rtc.IsDateTimeValid() && Rtc.GetIsRunning()) {
 | 
					    if (Rtc.IsDateTimeValid() && Rtc.GetIsRunning()) {
 | 
				
			||||||
      RtcDateTime tt = Rtc.GetDateTime();
 | 
					      RtcDateTime tt = Rtc.GetDateTime();
 | 
				
			||||||
      t = tt.Epoch32Time();
 | 
					      t = tt.Epoch32Time(); // sec2000 -> epoch
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
					    I2C_MUTEX_UNLOCK();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return t;
 | 
					  return t;
 | 
				
			||||||
} // get_rtctime()
 | 
					} // get_rtctime()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float get_rtctemp(void) {
 | 
					float get_rtctemp(void) {
 | 
				
			||||||
  // block i2c bus access
 | 
					 | 
				
			||||||
  if (I2C_MUTEX_LOCK()) {
 | 
					  if (I2C_MUTEX_LOCK()) {
 | 
				
			||||||
    RtcTemperature temp = Rtc.GetTemperature();
 | 
					    RtcTemperature temp = Rtc.GetTemperature();
 | 
				
			||||||
    I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
					    I2C_MUTEX_UNLOCK();
 | 
				
			||||||
    return temp.AsFloatDegC();
 | 
					    return temp.AsFloatDegC();
 | 
				
			||||||
  } // while
 | 
					  }
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
} // get_rtctemp()
 | 
					} // get_rtctemp()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ static const char TAG[] = "main";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void time_sync() {
 | 
					void time_sync() {
 | 
				
			||||||
  // synchonization of systime with external time source (GPS/LORA)
 | 
					  // synchonization of systime with external time source (GPS/LORA)
 | 
				
			||||||
  // function is frequently called from cyclic.cpp
 | 
					  // frequently called from cyclic.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef TIME_SYNC_INTERVAL
 | 
					#ifdef TIME_SYNC_INTERVAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -25,12 +25,11 @@ void time_sync() {
 | 
				
			|||||||
#ifdef HAS_RTC
 | 
					#ifdef HAS_RTC
 | 
				
			||||||
  if (TimeIsSynced) { // recalibrate RTC, if we have one
 | 
					  if (TimeIsSynced) { // recalibrate RTC, if we have one
 | 
				
			||||||
    set_rtctime(now());
 | 
					    set_rtctime(now());
 | 
				
			||||||
  } 
 | 
					  } else { // we switch to fallback time after a while
 | 
				
			||||||
  else { // we switch to fallback time after a while
 | 
					 | 
				
			||||||
    if ((lastTimeSync >= (TIME_SYNC_TIMEOUT * 60000)) ||
 | 
					    if ((lastTimeSync >= (TIME_SYNC_TIMEOUT * 60000)) ||
 | 
				
			||||||
        !LastSyncTime) {       // sync stil due -> use RTC as fallback source
 | 
					        !LastSyncTime) { // sync is still due -> use RTC as fallback source
 | 
				
			||||||
      syncTime(get_rtctime()); // sync with RTC time
 | 
					      syncTime(get_rtctime()); // sync with RTC time
 | 
				
			||||||
      TimeIsSynced = false;    // 
 | 
					      TimeIsSynced = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -40,33 +39,33 @@ void time_sync() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// helper function to sync time on start of next second
 | 
					// helper function to sync time on start of next second
 | 
				
			||||||
int syncTime(time_t t) {
 | 
					int syncTime(time_t t) {
 | 
				
			||||||
  if (t) {
 | 
					  if (TimeIsValid(t)) {
 | 
				
			||||||
    TimeIsSynced = wait_for_pulse(); // wait for next 1pps timepulse
 | 
					    TimeIsSynced = wait_for_pulse(); // wait for next 1pps timepulse
 | 
				
			||||||
    setTime(t);
 | 
					    setTime(t);
 | 
				
			||||||
    adjustTime(1);        // forward time to next second
 | 
					    adjustTime(1);        // forward time to next second
 | 
				
			||||||
    LastSyncTime = now(); // store time of this sync
 | 
					    LastSyncTime = now(); // store time of this sync
 | 
				
			||||||
    ESP_LOGD(TAG, "System time was set to %02d:%02d:%02d", hour(t), minute(t),
 | 
					    ESP_LOGD(TAG, "Time was set to %02d:%02d:%02d", hour(t), minute(t),
 | 
				
			||||||
             second(t));
 | 
					             second(t));
 | 
				
			||||||
    return 1; // success
 | 
					    return 1; // success
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    ESP_LOGD(TAG, "System time sync attempt failed");
 | 
					    ESP_LOGD(TAG, "Time sync attempt failed");
 | 
				
			||||||
    TimeIsSynced = false;
 | 
					    TimeIsSynced = false;
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // failure
 | 
					  // failure
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int syncTime(uint32_t t) { // t is epoch seconds starting 1.1.1970
 | 
					int syncTime(uint32_t t) { // t is UTC time in seconds epoch
 | 
				
			||||||
  return syncTime(static_cast<time_t>(t));
 | 
					  return syncTime(static_cast<time_t>(t));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// helper function to sync moment on timepulse
 | 
					// helper function to sync moment on timepulse
 | 
				
			||||||
bool wait_for_pulse(void) {
 | 
					int wait_for_pulse(void) {
 | 
				
			||||||
  // sync on top of next second with 1pps timepulse
 | 
					  // sync on top of next second with 1pps timepulse
 | 
				
			||||||
  if (xSemaphoreTake(TimePulse, pdMS_TO_TICKS(1000)) == pdTRUE)
 | 
					  if (xSemaphoreTake(TimePulse, pdMS_TO_TICKS(1000)) == pdTRUE)
 | 
				
			||||||
    return true; // success
 | 
					    return 1; // success
 | 
				
			||||||
  ESP_LOGD(TAG, "Missing timepulse");
 | 
					  ESP_LOGD(TAG, "Missing timepulse");
 | 
				
			||||||
  return false;
 | 
					  return 0; // failure
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// helper function to setup a pulse per second for time synchronisation
 | 
					// helper function to setup a pulse per second for time synchronisation
 | 
				
			||||||
@ -95,7 +94,7 @@ int timepulse_init() {
 | 
				
			|||||||
    ESP_LOGI(TAG, "Timepulse: external (RTC)");
 | 
					    ESP_LOGI(TAG, "Timepulse: external (RTC)");
 | 
				
			||||||
    return 1; // success
 | 
					    return 1; // success
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    ESP_LOGE(TAG, "I2c bus busy - RTC initialization error");
 | 
					    ESP_LOGE(TAG, "RTC initialization error, I2C bus busy");
 | 
				
			||||||
    return 0; // failure
 | 
					    return 0; // failure
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return 1; // success
 | 
					  return 1; // success
 | 
				
			||||||
@ -132,6 +131,34 @@ void IRAM_ATTR CLOCKIRQ(void) {
 | 
				
			|||||||
  portYIELD_FROM_ISR();
 | 
					  portYIELD_FROM_ISR();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// helper function to check plausibility of a time
 | 
				
			||||||
 | 
					int TimeIsValid(time_t 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());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// helper function to convert compile time to UTC time
 | 
				
			||||||
 | 
					time_t compiledUTC(void) {
 | 
				
			||||||
 | 
					  time_t t = RtcDateTime(__DATE__, __TIME__).Epoch32Time();
 | 
				
			||||||
 | 
					  return myTZ.toUTC(t);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// helper function to convert gps date/time into time_t
 | 
				
			||||||
 | 
					time_t tmConvert_t(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh,
 | 
				
			||||||
 | 
					                   uint8_t mm, uint8_t ss) {
 | 
				
			||||||
 | 
					  tmElements_t tm;
 | 
				
			||||||
 | 
					  tm.Year =
 | 
				
			||||||
 | 
					      CalendarYrToTm(YYYY); // year offset from 1970 in time.h
 | 
				
			||||||
 | 
					  tm.Month = MM;
 | 
				
			||||||
 | 
					  tm.Day = DD;
 | 
				
			||||||
 | 
					  tm.Hour = hh;
 | 
				
			||||||
 | 
					  tm.Minute = mm;
 | 
				
			||||||
 | 
					  tm.Second = ss;
 | 
				
			||||||
 | 
					  return makeTime(tm);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined HAS_IF482 || defined HAS_DCF77
 | 
					#if defined HAS_IF482 || defined HAS_DCF77
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined HAS_DCF77 && defined HAS_IF482
 | 
					#if defined HAS_DCF77 && defined HAS_IF482
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user