2015-06-29 21:19:24 +02:00
|
|
|
/*guys, srsly, turn on warnings in the makefile*/
|
|
|
|
#if defined(__GNUC__)
|
|
|
|
#pragma GCC diagnostic warning "-Wall"
|
|
|
|
#pragma GCC diagnostic warning "-Wextra"
|
|
|
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*-------------------------------------
|
|
|
|
NEW TIMER API
|
|
|
|
---------------------------------------
|
|
|
|
|
|
|
|
tmr.wdclr() -- not changed
|
|
|
|
tmr.now() -- not changed
|
|
|
|
tmr.time() -- not changed
|
|
|
|
tmr.delay() -- not changed
|
|
|
|
tmr.alarm() -- not changed
|
|
|
|
tmr.stop() -- changed, see below. use tmr.unregister for old functionality
|
|
|
|
|
|
|
|
tmr.register(id, interval, mode, function)
|
2015-06-29 23:15:30 +02:00
|
|
|
bind function with timer and set the interval in ms
|
2015-06-29 21:19:24 +02:00
|
|
|
the mode can be:
|
|
|
|
tmr.ALARM_SINGLE for a single run alarm
|
|
|
|
tmr.ALARM_SEMI for a multiple single run alarm
|
|
|
|
tmr.ALARM_AUTO for a repating alarm
|
|
|
|
tmr.register does NOT start the timer
|
|
|
|
tmr.alarm is a tmr.register & tmr.start macro
|
|
|
|
tmr.unregister(id)
|
2015-06-29 23:15:30 +02:00
|
|
|
stop alarm, unbind function and clean up memory
|
2015-06-29 21:19:24 +02:00
|
|
|
not needed for ALARM_SINGLE, as it unregisters itself
|
|
|
|
tmr.start(id)
|
|
|
|
ret: bool
|
|
|
|
start a alarm, returns true on success
|
|
|
|
tmr.stop(id)
|
|
|
|
ret: bool
|
|
|
|
stops a alarm, returns true on success
|
|
|
|
this call dose not free any memory, to do so use tmr.unregister
|
|
|
|
stopped alarms can be started with start
|
2015-06-29 23:15:30 +02:00
|
|
|
tmr.interval(id, interval)
|
|
|
|
set alarm interval, running alarm will be restarted
|
2015-06-29 21:19:24 +02:00
|
|
|
tmr.state(id)
|
|
|
|
ret: (bool, int) or nil
|
|
|
|
returns alarm status (true=started/false=stopped) and mode
|
|
|
|
nil if timer is unregistered
|
2015-06-29 23:15:30 +02:00
|
|
|
tmr.softwd(int)
|
|
|
|
set a negative value to stop the timer
|
|
|
|
any other value starts the timer, when the
|
|
|
|
countdown reaches zero, the device restarts
|
|
|
|
the timer units are seconds
|
2015-06-29 21:19:24 +02:00
|
|
|
*/
|
|
|
|
|
2015-12-16 06:04:58 +01:00
|
|
|
#include "module.h"
|
2014-12-22 12:35:05 +01:00
|
|
|
#include "lauxlib.h"
|
|
|
|
#include "platform.h"
|
|
|
|
#include "c_types.h"
|
2016-01-22 00:55:57 +01:00
|
|
|
#include "user_interface.h"
|
2016-05-26 10:36:20 +02:00
|
|
|
#include "rom.h"
|
2014-12-22 12:35:05 +01:00
|
|
|
|
2015-06-29 21:19:24 +02:00
|
|
|
#define TIMER_MODE_OFF 3
|
|
|
|
#define TIMER_MODE_SINGLE 0
|
|
|
|
#define TIMER_MODE_SEMI 2
|
|
|
|
#define TIMER_MODE_AUTO 1
|
|
|
|
#define TIMER_IDLE_FLAG (1<<7)
|
|
|
|
|
2016-05-07 11:30:04 +02:00
|
|
|
#define STRINGIFY_VAL(x) #x
|
|
|
|
#define STRINGIFY(x) STRINGIFY_VAL(x)
|
|
|
|
|
|
|
|
// assuming system_timer_reinit() has *not* been called
|
|
|
|
#define MAX_TIMEOUT_DEF 6870947 //SDK 1.5.3 limit (0x68D7A3)
|
|
|
|
|
|
|
|
static const uint32 MAX_TIMEOUT=MAX_TIMEOUT_DEF;
|
|
|
|
static const char* MAX_TIMEOUT_ERR_STR = "Range: 1-"STRINGIFY(MAX_TIMEOUT_DEF);
|
|
|
|
|
2015-06-29 21:19:24 +02:00
|
|
|
typedef struct{
|
|
|
|
os_timer_t os;
|
|
|
|
sint32_t lua_ref;
|
|
|
|
uint32_t interval;
|
|
|
|
uint8_t mode;
|
|
|
|
}timer_struct_t;
|
Initial pass at switching to RTOS SDK.
This compiles, links, and starts the RTOS without crashing and burning.
Lua environment does not yet start due to the different task architecture.
Known pain points:
- task implementation needs to be rewritten for RTOS (next up on my TODO)
- secure espconn does not exist, all secure espconn stuff has been #if 0'd
- lwip now built from within the RTOS SDK, but does not appear to include
MDNS support. Investigation needed.
- there is no access to FRC1 NMI, not sure if we ever actually used that
however. Also #if 0'd out for now.
- new timing constraints introduced by the RTOS, all use of ets_delay_us()
and os_delay_us() needs to be reviewed (the tsl2561 driver in particular).
- even more confusion with ets_ vs os_ vs c_ vs non-prefixed versions.
In the long run everything should be switched to non-prefixed versions.
- system_set_os_print() not available, needs to be reimplemented
- all the RTOS rodata is loaded into RAM, as it apparently uses some
constants while the flash isn't mapped, so our exception handler can't
work its magic. This should be narrowed down to the minimum possible
at some point.
- with each task having its own stack in RTOS, we probably need change
flash-page buffers from the stack to the heap in a bunch of places.
A single, shared, page buffer *might* be possible if we limit ourselves
to running NodeMCU in a single task.
- there's a ton of junk in the sdk-overrides now; over time the core code
should be updated to not need those shims
2016-05-24 07:05:01 +02:00
|
|
|
typedef timer_struct_t* ptimer_t;
|
2015-06-29 21:19:24 +02:00
|
|
|
|
2016-03-24 06:27:15 +01:00
|
|
|
// The previous implementation extended the rtc counter to 64 bits, and then
|
|
|
|
// applied rtc2sec with the current calibration value to that 64 bit value.
|
|
|
|
// This means that *ALL* clock ticks since bootup are counted with the *current*
|
|
|
|
// clock period. In extreme cases (long uptime, sudden temperature change), this
|
|
|
|
// could result in tmr.time() going backwards....
|
|
|
|
// This implementation instead applies rtc2usec to short time intervals only (the
|
|
|
|
// longest being around 1 second), and then accumulates the resulting microseconds
|
|
|
|
// in a 64 bit counter. That's guaranteed to be monotonic, and should be a lot closer
|
|
|
|
// to representing an actual uptime.
|
|
|
|
static uint32_t rtc_time_cali=0;
|
|
|
|
static uint32_t last_rtc_time=0;
|
|
|
|
static uint64_t last_rtc_time_us=0;
|
2016-02-25 02:08:08 +01:00
|
|
|
|
2015-06-29 21:19:24 +02:00
|
|
|
static sint32_t soft_watchdog = -1;
|
|
|
|
static timer_struct_t alarm_timers[NUM_TMR];
|
|
|
|
static os_timer_t rtc_timer;
|
|
|
|
|
|
|
|
static void alarm_timer_common(void* arg){
|
Initial pass at switching to RTOS SDK.
This compiles, links, and starts the RTOS without crashing and burning.
Lua environment does not yet start due to the different task architecture.
Known pain points:
- task implementation needs to be rewritten for RTOS (next up on my TODO)
- secure espconn does not exist, all secure espconn stuff has been #if 0'd
- lwip now built from within the RTOS SDK, but does not appear to include
MDNS support. Investigation needed.
- there is no access to FRC1 NMI, not sure if we ever actually used that
however. Also #if 0'd out for now.
- new timing constraints introduced by the RTOS, all use of ets_delay_us()
and os_delay_us() needs to be reviewed (the tsl2561 driver in particular).
- even more confusion with ets_ vs os_ vs c_ vs non-prefixed versions.
In the long run everything should be switched to non-prefixed versions.
- system_set_os_print() not available, needs to be reimplemented
- all the RTOS rodata is loaded into RAM, as it apparently uses some
constants while the flash isn't mapped, so our exception handler can't
work its magic. This should be narrowed down to the minimum possible
at some point.
- with each task having its own stack in RTOS, we probably need change
flash-page buffers from the stack to the heap in a bunch of places.
A single, shared, page buffer *might* be possible if we limit ourselves
to running NodeMCU in a single task.
- there's a ton of junk in the sdk-overrides now; over time the core code
should be updated to not need those shims
2016-05-24 07:05:01 +02:00
|
|
|
ptimer_t tmr = &alarm_timers[(uint32_t)arg];
|
2016-02-25 02:08:08 +01:00
|
|
|
lua_State* L = lua_getstate();
|
|
|
|
if(tmr->lua_ref == LUA_NOREF)
|
2015-06-29 21:19:24 +02:00
|
|
|
return;
|
2016-02-25 02:08:08 +01:00
|
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
2015-06-29 21:19:24 +02:00
|
|
|
//if the timer was set to single run we clean up after it
|
|
|
|
if(tmr->mode == TIMER_MODE_SINGLE){
|
2016-02-25 02:08:08 +01:00
|
|
|
luaL_unref(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
2015-06-29 21:19:24 +02:00
|
|
|
tmr->lua_ref = LUA_NOREF;
|
|
|
|
tmr->mode = TIMER_MODE_OFF;
|
|
|
|
}else if(tmr->mode == TIMER_MODE_SEMI){
|
|
|
|
tmr->mode |= TIMER_IDLE_FLAG;
|
|
|
|
}
|
2016-02-25 02:08:08 +01:00
|
|
|
lua_call(L, 0, 0);
|
2015-06-29 21:19:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Lua: tmr.delay( us )
|
|
|
|
static int tmr_delay( lua_State* L ){
|
|
|
|
sint32_t us = luaL_checkinteger(L, 1);
|
|
|
|
if(us <= 0)
|
|
|
|
return luaL_error(L, "wrong arg range");
|
Initial pass at switching to RTOS SDK.
This compiles, links, and starts the RTOS without crashing and burning.
Lua environment does not yet start due to the different task architecture.
Known pain points:
- task implementation needs to be rewritten for RTOS (next up on my TODO)
- secure espconn does not exist, all secure espconn stuff has been #if 0'd
- lwip now built from within the RTOS SDK, but does not appear to include
MDNS support. Investigation needed.
- there is no access to FRC1 NMI, not sure if we ever actually used that
however. Also #if 0'd out for now.
- new timing constraints introduced by the RTOS, all use of ets_delay_us()
and os_delay_us() needs to be reviewed (the tsl2561 driver in particular).
- even more confusion with ets_ vs os_ vs c_ vs non-prefixed versions.
In the long run everything should be switched to non-prefixed versions.
- system_set_os_print() not available, needs to be reimplemented
- all the RTOS rodata is loaded into RAM, as it apparently uses some
constants while the flash isn't mapped, so our exception handler can't
work its magic. This should be narrowed down to the minimum possible
at some point.
- with each task having its own stack in RTOS, we probably need change
flash-page buffers from the stack to the heap in a bunch of places.
A single, shared, page buffer *might* be possible if we limit ourselves
to running NodeMCU in a single task.
- there's a ton of junk in the sdk-overrides now; over time the core code
should be updated to not need those shims
2016-05-24 07:05:01 +02:00
|
|
|
while(us >= 65000){
|
|
|
|
us -= 65000;
|
|
|
|
os_delay_us(65000);
|
2015-10-27 04:31:17 +01:00
|
|
|
system_soft_wdt_feed ();
|
2015-06-29 21:19:24 +02:00
|
|
|
}
|
|
|
|
if(us>0){
|
|
|
|
os_delay_us(us);
|
2015-10-27 04:31:17 +01:00
|
|
|
system_soft_wdt_feed ();
|
2015-06-29 21:19:24 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Lua: tmr.now() , return system timer in us
|
|
|
|
static int tmr_now(lua_State* L){
|
|
|
|
uint32_t now = 0x7FFFFFFF & system_get_time();
|
|
|
|
lua_pushinteger(L, now);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Lua: tmr.register( id, interval, mode, function )
|
|
|
|
static int tmr_register(lua_State* L){
|
|
|
|
uint32_t id = luaL_checkinteger(L, 1);
|
2016-05-07 11:30:04 +02:00
|
|
|
uint32_t interval = luaL_checkinteger(L, 2);
|
2015-06-29 21:19:24 +02:00
|
|
|
uint8_t mode = luaL_checkinteger(L, 3);
|
2016-05-07 11:30:04 +02:00
|
|
|
//Check if provided parameters are valid
|
|
|
|
MOD_CHECK_ID(tmr, id);
|
|
|
|
luaL_argcheck(L, (interval > 0 && interval <= MAX_TIMEOUT), 2, MAX_TIMEOUT_ERR_STR);
|
|
|
|
luaL_argcheck(L, (mode == TIMER_MODE_SINGLE || mode == TIMER_MODE_SEMI || mode == TIMER_MODE_AUTO), 3, "Invalid mode");
|
|
|
|
luaL_argcheck(L, (lua_type(L, 4) == LUA_TFUNCTION || lua_type(L, 4) == LUA_TLIGHTFUNCTION), 4, "Must be function");
|
2015-06-29 21:19:24 +02:00
|
|
|
//get the lua function reference
|
|
|
|
lua_pushvalue(L, 4);
|
|
|
|
sint32_t ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
Initial pass at switching to RTOS SDK.
This compiles, links, and starts the RTOS without crashing and burning.
Lua environment does not yet start due to the different task architecture.
Known pain points:
- task implementation needs to be rewritten for RTOS (next up on my TODO)
- secure espconn does not exist, all secure espconn stuff has been #if 0'd
- lwip now built from within the RTOS SDK, but does not appear to include
MDNS support. Investigation needed.
- there is no access to FRC1 NMI, not sure if we ever actually used that
however. Also #if 0'd out for now.
- new timing constraints introduced by the RTOS, all use of ets_delay_us()
and os_delay_us() needs to be reviewed (the tsl2561 driver in particular).
- even more confusion with ets_ vs os_ vs c_ vs non-prefixed versions.
In the long run everything should be switched to non-prefixed versions.
- system_set_os_print() not available, needs to be reimplemented
- all the RTOS rodata is loaded into RAM, as it apparently uses some
constants while the flash isn't mapped, so our exception handler can't
work its magic. This should be narrowed down to the minimum possible
at some point.
- with each task having its own stack in RTOS, we probably need change
flash-page buffers from the stack to the heap in a bunch of places.
A single, shared, page buffer *might* be possible if we limit ourselves
to running NodeMCU in a single task.
- there's a ton of junk in the sdk-overrides now; over time the core code
should be updated to not need those shims
2016-05-24 07:05:01 +02:00
|
|
|
ptimer_t tmr = &alarm_timers[id];
|
2015-06-29 21:19:24 +02:00
|
|
|
if(!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF)
|
|
|
|
ets_timer_disarm(&tmr->os);
|
|
|
|
//there was a bug in this part, the second part of the following condition was missing
|
|
|
|
if(tmr->lua_ref != LUA_NOREF && tmr->lua_ref != ref)
|
|
|
|
luaL_unref(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
|
|
|
tmr->lua_ref = ref;
|
|
|
|
tmr->mode = mode|TIMER_IDLE_FLAG;
|
|
|
|
tmr->interval = interval;
|
|
|
|
ets_timer_setfn(&tmr->os, alarm_timer_common, (void*)id);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Lua: tmr.start( id )
|
|
|
|
static int tmr_start(lua_State* L){
|
|
|
|
uint8_t id = luaL_checkinteger(L, 1);
|
|
|
|
MOD_CHECK_ID(tmr,id);
|
Initial pass at switching to RTOS SDK.
This compiles, links, and starts the RTOS without crashing and burning.
Lua environment does not yet start due to the different task architecture.
Known pain points:
- task implementation needs to be rewritten for RTOS (next up on my TODO)
- secure espconn does not exist, all secure espconn stuff has been #if 0'd
- lwip now built from within the RTOS SDK, but does not appear to include
MDNS support. Investigation needed.
- there is no access to FRC1 NMI, not sure if we ever actually used that
however. Also #if 0'd out for now.
- new timing constraints introduced by the RTOS, all use of ets_delay_us()
and os_delay_us() needs to be reviewed (the tsl2561 driver in particular).
- even more confusion with ets_ vs os_ vs c_ vs non-prefixed versions.
In the long run everything should be switched to non-prefixed versions.
- system_set_os_print() not available, needs to be reimplemented
- all the RTOS rodata is loaded into RAM, as it apparently uses some
constants while the flash isn't mapped, so our exception handler can't
work its magic. This should be narrowed down to the minimum possible
at some point.
- with each task having its own stack in RTOS, we probably need change
flash-page buffers from the stack to the heap in a bunch of places.
A single, shared, page buffer *might* be possible if we limit ourselves
to running NodeMCU in a single task.
- there's a ton of junk in the sdk-overrides now; over time the core code
should be updated to not need those shims
2016-05-24 07:05:01 +02:00
|
|
|
ptimer_t tmr = &alarm_timers[id];
|
2015-06-29 21:19:24 +02:00
|
|
|
//we return false if the timer is not idle
|
|
|
|
if(!(tmr->mode&TIMER_IDLE_FLAG)){
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
}else{
|
|
|
|
tmr->mode &= ~TIMER_IDLE_FLAG;
|
|
|
|
ets_timer_arm_new(&tmr->os, tmr->interval, tmr->mode==TIMER_MODE_AUTO, 1);
|
|
|
|
lua_pushboolean(L, 1);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Lua: tmr.alarm( id, interval, repeat, function )
|
|
|
|
static int tmr_alarm(lua_State* L){
|
|
|
|
tmr_register(L);
|
|
|
|
return tmr_start(L);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Lua: tmr.stop( id )
|
|
|
|
static int tmr_stop(lua_State* L){
|
|
|
|
uint8_t id = luaL_checkinteger(L, 1);
|
|
|
|
MOD_CHECK_ID(tmr,id);
|
Initial pass at switching to RTOS SDK.
This compiles, links, and starts the RTOS without crashing and burning.
Lua environment does not yet start due to the different task architecture.
Known pain points:
- task implementation needs to be rewritten for RTOS (next up on my TODO)
- secure espconn does not exist, all secure espconn stuff has been #if 0'd
- lwip now built from within the RTOS SDK, but does not appear to include
MDNS support. Investigation needed.
- there is no access to FRC1 NMI, not sure if we ever actually used that
however. Also #if 0'd out for now.
- new timing constraints introduced by the RTOS, all use of ets_delay_us()
and os_delay_us() needs to be reviewed (the tsl2561 driver in particular).
- even more confusion with ets_ vs os_ vs c_ vs non-prefixed versions.
In the long run everything should be switched to non-prefixed versions.
- system_set_os_print() not available, needs to be reimplemented
- all the RTOS rodata is loaded into RAM, as it apparently uses some
constants while the flash isn't mapped, so our exception handler can't
work its magic. This should be narrowed down to the minimum possible
at some point.
- with each task having its own stack in RTOS, we probably need change
flash-page buffers from the stack to the heap in a bunch of places.
A single, shared, page buffer *might* be possible if we limit ourselves
to running NodeMCU in a single task.
- there's a ton of junk in the sdk-overrides now; over time the core code
should be updated to not need those shims
2016-05-24 07:05:01 +02:00
|
|
|
ptimer_t tmr = &alarm_timers[id];
|
2015-06-29 21:19:24 +02:00
|
|
|
//we return false if the timer is idle (of not registered)
|
|
|
|
if(!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF){
|
|
|
|
tmr->mode |= TIMER_IDLE_FLAG;
|
|
|
|
ets_timer_disarm(&tmr->os);
|
|
|
|
lua_pushboolean(L, 1);
|
|
|
|
}else{
|
|
|
|
lua_pushboolean(L, 0);
|
|
|
|
}
|
|
|
|
return 1;
|
2014-12-22 12:35:05 +01:00
|
|
|
}
|
|
|
|
|
2015-06-29 21:19:24 +02:00
|
|
|
// Lua: tmr.unregister( id )
|
|
|
|
static int tmr_unregister(lua_State* L){
|
|
|
|
uint8_t id = luaL_checkinteger(L, 1);
|
|
|
|
MOD_CHECK_ID(tmr,id);
|
Initial pass at switching to RTOS SDK.
This compiles, links, and starts the RTOS without crashing and burning.
Lua environment does not yet start due to the different task architecture.
Known pain points:
- task implementation needs to be rewritten for RTOS (next up on my TODO)
- secure espconn does not exist, all secure espconn stuff has been #if 0'd
- lwip now built from within the RTOS SDK, but does not appear to include
MDNS support. Investigation needed.
- there is no access to FRC1 NMI, not sure if we ever actually used that
however. Also #if 0'd out for now.
- new timing constraints introduced by the RTOS, all use of ets_delay_us()
and os_delay_us() needs to be reviewed (the tsl2561 driver in particular).
- even more confusion with ets_ vs os_ vs c_ vs non-prefixed versions.
In the long run everything should be switched to non-prefixed versions.
- system_set_os_print() not available, needs to be reimplemented
- all the RTOS rodata is loaded into RAM, as it apparently uses some
constants while the flash isn't mapped, so our exception handler can't
work its magic. This should be narrowed down to the minimum possible
at some point.
- with each task having its own stack in RTOS, we probably need change
flash-page buffers from the stack to the heap in a bunch of places.
A single, shared, page buffer *might* be possible if we limit ourselves
to running NodeMCU in a single task.
- there's a ton of junk in the sdk-overrides now; over time the core code
should be updated to not need those shims
2016-05-24 07:05:01 +02:00
|
|
|
ptimer_t tmr = &alarm_timers[id];
|
2015-06-29 21:19:24 +02:00
|
|
|
if(!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF)
|
|
|
|
ets_timer_disarm(&tmr->os);
|
|
|
|
if(tmr->lua_ref != LUA_NOREF)
|
|
|
|
luaL_unref(L, LUA_REGISTRYINDEX, tmr->lua_ref);
|
|
|
|
tmr->lua_ref = LUA_NOREF;
|
|
|
|
tmr->mode = TIMER_MODE_OFF;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-29 23:15:30 +02:00
|
|
|
// Lua: tmr.interval( id, interval )
|
|
|
|
static int tmr_interval(lua_State* L){
|
|
|
|
uint8_t id = luaL_checkinteger(L, 1);
|
|
|
|
MOD_CHECK_ID(tmr,id);
|
Initial pass at switching to RTOS SDK.
This compiles, links, and starts the RTOS without crashing and burning.
Lua environment does not yet start due to the different task architecture.
Known pain points:
- task implementation needs to be rewritten for RTOS (next up on my TODO)
- secure espconn does not exist, all secure espconn stuff has been #if 0'd
- lwip now built from within the RTOS SDK, but does not appear to include
MDNS support. Investigation needed.
- there is no access to FRC1 NMI, not sure if we ever actually used that
however. Also #if 0'd out for now.
- new timing constraints introduced by the RTOS, all use of ets_delay_us()
and os_delay_us() needs to be reviewed (the tsl2561 driver in particular).
- even more confusion with ets_ vs os_ vs c_ vs non-prefixed versions.
In the long run everything should be switched to non-prefixed versions.
- system_set_os_print() not available, needs to be reimplemented
- all the RTOS rodata is loaded into RAM, as it apparently uses some
constants while the flash isn't mapped, so our exception handler can't
work its magic. This should be narrowed down to the minimum possible
at some point.
- with each task having its own stack in RTOS, we probably need change
flash-page buffers from the stack to the heap in a bunch of places.
A single, shared, page buffer *might* be possible if we limit ourselves
to running NodeMCU in a single task.
- there's a ton of junk in the sdk-overrides now; over time the core code
should be updated to not need those shims
2016-05-24 07:05:01 +02:00
|
|
|
ptimer_t tmr = &alarm_timers[id];
|
2016-05-07 11:30:04 +02:00
|
|
|
uint32_t interval = luaL_checkinteger(L, 2);
|
|
|
|
luaL_argcheck(L, (interval > 0 && interval <= MAX_TIMEOUT), 2, MAX_TIMEOUT_ERR_STR);
|
2015-06-29 23:15:30 +02:00
|
|
|
if(tmr->mode != TIMER_MODE_OFF){
|
|
|
|
tmr->interval = interval;
|
|
|
|
if(!(tmr->mode&TIMER_IDLE_FLAG)){
|
|
|
|
ets_timer_disarm(&tmr->os);
|
|
|
|
ets_timer_arm_new(&tmr->os, tmr->interval, tmr->mode==TIMER_MODE_AUTO, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-29 21:19:24 +02:00
|
|
|
// Lua: tmr.state( id )
|
|
|
|
static int tmr_state(lua_State* L){
|
|
|
|
uint8_t id = luaL_checkinteger(L, 1);
|
|
|
|
MOD_CHECK_ID(tmr,id);
|
Initial pass at switching to RTOS SDK.
This compiles, links, and starts the RTOS without crashing and burning.
Lua environment does not yet start due to the different task architecture.
Known pain points:
- task implementation needs to be rewritten for RTOS (next up on my TODO)
- secure espconn does not exist, all secure espconn stuff has been #if 0'd
- lwip now built from within the RTOS SDK, but does not appear to include
MDNS support. Investigation needed.
- there is no access to FRC1 NMI, not sure if we ever actually used that
however. Also #if 0'd out for now.
- new timing constraints introduced by the RTOS, all use of ets_delay_us()
and os_delay_us() needs to be reviewed (the tsl2561 driver in particular).
- even more confusion with ets_ vs os_ vs c_ vs non-prefixed versions.
In the long run everything should be switched to non-prefixed versions.
- system_set_os_print() not available, needs to be reimplemented
- all the RTOS rodata is loaded into RAM, as it apparently uses some
constants while the flash isn't mapped, so our exception handler can't
work its magic. This should be narrowed down to the minimum possible
at some point.
- with each task having its own stack in RTOS, we probably need change
flash-page buffers from the stack to the heap in a bunch of places.
A single, shared, page buffer *might* be possible if we limit ourselves
to running NodeMCU in a single task.
- there's a ton of junk in the sdk-overrides now; over time the core code
should be updated to not need those shims
2016-05-24 07:05:01 +02:00
|
|
|
ptimer_t tmr = &alarm_timers[id];
|
2015-06-29 21:19:24 +02:00
|
|
|
if(tmr->mode == TIMER_MODE_OFF){
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
lua_pushboolean(L, (tmr->mode&TIMER_IDLE_FLAG)==0);
|
|
|
|
lua_pushinteger(L, tmr->mode&(~TIMER_IDLE_FLAG));
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*I left the led comments 'couse I don't know
|
|
|
|
why they are here*/
|
|
|
|
|
2014-12-22 12:35:05 +01:00
|
|
|
// extern void update_key_led();
|
2015-06-29 21:19:24 +02:00
|
|
|
// Lua: tmr.wdclr()
|
|
|
|
static int tmr_wdclr( lua_State* L ){
|
2015-10-27 04:31:17 +01:00
|
|
|
system_soft_wdt_feed ();
|
2015-06-29 21:19:24 +02:00
|
|
|
// update_key_led();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//system_rtc_clock_cali_proc() returns
|
|
|
|
//a fixed point value (12 bit fraction part)
|
|
|
|
//it tells how many rtc clock ticks represent 1us.
|
|
|
|
//the high 64 bits of the uint64_t multiplication
|
|
|
|
//are unnedded (I did the math)
|
2016-03-24 06:27:15 +01:00
|
|
|
static uint32_t rtc2usec(uint64_t rtc){
|
|
|
|
return (rtc*rtc_time_cali)>>12;
|
2015-06-29 21:19:24 +02:00
|
|
|
}
|
|
|
|
|
2016-03-24 06:27:15 +01:00
|
|
|
// This returns the number of microseconds uptime. Note that it relies on the rtc clock,
|
|
|
|
// which is notoriously temperature dependent
|
|
|
|
inline static uint64_t rtc_timer_update(bool do_calibration){
|
|
|
|
if (do_calibration || rtc_time_cali==0)
|
|
|
|
rtc_time_cali=system_rtc_clock_cali_proc();
|
2015-06-29 21:19:24 +02:00
|
|
|
|
|
|
|
uint32_t current = system_get_rtc_time();
|
2016-03-24 06:27:15 +01:00
|
|
|
uint32_t since_last=current-last_rtc_time; // This will transparently deal with wraparound
|
|
|
|
uint32_t us_since_last=rtc2usec(since_last);
|
|
|
|
uint64_t now=last_rtc_time_us+us_since_last;
|
|
|
|
|
|
|
|
// Only update if at least 100ms has passed since we last updated.
|
|
|
|
// This prevents the rounding errors in rtc2usec from accumulating
|
|
|
|
if (us_since_last>=100000)
|
|
|
|
{
|
|
|
|
last_rtc_time=current;
|
|
|
|
last_rtc_time_us=now;
|
|
|
|
}
|
|
|
|
return now;
|
2015-06-29 21:19:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void rtc_callback(void *arg){
|
2016-03-24 06:27:15 +01:00
|
|
|
rtc_timer_update(true);
|
2015-06-29 21:19:24 +02:00
|
|
|
if(soft_watchdog > 0){
|
|
|
|
soft_watchdog--;
|
|
|
|
if(soft_watchdog == 0)
|
|
|
|
system_restart();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Lua: tmr.time() , return rtc time in second
|
|
|
|
static int tmr_time( lua_State* L ){
|
2016-03-24 06:27:15 +01:00
|
|
|
uint64_t us=rtc_timer_update(false);
|
|
|
|
lua_pushinteger(L, us/1000000);
|
2015-06-29 21:19:24 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Lua: tmr.softwd( value )
|
|
|
|
static int tmr_softwd( lua_State* L ){
|
|
|
|
soft_watchdog = luaL_checkinteger(L, 1);
|
|
|
|
return 0;
|
2014-12-29 02:29:19 +01:00
|
|
|
}
|
|
|
|
|
2014-12-22 12:35:05 +01:00
|
|
|
// Module function map
|
|
|
|
|
2015-12-16 06:04:58 +01:00
|
|
|
static const LUA_REG_TYPE tmr_map[] = {
|
2015-12-13 03:29:37 +01:00
|
|
|
{ LSTRKEY( "delay" ), LFUNCVAL( tmr_delay ) },
|
|
|
|
{ LSTRKEY( "now" ), LFUNCVAL( tmr_now ) },
|
|
|
|
{ LSTRKEY( "wdclr" ), LFUNCVAL( tmr_wdclr ) },
|
|
|
|
{ LSTRKEY( "softwd" ), LFUNCVAL( tmr_softwd ) },
|
|
|
|
{ LSTRKEY( "time" ), LFUNCVAL( tmr_time ) },
|
|
|
|
{ LSTRKEY( "register" ), LFUNCVAL( tmr_register ) },
|
|
|
|
{ LSTRKEY( "alarm" ), LFUNCVAL( tmr_alarm ) },
|
|
|
|
{ LSTRKEY( "start" ), LFUNCVAL( tmr_start ) },
|
|
|
|
{ LSTRKEY( "stop" ), LFUNCVAL( tmr_stop ) },
|
|
|
|
{ LSTRKEY( "unregister" ), LFUNCVAL( tmr_unregister ) },
|
|
|
|
{ LSTRKEY( "state" ), LFUNCVAL( tmr_state ) },
|
|
|
|
{ LSTRKEY( "interval" ), LFUNCVAL( tmr_interval) },
|
2015-06-29 21:19:24 +02:00
|
|
|
{ LSTRKEY( "ALARM_SINGLE" ), LNUMVAL( TIMER_MODE_SINGLE ) },
|
2015-12-13 03:29:37 +01:00
|
|
|
{ LSTRKEY( "ALARM_SEMI" ), LNUMVAL( TIMER_MODE_SEMI ) },
|
|
|
|
{ LSTRKEY( "ALARM_AUTO" ), LNUMVAL( TIMER_MODE_AUTO ) },
|
2015-06-29 21:19:24 +02:00
|
|
|
{ LNILKEY, LNILVAL }
|
2014-12-22 12:35:05 +01:00
|
|
|
};
|
|
|
|
|
2015-12-16 06:04:58 +01:00
|
|
|
int luaopen_tmr( lua_State *L ){
|
2015-06-29 21:19:24 +02:00
|
|
|
int i;
|
|
|
|
for(i=0; i<NUM_TMR; i++){
|
|
|
|
alarm_timers[i].lua_ref = LUA_NOREF;
|
|
|
|
alarm_timers[i].mode = TIMER_MODE_OFF;
|
|
|
|
ets_timer_disarm(&alarm_timers[i].os);
|
|
|
|
}
|
2016-03-24 06:27:15 +01:00
|
|
|
last_rtc_time=system_get_rtc_time(); // Right now is time 0
|
|
|
|
last_rtc_time_us=0;
|
|
|
|
|
2015-06-29 21:19:24 +02:00
|
|
|
ets_timer_disarm(&rtc_timer);
|
|
|
|
ets_timer_setfn(&rtc_timer, rtc_callback, NULL);
|
|
|
|
ets_timer_arm_new(&rtc_timer, 1000, 1, 1);
|
2015-12-13 03:29:37 +01:00
|
|
|
return 0;
|
2014-12-22 12:35:05 +01:00
|
|
|
}
|
2015-12-16 06:04:58 +01:00
|
|
|
|
|
|
|
NODEMCU_MODULE(TMR, "tmr", tmr_map, luaopen_tmr);
|