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

This commit is contained in:
Philip Gladstone 2020-08-08 07:32:14 -04:00 committed by GitHub
parent 28c6bda9b4
commit 995114b736
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 13 deletions

View File

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

View File

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

View File

@ -148,7 +148,7 @@ static uint8_t using_offset;
static uint8_t the_offset; static uint8_t the_offset;
static uint8_t pending_LI; static uint8_t pending_LI;
static int32_t next_midnight; static int32_t next_midnight;
static uint64_t pll_increment; static int32_t pll_increment;
#define PLL_A (1 << (32 - 11)) #define PLL_A (1 << (32 - 11))
#define PLL_B (1 << (32 - 11 - 2)) #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)) { if (state->is_on_timeout && state->best.delta > SUS_TO_FRAC(-200000) && state->best.delta < SUS_TO_FRAC(200000)) {
// Adjust rate // Adjust rate
// f is frequency -- f should be 1 << 32 for nominal // 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, (int32_t) pll_increment); sntp_dbg("delta=%d, increment=%d, ", (int32_t) state->best.delta, pll_increment);
int64_t f = ((state->best.delta * PLL_A) >> 32) + pll_increment; int f = ((state->best.delta * PLL_A) >> 32) + pll_increment;
pll_increment += (state->best.delta * PLL_B) >> 32; pll_increment += (state->best.delta * PLL_B) >> 32;
sntp_dbg("f=%d, increment=%d\n", (int32_t) f, (int32_t) pll_increment); sntp_dbg("f=%d, increment=%d\n", f, pll_increment);
rtctime_adjust_rate((int32_t) f); rtctime_adjust_rate(f);
} else { } else {
rtctime_settimeofday (&tv); 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); luaL_unref (L, LUA_REGISTRYINDEX, state->list_ref);
state->list_ref = luaL_ref(L, LUA_REGISTRYINDEX); state->list_ref = luaL_ref(L, LUA_REGISTRYINDEX);
sntp_dolookups(L); sntp_dolookups(L);

View File

@ -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. 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 #### Syntax
`rtctime.set(seconds, microseconds, [rate])` `rtctime.set([seconds], [microseconds], [rate])`
#### Parameters #### Parameters
- `seconds` the seconds part, counted from the Unix epoch - `seconds` the seconds part, counted from the Unix epoch