From 995114b73680c6c7802a7dadcb1fc875d461effc Mon Sep 17 00:00:00 2001 From: Philip Gladstone Date: Sat, 8 Aug 2020 07:32:14 -0400 Subject: [PATCH] Add support to set the clock rate and have sntp use it. (#3236) --- app/include/rtc/rtctime.h | 1 + app/modules/rtctime.c | 19 +++++++++++++------ app/modules/sntp.c | 16 ++++++++++------ docs/modules/rtctime.md | 5 ++++- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/app/include/rtc/rtctime.h b/app/include/rtc/rtctime.h index 5cb7b83d..7823ab9f 100644 --- a/app/include/rtc/rtctime.h +++ b/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); diff --git a/app/modules/rtctime.c b/app/modules/rtctime.c index 3723f2b8..8601924c 100644 --- a/app/modules/rtctime.c +++ b/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)); diff --git a/app/modules/sntp.c b/app/modules/sntp.c index a21e7ec7..68f67ff6 100644 --- a/app/modules/sntp.c +++ b/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); diff --git a/docs/modules/rtctime.md b/docs/modules/rtctime.md index c35fed47..9a93fc10 100644 --- a/docs/modules/rtctime.md +++ b/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