From 7fbad1612f2b10d674163af4f7d524fdb7c27c16 Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Sun, 1 Oct 2017 13:34:33 +1100 Subject: [PATCH 01/12] Add protocol to network.WLAN.config and LR constant. (cherry picked from commit 00b709d2c0846b76d2b8614df39ff160e1044011) --- ports/esp32/Makefile | 4 ++++ ports/esp32/modnetwork.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 0e0b73c53012..075306255e46 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -38,6 +38,10 @@ ESPCOMP = $(ESPIDF)/components ESPTOOL ?= $(ESPCOMP)/esptool_py/esptool/esptool.py # verify the ESP IDF version +<<<<<<< HEAD +======= +ESPIDF_SUPHASH := e6afe28bafe5db5ab79fae213f2e8e1ccd9f937c +>>>>>>> 00b709d2c... Add protocol to network.WLAN.config and LR constant. ESPIDF_CURHASH := $(shell git -C $(ESPIDF) show -s --pretty=format:'%H') ifneq ($(ESPIDF_CURHASH),$(ESPIDF_SUPHASH)) $(info ** WARNING **) diff --git a/ports/esp32/modnetwork.c b/ports/esp32/modnetwork.c index 2e305823f67a..ddd7575bda45 100644 --- a/ports/esp32/modnetwork.c +++ b/ports/esp32/modnetwork.c @@ -532,6 +532,10 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs ESP_EXCEPTIONS(esp_wifi_set_mac(self->if_id, bufinfo.buf)); break; } + case QS(MP_QSTR_protocol): { + esp_wifi_set_protocol(self->if_id, mp_obj_get_int(kwargs->table[i].value)); + break; + } case QS(MP_QSTR_essid): { req_if = WIFI_IF_AP; mp_uint_t len; @@ -679,6 +683,7 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_phy_mode), MP_ROM_PTR(&esp_phy_mode_obj) }, #if MODNETWORK_INCLUDE_CONSTANTS +<<<<<<< HEAD { MP_ROM_QSTR(MP_QSTR_STA_IF), MP_ROM_INT(WIFI_IF_STA)}, { MP_ROM_QSTR(MP_QSTR_AP_IF), MP_ROM_INT(WIFI_IF_AP)}, @@ -705,6 +710,39 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_STAT_BEACON_TIMEOUT), MP_ROM_INT(WIFI_REASON_BEACON_TIMEOUT)}, { MP_ROM_QSTR(MP_QSTR_STAT_ASSOC_FAIL), MP_ROM_INT(WIFI_REASON_ASSOC_FAIL)}, { MP_ROM_QSTR(MP_QSTR_STAT_HANDSHAKE_TIMEOUT), MP_ROM_INT(WIFI_REASON_HANDSHAKE_TIMEOUT)}, +======= + { MP_OBJ_NEW_QSTR(MP_QSTR_STA_IF), + MP_OBJ_NEW_SMALL_INT(WIFI_IF_STA)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_AP_IF), + MP_OBJ_NEW_SMALL_INT(WIFI_IF_AP)}, + + { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_11B), + MP_OBJ_NEW_SMALL_INT(WIFI_PROTOCOL_11B) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_11G), + MP_OBJ_NEW_SMALL_INT(WIFI_PROTOCOL_11G) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_11N), + MP_OBJ_NEW_SMALL_INT(WIFI_PROTOCOL_11N) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_LR), + MP_OBJ_NEW_SMALL_INT(WIFI_PROTOCOL_LR) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_OPEN), + MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_OPEN) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_WEP), + MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_WEP) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_WPA_PSK), + MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_WPA_PSK) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_WPA2_PSK), + MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_WPA2_PSK) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_WPA_WPA2_PSK), + MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_WPA_WPA2_PSK) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_MAX), + MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_MAX) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_PHY_LAN8720), + MP_OBJ_NEW_SMALL_INT(PHY_LAN8720) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PHY_TLK110), + MP_OBJ_NEW_SMALL_INT(PHY_TLK110) }, +>>>>>>> 00b709d2c... Add protocol to network.WLAN.config and LR constant. #endif }; From 592666053e16b0070ee062188d12d0b68f3e4b3c Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Wed, 4 Oct 2017 10:19:58 +1100 Subject: [PATCH 02/12] ... start on espnow (cherry picked from commit 6177511a5a4c5cd0ea25e7bd6999fa8c7353372e) --- ports/esp32/Makefile | 9 ++ ports/esp32/esp_espnow.c | 182 +++++++++++++++++++++++++++++++++++++++ ports/esp32/modesp.c | 6 ++ ports/esp32/modnetwork.c | 39 +++++++-- ports/esp32/modnetwork.h | 9 ++ 5 files changed, 236 insertions(+), 9 deletions(-) create mode 100644 ports/esp32/esp_espnow.c diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 075306255e46..699b59e00981 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -171,8 +171,13 @@ SRC_C = \ network_lan.c \ modsocket.c \ modesp.c \ +<<<<<<< HEAD esp32_ulp.c \ modesp32.c \ +======= + esp_espnow.c \ + moduhashlib.c \ +>>>>>>> 6177511a5... ... start on espnow espneopixel.c \ machine_hw_spi.c \ machine_wdt.c \ @@ -679,7 +684,11 @@ APP_LD_ARGS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc APP_LD_ARGS += -L$(dir $(LIBSTDCXX_FILE_NAME)) -lstdc++ APP_LD_ARGS += $(LIBC_LIBM) APP_LD_ARGS += $(ESPCOMP)/esp32/libhal.a +<<<<<<< HEAD APP_LD_ARGS += -L$(ESPCOMP)/esp32/lib -lcore -lmesh -lnet80211 -lphy -lrtc -lpp -lwpa -lsmartconfig -lcoexist -lwps -lwpa2 +======= +APP_LD_ARGS += -L$(ESPCOMP)/esp32/lib -lcore -lnet80211 -lphy -lrtc -lpp -lwpa -lsmartconfig -lcoexist -lwps -lwpa2 -lespnow +>>>>>>> 6177511a5... ... start on espnow APP_LD_ARGS += $(OBJ) APP_LD_ARGS += --end-group diff --git a/ports/esp32/esp_espnow.c b/ports/esp32/esp_espnow.c new file mode 100644 index 000000000000..7bb258ec4417 --- /dev/null +++ b/ports/esp32/esp_espnow.c @@ -0,0 +1,182 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Nick Moore + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include +#include +#include + +#include "esp_log.h" +#include "esp_now.h" +#include "esp_wifi.h" + +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/nlr.h" +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/mperrno.h" + +#include "modnetwork.h" + +NORETURN void _esp_espnow_exceptions(esp_err_t e) { + switch (e) { + case ESP_ERR_ESPNOW_NOT_INIT: + mp_raise_msg(&mp_type_OSError, "ESP-Now Not Initialized"); + case ESP_ERR_ESPNOW_ARG: + mp_raise_msg(&mp_type_OSError, "ESP-Now Invalid Argument"); + case ESP_ERR_ESPNOW_NO_MEM: + mp_raise_msg(&mp_type_OSError, "ESP-Now Out Of Mem"); + case ESP_ERR_ESPNOW_FULL: + mp_raise_msg(&mp_type_OSError, "ESP-Now Peer List Full"); + case ESP_ERR_ESPNOW_NOT_FOUND: + mp_raise_msg(&mp_type_OSError, "ESP-Now Peer Not Found"); + case ESP_ERR_ESPNOW_INTERNAL: + mp_raise_msg(&mp_type_OSError, "ESP-Now Internal"); + case ESP_ERR_ESPNOW_EXIST: + mp_raise_msg(&mp_type_OSError, "ESP-Now Peer Exists"); + default: + nlr_raise(mp_obj_new_exception_msg_varg( + &mp_type_RuntimeError, "ESP-Now Unknown Error 0x%04x", e + )); + } +} + +static inline void esp_espnow_exceptions(esp_err_t e) { + if (e != ESP_OK) _esp_espnow_exceptions(e); +} + +static inline void _get_bytes(mp_obj_t str, size_t len, uint8_t *dst) { + size_t str_len; + const char *data = mp_obj_str_get_data(str, &str_len); + if (str_len != len) mp_raise_ValueError("bad len"); + memcpy(dst, data, len); +} + +// this is crap of course but lets try it + +static int recv_buf_len = 0; +uint8_t recv_mac[6]; +static uint8_t recv_buffer[250]; + +STATIC mp_obj_t espnow_recv() { + if (recv_buf_len < 1) return mp_const_none; + mp_obj_tuple_t *msg = mp_obj_new_tuple(2, NULL); + msg->items[0] = mp_obj_new_bytes(recv_mac, sizeof(recv_mac)); + msg->items[1] = mp_obj_new_bytes(recv_buffer, recv_buf_len); + recv_buf_len = 0; + return msg; +} + +MP_DEFINE_CONST_FUN_OBJ_0(espnow_recv_obj, espnow_recv); + +void simple_cb(const uint8_t *macaddr, const uint8_t *data, int len) +{ + if (len < sizeof(recv_buffer)) { + memcpy(recv_buffer, data, len); + memcpy(recv_mac, macaddr, 6); + recv_buf_len = len; + } +} + +static int initialized = 0; + +STATIC mp_obj_t espnow_init() { + if (!initialized) { + esp_now_init(); + initialized = 1; + esp_now_register_recv_cb(simple_cb); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(espnow_init_obj, espnow_init); + +STATIC mp_obj_t espnow_deinit() { + if (initialized) { + esp_now_deinit(); + initialized = 0; + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(espnow_deinit_obj, espnow_deinit); + +STATIC mp_obj_t espnow_set_pmk(mp_obj_t pmk) { + uint8_t buf[ESP_NOW_ETH_ALEN]; + _get_bytes(pmk, ESP_NOW_ETH_ALEN, buf); + esp_espnow_exceptions(esp_now_set_pmk(buf)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_set_pmk_obj, espnow_set_pmk); + +STATIC mp_obj_t espnow_add_peer(size_t n_args, const mp_obj_t *args) { + esp_now_peer_info_t peer = {0}; + peer.ifidx = ((wlan_if_obj_t *)MP_OBJ_TO_PTR(args[0]))->if_id; + _get_bytes(args[1], ESP_NOW_ETH_ALEN, peer.peer_addr); + _get_bytes(args[2], ESP_NOW_KEY_LEN, peer.lmk); + peer.encrypt = (n_args > 3 && mp_obj_is_true(args[3])) ? 1 : 0; + // leaving channel as 0 for autodetect + esp_espnow_exceptions(esp_now_add_peer(&peer)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_add_peer_obj, 3, 4, espnow_add_peer); + +STATIC mp_obj_t espnow_send(mp_obj_t addr, mp_obj_t msg) { + mp_uint_t len1; + const uint8_t *buf1 = (const uint8_t *)mp_obj_str_get_data(addr, &len1); + mp_uint_t len2; + const uint8_t *buf2 = (const uint8_t *)mp_obj_str_get_data(msg, &len2); + if (len1 != ESP_NOW_ETH_ALEN) mp_raise_ValueError("addr invalid"); + if (len2 > ESP_NOW_MAX_DATA_LEN) mp_raise_ValueError("Msg too long"); + esp_espnow_exceptions(esp_now_send(buf1, buf2, len2)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(espnow_send_obj, espnow_send); + +STATIC mp_obj_t espnow_send_all(mp_obj_t msg) { + mp_uint_t len; + const uint8_t *buf = (const uint8_t *)mp_obj_str_get_data(msg, &len); + if (len > ESP_NOW_MAX_DATA_LEN) mp_raise_ValueError("Msg too long"); + esp_espnow_exceptions(esp_now_send(NULL, buf, len)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_send_all_obj, espnow_send_all); + +STATIC const mp_rom_map_elem_t espnow_globals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&espnow_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espnow_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_pmk), MP_ROM_PTR(&espnow_set_pmk_obj) }, + { MP_ROM_QSTR(MP_QSTR_add_peer), MP_ROM_PTR(&espnow_add_peer_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&espnow_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_send_all), MP_ROM_PTR(&espnow_send_all_obj) }, + { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&espnow_recv_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(espnow_globals_dict, espnow_globals_dict_table); + +const mp_obj_module_t mp_module_esp_espnow = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&espnow_globals_dict, +}; diff --git a/ports/esp32/modesp.c b/ports/esp32/modesp.c index e614f77a6aea..95c5e390b9a2 100644 --- a/ports/esp32/modesp.c +++ b/ports/esp32/modesp.c @@ -122,6 +122,8 @@ STATIC mp_obj_t esp_neopixel_write_(mp_obj_t pin, mp_obj_t buf, mp_obj_t timing) } STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_neopixel_write_obj, esp_neopixel_write_); +extern const mp_obj_module_t mp_module_esp_espnow; + STATIC const mp_rom_map_elem_t esp_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp) }, @@ -138,6 +140,7 @@ STATIC const mp_rom_map_elem_t esp_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_neopixel_write), MP_ROM_PTR(&esp_neopixel_write_obj) }, { MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) }, +<<<<<<< HEAD // Constants for second arg of osdebug() { MP_ROM_QSTR(MP_QSTR_LOG_NONE), MP_ROM_INT((mp_uint_t)ESP_LOG_NONE)}, @@ -146,6 +149,9 @@ STATIC const mp_rom_map_elem_t esp_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_LOG_INFO), MP_ROM_INT((mp_uint_t)ESP_LOG_INFO)}, { MP_ROM_QSTR(MP_QSTR_LOG_DEBUG), MP_ROM_INT((mp_uint_t)ESP_LOG_DEBUG)}, { MP_ROM_QSTR(MP_QSTR_LOG_VERBOSE), MP_ROM_INT((mp_uint_t)ESP_LOG_VERBOSE)}, +======= + { MP_ROM_QSTR(MP_QSTR_espnow), MP_ROM_PTR(&mp_module_esp_espnow) }, +>>>>>>> 6177511a5... ... start on espnow }; STATIC MP_DEFINE_CONST_DICT(esp_module_globals, esp_module_globals_table); diff --git a/ports/esp32/modnetwork.c b/ports/esp32/modnetwork.c index ddd7575bda45..48ea3403537c 100644 --- a/ports/esp32/modnetwork.c +++ b/ports/esp32/modnetwork.c @@ -53,7 +53,7 @@ #define MODNETWORK_INCLUDE_CONSTANTS (1) -NORETURN void _esp_exceptions(esp_err_t e) { +NORETURN void _esp_network_exceptions(esp_err_t e) { switch (e) { case ESP_ERR_WIFI_NOT_INIT: mp_raise_msg(&mp_type_OSError, "Wifi Not Initialized"); @@ -100,16 +100,11 @@ NORETURN void _esp_exceptions(esp_err_t e) { } } -static inline void esp_exceptions(esp_err_t e) { - if (e != ESP_OK) _esp_exceptions(e); +static inline void esp_network_exceptions(esp_err_t e) { + if (e != ESP_OK) _esp_network_exceptions(e); } -#define ESP_EXCEPTIONS(x) do { esp_exceptions(x); } while (0); - -typedef struct _wlan_if_obj_t { - mp_obj_base_t base; - int if_id; -} wlan_if_obj_t; +#define ESP_EXCEPTIONS(x) do { esp_network_exceptions(x); } while (0); const mp_obj_type_t wlan_if_type; STATIC const wlan_if_obj_t wlan_sta_obj = {{&wlan_if_type}, WIFI_IF_STA}; @@ -491,12 +486,38 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) { ESP_EXCEPTIONS(tcpip_adapter_dhcps_start(WIFI_IF_AP)); } } else { +<<<<<<< HEAD // check for the correct string const char *mode = mp_obj_str_get_str(args[1]); if ((self->if_id != WIFI_IF_STA && self->if_id != ESP_IF_ETH) || strcmp("dhcp", mode)) { mp_raise_ValueError("invalid arguments"); } ESP_EXCEPTIONS(tcpip_adapter_dhcpc_start(self->if_id)); +======= + netutils_parse_ipv4_addr(items[1], (void*)&info.netmask, NETUTILS_BIG); + } + netutils_parse_ipv4_addr(items[2], (void*)&info.gw, NETUTILS_BIG); + netutils_parse_ipv4_addr(items[3], (void*)&dns_info.ip, NETUTILS_BIG); + // To set a static IP we have to disable DHCP first +<<<<<<< HEAD + if (self->if_id == WIFI_IF_STA || self->if_id == ESP_IF_ETH) { + esp_err_t e = tcpip_adapter_dhcpc_stop(self->if_id); + if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) _esp_exceptions(e); + ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(self->if_id, &info)); + ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(self->if_id, TCPIP_ADAPTER_DNS_MAIN, &dns_info)); +======= + if (self->if_id == WIFI_IF_STA) { + esp_err_t e = tcpip_adapter_dhcpc_stop(WIFI_IF_STA); + if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) _esp_network_exceptions(e); + ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(WIFI_IF_STA, &info)); +>>>>>>> ... start on espnow + } else if (self->if_id == WIFI_IF_AP) { + esp_err_t e = tcpip_adapter_dhcps_stop(WIFI_IF_AP); + if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) _esp_network_exceptions(e); + ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(WIFI_IF_AP, &info)); + ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(WIFI_IF_AP, TCPIP_ADAPTER_DNS_MAIN, &dns_info)); + ESP_EXCEPTIONS(tcpip_adapter_dhcps_start(WIFI_IF_AP)); +>>>>>>> 6177511a5... ... start on espnow } return mp_const_none; } diff --git a/ports/esp32/modnetwork.h b/ports/esp32/modnetwork.h index b8dc1b85280f..179b877757e9 100644 --- a/ports/esp32/modnetwork.h +++ b/ports/esp32/modnetwork.h @@ -31,6 +31,15 @@ enum { PHY_LAN8720, PHY_TLK110 }; MP_DECLARE_CONST_FUN_OBJ_KW(get_lan_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj); +<<<<<<< HEAD void usocket_events_deinit(void); #endif +======= +typedef struct _wlan_if_obj_t { + mp_obj_base_t base; + int if_id; +} wlan_if_obj_t; + +#endif // MICROPY_INCLUDED_ESP32_MODESP_MODNETWORK_H +>>>>>>> 6177511a5... ... start on espnow From 1854d056622b6063ef5acd23c2258d43e80582cf Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Sun, 8 Oct 2017 23:52:18 +1100 Subject: [PATCH 03/12] use freertos queue for esp now (cherry picked from commit 0918f0516f6906d167c3deed101cff9c993db2a8) --- ports/esp32/Makefile | 4 ++++ ports/esp32/esp_espnow.c | 52 ++++++++++++++++++++++++---------------- ports/esp32/modnetwork.c | 9 +------ 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 699b59e00981..60538ffb3ffc 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -39,9 +39,13 @@ ESPTOOL ?= $(ESPCOMP)/esptool_py/esptool/esptool.py # verify the ESP IDF version <<<<<<< HEAD +<<<<<<< HEAD ======= ESPIDF_SUPHASH := e6afe28bafe5db5ab79fae213f2e8e1ccd9f937c >>>>>>> 00b709d2c... Add protocol to network.WLAN.config and LR constant. +======= +ESPIDF_SUPHASH := 2c95a77cf93781f296883d5dbafcdc18e4389656 +>>>>>>> 0918f0516... use freertos queue for esp now ESPIDF_CURHASH := $(shell git -C $(ESPIDF) show -s --pretty=format:'%H') ifneq ($(ESPIDF_CURHASH),$(ESPIDF_SUPHASH)) $(info ** WARNING **) diff --git a/ports/esp32/esp_espnow.c b/ports/esp32/esp_espnow.c index 7bb258ec4417..af3a0ce3dec5 100644 --- a/ports/esp32/esp_espnow.c +++ b/ports/esp32/esp_espnow.c @@ -33,6 +33,8 @@ #include "esp_now.h" #include "esp_wifi.h" +#include "freertos/queue.h" + #include "py/runtime.h" #include "py/mphal.h" #include "py/nlr.h" @@ -79,28 +81,34 @@ static inline void _get_bytes(mp_obj_t str, size_t len, uint8_t *dst) { // this is crap of course but lets try it -static int recv_buf_len = 0; -uint8_t recv_mac[6]; -static uint8_t recv_buffer[250]; +typedef struct { + uint8_t macaddr[ESP_NOW_ETH_ALEN]; + uint16_t len; + uint8_t data[ESP_NOW_MAX_DATA_LEN]; +} esp_now_queue_t; + +QueueHandle_t esp_now_queue; STATIC mp_obj_t espnow_recv() { - if (recv_buf_len < 1) return mp_const_none; + static esp_now_queue_t queue_item = { 0 }; + int r = xQueueReceive(esp_now_queue, &queue_item, 0); + if (r != pdTRUE) return mp_const_none; mp_obj_tuple_t *msg = mp_obj_new_tuple(2, NULL); - msg->items[0] = mp_obj_new_bytes(recv_mac, sizeof(recv_mac)); - msg->items[1] = mp_obj_new_bytes(recv_buffer, recv_buf_len); - recv_buf_len = 0; + msg->items[0] = mp_obj_new_bytes(queue_item.macaddr, ESP_NOW_ETH_ALEN); + msg->items[1] = mp_obj_new_bytes(queue_item.data, queue_item.len); return msg; } MP_DEFINE_CONST_FUN_OBJ_0(espnow_recv_obj, espnow_recv); -void simple_cb(const uint8_t *macaddr, const uint8_t *data, int len) +void recv_cb(const uint8_t *macaddr, const uint8_t *data, int len) { - if (len < sizeof(recv_buffer)) { - memcpy(recv_buffer, data, len); - memcpy(recv_mac, macaddr, 6); - recv_buf_len = len; - } + // this is double copying, perhaps I should be just queueing the pointers + static esp_now_queue_t queue_item = { 0 }; + queue_item.len = len; + memcpy(queue_item.macaddr, macaddr, ESP_NOW_ETH_ALEN); + memcpy(queue_item.data, data, len); + xQueueSend(esp_now_queue, &queue_item, 0); } static int initialized = 0; @@ -108,8 +116,9 @@ static int initialized = 0; STATIC mp_obj_t espnow_init() { if (!initialized) { esp_now_init(); + esp_now_queue = xQueueCreate(5, sizeof(esp_now_queue_t)); initialized = 1; - esp_now_register_recv_cb(simple_cb); + esp_now_register_recv_cb(recv_cb); } return mp_const_none; } @@ -118,6 +127,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(espnow_init_obj, espnow_init); STATIC mp_obj_t espnow_deinit() { if (initialized) { esp_now_deinit(); + vQueueDelete(esp_now_queue); initialized = 0; } return mp_const_none; @@ -125,8 +135,8 @@ STATIC mp_obj_t espnow_deinit() { MP_DEFINE_CONST_FUN_OBJ_0(espnow_deinit_obj, espnow_deinit); STATIC mp_obj_t espnow_set_pmk(mp_obj_t pmk) { - uint8_t buf[ESP_NOW_ETH_ALEN]; - _get_bytes(pmk, ESP_NOW_ETH_ALEN, buf); + uint8_t buf[ESP_NOW_KEY_LEN]; + _get_bytes(pmk, ESP_NOW_KEY_LEN, buf); esp_espnow_exceptions(esp_now_set_pmk(buf)); return mp_const_none; } @@ -134,15 +144,17 @@ MP_DEFINE_CONST_FUN_OBJ_1(espnow_set_pmk_obj, espnow_set_pmk); STATIC mp_obj_t espnow_add_peer(size_t n_args, const mp_obj_t *args) { esp_now_peer_info_t peer = {0}; + // leaving channel as 0 for autodetect peer.ifidx = ((wlan_if_obj_t *)MP_OBJ_TO_PTR(args[0]))->if_id; _get_bytes(args[1], ESP_NOW_ETH_ALEN, peer.peer_addr); - _get_bytes(args[2], ESP_NOW_KEY_LEN, peer.lmk); - peer.encrypt = (n_args > 3 && mp_obj_is_true(args[3])) ? 1 : 0; - // leaving channel as 0 for autodetect + if (n_args > 2) { + _get_bytes(args[2], ESP_NOW_KEY_LEN, peer.lmk); + peer.encrypt = 1; + } esp_espnow_exceptions(esp_now_add_peer(&peer)); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_add_peer_obj, 3, 4, espnow_add_peer); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_add_peer_obj, 2, 3, espnow_add_peer); STATIC mp_obj_t espnow_send(mp_obj_t addr, mp_obj_t msg) { mp_uint_t len1; diff --git a/ports/esp32/modnetwork.c b/ports/esp32/modnetwork.c index 48ea3403537c..e3bd17c52d98 100644 --- a/ports/esp32/modnetwork.c +++ b/ports/esp32/modnetwork.c @@ -499,18 +499,11 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) { netutils_parse_ipv4_addr(items[2], (void*)&info.gw, NETUTILS_BIG); netutils_parse_ipv4_addr(items[3], (void*)&dns_info.ip, NETUTILS_BIG); // To set a static IP we have to disable DHCP first -<<<<<<< HEAD - if (self->if_id == WIFI_IF_STA || self->if_id == ESP_IF_ETH) { - esp_err_t e = tcpip_adapter_dhcpc_stop(self->if_id); - if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) _esp_exceptions(e); - ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(self->if_id, &info)); - ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(self->if_id, TCPIP_ADAPTER_DNS_MAIN, &dns_info)); -======= if (self->if_id == WIFI_IF_STA) { esp_err_t e = tcpip_adapter_dhcpc_stop(WIFI_IF_STA); if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) _esp_network_exceptions(e); ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(WIFI_IF_STA, &info)); ->>>>>>> ... start on espnow + ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(self->if_id, TCPIP_ADAPTER_DNS_MAIN, &dns_info)); } else if (self->if_id == WIFI_IF_AP) { esp_err_t e = tcpip_adapter_dhcps_stop(WIFI_IF_AP); if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) _esp_network_exceptions(e); From b0b462f295714751aa3994543be0a3b8f367735b Mon Sep 17 00:00:00 2001 From: Nick Moore Date: Thu, 23 Nov 2017 14:57:20 +1100 Subject: [PATCH 04/12] Switch to callbacks for send/recv (cherry picked from commit 3036a8bcacca75300010e0e1ceec9f20c3880023) --- ports/esp32/esp_espnow.c | 63 ++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/ports/esp32/esp_espnow.c b/ports/esp32/esp_espnow.c index af3a0ce3dec5..1b254fac410c 100644 --- a/ports/esp32/esp_espnow.c +++ b/ports/esp32/esp_espnow.c @@ -33,8 +33,6 @@ #include "esp_now.h" #include "esp_wifi.h" -#include "freertos/queue.h" - #include "py/runtime.h" #include "py/mphal.h" #include "py/nlr.h" @@ -79,36 +77,27 @@ static inline void _get_bytes(mp_obj_t str, size_t len, uint8_t *dst) { memcpy(dst, data, len); } -// this is crap of course but lets try it - -typedef struct { - uint8_t macaddr[ESP_NOW_ETH_ALEN]; - uint16_t len; - uint8_t data[ESP_NOW_MAX_DATA_LEN]; -} esp_now_queue_t; +static mp_obj_t send_cb_obj = mp_const_none; +static mp_obj_t recv_cb_obj = mp_const_none; -QueueHandle_t esp_now_queue; - -STATIC mp_obj_t espnow_recv() { - static esp_now_queue_t queue_item = { 0 }; - int r = xQueueReceive(esp_now_queue, &queue_item, 0); - if (r != pdTRUE) return mp_const_none; - mp_obj_tuple_t *msg = mp_obj_new_tuple(2, NULL); - msg->items[0] = mp_obj_new_bytes(queue_item.macaddr, ESP_NOW_ETH_ALEN); - msg->items[1] = mp_obj_new_bytes(queue_item.data, queue_item.len); - return msg; +STATIC void IRAM_ATTR send_cb(const uint8_t *macaddr, esp_now_send_status_t status) +{ + if (send_cb_obj != mp_const_none) { + mp_obj_tuple_t *msg = mp_obj_new_tuple(2, NULL); + msg->items[0] = mp_obj_new_bytes(macaddr, ESP_NOW_ETH_ALEN); + msg->items[1] = (status == ESP_NOW_SEND_SUCCESS) ? mp_const_true : mp_const_false; + mp_sched_schedule(send_cb_obj, msg); + } } -MP_DEFINE_CONST_FUN_OBJ_0(espnow_recv_obj, espnow_recv); - -void recv_cb(const uint8_t *macaddr, const uint8_t *data, int len) +STATIC void IRAM_ATTR recv_cb(const uint8_t *macaddr, const uint8_t *data, int len) { - // this is double copying, perhaps I should be just queueing the pointers - static esp_now_queue_t queue_item = { 0 }; - queue_item.len = len; - memcpy(queue_item.macaddr, macaddr, ESP_NOW_ETH_ALEN); - memcpy(queue_item.data, data, len); - xQueueSend(esp_now_queue, &queue_item, 0); + if (recv_cb_obj != mp_const_none) { + mp_obj_tuple_t *msg = mp_obj_new_tuple(2, NULL); + msg->items[0] = mp_obj_new_bytes(macaddr, ESP_NOW_ETH_ALEN); + msg->items[1] = mp_obj_new_bytes(data, len); + mp_sched_schedule(recv_cb_obj, msg); + } } static int initialized = 0; @@ -116,9 +105,9 @@ static int initialized = 0; STATIC mp_obj_t espnow_init() { if (!initialized) { esp_now_init(); - esp_now_queue = xQueueCreate(5, sizeof(esp_now_queue_t)); initialized = 1; esp_now_register_recv_cb(recv_cb); + esp_now_register_send_cb(send_cb); } return mp_const_none; } @@ -127,13 +116,24 @@ MP_DEFINE_CONST_FUN_OBJ_0(espnow_init_obj, espnow_init); STATIC mp_obj_t espnow_deinit() { if (initialized) { esp_now_deinit(); - vQueueDelete(esp_now_queue); initialized = 0; } return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_0(espnow_deinit_obj, espnow_deinit); +STATIC mp_obj_t espnow_set_send_cb(mp_obj_t cb) { + send_cb_obj = cb; + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_set_send_cb_obj, espnow_set_send_cb); + +STATIC mp_obj_t espnow_set_recv_cb(mp_obj_t cb) { + recv_cb_obj = cb; + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(espnow_set_recv_cb_obj, espnow_set_recv_cb); + STATIC mp_obj_t espnow_set_pmk(mp_obj_t pmk) { uint8_t buf[ESP_NOW_KEY_LEN]; _get_bytes(pmk, ESP_NOW_KEY_LEN, buf); @@ -184,7 +184,8 @@ STATIC const mp_rom_map_elem_t espnow_globals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_add_peer), MP_ROM_PTR(&espnow_add_peer_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&espnow_send_obj) }, { MP_ROM_QSTR(MP_QSTR_send_all), MP_ROM_PTR(&espnow_send_all_obj) }, - { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&espnow_recv_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_send_cb), MP_ROM_PTR(&espnow_set_send_cb_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_recv_cb), MP_ROM_PTR(&espnow_set_recv_cb_obj) }, }; STATIC MP_DEFINE_CONST_DICT(espnow_globals_dict, espnow_globals_dict_table); From 0ea5a37def6b3bbb1b8123fe8c5eea380d81699b Mon Sep 17 00:00:00 2001 From: shawwwn Date: Sun, 9 Sep 2018 23:14:52 -0700 Subject: [PATCH 05/12] clean up conflicts --- ports/esp32/Makefile | 25 ++++-------------- ports/esp32/modesp.c | 4 +-- ports/esp32/modnetwork.c | 55 +--------------------------------------- ports/esp32/modnetwork.h | 5 +--- 4 files changed, 8 insertions(+), 81 deletions(-) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 60538ffb3ffc..48aa0266ac1d 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -1,12 +1,13 @@ include ../../py/mkenv.mk +CONFIG_SPIRAM_SUPPORT = 0 # qstr definitions (must come before including py.mk) QSTR_DEFS = qstrdefsport.h MICROPY_PY_USSL = 0 -MICROPY_SSL_AXTLS = 0 +MICROPY_SSL_AXTLS = 1 MICROPY_FATFS = 1 -MICROPY_PY_BTREE = 1 +MICROPY_PY_BTREE = 0 #FROZEN_DIR = scripts FROZEN_MPY_DIR = modules @@ -14,7 +15,7 @@ FROZEN_MPY_DIR = modules # include py core make definitions include $(TOP)/py/py.mk -PORT ?= /dev/ttyUSB0 +PORT ?= COM6 BAUD ?= 460800 FLASH_MODE ?= dio FLASH_FREQ ?= 40m @@ -38,14 +39,6 @@ ESPCOMP = $(ESPIDF)/components ESPTOOL ?= $(ESPCOMP)/esptool_py/esptool/esptool.py # verify the ESP IDF version -<<<<<<< HEAD -<<<<<<< HEAD -======= -ESPIDF_SUPHASH := e6afe28bafe5db5ab79fae213f2e8e1ccd9f937c ->>>>>>> 00b709d2c... Add protocol to network.WLAN.config and LR constant. -======= -ESPIDF_SUPHASH := 2c95a77cf93781f296883d5dbafcdc18e4389656 ->>>>>>> 0918f0516... use freertos queue for esp now ESPIDF_CURHASH := $(shell git -C $(ESPIDF) show -s --pretty=format:'%H') ifneq ($(ESPIDF_CURHASH),$(ESPIDF_SUPHASH)) $(info ** WARNING **) @@ -175,13 +168,9 @@ SRC_C = \ network_lan.c \ modsocket.c \ modesp.c \ -<<<<<<< HEAD esp32_ulp.c \ modesp32.c \ -======= esp_espnow.c \ - moduhashlib.c \ ->>>>>>> 6177511a5... ... start on espnow espneopixel.c \ machine_hw_spi.c \ machine_wdt.c \ @@ -688,11 +677,7 @@ APP_LD_ARGS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc APP_LD_ARGS += -L$(dir $(LIBSTDCXX_FILE_NAME)) -lstdc++ APP_LD_ARGS += $(LIBC_LIBM) APP_LD_ARGS += $(ESPCOMP)/esp32/libhal.a -<<<<<<< HEAD -APP_LD_ARGS += -L$(ESPCOMP)/esp32/lib -lcore -lmesh -lnet80211 -lphy -lrtc -lpp -lwpa -lsmartconfig -lcoexist -lwps -lwpa2 -======= -APP_LD_ARGS += -L$(ESPCOMP)/esp32/lib -lcore -lnet80211 -lphy -lrtc -lpp -lwpa -lsmartconfig -lcoexist -lwps -lwpa2 -lespnow ->>>>>>> 6177511a5... ... start on espnow +APP_LD_ARGS += -L$(ESPCOMP)/esp32/lib -lcore -lmesh -lnet80211 -lphy -lrtc -lpp -lwpa -lsmartconfig -lcoexist -lwps -lwpa2 -lespnow APP_LD_ARGS += $(OBJ) APP_LD_ARGS += --end-group diff --git a/ports/esp32/modesp.c b/ports/esp32/modesp.c index 95c5e390b9a2..051cc355e464 100644 --- a/ports/esp32/modesp.c +++ b/ports/esp32/modesp.c @@ -140,7 +140,6 @@ STATIC const mp_rom_map_elem_t esp_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_neopixel_write), MP_ROM_PTR(&esp_neopixel_write_obj) }, { MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) }, -<<<<<<< HEAD // Constants for second arg of osdebug() { MP_ROM_QSTR(MP_QSTR_LOG_NONE), MP_ROM_INT((mp_uint_t)ESP_LOG_NONE)}, @@ -149,9 +148,8 @@ STATIC const mp_rom_map_elem_t esp_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_LOG_INFO), MP_ROM_INT((mp_uint_t)ESP_LOG_INFO)}, { MP_ROM_QSTR(MP_QSTR_LOG_DEBUG), MP_ROM_INT((mp_uint_t)ESP_LOG_DEBUG)}, { MP_ROM_QSTR(MP_QSTR_LOG_VERBOSE), MP_ROM_INT((mp_uint_t)ESP_LOG_VERBOSE)}, -======= + { MP_ROM_QSTR(MP_QSTR_espnow), MP_ROM_PTR(&mp_module_esp_espnow) }, ->>>>>>> 6177511a5... ... start on espnow }; STATIC MP_DEFINE_CONST_DICT(esp_module_globals, esp_module_globals_table); diff --git a/ports/esp32/modnetwork.c b/ports/esp32/modnetwork.c index e3bd17c52d98..5f2fbec94401 100644 --- a/ports/esp32/modnetwork.c +++ b/ports/esp32/modnetwork.c @@ -486,31 +486,12 @@ STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) { ESP_EXCEPTIONS(tcpip_adapter_dhcps_start(WIFI_IF_AP)); } } else { -<<<<<<< HEAD // check for the correct string const char *mode = mp_obj_str_get_str(args[1]); if ((self->if_id != WIFI_IF_STA && self->if_id != ESP_IF_ETH) || strcmp("dhcp", mode)) { mp_raise_ValueError("invalid arguments"); } ESP_EXCEPTIONS(tcpip_adapter_dhcpc_start(self->if_id)); -======= - netutils_parse_ipv4_addr(items[1], (void*)&info.netmask, NETUTILS_BIG); - } - netutils_parse_ipv4_addr(items[2], (void*)&info.gw, NETUTILS_BIG); - netutils_parse_ipv4_addr(items[3], (void*)&dns_info.ip, NETUTILS_BIG); - // To set a static IP we have to disable DHCP first - if (self->if_id == WIFI_IF_STA) { - esp_err_t e = tcpip_adapter_dhcpc_stop(WIFI_IF_STA); - if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) _esp_network_exceptions(e); - ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(WIFI_IF_STA, &info)); - ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(self->if_id, TCPIP_ADAPTER_DNS_MAIN, &dns_info)); - } else if (self->if_id == WIFI_IF_AP) { - esp_err_t e = tcpip_adapter_dhcps_stop(WIFI_IF_AP); - if (e != ESP_OK && e != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED) _esp_network_exceptions(e); - ESP_EXCEPTIONS(tcpip_adapter_set_ip_info(WIFI_IF_AP, &info)); - ESP_EXCEPTIONS(tcpip_adapter_set_dns_info(WIFI_IF_AP, TCPIP_ADAPTER_DNS_MAIN, &dns_info)); - ESP_EXCEPTIONS(tcpip_adapter_dhcps_start(WIFI_IF_AP)); ->>>>>>> 6177511a5... ... start on espnow } return mp_const_none; } @@ -697,14 +678,13 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_phy_mode), MP_ROM_PTR(&esp_phy_mode_obj) }, #if MODNETWORK_INCLUDE_CONSTANTS -<<<<<<< HEAD { MP_ROM_QSTR(MP_QSTR_STA_IF), MP_ROM_INT(WIFI_IF_STA)}, { MP_ROM_QSTR(MP_QSTR_AP_IF), MP_ROM_INT(WIFI_IF_AP)}, { MP_ROM_QSTR(MP_QSTR_MODE_11B), MP_ROM_INT(WIFI_PROTOCOL_11B) }, { MP_ROM_QSTR(MP_QSTR_MODE_11G), MP_ROM_INT(WIFI_PROTOCOL_11G) }, { MP_ROM_QSTR(MP_QSTR_MODE_11N), MP_ROM_INT(WIFI_PROTOCOL_11N) }, - + { MP_ROM_QSTR(MP_QSTR_MODE_LR), MP_ROM_INT(WIFI_PROTOCOL_LR) }, { MP_ROM_QSTR(MP_QSTR_AUTH_OPEN), MP_ROM_INT(WIFI_AUTH_OPEN) }, { MP_ROM_QSTR(MP_QSTR_AUTH_WEP), MP_ROM_INT(WIFI_AUTH_WEP) }, { MP_ROM_QSTR(MP_QSTR_AUTH_WPA_PSK), MP_ROM_INT(WIFI_AUTH_WPA_PSK) }, @@ -724,39 +704,6 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_STAT_BEACON_TIMEOUT), MP_ROM_INT(WIFI_REASON_BEACON_TIMEOUT)}, { MP_ROM_QSTR(MP_QSTR_STAT_ASSOC_FAIL), MP_ROM_INT(WIFI_REASON_ASSOC_FAIL)}, { MP_ROM_QSTR(MP_QSTR_STAT_HANDSHAKE_TIMEOUT), MP_ROM_INT(WIFI_REASON_HANDSHAKE_TIMEOUT)}, -======= - { MP_OBJ_NEW_QSTR(MP_QSTR_STA_IF), - MP_OBJ_NEW_SMALL_INT(WIFI_IF_STA)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_AP_IF), - MP_OBJ_NEW_SMALL_INT(WIFI_IF_AP)}, - - { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_11B), - MP_OBJ_NEW_SMALL_INT(WIFI_PROTOCOL_11B) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_11G), - MP_OBJ_NEW_SMALL_INT(WIFI_PROTOCOL_11G) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_11N), - MP_OBJ_NEW_SMALL_INT(WIFI_PROTOCOL_11N) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_LR), - MP_OBJ_NEW_SMALL_INT(WIFI_PROTOCOL_LR) }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_OPEN), - MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_OPEN) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_WEP), - MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_WEP) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_WPA_PSK), - MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_WPA_PSK) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_WPA2_PSK), - MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_WPA2_PSK) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_WPA_WPA2_PSK), - MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_WPA_WPA2_PSK) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_AUTH_MAX), - MP_OBJ_NEW_SMALL_INT(WIFI_AUTH_MAX) }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_PHY_LAN8720), - MP_OBJ_NEW_SMALL_INT(PHY_LAN8720) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PHY_TLK110), - MP_OBJ_NEW_SMALL_INT(PHY_TLK110) }, ->>>>>>> 00b709d2c... Add protocol to network.WLAN.config and LR constant. #endif }; diff --git a/ports/esp32/modnetwork.h b/ports/esp32/modnetwork.h index 179b877757e9..8420f7757792 100644 --- a/ports/esp32/modnetwork.h +++ b/ports/esp32/modnetwork.h @@ -31,15 +31,12 @@ enum { PHY_LAN8720, PHY_TLK110 }; MP_DECLARE_CONST_FUN_OBJ_KW(get_lan_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj); -<<<<<<< HEAD void usocket_events_deinit(void); -#endif -======= typedef struct _wlan_if_obj_t { mp_obj_base_t base; int if_id; } wlan_if_obj_t; #endif // MICROPY_INCLUDED_ESP32_MODESP_MODNETWORK_H ->>>>>>> 6177511a5... ... start on espnow + From 2aa06947639cbb65ead7eee5ebcb883d919f6541 Mon Sep 17 00:00:00 2001 From: shawwwn Date: Sun, 9 Sep 2018 23:19:49 -0700 Subject: [PATCH 06/12] revert makefile --- ports/esp32/Makefile | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 48aa0266ac1d..0e0b73c53012 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -1,13 +1,12 @@ include ../../py/mkenv.mk -CONFIG_SPIRAM_SUPPORT = 0 # qstr definitions (must come before including py.mk) QSTR_DEFS = qstrdefsport.h MICROPY_PY_USSL = 0 -MICROPY_SSL_AXTLS = 1 +MICROPY_SSL_AXTLS = 0 MICROPY_FATFS = 1 -MICROPY_PY_BTREE = 0 +MICROPY_PY_BTREE = 1 #FROZEN_DIR = scripts FROZEN_MPY_DIR = modules @@ -15,7 +14,7 @@ FROZEN_MPY_DIR = modules # include py core make definitions include $(TOP)/py/py.mk -PORT ?= COM6 +PORT ?= /dev/ttyUSB0 BAUD ?= 460800 FLASH_MODE ?= dio FLASH_FREQ ?= 40m @@ -170,7 +169,6 @@ SRC_C = \ modesp.c \ esp32_ulp.c \ modesp32.c \ - esp_espnow.c \ espneopixel.c \ machine_hw_spi.c \ machine_wdt.c \ @@ -677,7 +675,7 @@ APP_LD_ARGS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc APP_LD_ARGS += -L$(dir $(LIBSTDCXX_FILE_NAME)) -lstdc++ APP_LD_ARGS += $(LIBC_LIBM) APP_LD_ARGS += $(ESPCOMP)/esp32/libhal.a -APP_LD_ARGS += -L$(ESPCOMP)/esp32/lib -lcore -lmesh -lnet80211 -lphy -lrtc -lpp -lwpa -lsmartconfig -lcoexist -lwps -lwpa2 -lespnow +APP_LD_ARGS += -L$(ESPCOMP)/esp32/lib -lcore -lmesh -lnet80211 -lphy -lrtc -lpp -lwpa -lsmartconfig -lcoexist -lwps -lwpa2 APP_LD_ARGS += $(OBJ) APP_LD_ARGS += --end-group From 38e23fd175a900f5531fc03189ae5a07434913b6 Mon Sep 17 00:00:00 2001 From: shawwwn Date: Sun, 9 Sep 2018 23:22:16 -0700 Subject: [PATCH 07/12] espnow makefile --- ports/esp32/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 0e0b73c53012..6a1b7ebc5456 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -167,6 +167,7 @@ SRC_C = \ network_lan.c \ modsocket.c \ modesp.c \ + esp_espnow.c \ esp32_ulp.c \ modesp32.c \ espneopixel.c \ @@ -675,7 +676,7 @@ APP_LD_ARGS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc APP_LD_ARGS += -L$(dir $(LIBSTDCXX_FILE_NAME)) -lstdc++ APP_LD_ARGS += $(LIBC_LIBM) APP_LD_ARGS += $(ESPCOMP)/esp32/libhal.a -APP_LD_ARGS += -L$(ESPCOMP)/esp32/lib -lcore -lmesh -lnet80211 -lphy -lrtc -lpp -lwpa -lsmartconfig -lcoexist -lwps -lwpa2 +APP_LD_ARGS += -L$(ESPCOMP)/esp32/lib -lcore -lmesh -lnet80211 -lphy -lrtc -lpp -lwpa -lsmartconfig -lcoexist -lwps -lwpa2 -lespnow APP_LD_ARGS += $(OBJ) APP_LD_ARGS += --end-group From 43dd1c6d4c7f051f9a550292916b33264654656c Mon Sep 17 00:00:00 2001 From: shawwwn Date: Sun, 9 Sep 2018 23:33:04 -0700 Subject: [PATCH 08/12] clean up conflicts in modnetwork.c --- ports/esp32/modnetwork.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/ports/esp32/modnetwork.c b/ports/esp32/modnetwork.c index 5f2fbec94401..5061f2913afa 100644 --- a/ports/esp32/modnetwork.c +++ b/ports/esp32/modnetwork.c @@ -53,7 +53,7 @@ #define MODNETWORK_INCLUDE_CONSTANTS (1) -NORETURN void _esp_network_exceptions(esp_err_t e) { +NORETURN void _esp_exceptions(esp_err_t e) { switch (e) { case ESP_ERR_WIFI_NOT_INIT: mp_raise_msg(&mp_type_OSError, "Wifi Not Initialized"); @@ -100,18 +100,18 @@ NORETURN void _esp_network_exceptions(esp_err_t e) { } } -static inline void esp_network_exceptions(esp_err_t e) { - if (e != ESP_OK) _esp_network_exceptions(e); +static inline void esp_exceptions(esp_err_t e) { + if (e != ESP_OK) _esp_exceptions(e); } -#define ESP_EXCEPTIONS(x) do { esp_network_exceptions(x); } while (0); +#define ESP_EXCEPTIONS(x) do { esp_exceptions(x); } while (0); const mp_obj_type_t wlan_if_type; STATIC const wlan_if_obj_t wlan_sta_obj = {{&wlan_if_type}, WIFI_IF_STA}; STATIC const wlan_if_obj_t wlan_ap_obj = {{&wlan_if_type}, WIFI_IF_AP}; // Set to "true" if esp_wifi_start() was called -static bool wifi_started = false; +bool wifi_started = false; // Set to "true" if the STA interface is requested to be connected by the // user, used for automatic reassociation. @@ -528,9 +528,9 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs break; } case QS(MP_QSTR_protocol): { - esp_wifi_set_protocol(self->if_id, mp_obj_get_int(kwargs->table[i].value)); - break; - } + ESP_EXCEPTIONS(esp_wifi_set_protocol(self->if_id, mp_obj_get_int(kwargs->table[i].value))); + break; + } case QS(MP_QSTR_essid): { req_if = WIFI_IF_AP; mp_uint_t len; @@ -602,6 +602,12 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs ESP_EXCEPTIONS(esp_wifi_get_mac(self->if_id, mac)); return mp_obj_new_bytes(mac, sizeof(mac)); } + case QS(MP_QSTR_protocol): { + uint8_t protocol_bitmap; + ESP_EXCEPTIONS(esp_wifi_get_protocol(self->if_id, &protocol_bitmap)); + val = MP_OBJ_NEW_SMALL_INT(protocol_bitmap); + break; + } case QS(MP_QSTR_essid): if (self->if_id == WIFI_IF_STA) { val = mp_obj_new_str((char*)cfg.sta.ssid, strlen((char*)cfg.sta.ssid)); @@ -685,6 +691,7 @@ STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_MODE_11G), MP_ROM_INT(WIFI_PROTOCOL_11G) }, { MP_ROM_QSTR(MP_QSTR_MODE_11N), MP_ROM_INT(WIFI_PROTOCOL_11N) }, { MP_ROM_QSTR(MP_QSTR_MODE_LR), MP_ROM_INT(WIFI_PROTOCOL_LR) }, + { MP_ROM_QSTR(MP_QSTR_AUTH_OPEN), MP_ROM_INT(WIFI_AUTH_OPEN) }, { MP_ROM_QSTR(MP_QSTR_AUTH_WEP), MP_ROM_INT(WIFI_AUTH_WEP) }, { MP_ROM_QSTR(MP_QSTR_AUTH_WPA_PSK), MP_ROM_INT(WIFI_AUTH_WPA_PSK) }, From 6a45bbd724f25e3d7b1b9ebc7386b9aba10617de Mon Sep 17 00:00:00 2001 From: shawwwn Date: Mon, 10 Sep 2018 00:47:56 -0700 Subject: [PATCH 09/12] revamp espnow, add workarounds for IDF bugs workarounds: * esp_now_send() will send from whatever IF that is active/available * esp_now_mod_peer() will not crash the system --- ports/esp32/esp_espnow.c | 209 ++++++++++++++++++++++++++++++--------- ports/esp32/modnetwork.h | 2 + 2 files changed, 166 insertions(+), 45 deletions(-) diff --git a/ports/esp32/esp_espnow.c b/ports/esp32/esp_espnow.c index 1b254fac410c..e976a9983d5b 100644 --- a/ports/esp32/esp_espnow.c +++ b/ports/esp32/esp_espnow.c @@ -32,6 +32,7 @@ #include "esp_log.h" #include "esp_now.h" #include "esp_wifi.h" +#include "esp_wifi_types.h" #include "py/runtime.h" #include "py/mphal.h" @@ -70,9 +71,11 @@ static inline void esp_espnow_exceptions(esp_err_t e) { if (e != ESP_OK) _esp_espnow_exceptions(e); } +#define ESPNOW_EXCEPTIONS(x) do { esp_espnow_exceptions(x); } while (0); + static inline void _get_bytes(mp_obj_t str, size_t len, uint8_t *dst) { size_t str_len; - const char *data = mp_obj_str_get_data(str, &str_len); + const char *data = mp_obj_str_get_data(str, &str_len); if (str_len != len) mp_raise_ValueError("bad len"); memcpy(dst, data, len); } @@ -86,7 +89,7 @@ STATIC void IRAM_ATTR send_cb(const uint8_t *macaddr, esp_now_send_status_t stat mp_obj_tuple_t *msg = mp_obj_new_tuple(2, NULL); msg->items[0] = mp_obj_new_bytes(macaddr, ESP_NOW_ETH_ALEN); msg->items[1] = (status == ESP_NOW_SEND_SUCCESS) ? mp_const_true : mp_const_false; - mp_sched_schedule(send_cb_obj, msg); + mp_sched_schedule(send_cb_obj, msg); } } @@ -96,7 +99,7 @@ STATIC void IRAM_ATTR recv_cb(const uint8_t *macaddr, const uint8_t *data, int l mp_obj_tuple_t *msg = mp_obj_new_tuple(2, NULL); msg->items[0] = mp_obj_new_bytes(macaddr, ESP_NOW_ETH_ALEN); msg->items[1] = mp_obj_new_bytes(data, len); - mp_sched_schedule(recv_cb_obj, msg); + mp_sched_schedule(recv_cb_obj, msg); } } @@ -104,88 +107,204 @@ static int initialized = 0; STATIC mp_obj_t espnow_init() { if (!initialized) { - esp_now_init(); + ESPNOW_EXCEPTIONS(esp_now_init()); initialized = 1; - esp_now_register_recv_cb(recv_cb); - esp_now_register_send_cb(send_cb); + + ESPNOW_EXCEPTIONS(esp_now_register_recv_cb(recv_cb)); + ESPNOW_EXCEPTIONS(esp_now_register_send_cb(send_cb)); } return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_0(espnow_init_obj, espnow_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(espnow_init_obj, espnow_init); STATIC mp_obj_t espnow_deinit() { if (initialized) { - esp_now_deinit(); + ESPNOW_EXCEPTIONS(esp_now_deinit()); initialized = 0; } return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_0(espnow_deinit_obj, espnow_deinit); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(espnow_deinit_obj, espnow_deinit); + +STATIC mp_obj_t espnow_on_send(size_t n_args, const mp_obj_t *args) { + if (n_args == 0) { + return send_cb_obj; + } -STATIC mp_obj_t espnow_set_send_cb(mp_obj_t cb) { - send_cb_obj = cb; + send_cb_obj = args[0]; return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_1(espnow_set_send_cb_obj, espnow_set_send_cb); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_on_send_obj, 0, 1, espnow_on_send); -STATIC mp_obj_t espnow_set_recv_cb(mp_obj_t cb) { - recv_cb_obj = cb; +STATIC mp_obj_t espnow_on_recv(size_t n_args, const mp_obj_t *args) { + if (n_args == 0) { + return recv_cb_obj; + } + + recv_cb_obj = args[0]; return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_1(espnow_set_recv_cb_obj, espnow_set_recv_cb); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_on_recv_obj, 0, 1, espnow_on_recv); -STATIC mp_obj_t espnow_set_pmk(mp_obj_t pmk) { +// pmk(primary_key) +STATIC mp_obj_t espnow_pmk(mp_obj_t key) { uint8_t buf[ESP_NOW_KEY_LEN]; - _get_bytes(pmk, ESP_NOW_KEY_LEN, buf); - esp_espnow_exceptions(esp_now_set_pmk(buf)); + _get_bytes(key, ESP_NOW_KEY_LEN, buf); + ESPNOW_EXCEPTIONS(esp_now_set_pmk(buf)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_pmk_obj, espnow_pmk); + +// lmk(peer_mac, local_key) +STATIC mp_obj_t espnow_lmk(mp_obj_t addr, mp_obj_t key) { + mp_uint_t addr_len; + const uint8_t *addr_buf = (const uint8_t *)mp_obj_str_get_data(addr, &addr_len); + if (addr_len != ESP_NOW_ETH_ALEN) mp_raise_ValueError("addr invalid"); + esp_now_peer_info_t peer; + ESPNOW_EXCEPTIONS(esp_now_get_peer(addr_buf, &peer)); + + // set peer lmk + bool encrypt = (key != mp_const_none); + bool re_add = (peer.encrypt != encrypt); + if (encrypt) _get_bytes(key, ESP_NOW_KEY_LEN, peer.lmk); + if (re_add) { + // workaround for calling esp_now_mod_peer() to + // change encryption status will crash the system + peer.encrypt = encrypt; + ESPNOW_EXCEPTIONS(esp_now_del_peer(addr_buf)); + ESPNOW_EXCEPTIONS(esp_now_add_peer(&peer)); + } else { + ESPNOW_EXCEPTIONS(esp_now_mod_peer(&peer)); + } return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_1(espnow_set_pmk_obj, espnow_set_pmk); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espnow_lmk_obj, espnow_lmk); +// add_peer(peer_mac, [local_key]) STATIC mp_obj_t espnow_add_peer(size_t n_args, const mp_obj_t *args) { esp_now_peer_info_t peer = {0}; - // leaving channel as 0 for autodetect - peer.ifidx = ((wlan_if_obj_t *)MP_OBJ_TO_PTR(args[0]))->if_id; - _get_bytes(args[1], ESP_NOW_ETH_ALEN, peer.peer_addr); - if (n_args > 2) { - _get_bytes(args[2], ESP_NOW_KEY_LEN, peer.lmk); + _get_bytes(args[0], ESP_NOW_ETH_ALEN, peer.peer_addr); + if (n_args > 1) { + _get_bytes(args[1], ESP_NOW_KEY_LEN, peer.lmk); peer.encrypt = 1; } - esp_espnow_exceptions(esp_now_add_peer(&peer)); + + ESPNOW_EXCEPTIONS(esp_now_add_peer(&peer)); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_add_peer_obj, 2, 3, espnow_add_peer); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_add_peer_obj, 1, 2, espnow_add_peer); -STATIC mp_obj_t espnow_send(mp_obj_t addr, mp_obj_t msg) { - mp_uint_t len1; - const uint8_t *buf1 = (const uint8_t *)mp_obj_str_get_data(addr, &len1); - mp_uint_t len2; - const uint8_t *buf2 = (const uint8_t *)mp_obj_str_get_data(msg, &len2); - if (len1 != ESP_NOW_ETH_ALEN) mp_raise_ValueError("addr invalid"); - if (len2 > ESP_NOW_MAX_DATA_LEN) mp_raise_ValueError("Msg too long"); - esp_espnow_exceptions(esp_now_send(buf1, buf2, len2)); +// del_peer(peer_mac) +STATIC mp_obj_t espnow_del_peer(mp_obj_t addr) { + mp_uint_t addr_len; + const uint8_t *addr_buf = (const uint8_t *)mp_obj_str_get_data(addr, &addr_len); + if (addr_len != ESP_NOW_ETH_ALEN) mp_raise_ValueError("addr invalid"); + ESPNOW_EXCEPTIONS(esp_now_del_peer(addr_buf)); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_2(espnow_send_obj, espnow_send); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_del_peer_obj, espnow_del_peer); + +// this workaround enables ESP32 to send from whatever IF that is +// active +// if_id == wifi_mode - 1 +#define IS_IF_AVAILABLE(mode, if_id) ({ (mode & (if_id+1)) != 0; }) +#define AVAILABLE_IF(mode) ({ \ + int if_id = -1; \ + for (int i=WIFI_MODE_STA; i<=WIFI_MODE_AP; i++) { \ + if (mode & i) { \ + if_id = i-1; \ + } \ + } \ + if_id; \ +}) \ + +STATIC mp_obj_t espnow_send(mp_obj_t addr, mp_obj_t msg) { + if (!wifi_started) goto espnow_wifi_err; + + mp_uint_t addr_len; + const uint8_t *addr_buf; + mp_uint_t msg_len; + const uint8_t *msg_buf = (const uint8_t *)mp_obj_str_get_data(msg, &msg_len); + if (msg_len > ESP_NOW_MAX_DATA_LEN) mp_raise_ValueError("msg too long"); + + wifi_mode_t mode; + ESPNOW_EXCEPTIONS(esp_wifi_get_mode(&mode)); + bool first = true; + int new_if = -1; + if (addr == mp_const_none) { + // send to all + esp_now_peer_info_t peer; + esp_err_t e = esp_now_fetch_peer(true, &peer); + ESPNOW_EXCEPTIONS(e); // raise error if nobody to send to + while (e == ESP_OK) { + if (!IS_IF_AVAILABLE(mode, peer.ifidx)) { + if (first) { + new_if = AVAILABLE_IF(mode); + if (new_if < 0) goto espnow_wifi_err; + first = false; + } + peer.ifidx = new_if; + ESPNOW_EXCEPTIONS(esp_now_mod_peer(&peer)); + } + addr_buf = peer.peer_addr; + ESPNOW_EXCEPTIONS(esp_now_send(addr_buf, msg_buf, msg_len)); + e = esp_now_fetch_peer(false, &peer); + } + } else { + // send to one + addr_buf = (const uint8_t *)mp_obj_str_get_data(addr, &addr_len); + if (addr_len != ESP_NOW_ETH_ALEN) mp_raise_ValueError("addr invalid"); + + esp_now_peer_info_t peer; + ESPNOW_EXCEPTIONS(esp_now_get_peer(addr_buf, &peer)); + if (!IS_IF_AVAILABLE(mode, peer.ifidx)) { + new_if = AVAILABLE_IF(mode); + if (new_if < 0) goto espnow_wifi_err; + peer.ifidx = new_if; + ESPNOW_EXCEPTIONS(esp_now_mod_peer(&peer)); + } + ESPNOW_EXCEPTIONS(esp_now_send(addr_buf, msg_buf, msg_len)); + } -STATIC mp_obj_t espnow_send_all(mp_obj_t msg) { - mp_uint_t len; - const uint8_t *buf = (const uint8_t *)mp_obj_str_get_data(msg, &len); - if (len > ESP_NOW_MAX_DATA_LEN) mp_raise_ValueError("Msg too long"); - esp_espnow_exceptions(esp_now_send(NULL, buf, len)); return mp_const_none; + +espnow_wifi_err: + mp_raise_msg(&mp_type_OSError, "wifi not active"); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espnow_send_obj, espnow_send); + +STATIC mp_obj_t espnow_peer_count() { + esp_now_peer_num_t peer_num = {0}; + ESPNOW_EXCEPTIONS(esp_now_get_peer_num(&peer_num)); + + mp_obj_t tuple[2]; + tuple[0] = mp_obj_new_int(peer_num.total_num); + tuple[1] = mp_obj_new_int(peer_num.encrypt_num); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(espnow_peer_count_obj, espnow_peer_count); + +STATIC mp_obj_t espnow_version() { + uint32_t version; + ESPNOW_EXCEPTIONS(esp_now_get_version(&version)); + return mp_obj_new_int(version); } -MP_DEFINE_CONST_FUN_OBJ_1(espnow_send_all_obj, espnow_send_all); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(espnow_version_obj, espnow_version); STATIC const mp_rom_map_elem_t espnow_globals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_espnow) }, { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&espnow_init_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espnow_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_pmk), MP_ROM_PTR(&espnow_set_pmk_obj) }, + { MP_ROM_QSTR(MP_QSTR_pmk), MP_ROM_PTR(&espnow_pmk_obj) }, + { MP_ROM_QSTR(MP_QSTR_lmk), MP_ROM_PTR(&espnow_lmk_obj) }, { MP_ROM_QSTR(MP_QSTR_add_peer), MP_ROM_PTR(&espnow_add_peer_obj) }, + { MP_ROM_QSTR(MP_QSTR_del_peer), MP_ROM_PTR(&espnow_del_peer_obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&espnow_send_obj) }, - { MP_ROM_QSTR(MP_QSTR_send_all), MP_ROM_PTR(&espnow_send_all_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_send_cb), MP_ROM_PTR(&espnow_set_send_cb_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_recv_cb), MP_ROM_PTR(&espnow_set_recv_cb_obj) }, + { MP_ROM_QSTR(MP_QSTR_on_send), MP_ROM_PTR(&espnow_on_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_on_recv), MP_ROM_PTR(&espnow_on_recv_obj) }, + { MP_ROM_QSTR(MP_QSTR_peer_count), MP_ROM_PTR(&espnow_peer_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_version), MP_ROM_PTR(&espnow_version_obj) }, }; STATIC MP_DEFINE_CONST_DICT(espnow_globals_dict, espnow_globals_dict_table); diff --git a/ports/esp32/modnetwork.h b/ports/esp32/modnetwork.h index 8420f7757792..ed26312dc5a7 100644 --- a/ports/esp32/modnetwork.h +++ b/ports/esp32/modnetwork.h @@ -33,6 +33,8 @@ MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj); void usocket_events_deinit(void); +extern bool wifi_started; + typedef struct _wlan_if_obj_t { mp_obj_base_t base; int if_id; From 8724967a081d2d453183086c9bba24d4bd7c0553 Mon Sep 17 00:00:00 2001 From: shawwwn Date: Mon, 10 Sep 2018 00:50:19 -0700 Subject: [PATCH 10/12] add espnow for esp8266 --- ports/esp8266/Makefile | 3 +- ports/esp8266/esp_espnow.c | 254 +++++++++++++++++++++++++++++++++++++ ports/esp8266/modesp.c | 8 +- 3 files changed, 262 insertions(+), 3 deletions(-) create mode 100644 ports/esp8266/esp_espnow.c diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile index 8dc20626bcdb..96826b4fd26f 100644 --- a/ports/esp8266/Makefile +++ b/ports/esp8266/Makefile @@ -44,7 +44,7 @@ CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib -DUART_OS=$(U LDSCRIPT = esp8266.ld LDFLAGS = -nostdlib -T $(LDSCRIPT) -Map=$(@:.elf=.map) --cref -LIBS = -L$(ESP_SDK)/lib -lmain -ljson -llwip_open -lpp -lnet80211 -lwpa -lphy -lnet80211 $(LDFLAGS_MOD) +LIBS = -L$(ESP_SDK)/lib -lmain -ljson -llwip_open -lpp -lnet80211 -lwpa -lphy -lnet80211 -lespnow $(LDFLAGS_MOD) LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) LIBS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc @@ -82,6 +82,7 @@ SRC_C = \ machine_wdt.c \ machine_hspi.c \ modesp.c \ + esp_espnow.c \ modnetwork.c \ modutime.c \ moduos.c \ diff --git a/ports/esp8266/esp_espnow.c b/ports/esp8266/esp_espnow.c new file mode 100644 index 000000000000..2660dfd7205d --- /dev/null +++ b/ports/esp8266/esp_espnow.c @@ -0,0 +1,254 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Nick Moore + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include +#include +#include + +#include "c_types.h" +#include "espnow.h" + +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/nlr.h" +#include "py/objlist.h" +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/mperrno.h" + +#define ESP_NOW_ETH_ALEN 6 /*!< Length of ESPNOW peer MAC address */ +#define ESP_NOW_KEY_LEN 16 /*!< Length of ESPNOW peer local master key */ +#define ESP_NOW_MAX_DATA_LEN 250 /*!< Maximum length of ESPNOW data which is sent very time */ + +enum mt_tx_status { + MT_TX_STATUS_OK = 0, + MT_TX_STATUS_FAILED, +}; + +static inline void esp_espnow_exceptions(int e) { + if (e != 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "ESP-Now Unknown Error 0x%04x", e)); + } +} + +#define ESPNOW_EXCEPTIONS(x) do { esp_espnow_exceptions(x); } while (0); + +#define ESP_NOW_PEER_EXIST(addr_buf) do { \ + int e = esp_now_is_peer_exist(addr_buf); \ + if (e == 0) { \ + mp_raise_msg(&mp_type_OSError, "ESP-Now Peer Not Found"); \ + } else if (e < 0) { \ + esp_espnow_exceptions(e); \ + } \ +} while (0); \ + +static inline void _get_bytes(mp_obj_t str, size_t len, uint8_t *dst) { + size_t str_len; + const char *data = mp_obj_str_get_data(str, &str_len); + if (str_len != len) mp_raise_ValueError("bad len"); + memcpy(dst, data, len); +} + +static mp_obj_t send_cb_obj = mp_const_none; +static mp_obj_t recv_cb_obj = mp_const_none; + +STATIC void send_cb(u8 *mac_addr, u8 status) +{ + if (send_cb_obj != mp_const_none) { + mp_obj_tuple_t *msg = mp_obj_new_tuple(2, NULL); + msg->items[0] = mp_obj_new_bytes(mac_addr, ESP_NOW_ETH_ALEN); + msg->items[1] = (status == MT_TX_STATUS_OK) ? mp_const_true : mp_const_false; + mp_sched_schedule(send_cb_obj, msg); + } +} + +STATIC void recv_cb(u8 *mac_addr, u8 *data, u8 len) +{ + if (recv_cb_obj != mp_const_none) { + mp_obj_tuple_t *msg = mp_obj_new_tuple(2, NULL); + msg->items[0] = mp_obj_new_bytes(mac_addr, ESP_NOW_ETH_ALEN); + msg->items[1] = mp_obj_new_bytes(data, len); + mp_sched_schedule(recv_cb_obj, msg); + } +} + +static int initialized = 0; + +STATIC mp_obj_t espnow_init() { + if (!initialized) { + ESPNOW_EXCEPTIONS(esp_now_init()); + ESPNOW_EXCEPTIONS(esp_now_set_self_role(ESP_NOW_ROLE_COMBO)); + initialized = 1; + + ESPNOW_EXCEPTIONS(esp_now_register_recv_cb(recv_cb)); + ESPNOW_EXCEPTIONS(esp_now_register_send_cb(send_cb)); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(espnow_init_obj, espnow_init); + +STATIC mp_obj_t espnow_deinit() { + if (initialized) { + ESPNOW_EXCEPTIONS(esp_now_deinit()); + initialized = 0; + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(espnow_deinit_obj, espnow_deinit); + +STATIC mp_obj_t espnow_on_send(size_t n_args, const mp_obj_t *args) { + if (n_args == 0) { + return send_cb_obj; + } + + send_cb_obj = args[0]; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_on_send_obj, 0, 1, espnow_on_send); + +STATIC mp_obj_t espnow_on_recv(size_t n_args, const mp_obj_t *args) { + if (n_args == 0) { + return recv_cb_obj; + } + + recv_cb_obj = args[0]; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_on_recv_obj, 0, 1, espnow_on_recv); + +// pmk(primary_key) +STATIC mp_obj_t espnow_pmk(mp_obj_t key) { + uint8_t key_buf[ESP_NOW_KEY_LEN]; + _get_bytes(key, ESP_NOW_KEY_LEN, key_buf); + ESPNOW_EXCEPTIONS(esp_now_set_kok(key_buf, ESP_NOW_KEY_LEN)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_pmk_obj, espnow_pmk); + +// lmk(peer_mac, local_key) +STATIC mp_obj_t espnow_lmk(mp_obj_t addr, mp_obj_t key) { + mp_uint_t addr_len; + u8 *addr_buf = (u8 *)mp_obj_str_get_data(addr, &addr_len); + if (addr_len != ESP_NOW_ETH_ALEN) mp_raise_ValueError("addr invalid"); + + if (key == mp_const_none) { + ESPNOW_EXCEPTIONS(esp_now_set_peer_key(addr_buf, NULL, 0)); + } else { + u8 key_buf[ESP_NOW_KEY_LEN]; + _get_bytes(key, ESP_NOW_KEY_LEN, key_buf); + ESPNOW_EXCEPTIONS(esp_now_set_peer_key(addr_buf, key_buf, ESP_NOW_KEY_LEN)); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espnow_lmk_obj, espnow_lmk); + +// add_peer(peer_mac, [local_key]) +STATIC mp_obj_t espnow_add_peer(size_t n_args, const mp_obj_t *args) { + u8 peer_addr[ESP_NOW_ETH_ALEN]; + _get_bytes(args[0], ESP_NOW_ETH_ALEN, peer_addr); + u8 *lmk_buf = NULL; + + if (n_args > 1) { + mp_uint_t lmk_len; + lmk_buf = (u8 *)mp_obj_str_get_data(args[1], &lmk_len);; + if (lmk_len != ESP_NOW_KEY_LEN) mp_raise_ValueError("key invalid"); + } + + uint8_t channel = 0; + + ESPNOW_EXCEPTIONS(esp_now_add_peer(peer_addr, ESP_NOW_ROLE_COMBO, channel, lmk_buf, ESP_NOW_KEY_LEN)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_add_peer_obj, 1, 2, espnow_add_peer); + +// del_peer(peer_mac) +STATIC mp_obj_t espnow_del_peer(mp_obj_t addr) { + mp_uint_t addr_len; + u8 *addr_buf = (u8 *)mp_obj_str_get_data(addr, &addr_len); + if (addr_len != ESP_NOW_ETH_ALEN) mp_raise_ValueError("addr invalid"); + ESP_NOW_PEER_EXIST(addr_buf); + ESPNOW_EXCEPTIONS(esp_now_del_peer(addr_buf)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_del_peer_obj, espnow_del_peer); + +STATIC mp_obj_t espnow_send(mp_obj_t addr, mp_obj_t msg) { + mp_uint_t addr_len; + u8 *addr_buf; + mp_uint_t msg_len; + u8 *msg_buf = (u8 *)mp_obj_str_get_data(msg, &msg_len); + if (msg_len > ESP_NOW_MAX_DATA_LEN) mp_raise_ValueError("msg too long"); + + if (addr == mp_const_none) { + // send to all + ESPNOW_EXCEPTIONS(esp_now_send(NULL, msg_buf, msg_len)); + } else { + // send to one + addr_buf = (u8 *)mp_obj_str_get_data(addr, &addr_len); + if (addr_len != ESP_NOW_ETH_ALEN) mp_raise_ValueError("addr invalid"); + ESPNOW_EXCEPTIONS(esp_now_send(addr_buf, msg_buf, msg_len)); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(espnow_send_obj, espnow_send); + +STATIC mp_obj_t espnow_peer_count() { + uint8_t all_cnt, encryp_cnt; + ESPNOW_EXCEPTIONS(esp_now_get_cnt_info(&all_cnt, &encryp_cnt)); + + mp_obj_t tuple[2] = { + mp_obj_new_int(all_cnt), + mp_obj_new_int(encryp_cnt), + }; + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(espnow_peer_count_obj, espnow_peer_count); + +STATIC ICACHE_FLASH_ATTR mp_obj_t espnow_version() { + return mp_obj_new_int(0); // 0 for esp8266, 1 for esp32 +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(espnow_version_obj, espnow_version); + +STATIC const mp_rom_map_elem_t espnow_globals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_espnow) }, + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&espnow_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espnow_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_pmk), MP_ROM_PTR(&espnow_pmk_obj) }, + { MP_ROM_QSTR(MP_QSTR_lmk), MP_ROM_PTR(&espnow_lmk_obj) }, + { MP_ROM_QSTR(MP_QSTR_add_peer), MP_ROM_PTR(&espnow_add_peer_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&espnow_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_on_send), MP_ROM_PTR(&espnow_on_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_on_recv), MP_ROM_PTR(&espnow_on_recv_obj) }, + { MP_ROM_QSTR(MP_QSTR_peer_count), MP_ROM_PTR(&espnow_peer_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_version), MP_ROM_PTR(&espnow_version_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(espnow_globals_dict, espnow_globals_dict_table); + +const mp_obj_module_t mp_module_esp_espnow = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&espnow_globals_dict, +}; diff --git a/ports/esp8266/modesp.c b/ports/esp8266/modesp.c index 4ea3435f99d7..a4f695820488 100644 --- a/ports/esp8266/modesp.c +++ b/ports/esp8266/modesp.c @@ -355,6 +355,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_set_native_code_location_obj, esp_set_nativ #endif +extern const mp_obj_module_t mp_module_esp_espnow; + STATIC const mp_rom_map_elem_t esp_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp) }, @@ -385,11 +387,13 @@ STATIC const mp_rom_map_elem_t esp_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_set_native_code_location), MP_ROM_PTR(&esp_set_native_code_location_obj) }, #endif -#if MODESP_INCLUDE_CONSTANTS + #if MODESP_INCLUDE_CONSTANTS { MP_ROM_QSTR(MP_QSTR_SLEEP_NONE), MP_ROM_INT(NONE_SLEEP_T) }, { MP_ROM_QSTR(MP_QSTR_SLEEP_LIGHT), MP_ROM_INT(LIGHT_SLEEP_T) }, { MP_ROM_QSTR(MP_QSTR_SLEEP_MODEM), MP_ROM_INT(MODEM_SLEEP_T) }, -#endif + #endif + + { MP_ROM_QSTR(MP_QSTR_espnow), MP_ROM_PTR(&mp_module_esp_espnow) }, }; STATIC MP_DEFINE_CONST_DICT(esp_module_globals, esp_module_globals_table); From 4e26efaf49b43969470a2b694c22376561e41455 Mon Sep 17 00:00:00 2001 From: shawwwn Date: Mon, 10 Sep 2018 00:53:02 -0700 Subject: [PATCH 11/12] move libespnow.a to irom --- ports/esp8266/esp8266_common.ld | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/esp8266/esp8266_common.ld b/ports/esp8266/esp8266_common.ld index f4b4207f27e3..3e3cd7618552 100644 --- a/ports/esp8266/esp8266_common.ld +++ b/ports/esp8266/esp8266_common.ld @@ -83,6 +83,7 @@ SECTIONS *libnet80211.a:(.literal.* .text.*) *libwpa.a:(.literal.* .text.*) *libwpa2.a:(.literal.* .text.*) + *libespnow.a:(.literal.* .text.*) /* we put some specific text in this section */ From 21e3426f7dec96c46d921fa16bb8e5db06572771 Mon Sep 17 00:00:00 2001 From: shawwwn Date: Mon, 10 Sep 2018 00:57:19 -0700 Subject: [PATCH 12/12] copyright info --- ports/esp32/esp_espnow.c | 1 + ports/esp8266/esp_espnow.c | 1 + 2 files changed, 2 insertions(+) diff --git a/ports/esp32/esp_espnow.c b/ports/esp32/esp_espnow.c index e976a9983d5b..00547894b4e2 100644 --- a/ports/esp32/esp_espnow.c +++ b/ports/esp32/esp_espnow.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2017 Nick Moore + * Copyright (c) 2018 shawwwn * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/esp8266/esp_espnow.c b/ports/esp8266/esp_espnow.c index 2660dfd7205d..8ef1991c92fd 100644 --- a/ports/esp8266/esp_espnow.c +++ b/ports/esp8266/esp_espnow.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2017 Nick Moore + * Copyright (c) 2018 shawwwn * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal