Преглед на файлове

Add support to set the clock rate and have sntp use it. (#3236)

Philip Gladstone преди 3 години
родител
ревизия
995114b736
променени са 4 файла, в които са добавени 28 реда и са изтрити 13 реда
  1. 1 0
      app/include/rtc/rtctime.h
  2. 13 6
      app/modules/rtctime.c
  3. 10 6
      app/modules/sntp.c
  4. 4 1
      docs/modules/rtctime.md

+ 1 - 0
app/include/rtc/rtctime.h

@@ -63,6 +63,7 @@ struct rtc_tm{
 void TEXT_SECTION_ATTR rtctime_early_startup (void);
 void rtctime_late_startup (void);
 void rtctime_adjust_rate (int rate);
+int rtctime_get_rate (void);
 void rtctime_gettimeofday (struct rtc_timeval *tv);
 void rtctime_settimeofday (const struct rtc_timeval *tv);
 bool rtctime_have_time (void);

+ 13 - 6
app/modules/rtctime.c

@@ -57,6 +57,11 @@ void rtctime_late_startup (void)
   rtc_time_switch_system ();
 }
 
+int rtctime_get_rate (void)
+{
+  return rtc_time_get_rate();
+}
+
 void rtctime_adjust_rate (int rate)
 {
   rtc_time_set_rate (rate);
@@ -131,13 +136,15 @@ static int rtctime_set (lua_State *L)
   if (!rtc_time_check_magic ())
     rtc_time_prepare ();
 
-  uint32_t sec = luaL_checkinteger (L, 1);
-  uint32_t usec = 0;
-  if (lua_isnumber (L, 2))
-    usec = lua_tointeger (L, 2);
+  if (lua_isnumber(L, 1)) {
+    uint32_t sec = luaL_checkinteger (L, 1);
+    uint32_t usec = 0;
+    if (lua_isnumber (L, 2))
+      usec = lua_tointeger (L, 2);
 
-  struct rtc_timeval tv = { sec, usec };
-  rtctime_settimeofday (&tv);
+    struct rtc_timeval tv = { sec, usec };
+    rtctime_settimeofday (&tv);
+  }
 
   if (lua_isnumber(L, 3))
     rtc_time_set_rate(lua_tointeger(L, 3));

+ 10 - 6
app/modules/sntp.c

@@ -148,7 +148,7 @@ static uint8_t using_offset;
 static uint8_t the_offset;
 static uint8_t pending_LI;
 static int32_t next_midnight;
-static uint64_t pll_increment;
+static int32_t pll_increment;
 
 #define PLL_A   (1 << (32 - 11))
 #define PLL_B   (1 << (32 - 11 - 2))
@@ -257,12 +257,12 @@ static void sntp_handle_result(lua_State *L) {
   }
   if (state->is_on_timeout && state->best.delta > SUS_TO_FRAC(-200000) && state->best.delta < SUS_TO_FRAC(200000)) {
     // Adjust rate
-    // f is frequency -- f should be 1 << 32 for nominal
-    sntp_dbg("delta=%d, increment=%d, ", (int32_t) state->best.delta, (int32_t) pll_increment);
-    int64_t f = ((state->best.delta * PLL_A) >> 32) + pll_increment;
+    // f is frequency -- f should be 1 << 32 for nominal -- but we store it as an offset
+    sntp_dbg("delta=%d, increment=%d, ", (int32_t) state->best.delta, pll_increment);
+    int f = ((state->best.delta * PLL_A) >> 32) + pll_increment;
     pll_increment += (state->best.delta * PLL_B) >> 32;
-    sntp_dbg("f=%d, increment=%d\n", (int32_t) f, (int32_t) pll_increment);
-    rtctime_adjust_rate((int32_t) f);
+    sntp_dbg("f=%d, increment=%d\n", f, pll_increment);
+    rtctime_adjust_rate(f);
   } else {
     rtctime_settimeofday (&tv);
   }
@@ -824,6 +824,10 @@ static int sntp_sync (lua_State *L)
     }
   }
 
+#ifdef LUA_USE_MODULES_RTCTIME
+  pll_increment = rtctime_get_rate();
+#endif
+
   luaL_unref (L, LUA_REGISTRYINDEX, state->list_ref);
   state->list_ref = luaL_ref(L, LUA_REGISTRYINDEX);
   sntp_dolookups(L);

+ 4 - 1
docs/modules/rtctime.md

@@ -139,8 +139,11 @@ It is highly recommended that the timestamp is obtained via NTP (see [SNTP modul
 
 Values very close to the epoch are not supported. This is a side effect of keeping the memory requirements as low as possible. Considering that it's no longer 1970, this is not considered a problem.
 
+Times are specified across two arguments, seconds and microseconds. If microseconds are not specified, the default is 0 (i.e., time is exactly at the boundary between two seconds).
+In addition to the time, a third argument specifies the local clock's drift rate estimate, as documented in `rtctime.get()`. If this argument is not given or is `nil`, the current rate estimate will not be altered, and the rate estimate may be set without changing the time by leaving the seconds and microseconds arguments `nil`. The rate is not (unfortunately) a fixed parameter for a particular nodemcu board. It varies with (at least) the temperature and the age of the board.
+
 #### Syntax
-`rtctime.set(seconds, microseconds, [rate])`
+`rtctime.set([seconds], [microseconds], [rate])`
 
 #### Parameters
 - `seconds` the seconds part, counted from the Unix epoch