diff --git a/app/lwip/app/espconn_tcp.c b/app/lwip/app/espconn_tcp.c index 49942e4e..b1ebfde4 100644 --- a/app/lwip/app/espconn_tcp.c +++ b/app/lwip/app/espconn_tcp.c @@ -434,9 +434,9 @@ espconn_Task(os_event_t *events) break; case SIG_ESPCONN_ERRER: /*remove the node from the client's active connection list*/ - espconn_list_delete(&plink_active, task_msg); if (espconn_manual_recv_enabled(task_msg)) espconn_list_delete(&plink_active, task_msg); + espconn_tcp_reconnect(task_msg); break; case SIG_ESPCONN_CLOSE: /*remove the node from the client's active connection list*/ diff --git a/app/modules/ds18b20.c b/app/modules/ds18b20.c index e7da45ca..3a211e3a 100644 --- a/app/modules/ds18b20.c +++ b/app/modules/ds18b20.c @@ -197,6 +197,7 @@ static int ds18b20_lua_read(lua_State *L) { static int ds18b20_read_device(uint8_t *ds18b20_device_rom) { lua_State *L = lua_getstate(); + int16_t ds18b20_raw_temp; if (onewire_crc8(ds18b20_device_rom,7) == ds18b20_device_rom[7]) { @@ -221,8 +222,9 @@ static int ds18b20_read_device(uint8_t *ds18b20_device_rom) { lua_pushfstring(L, "%d:%d:%d:%d:%d:%d:%d:%d", ds18b20_device_rom[0], ds18b20_device_rom[1], ds18b20_device_rom[2], ds18b20_device_rom[3], ds18b20_device_rom[4], ds18b20_device_rom[5], ds18b20_device_rom[6], ds18b20_device_rom[7]); ds18b20_device_scratchpad_conf = (ds18b20_device_scratchpad[4] >> 5) + 9; - ds18b20_device_scratchpad_temp = ((int8_t)(ds18b20_device_scratchpad[1] << 4) + (ds18b20_device_scratchpad[0] >> 4) + ((double)(ds18b20_device_scratchpad[0] & 0x0F) / 16)); - ds18b20_device_scratchpad_temp_dec = ((double)(ds18b20_device_scratchpad[0] & 0x0F) / 16 * 1000); + ds18b20_raw_temp = ((ds18b20_device_scratchpad[1] << 8) | ds18b20_device_scratchpad[0]); + ds18b20_device_scratchpad_temp = (double)ds18b20_raw_temp / 16; + ds18b20_device_scratchpad_temp_dec = (ds18b20_raw_temp - (ds18b20_raw_temp / 16 * 16)) * 1000 / 16; if (ds18b20_device_scratchpad_conf >= ds18b20_device_res) { ds18b20_device_res = ds18b20_device_scratchpad_conf; diff --git a/app/modules/file.c b/app/modules/file.c index 670fab89..26a91d94 100644 --- a/app/modules/file.c +++ b/app/modules/file.c @@ -432,7 +432,8 @@ static int file_g_read( lua_State* L, int n, int16_t end_char, int fd ) luaM_free(L, heap_mem); heap_mem = NULL; } - return 0; + lua_pushnil(L); + return 1; } vfs_lseek(fd, -(n - i), VFS_SEEK_CUR); diff --git a/app/modules/node.c b/app/modules/node.c index 52c291d7..b20502e3 100644 --- a/app/modules/node.c +++ b/app/modules/node.c @@ -40,10 +40,15 @@ static int node_restart( lua_State* L ) return 0; } +static int dsleepMax( lua_State *L ) { + lua_pushnumber(L, (uint64_t)system_rtc_clock_cali_proc()*(0x80000000-1)/(0x1000)); + return 1; +} + // Lua: dsleep( us, option ) static int node_deepsleep( lua_State* L ) { - uint32 us; + uint64 us; uint8 option; //us = luaL_checkinteger( L, 1 ); // Set deleep option, skip if nil @@ -105,13 +110,18 @@ static int node_sleep( lua_State* L ) cfg.resume_cb_ptr = &node_sleep_resume_cb; pmSleep_suspend(&cfg); #else - c_printf("\n The option \"timer_suspend_enable\" in \"app/include/user_config.h\" was disabled during FW build!\n"); - return luaL_error(L, "light sleep is unavailable"); + dbg_printf("\n The option \"TIMER_SUSPEND_ENABLE\" in \"app/include/user_config.h\" was disabled during FW build!\n"); + return luaL_error(L, "node.sleep() is unavailable"); #endif return 0; } +#else +static int node_sleep( lua_State* L ) +{ + dbg_printf("\n The options \"TIMER_SUSPEND_ENABLE\" and \"PMSLEEP_ENABLE\" in \"app/include/user_config.h\" were disabled during FW build!\n"); + return luaL_error(L, "node.sleep() is unavailable"); +} #endif //PMSLEEP_ENABLE - static int node_info( lua_State* L ) { lua_pushinteger(L, NODE_VERSION_MAJOR); @@ -367,6 +377,13 @@ static int node_setcpufreq(lua_State* L) return 1; } +// Lua: freq = node.getcpufreq() +static int node_getcpufreq(lua_State* L) +{ + lua_pushinteger(L, system_get_cpu_freq()); + return 1; +} + // Lua: code, reason [, exccause, epc1, epc2, epc3, excvaddr, depc ] = bootreason() static int node_bootreason (lua_State *L) { @@ -590,10 +607,11 @@ static const LUA_REG_TYPE node_map[] = { LSTRKEY( "flashreload" ), LFUNCVAL( luaN_reload_reboot ) }, { LSTRKEY( "flashindex" ), LFUNCVAL( luaN_index ) }, #endif - { LSTRKEY( "restart" ), LFUNCVAL( node_restart ) }, - { LSTRKEY( "dsleep" ), LFUNCVAL( node_deepsleep ) }, -#ifdef PMSLEEP_ENABLE + { LSTRKEY( "restart" ), LFUNCVAL( node_restart ) }, + { LSTRKEY( "dsleep" ), LFUNCVAL( node_deepsleep ) }, + { LSTRKEY( "dsleepMax" ), LFUNCVAL( dsleepMax ) }, { LSTRKEY( "sleep" ), LFUNCVAL( node_sleep ) }, +#ifdef PMSLEEP_ENABLE PMSLEEP_INT_MAP, #endif { LSTRKEY( "chipid" ), LFUNCVAL( node_chipid ) }, @@ -607,6 +625,7 @@ static const LUA_REG_TYPE node_map[] = { LSTRKEY( "CPU80MHZ" ), LNUMVAL( CPU80MHZ ) }, { LSTRKEY( "CPU160MHZ" ), LNUMVAL( CPU160MHZ ) }, { LSTRKEY( "setcpufreq" ), LFUNCVAL( node_setcpufreq) }, + { LSTRKEY( "getcpufreq" ), LFUNCVAL( node_getcpufreq) }, { LSTRKEY( "bootreason" ), LFUNCVAL( node_bootreason) }, { LSTRKEY( "restore" ), LFUNCVAL( node_restore) }, { LSTRKEY( "random" ), LFUNCVAL( node_random) }, diff --git a/app/modules/wifi.c b/app/modules/wifi.c index 8ff1db39..1e701547 100644 --- a/app/modules/wifi.c +++ b/app/modules/wifi.c @@ -512,16 +512,16 @@ static int wifi_resume(lua_State* L) /* End WiFi suspend functions*/ #else -static char *susp_note_str = "\n The option \"pmsleep_enable\" in \"app/include/user_config.h\" was disabled during FW build!\n"; +static char *susp_note_str = "\n The option \"PMSLEEP_ENABLE\" in \"app/include/user_config.h\" was disabled during FW build!\n"; static char *susp_unavailable_str = "wifi.suspend is unavailable"; static int wifi_suspend(lua_State* L){ - c_sprintf("%s", susp_note_str); + dbg_printf("%s", susp_note_str); return luaL_error(L, susp_unavailable_str); } static int wifi_resume(lua_State* L){ - c_sprintf("%s", susp_note_str); + dbg_printf("%s", susp_note_str); return luaL_error(L, susp_unavailable_str); } #endif @@ -1158,8 +1158,9 @@ static int wifi_station_listap( lua_State* L ) { return luaL_error( L, "Can't list ap in SOFTAP mode" ); } - struct scan_config scan_cfg; - memset(&scan_cfg, 0, sizeof(scan_cfg)); + // set safe defaults for scan time, all other members are initialized with 0 + // source: https://github.com/espressif/ESP8266_NONOS_SDK/issues/103 + struct scan_config scan_cfg = {.scan_time = {.passive=120, .active = {.max=120, .min=60}}}; getap_output_format=0; @@ -1787,7 +1788,7 @@ static int wifi_ap_listclient( lua_State* L ) { if (wifi_get_opmode() == STATION_MODE) { - return luaL_error( L, "Can't list client in STATION_MODE mode" ); + return luaL_error( L, "Can't list clients in STATION mode" ); } char temp[64]; @@ -1800,10 +1801,9 @@ static int wifi_ap_listclient( lua_State* L ) { c_sprintf(temp, MACSTR, MAC2STR(station->bssid)); wifi_add_sprintf_field(L, temp, IPSTR, IP2STR(&station->ip)); - next_station = STAILQ_NEXT(station, next); - c_free(station); - station = next_station; + station = STAILQ_NEXT(station, next); } + wifi_softap_free_station_info(); return 1; } diff --git a/app/modules/wifi_common.h b/app/modules/wifi_common.h index 122e4615..789633a3 100644 --- a/app/modules/wifi_common.h +++ b/app/modules/wifi_common.h @@ -19,21 +19,17 @@ void wifi_add_sprintf_field(lua_State* L, char* name, char* string, ...); void wifi_add_int_field(lua_State* L, char* name, lua_Integer integer); -static inline void register_lua_cb(lua_State* L,int* cb_ref) -{ +static inline void register_lua_cb(lua_State* L,int* cb_ref){ int ref=luaL_ref(L, LUA_REGISTRYINDEX); - if( *cb_ref != LUA_NOREF) - { - luaL_unref(L, LUA_REGISTRYINDEX, *cb_ref); + if( *cb_ref != LUA_NOREF){ + luaL_unref(L, LUA_REGISTRYINDEX, *cb_ref); } *cb_ref = ref; } -static inline void unregister_lua_cb(lua_State* L, int* cb_ref) -{ - if(*cb_ref != LUA_NOREF) - { - luaL_unref(L, LUA_REGISTRYINDEX, *cb_ref); +static inline void unregister_lua_cb(lua_State* L, int* cb_ref){ + if(*cb_ref != LUA_NOREF){ + luaL_unref(L, LUA_REGISTRYINDEX, *cb_ref); *cb_ref = LUA_NOREF; } } @@ -47,13 +43,13 @@ void wifi_change_default_host_name(void); #endif #if defined(EVENT_DEBUG) || defined(NODE_DEBUG) -#define EVENT_DBG(...) c_printf(__VA_ARGS__) +#define EVENT_DBG(fmt, ...) c_printf("\n EVENT_DBG(%s): "fmt"\n", __FUNCTION__, ##__VA_ARGS__) + #else #define EVENT_DBG(...) //c_printf(__VA_ARGS__) #endif -enum wifi_suspension_state -{ +enum wifi_suspension_state{ WIFI_AWAKE = 0, WIFI_SUSPENSION_PENDING = 1, WIFI_SUSPENDED = 2 diff --git a/app/modules/wifi_eventmon.c b/app/modules/wifi_eventmon.c index 66bd9827..06bce2a3 100644 --- a/app/modules/wifi_eventmon.c +++ b/app/modules/wifi_eventmon.c @@ -22,13 +22,6 @@ //variables for wifi event monitor static task_handle_t wifi_event_monitor_task_id; //variable to hold task id for task handler(process_event_queue) -typedef struct evt_queue{ - System_Event_t *evt; - struct evt_queue * next; -}evt_queue_t; //structure to hold pointers to event info and next item in queue - -static evt_queue_t *wifi_event_queue_head; //pointer to beginning of queue -static evt_queue_t *wifi_event_queue_tail; //pointer to end of queue static int wifi_event_cb_ref[EVENT_MAX+1] = { [0 ... EVENT_MAX] = LUA_NOREF}; //holds references to registered Lua callbacks #ifdef LUA_USE_MODULES_WIFI_MONITOR @@ -62,9 +55,11 @@ int wifi_event_monitor_register(lua_State* L) } } +static sint32_t event_queue_ref = LUA_NOREF; + static void wifi_event_monitor_handle_event_cb(System_Event_t *evt) { - EVENT_DBG("\n\twifi_event_monitor_handle_event_cb is called\n"); + EVENT_DBG("was called (Event:%d)", evt->event); #ifdef LUA_USE_MODULES_WIFI_MONITOR if (hook_fn && hook_fn(evt)) { @@ -79,38 +74,66 @@ static void wifi_event_monitor_handle_event_cb(System_Event_t *evt) evt->event == EVENT_SOFTAPMODE_STADISCONNECTED || evt->event == EVENT_SOFTAPMODE_PROBEREQRECVED || evt->event == EVENT_OPMODE_CHANGED))) { - evt_queue_t *temp = (evt_queue_t*)c_malloc(sizeof(evt_queue_t)); //allocate memory for new queue item - temp->evt = (System_Event_t*)c_malloc(sizeof(System_Event_t)); //allocate memory to hold event structure - if(!temp || !temp->evt) - { - luaL_error(lua_getstate(), "wifi.eventmon malloc: out of memory"); - return; + lua_State* L = lua_getstate(); + if(event_queue_ref == LUA_NOREF){ //if event queue has not been created, create it now + lua_newtable(L); + event_queue_ref = luaL_ref(L, LUA_REGISTRYINDEX); } - c_memcpy(temp->evt, evt, sizeof(System_Event_t)); //copy event data to new struct + lua_rawgeti(L, LUA_REGISTRYINDEX, event_queue_ref); - if(wifi_event_queue_head == NULL && wifi_event_queue_tail == NULL)// if queue is empty add item to queue - { - wifi_event_queue_head = wifi_event_queue_tail = temp; - EVENT_DBG("\n\tqueue empty, adding event and posting task\n"); + System_Event_t* evt_tmp = lua_newuserdata(L, sizeof(System_Event_t)); + c_memcpy(evt_tmp, evt, sizeof(System_Event_t)); //copy event data to new struct + sint32_t evt_ud_ref = luaL_ref(L, LUA_REGISTRYINDEX); + size_t queue_len = lua_objlen(L, -1); + + //add event to queue + lua_pushnumber(L, queue_len+1); + lua_pushnumber(L, evt_ud_ref); + lua_rawset(L, -3); + + if(queue_len == 0){ //if queue was empty, post task + EVENT_DBG("Posting task"); task_post_low(wifi_event_monitor_task_id, false); } - else //if queue is not empty append item to end of queue - { - wifi_event_queue_tail->next=temp; - wifi_event_queue_tail=temp; - EVENT_DBG("\n\tqueue not empty, appending queue\n"); - } - } -} + else{ + EVENT_DBG("Appending queue, items in queue: %d", lua_objlen(L, -1)); + } + lua_pop(L, 1); + } //else{} //there are no callbacks registered, so the event can't be processed +} static void wifi_event_monitor_process_event_queue(task_param_t param, uint8 priority) { lua_State* L = lua_getstate(); - evt_queue_t *temp = wifi_event_queue_head; //copy event_queue_head pointer to temporary pointer - System_Event_t *evt = temp->evt; //copy event data pointer to temporary pointer + lua_rawgeti(L, LUA_REGISTRYINDEX, event_queue_ref); + int index = 1; + lua_rawgeti(L, 1, index); + sint32 event_ref = lua_tonumber(L, -1); + lua_pop(L, 1); - EVENT_DBG("\t\tevent %u\n", evt->event); + //remove event reference from queue + int queue_length = lua_objlen(L, 1); + lua_rawgeti(L, 1, index); + for(; index0){ + task_post_low(wifi_event_monitor_task_id, false); //post task to process next item in queue + EVENT_DBG("%d events left in queue, posting task", queue_length); + } + lua_pop(L, 1); //pop event queue from stack if(wifi_event_cb_ref[evt->event] != LUA_NOREF) // check if user has registered a callback { @@ -130,107 +153,97 @@ static void wifi_event_monitor_process_event_queue(task_param_t param, uint8 pri switch (evt->event) { case EVENT_STAMODE_CONNECTED: - EVENT_DBG("\n\tSTAMODE_CONNECTED\n"); + EVENT_DBG("Event: %d (STAMODE_CONNECTED)", EVENT_STAMODE_CONNECTED); wifi_add_sprintf_field(L, "SSID", (char*)evt->event_info.connected.ssid); wifi_add_sprintf_field(L, "BSSID", MACSTR, MAC2STR(evt->event_info.connected.bssid)); wifi_add_int_field(L, "channel", evt->event_info.connected.channel); - EVENT_DBG("\tConnected to SSID %s, Channel %d\n", + EVENT_DBG("Connected to SSID %s, Channel %d", evt->event_info.connected.ssid, evt->event_info.connected.channel); break; case EVENT_STAMODE_DISCONNECTED: - EVENT_DBG("\n\tSTAMODE_DISCONNECTED\n"); + EVENT_DBG("Event: %d (STAMODE_DISCONNECTED)", EVENT_STAMODE_DISCONNECTED); wifi_add_sprintf_field(L, "SSID", (char*)evt->event_info.disconnected.ssid); wifi_add_int_field(L, "reason", evt->event_info.disconnected.reason); wifi_add_sprintf_field(L, "BSSID", MACSTR, MAC2STR(evt->event_info.disconnected.bssid)); - EVENT_DBG("\tDisconnect from SSID %s, reason %d\n", + EVENT_DBG("Disconnect from SSID %s, reason %d", evt->event_info.disconnected.ssid, evt->event_info.disconnected.reason); break; case EVENT_STAMODE_AUTHMODE_CHANGE: - EVENT_DBG("\n\tSTAMODE_AUTHMODE_CHANGE\n"); + EVENT_DBG("Event: %d (STAMODE_AUTHMODE_CHANGE)", EVENT_STAMODE_AUTHMODE_CHANGE); wifi_add_int_field(L, "old_auth_mode", evt->event_info.auth_change.old_mode); wifi_add_int_field(L, "new_auth_mode", evt->event_info.auth_change.new_mode); - EVENT_DBG("\tAuthmode: %u -> %u\n", + EVENT_DBG("Authmode: %u -> %u", evt->event_info.auth_change.old_mode, evt->event_info.auth_change.new_mode); break; case EVENT_STAMODE_GOT_IP: - EVENT_DBG("\n\tGOT_IP\n"); + EVENT_DBG("Event: %d (STAMODE_GOT_IP)", EVENT_STAMODE_GOT_IP); wifi_add_sprintf_field(L, "IP", IPSTR, IP2STR(&evt->event_info.got_ip.ip)); wifi_add_sprintf_field(L, "netmask", IPSTR, IP2STR(&evt->event_info.got_ip.mask)); wifi_add_sprintf_field(L, "gateway", IPSTR, IP2STR(&evt->event_info.got_ip.gw)); - EVENT_DBG("\tIP:" IPSTR ",Mask:" IPSTR ",GW:" IPSTR "\n", + EVENT_DBG("IP:" IPSTR ",Mask:" IPSTR ",GW:" IPSTR "", IP2STR(&evt->event_info.got_ip.ip), IP2STR(&evt->event_info.got_ip.mask), IP2STR(&evt->event_info.got_ip.gw)); break; case EVENT_STAMODE_DHCP_TIMEOUT: - EVENT_DBG("\n\tSTAMODE_DHCP_TIMEOUT\n"); + EVENT_DBG("Event: %d (STAMODE_DHCP_TIMEOUT)", EVENT_STAMODE_DHCP_TIMEOUT); break; case EVENT_SOFTAPMODE_STACONNECTED: - EVENT_DBG("\n\tSOFTAPMODE_STACONNECTED\n"); + EVENT_DBG("Event: %d (SOFTAPMODE_STACONNECTED)", EVENT_SOFTAPMODE_STACONNECTED); wifi_add_sprintf_field(L, "MAC", MACSTR, MAC2STR(evt->event_info.sta_connected.mac)); wifi_add_int_field(L, "AID", evt->event_info.sta_connected.aid); - EVENT_DBG("\tStation: " MACSTR "join, AID = %d\n", + EVENT_DBG("Station: " MACSTR "join, AID = %d", MAC2STR(evt->event_info.sta_connected.mac), evt->event_info.sta_connected.aid); break; case EVENT_SOFTAPMODE_STADISCONNECTED: - EVENT_DBG("\n\tSOFTAPMODE_STADISCONNECTED\n"); + EVENT_DBG("Event: %d (SOFTAPMODE_STADISCONNECTED)", EVENT_SOFTAPMODE_STADISCONNECTED); wifi_add_sprintf_field(L, "MAC", MACSTR, MAC2STR(evt->event_info.sta_disconnected.mac)); wifi_add_int_field(L, "AID", evt->event_info.sta_disconnected.aid); - EVENT_DBG("\tstation: " MACSTR "leave, AID = %d\n", + EVENT_DBG("station: " MACSTR "leave, AID = %d", MAC2STR(evt->event_info.sta_disconnected.mac), evt->event_info.sta_disconnected.aid); break; case EVENT_SOFTAPMODE_PROBEREQRECVED: - EVENT_DBG("\n\tSOFTAPMODE_PROBEREQRECVED\n"); + EVENT_DBG("Event: %d (SOFTAPMODE_PROBEREQRECVED)", EVENT_SOFTAPMODE_PROBEREQRECVED); wifi_add_sprintf_field(L, "MAC", MACSTR, MAC2STR(evt->event_info.ap_probereqrecved.mac)); wifi_add_int_field(L, "RSSI", evt->event_info.ap_probereqrecved.rssi); - EVENT_DBG("Station PROBEREQ: " MACSTR " RSSI = %d\n", + EVENT_DBG("Station PROBEREQ: " MACSTR " RSSI = %d", MAC2STR(evt->event_info.ap_probereqrecved.mac), evt->event_info.ap_probereqrecved.rssi); break; case EVENT_OPMODE_CHANGED: - EVENT_DBG("\n\tOPMODE_CHANGED\n"); + EVENT_DBG("Event: %d (OPMODE_CHANGED)", EVENT_OPMODE_CHANGED); wifi_add_int_field(L, "old_mode", evt->event_info.opmode_changed.old_opmode); wifi_add_int_field(L, "new_mode", evt->event_info.opmode_changed.new_opmode); - EVENT_DBG("\topmode: %u -> %u\n", + EVENT_DBG("opmode: %u -> %u", evt->event_info.opmode_changed.old_opmode, evt->event_info.opmode_changed.new_opmode); break; default://if event is not implemented, return event id - EVENT_DBG("\n\tswitch/case default\n"); + EVENT_DBG("Event: %d (switch/case default)", evt->event); wifi_add_sprintf_field(L, "info", "event %u not implemented", evt->event); break; } + + luaL_unref(L, LUA_REGISTRYINDEX, event_ref); //the userdata containing event info is no longer needed + event_ref = LUA_NOREF; + lua_call(L, 1, 0); //execute user's callback and pass Lua table - - if (wifi_event_queue_head == wifi_event_queue_tail) //if queue is empty.. - { - wifi_event_queue_head = wifi_event_queue_tail = NULL; //set queue pointers to NULL - EVENT_DBG("\n\tQueue empty\n"); - } - else //if queue is not empty... - { - wifi_event_queue_head = wifi_event_queue_head->next; //append item to end of queue - EVENT_DBG("\n\tmore in queue, posting task...\n"); - task_post_low(wifi_event_monitor_task_id, false); //post task to process next item in queue - } - - c_free(evt); //free memory used by event structure - c_free(temp); //free memory used by queue structure + return; } #ifdef WIFI_EVENT_MONITOR_DISCONNECT_REASON_LIST_ENABLE diff --git a/app/pm/swtimer.c b/app/pm/swtimer.c index bedbf954..9042b3b1 100644 --- a/app/pm/swtimer.c +++ b/app/pm/swtimer.c @@ -57,7 +57,7 @@ //this section specifies which lua registry to use. LUA_GLOBALSINDEX or LUA_REGISTRYINDEX #ifdef SWTMR_DEBUG -#define SWTMR_DBG(fmt, ...) c_printf("\n SWTMR_DBG(%s): "fmt"\n", __FUNCTION__, ##__VA_ARGS__) +#define SWTMR_DBG(fmt, ...) dbg_printf("\n SWTMR_DBG(%s): "fmt"\n", __FUNCTION__, ##__VA_ARGS__) #define L_REGISTRY LUA_GLOBALSINDEX #define CB_LIST_STR "timer_cb_ptrs" #define SUSP_LIST_STR "suspended_tmr_LL_head" @@ -83,7 +83,7 @@ typedef struct cb_registry_item{ /* Internal variables */ static tmr_cb_queue_t* register_queue = NULL; -static task_handle_t cb_register_task_id = NULL; //variable to hold task id for task handler(process_cb_register_queue) +static task_handle_t cb_register_task_id = 0; //variable to hold task id for task handler(process_cb_register_queue) /* Function declarations */ //void swtmr_cb_register(void* timer_cb_ptr, uint8 resume_policy); @@ -173,7 +173,7 @@ void swtmr_suspend_timers(){ */ while(timer_ptr != NULL){ os_timer_t* next_timer = (os_timer_t*)0xffffffff; - for(int i = 0; i < registered_cb_qty; i++){ + for(size_t i = 0; i < registered_cb_qty; i++){ if(timer_ptr->timer_func == cb_reg_array[i]->tmr_cb_ptr){ //current timer will be suspended, next timer's pointer will be needed to continue processing timer_list @@ -394,9 +394,8 @@ static void add_to_reg_queue(void* timer_cb_ptr, uint8 suspend_policy){ tmr_cb_queue_t* queue_temp = c_zalloc(sizeof(tmr_cb_queue_t)); if(!queue_temp){ //it's boot time currently and we're already out of memory, something is very wrong... - c_printf("\n\t%s:out of memory, system halted!\n", __FUNCTION__); - while(1) - system_soft_wdt_feed(); + dbg_printf("\n\t%s:out of memory, rebooting.", __FUNCTION__); + system_restart(); } queue_temp->tmr_cb_ptr = timer_cb_ptr; queue_temp->suspend_policy = suspend_policy; @@ -476,8 +475,8 @@ int print_timer_list(lua_State* L){ os_timer_t* timer_list_ptr = timer_list; - c_printf("\n\tCurrent FRC2: %u\n", RTC_REG_READ(FRC2_COUNT_ADDRESS)); - c_printf("\ttimer_list:\n"); + dbg_printf("\n\tCurrent FRC2: %u\n", RTC_REG_READ(FRC2_COUNT_ADDRESS)); + dbg_printf("\ttimer_list:\n"); while(timer_list_ptr != NULL){ bool registered_flag = FALSE; for(int i=0; i < registered_cb_qty; i++){ @@ -486,7 +485,7 @@ int print_timer_list(lua_State* L){ break; } } - c_printf("\tptr:%p\tcb:%p\texpire:%8u\tperiod:%8u\tnext:%p\t%s\n", + dbg_printf("\tptr:%p\tcb:%p\texpire:%8u\tperiod:%8u\tnext:%p\t%s\n", timer_list_ptr, timer_list_ptr->timer_func, timer_list_ptr->timer_expire, timer_list_ptr->timer_period, timer_list_ptr->timer_next, registered_flag ? "Registered" : ""); timer_list_ptr = timer_list_ptr->timer_next; } @@ -513,9 +512,9 @@ int print_susp_timer_list(lua_State* L){ } os_timer_t* susp_timer_list_ptr = lua_touserdata(L, -1); - c_printf("\n\tsuspended_timer_list:\n"); + dbg_printf("\n\tsuspended_timer_list:\n"); while(susp_timer_list_ptr != NULL){ - c_printf("\tptr:%p\tcb:%p\texpire:%8u\tperiod:%8u\tnext:%p\n",susp_timer_list_ptr, susp_timer_list_ptr->timer_func, susp_timer_list_ptr->timer_expire, susp_timer_list_ptr->timer_period, susp_timer_list_ptr->timer_next); + dbg_printf("\tptr:%p\tcb:%p\texpire:%8u\tperiod:%8u\tnext:%p\n",susp_timer_list_ptr, susp_timer_list_ptr->timer_func, susp_timer_list_ptr->timer_expire, susp_timer_list_ptr->timer_period, susp_timer_list_ptr->timer_next); susp_timer_list_ptr = susp_timer_list_ptr->timer_next; } return 0; diff --git a/docs/en/modules/node.md b/docs/en/modules/node.md index 86281fd6..76ef92ca 100644 --- a/docs/en/modules/node.md +++ b/docs/en/modules/node.md @@ -87,9 +87,8 @@ dofile("hello.lc") Enters deep sleep mode, wakes up when timed out. -The maximum sleep time is 4294967295us, ~71 minutes. This is an SDK limitation. -Firmware from before 05 Jan 2016 have a maximum sleeptime of ~35 minutes. - +Theoretical maximum deep sleep duration can be found with [`node.dsleepMax()`](#nodedsleepmax). ["Max deep sleep for ESP8266"](https://thingpulse.com/max-deep-sleep-for-esp8266/) claims the realistic maximum be around 3.5h. + !!! caution This function can only be used in the condition that esp8266 PIN32(RST) and PIN8(XPD_DCDC aka GPIO16) are connected together. Using sleep(0) will set no wake up timer, connect a GPIO to pin RST, the chip will wake up by a falling-edge on pin RST. @@ -107,10 +106,7 @@ Firmware from before 05 Jan 2016 have a maximum sleeptime of ~35 minutes. - 1, RF_CAL after deep-sleep wake up, there will be large current - 2, no RF_CAL after deep-sleep wake up, there will only be small current - 4, disable RF after deep-sleep wake up, just like modem sleep, there will be the smallest current - - `instant` number (integer) or `nil`. If present and non-zero, do not use - the normal grace time before entering deep sleep. This is a largely - undocumented feature, and is only briefly mentioned in Espressif's - [low power solutions](https://espressif.com/sites/default/files/documentation/9b-esp8266_low_power_solutions_en.pdf#page=10) document (chapter 4.5). + - `instant` number (integer) or `nil`. If present and non-zero, the chip will enter Deep-sleep immediately and will not wait for the Wi-Fi core to be shutdown. #### Returns `nil` @@ -131,6 +127,37 @@ node.dsleep(nil,4) - [`wifi.suspend()`](wifi.md#wifisuspend) - [`wifi.resume()`](wifi.md#wifiresume) - [`node.sleep()`](#nodesleep) +- [`node.dsleepMax()`](#nodedsleepmax) + +## node.dsleepMax() + +Returns the current theoretical maximum deep sleep duration. + +!!! caution + + While it is possible to specify a longer sleep time than the theoretical maximum sleep duration, it is not recommended to exceed this maximum. In tests documented at ["Max deep sleep for ESP8266"](https://thingpulse.com/max-deep-sleep-for-esp8266/) the device never woke up again if the specified sleep time was beyond `dsleepMax()`. + + +!!! note + + This theoretical maximum is dependent on ambient temperature: lower temp = shorter sleep duration, higher temp = longer sleep duration + +#### Syntax +`node.dsleepMax()` + +#### Parameters + none + +#### Returns +`max_duration` + +#### Example +```lua +node.dsleep(node.dsleepMax()) +``` + +#### See also +- [`node.dsleep()`](#nodedsleep) ## node.flashid() @@ -192,6 +219,27 @@ none #### Returns flash size in bytes (integer) +## node.getcpufreq() + +Get the current CPU Frequency. + +#### Syntax +`node.getcpufreq()` + +#### Parameters +none + +#### Returns +Current CPU frequency (number) + +#### Example +```lua +do + local cpuFreq = node.getcpufreq() + print("The current CPU frequency is " .. cpuFreq .. " MHz") +end +``` + ## node.heap() Returns the current available heap size in bytes. Note that due to fragmentation, actual allocations of this size may not be possible. diff --git a/docs/en/modules/sqlite3.md b/docs/en/modules/sqlite3.md index a18f382e..bba6647c 100644 --- a/docs/en/modules/sqlite3.md +++ b/docs/en/modules/sqlite3.md @@ -9,7 +9,7 @@ This module depens on [SQLite3](http://www.sqlite.org/) library developed by Dwa For instruction on how to use this module or further documentation, please, refer to [LuaSQLite3 Documentation](http://lua.sqlite.org/index.cgi/doc/tip/doc/lsqlite3.wiki). -This module is a stripped down version of SQLite, with every possible OMIT_\* configuration enable. The enabled OMIT_\* directives are available in the module's [Makefile](../../../app/sqlite3/Makefile). +This module is a stripped down version of SQLite, with every possible OMIT_\* configuration enable. The enabled OMIT_\* directives are available in the module's [config file](../../../app/sqlite3/config_ext.h). The SQLite3 module vfs layer integration with NodeMCU was developed by me. diff --git a/lua_examples/webap_toggle_pin.lua b/lua_examples/webap_toggle_pin.lua index 7d5a558d..60de70a6 100644 --- a/lua_examples/webap_toggle_pin.lua +++ b/lua_examples/webap_toggle_pin.lua @@ -1,31 +1,31 @@ wifi.setmode(wifi.SOFTAP) -wifi.ap.config({ssid="test",pwd="12345678"}) +wifi.ap.config({ ssid = "test", pwd = "12345678" }) gpio.mode(1, gpio.OUTPUT) -srv=net.createServer(net.TCP) -srv:listen(80,function(conn) - conn:on("receive", function(client,request) - local buf = "" - local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP") - if(method == nil)then - _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP") - end - local _GET = {} - if (vars ~= nil)then - for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do - _GET[k] = v - end - end - buf = buf.."

Hello, NodeMcu.

Turn PIN1
" - client:send(buf) - end) - conn:on("sent", function (c) c:close() end) +srv = net.createServer(net.TCP) +srv:listen(80, function(conn) + conn:on("receive", function(client, request) + local buf = "" + local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP") + if (method == nil) then + _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP") + end + local _GET = {} + if (vars ~= nil) then + for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do + _GET[k] = v + end + end + buf = buf .. "

Hello, this is NodeMCU.

Turn PIN1
" + client:send(buf) + end) + conn:on("sent", function(c) c:close() end) end)