Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Aug 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/include/rtc/rtctime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
19 changes: 13 additions & 6 deletions app/modules/rtctime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand Down
16 changes: 10 additions & 6 deletions app/modules/sntp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion docs/modules/rtctime.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down