From 96ac53733578f8f790ef88d9217df0bf7403c8f2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 18:29:32 -0600 Subject: [PATCH 001/142] adding net_ppp --- src/nesper/esp/net/esp_netif_ppp.nim | 141 +++++++++++++++++++++++++ src/nesper/esp/net/esp_netif_types.nim | 2 +- 2 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 src/nesper/esp/net/esp_netif_ppp.nim diff --git a/src/nesper/esp/net/esp_netif_ppp.nim b/src/nesper/esp/net/esp_netif_ppp.nim new file mode 100644 index 00000000..2aecaef6 --- /dev/null +++ b/src/nesper/esp/net/esp_netif_ppp.nim @@ -0,0 +1,141 @@ +## +## SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD +## +## SPDX-License-Identifier: Apache-2.0 +## +## + +## @brief PPP event base +import ../../consts +import esp_netif_types + +type + + esp_netif_ppp_config_t* {.importc: "esp_netif_ppp_config_t", + header: "esp_netif_ppp.h", bycopy.} = object ## + ## @brief Configuration structure for PPP network interface + ## + ## + ppp_phase_event_enabled* {.importc: "ppp_phase_event_enabled".}: bool ## + ## < Enables events coming from PPP PHASE change + ppp_error_event_enabled* {.importc: "ppp_error_event_enabled".}: bool ## + ## < Enables events from main PPP state machine producing errors + when defined(CONFIG_LWIP_ENABLE_LCP_ECHO): + ppp_lcp_echo_disabled* {.importc: "ppp_lcp_echo_disabled".}: bool ## + ## #ifdef CONFIG_LWIP_ENABLE_LCP_ECHO + ## + when defined(CONFIG_LWIP_PPP_SERVER_SUPPORT): + ppp_our_ip4_addr* {.importc: "ppp_our_ip4_addr".}: esp_ip4_addr_t ## + ## #endif // CONFIG_LWIP_ENABLE_LCP_ECHO + ## #ifdef CONFIG_LWIP_PPP_SERVER_SUPPORT + ppp_their_ip4_addr* {.importc: "ppp_their_ip4_addr".}: esp_ip4_addr_t ## + ## < Set our preferred address, typically used when we're the PPP server + ppp_dns1_addr* {.importc: "ppp_dns1_addr".}: esp_ip4_addr_t ## + ## < DNS to provide if peer asks for it, typically used when we're the PPP server + ppp_dns2_addr* {.importc: "ppp_dns2_addr".}: esp_ip4_addr_t ## + ## < DNS to provide if peer asks for it, typically used when we're the PPP server + ppp_passive* {.importc: "ppp_passive".}: bool ## < Try once to initiate connection, stay silent if it fails, typically used when we're the PPP server + ## #endif // CONFIG_LWIP_PPP_SERVER_SUPPORT + +const + NETIF_PP_PHASE_OFFSET* = (0x100) ## @brief event id offset for PHASE related events + ## + ## All PPP related events are produced from esp-netif under `NETIF_PPP_STATUS`, this offset defines + ## helps distinguish between error and phase events + ## + NETIF_PPP_INTERNAL_ERR_OFFSET* = (0x200) ## @brief event id offset for internal errors + ## + ## + +type + + esp_netif_ppp_status_event_t* {.size: sizeof(cint).} = enum ## + ## @brief event ids for different PPP related events + ## + ## + NETIF_PPP_ERRORNONE = 0, ## No error. + NETIF_PPP_ERRORPARAM = 1, ## Invalid parameter. + NETIF_PPP_ERROROPEN = 2, ## Unable to open PPP session. + NETIF_PPP_ERRORDEVICE = 3, ## Invalid I/O device for PPP. + NETIF_PPP_ERRORALLOC = 4, ## Unable to allocate resources. + NETIF_PPP_ERRORUSER = 5, ## User interrupt. + NETIF_PPP_ERRORCONNECT = 6, ## Connection lost. + NETIF_PPP_ERRORAUTHFAIL = 7, ## Failed authentication challenge. + NETIF_PPP_ERRORPROTOCOL = 8, ## Failed to meet protocol. + NETIF_PPP_ERRORPEERDEAD = 9, ## Connection timeout + NETIF_PPP_ERRORIDLETIMEOUT = 10, ## Idle Timeout + NETIF_PPP_ERRORCONNECTTIME = 11, ## Max connect time reached + NETIF_PPP_ERRORLOOPBACK = 12, ## Loopback detected + + NETIF_PPP_PHASE_DEAD = NETIF_PP_PHASE_OFFSET + 0, + NETIF_PPP_PHASE_MASTER = NETIF_PP_PHASE_OFFSET + 1, + NETIF_PPP_PHASE_HOLDOFF = NETIF_PP_PHASE_OFFSET + 2, + NETIF_PPP_PHASE_INITIALIZE = NETIF_PP_PHASE_OFFSET + 3, + NETIF_PPP_PHASE_SERIALCONN = NETIF_PP_PHASE_OFFSET + 4, + NETIF_PPP_PHASE_DORMANT = NETIF_PP_PHASE_OFFSET + 5, + NETIF_PPP_PHASE_ESTABLISH = NETIF_PP_PHASE_OFFSET + 6, + NETIF_PPP_PHASE_AUTHENTICATE = NETIF_PP_PHASE_OFFSET + 7, + NETIF_PPP_PHASE_CALLBACK = NETIF_PP_PHASE_OFFSET + 8, + NETIF_PPP_PHASE_NETWORK = NETIF_PP_PHASE_OFFSET + 9, + NETIF_PPP_PHASE_RUNNING = NETIF_PP_PHASE_OFFSET + 10, + NETIF_PPP_PHASE_TERMINATE = NETIF_PP_PHASE_OFFSET + 11, + NETIF_PPP_PHASE_DISCONNECT = NETIF_PP_PHASE_OFFSET + 12, + + NETIF_PPP_CONNECT_FAILED = NETIF_PPP_INTERNAL_ERR_OFFSET + 0 + +type + + esp_netif_auth_type_t* {.size: sizeof(cint).} = enum ## + ## @brief definitions of different authorisation types + ## + ## + NETIF_PPP_AUTHTYPE_NONE = 0x00, + NETIF_PPP_AUTHTYPE_PAP = 0x01, + NETIF_PPP_AUTHTYPE_CHAP = 0x02, + NETIF_PPP_AUTHTYPE_MSCHAP = 0x04, + NETIF_PPP_AUTHTYPE_MSCHAP_V2 = 0x08, + NETIF_PPP_AUTHTYPE_EAP = 0x10 + + + +proc esp_netif_ppp_set_auth*(netif: ptr esp_netif_t; + authtype: esp_netif_auth_type_t; user: cstring; + passwd: cstring): esp_err_t {.cdecl, + importc: "esp_netif_ppp_set_auth", header: "esp_netif_ppp.h".} + ## + ## @brief Sets the auth parameters for the supplied esp-netif. + ## + ## @param[in] esp_netif Handle to esp-netif instance + ## @param[in] authtype Authorisation type + ## @param[in] user User name + ## @param[in] passwd Password + ## + ## @return ESP_OK on success, + ## ESP_ERR_ESP_NETIF_INVALID_PARAMS if the supplied netif is not of PPP type, or netif is null + ## + +proc esp_netif_ppp_set_params*(netif: ptr esp_netif_t; + config: ptr esp_netif_ppp_config_t): esp_err_t {. + cdecl, importc: "esp_netif_ppp_set_params", header: "esp_netif_ppp.h".} + ## + ## @brief Sets common parameters for the supplied esp-netif. + ## + ## @param[in] esp_netif Handle to esp-netif instance + ## @param[in] config Pointer to PPP netif configuration structure + ## + ## @return ESP_OK on success, + ## ESP_ERR_ESP_NETIF_INVALID_PARAMS if the supplied netif is not of PPP type, or netif is null + ## + +proc esp_netif_ppp_get_params*(netif: ptr esp_netif_t; + config: ptr esp_netif_ppp_config_t): esp_err_t {. + cdecl, importc: "esp_netif_ppp_get_params", header: "esp_netif_ppp.h".} + ## + ## @brief Gets parameters configured in the supplied esp-netif. + ## + ## @param[in] esp_netif Handle to esp-netif instance + ## @param[out] config Pointer to PPP netif configuration structure + ## + ## @return ESP_OK on success, + ## ESP_ERR_ESP_NETIF_INVALID_PARAMS if the supplied netif is not of PPP type, or netif is null + ## \ No newline at end of file diff --git a/src/nesper/esp/net/esp_netif_types.nim b/src/nesper/esp/net/esp_netif_types.nim index d945c3d5..68533617 100644 --- a/src/nesper/esp/net/esp_netif_types.nim +++ b/src/nesper/esp/net/esp_netif_types.nim @@ -33,7 +33,7 @@ const ## * @brief Type of esp_netif_object server const hdr = """#include - #include "esp_netif_types.h" """ + #include """ type esp_netif_t* {.importc: "esp_netif_t", header: hdr, bycopy.} = object From f50e62d271e1d8e634cfc8a71dfb136373c80781 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 18:56:24 -0600 Subject: [PATCH 002/142] adding net_ppp --- src/nesper/esp/net/esp_netif_net_stack.nim | 99 ++++++ src/nesper/esp/net/esp_netif_types.nim | 387 +++++++++++++-------- 2 files changed, 342 insertions(+), 144 deletions(-) create mode 100644 src/nesper/esp/net/esp_netif_net_stack.nim diff --git a/src/nesper/esp/net/esp_netif_net_stack.nim b/src/nesper/esp/net/esp_netif_net_stack.nim new file mode 100644 index 00000000..56f7e127 --- /dev/null +++ b/src/nesper/esp/net/esp_netif_net_stack.nim @@ -0,0 +1,99 @@ +## +## SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +## +## SPDX-License-Identifier: Apache-2.0 +## + +when defined(CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS): + type + esp_netif_recv_ret_t* = esp_err_t +else: + type + esp_netif_recv_ret_t* = void + +type + + init_fn_t* = proc (a1: ptr netif): err_t {.cdecl.} + + input_fn_t* = proc (netif: pointer; buffer: pointer; len: csize_t; eb: pointer): esp_netif_recv_ret_t {. + cdecl.} + + esp_netif_netstack_lwip_vanilla_config* {. + importc: "esp_netif_netstack_lwip_vanilla_config", + header: "esp_netif_net_stack.h", bycopy.} = object + init_fn* {.importc: "init_fn".}: init_fn_t + input_fn* {.importc: "input_fn".}: input_fn_t + + + esp_netif_netstack_lwip_ppp_config* {.importc: "esp_netif_netstack_lwip_ppp_config", + header: "esp_netif_net_stack.h", bycopy.} = object + input_fn* {.importc: "input_fn".}: input_fn_t + ppp_events* {.importc: "ppp_events".}: esp_netif_ppp_config_t + + + esp_netif_netstack_config* {.importc: "esp_netif_netstack_config", + header: "esp_netif_net_stack.h", bycopy.} = object ## + ## LWIP netif specific network stack configuration + lwip* {.importc: "lwip".}: esp_netif_netstack_lwip_vanilla_config + lwip_ppp* {.importc: "lwip_ppp".}: esp_netif_netstack_lwip_ppp_config + + + +proc ethernetif_init*(netif: ptr netif): err_t {.cdecl, + importc: "ethernetif_init", header: "esp_netif_net_stack.h".} + ## + ## + ## @brief LWIP's network stack init function for Ethernet + ## @param netif LWIP's network interface handle + ## @return ERR_OK on success + ## + +proc ethernetif_input*(h: pointer; buffer: pointer; len: csize_t; + l2_buff: pointer): esp_netif_recv_ret_t {.cdecl, + importc: "ethernetif_input", header: "esp_netif_net_stack.h".} + ## + ## + ## @brief LWIP's network stack input packet function for Ethernet + ## @param h LWIP's network interface handle + ## @param buffer Input buffer pointer + ## @param len Input buffer size + ## @param l2_buff External buffer pointer (to be passed to custom input-buffer free) + ## + +proc wlanif_init_ap*(netif: ptr netif): err_t {.cdecl, + importc: "wlanif_init_ap", header: "esp_netif_net_stack.h".} + ## + ## + ## @brief LWIP's network stack init function for WiFi (AP) + ## @param netif LWIP's network interface handle + ## @return ERR_OK on success + ## + +proc wlanif_init_sta*(netif: ptr netif): err_t {.cdecl, + importc: "wlanif_init_sta", header: "esp_netif_net_stack.h".} + ## + ## + ## @brief LWIP's network stack init function for WiFi (Station) + ## @param netif LWIP's network interface handle + ## @return ERR_OK on success + ## + +proc wlanif_init_nan*(netif: ptr netif): err_t {.cdecl, + importc: "wlanif_init_nan", header: "esp_netif_net_stack.h".} + ## + ## + ## @brief LWIP's network stack init function for WiFi Aware interface (NAN) + ## @param netif LWIP's network interface handle + ## @return ERR_OK on success + ## + +proc wlanif_input*(h: pointer; buffer: pointer; len: csize_t; l2_buff: pointer): esp_netif_recv_ret_t {. + cdecl, importc: "wlanif_input", header: "esp_netif_net_stack.h".} + ## + ## + ## @brief LWIP's network stack input packet function for WiFi (both STA/AP) + ## @param h LWIP's network interface handle + ## @param buffer Input buffer pointer + ## @param len Input buffer size + ## @param l2_buff External buffer pointer (to be passed to custom input-buffer free) + ## \ No newline at end of file diff --git a/src/nesper/esp/net/esp_netif_types.nim b/src/nesper/esp/net/esp_netif_types.nim index 68533617..89818c72 100644 --- a/src/nesper/esp/net/esp_netif_types.nim +++ b/src/nesper/esp/net/esp_netif_types.nim @@ -1,220 +1,319 @@ -## Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD ## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## http://www.apache.org/licenses/LICENSE-2.0 +## SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD ## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. - -## * -## @brief Definition of ESP-NETIF based errors +## SPDX-License-Identifier: Apache-2.0 ## import ../../consts + import esp_netif_ip_addr +const hdr = "esp_netif_types.h" + const - ESP_ERR_ESP_NETIF_BASE* = 0x00005000 - ESP_ERR_ESP_NETIF_INVALID_PARAMS* = ESP_ERR_ESP_NETIF_BASE + 0x00000001 - ESP_ERR_ESP_NETIF_IF_NOT_READY* = ESP_ERR_ESP_NETIF_BASE + 0x00000002 - ESP_ERR_ESP_NETIF_DHCPC_START_FAILED* = ESP_ERR_ESP_NETIF_BASE + 0x00000003 - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED* = ESP_ERR_ESP_NETIF_BASE + 0x00000004 - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED* = ESP_ERR_ESP_NETIF_BASE + 0x00000005 - ESP_ERR_ESP_NETIF_NO_MEM* = ESP_ERR_ESP_NETIF_BASE + 0x00000006 - ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED* = ESP_ERR_ESP_NETIF_BASE + 0x00000007 - ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED* = ESP_ERR_ESP_NETIF_BASE + 0x00000008 - ESP_ERR_ESP_NETIF_INIT_FAILED* = ESP_ERR_ESP_NETIF_BASE + 0x00000009 - ESP_ERR_ESP_NETIF_DNS_NOT_CONFIGURED* = ESP_ERR_ESP_NETIF_BASE + 0x0000000A - -## * @brief Type of esp_netif_object server -const hdr = """#include - #include """ + ESP_ERR_ESP_NETIF_BASE* = 0x5000 ## + ## @brief Definition of ESP-NETIF based errors + ## + ESP_ERR_ESP_NETIF_INVALID_PARAMS* = ESP_ERR_ESP_NETIF_BASE + 0x01 + ESP_ERR_ESP_NETIF_IF_NOT_READY* = ESP_ERR_ESP_NETIF_BASE + 0x02 + ESP_ERR_ESP_NETIF_DHCPC_START_FAILED* = ESP_ERR_ESP_NETIF_BASE + 0x03 + ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED* = ESP_ERR_ESP_NETIF_BASE + 0x04 + ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED* = ESP_ERR_ESP_NETIF_BASE + 0x05 + ESP_ERR_ESP_NETIF_NO_MEM* = ESP_ERR_ESP_NETIF_BASE + 0x06 + ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED* = ESP_ERR_ESP_NETIF_BASE + 0x07 + ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED* = ESP_ERR_ESP_NETIF_BASE + 0x08 + ESP_ERR_ESP_NETIF_INIT_FAILED* = ESP_ERR_ESP_NETIF_BASE + 0x09 + ESP_ERR_ESP_NETIF_DNS_NOT_CONFIGURED* = ESP_ERR_ESP_NETIF_BASE + 0x0A + ESP_ERR_ESP_NETIF_MLD6_FAILED* = ESP_ERR_ESP_NETIF_BASE + 0x0B + ESP_ERR_ESP_NETIF_IP6_ADDR_FAILED* = ESP_ERR_ESP_NETIF_BASE + 0x0C + ESP_ERR_ESP_NETIF_DHCPS_START_FAILED* = ESP_ERR_ESP_NETIF_BASE + 0x0D + ESP_ERR_ESP_NETIF_TX_FAILED* = ESP_ERR_ESP_NETIF_BASE + 0x0E + ESP_NETIF_BR_FLOOD* = -1 ## + ## @brief Definition of ESP-NETIF bridge control + ## + ESP_NETIF_BR_DROP* = 0 + ESP_NETIF_BR_FDW_CPU* = (1'u64 shl 63) + +## @brief Type of esp_netif_object server type - esp_netif_t* {.importc: "esp_netif_t", header: hdr, bycopy.} = object -## * @brief Type of DNS server + esp_netif_t* {.importc: "esp_netif_t", header: hdr, bycopy.} = object -type - esp_netif_dns_type_t* {.size: sizeof(cint).} = enum - ESP_NETIF_DNS_MAIN = 0, ## *< DNS main server address - ESP_NETIF_DNS_BACKUP, ## *< DNS backup server address (Wi-Fi STA and Ethernet only) - ESP_NETIF_DNS_FALLBACK, ## *< DNS fallback server address (Wi-Fi STA and Ethernet only) + esp_netif_dns_type_t* {.size: sizeof(cint).} = enum ## + ## @brief Type of DNS server + ESP_NETIF_DNS_MAIN = 0, ## < DNS main server address + ESP_NETIF_DNS_BACKUP, ## < DNS backup server address (Wi-Fi STA and Ethernet only) + ESP_NETIF_DNS_FALLBACK, ## < DNS fallback server address (Wi-Fi STA and Ethernet only) ESP_NETIF_DNS_MAX -## * @brief DNS server info - type - esp_netif_dns_info_t* {.importc: "esp_netif_dns_info_t", - header: hdr, bycopy.} = object - ip* {.importc: "ip".}: esp_ip_addr_t ## *< IPV4 address of DNS server + esp_netif_dns_info_t* {.importc: "esp_netif_dns_info_t", + header: hdr, bycopy.} = object ## + ## @brief DNS server info + ip* {.importc: "ip".}: esp_ip_addr_t + ## < IPV4 address of DNS server -## * @brief Status of DHCP client or DHCP server -type - esp_netif_dhcp_status_t* {.size: sizeof(cint).} = enum - ESP_NETIF_DHCP_INIT = 0, ## *< DHCP client/server is in initial state (not yet started) - ESP_NETIF_DHCP_STARTED, ## *< DHCP client/server has been started - ESP_NETIF_DHCP_STOPPED, ## *< DHCP client/server has been stopped + esp_netif_dhcp_status_t* {.size: sizeof(cint).} = enum ## + ## @brief Status of DHCP client or DHCP server + ESP_NETIF_DHCP_INIT = 0, ## < DHCP client/server is in initial state (not yet started) + ESP_NETIF_DHCP_STARTED, ## < DHCP client/server has been started + ESP_NETIF_DHCP_STOPPED, ## < DHCP client/server has been stopped ESP_NETIF_DHCP_STATUS_MAX -## * @brief Mode for DHCP client or DHCP server option functions - type - esp_netif_dhcp_option_mode_t* {.size: sizeof(cint).} = enum - ESP_NETIF_OP_START = 0, ESP_NETIF_OP_SET, ## *< Set option - ESP_NETIF_OP_GET, ## *< Get option - ESP_NETIF_OP_MAX + esp_netif_dhcp_option_mode_t* {.size: sizeof(cint).} = enum ## + ## @brief Mode for DHCP client or DHCP server option functions + ESP_NETIF_OP_START = 0, ESP_NETIF_OP_SET, ## < Set option + ESP_NETIF_OP_GET, ## < Get option + ESP_NETIF_OP_MAX -## * @brief Supported options for DHCP client or DHCP server type - esp_netif_dhcp_option_id_t* {.size: sizeof(cint).} = enum - ESP_NETIF_DOMAIN_NAME_SERVER = 6, ## *< Domain name server - ESP_NETIF_ROUTER_SOLICITATION_ADDRESS = 32, ## *< Solicitation router address - ESP_NETIF_REQUESTED_IP_ADDRESS = 50, ## *< Request specific IP address - ESP_NETIF_IP_ADDRESS_LEASE_TIME = 51, ## *< Request IP address lease time - ESP_NETIF_IP_REQUEST_RETRY_TIME = 52 ## *< Request IP address retry counter + esp_netif_dhcp_option_id_t* {.size: sizeof(cint).} = enum ## + ## @brief Supported options for DHCP client or DHCP server + ESP_NETIF_SUBNET_MASK = 1, ## < Network mask + ESP_NETIF_DOMAIN_NAME_SERVER = 6, ## < Domain name server + ESP_NETIF_ROUTER_SOLICITATION_ADDRESS = 32, ## < Solicitation router address + ESP_NETIF_VENDOR_SPECIFIC_INFO = 43, ## < Vendor Specific Information of a DHCP server + ESP_NETIF_REQUESTED_IP_ADDRESS = 50, ## < Request specific IP address + ESP_NETIF_IP_ADDRESS_LEASE_TIME = 51, ## < Request IP address lease time + ESP_NETIF_IP_REQUEST_RETRY_TIME = 52, ## < Request IP address retry counter + ESP_NETIF_VENDOR_CLASS_IDENTIFIER = 60, ## < Vendor Class Identifier of a DHCP client + ESP_NETIF_CAPTIVEPORTAL_URI = 114 ## < Captive Portal Identification -## * IP event declarations type - ip_event_t* {.size: sizeof(cint).} = enum - IP_EVENT_STA_GOT_IP, ## !< station got IP from connected AP - IP_EVENT_STA_LOST_IP, ## !< station lost IP and the IP is reset to 0 + + ip_event_t* {.size: sizeof(cint).} = enum ## IP event declarations + IP_EVENT_STA_GOT_IP, ## !< station got IP from connected AP + IP_EVENT_STA_LOST_IP, ## !< station lost IP and the IP is reset to 0 IP_EVENT_AP_STAIPASSIGNED, ## !< soft-AP assign an IP to a connected station - IP_EVENT_GOT_IP6, ## !< station or ap or ethernet interface v6IP addr is preferred - IP_EVENT_ETH_GOT_IP, ## !< ethernet got IP from connected AP - IP_EVENT_PPP_GOT_IP, ## !< PPP interface got IP - IP_EVENT_PPP_LOST_IP ## !< PPP interface lost IP + IP_EVENT_GOT_IP6, ## !< station or ap or ethernet interface v6IP addr is preferred + IP_EVENT_ETH_GOT_IP, ## !< ethernet got IP from connected AP + IP_EVENT_ETH_LOST_IP, ## !< ethernet lost IP and the IP is reset to 0 + IP_EVENT_PPP_GOT_IP, ## !< PPP interface got IP + IP_EVENT_PPP_LOST_IP, ## !< PPP interface lost IP + IP_EVENT_TX_RX ## !< transmitting/receiving data packet -## * @brief IP event base declaration +## @brief IP event base declaration # ESP_EVENT_DECLARE_BASE(IP_EVENT) -var IP_EVENT* {.importc: "$1", header: hdr.}: esp_event_base_t - -## * Event structure for IP_EVENT_STA_GOT_IP, IP_EVENT_ETH_GOT_IP events type - esp_netif_ip_info_t* {.importc: "esp_netif_ip_info_t", - header: hdr, bycopy.} = object - ip* {.importc: "ip".}: esp_ip4_addr_t ## *< Interface IPV4 address - netmask* {.importc: "netmask".}: esp_ip4_addr_t ## *< Interface IPV4 netmask - gw* {.importc: "gw".}: esp_ip4_addr_t ## *< Interface IPV4 gateway address + esp_netif_ip_info_t* {.importc: "esp_netif_ip_info_t", + header: hdr, bycopy.} = object ## + ## Event structure for IP_EVENT_STA_GOT_IP, IP_EVENT_ETH_GOT_IP events + ip* {.importc: "ip".}: esp_ip4_addr_t ## < Interface IPV4 address + netmask* {.importc: "netmask".}: esp_ip4_addr_t ## + ## < Interface IPV4 netmask + gw* {.importc: "gw".}: esp_ip4_addr_t + ## < Interface IPV4 gateway address -## * @brief IPV6 IP address information -## -type esp_netif_ip6_info_t* {.importc: "esp_netif_ip6_info_t", - header: hdr, bycopy.} = object - ip* {.importc: "ip".}: esp_ip6_addr_t ## *< Interface IPV6 address + header: hdr, bycopy.} = object ## + ## @brief IPV6 IP address information + ## + ip* {.importc: "ip".}: esp_ip6_addr_t + ## < Interface IPV6 address + + + ip_event_got_ip_t* {.importc: "ip_event_got_ip_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Event structure for IP_EVENT_GOT_IP event + ## + ## + esp_netif* {.importc: "esp_netif".}: ptr esp_netif_t ## + ## !< Pointer to corresponding esp-netif object + ip_info* {.importc: "ip_info".}: esp_netif_ip_info_t ## + ## !< IP address, netmask, gateway IP address + ip_changed* {.importc: "ip_changed".}: bool + ## !< Whether the assigned IP has changed or not + + + ip_event_got_ip6_t* {.importc: "ip_event_got_ip6_t", + header: hdr, bycopy.} = object ## + ## Event structure for IP_EVENT_GOT_IP6 event + esp_netif* {.importc: "esp_netif".}: ptr esp_netif_t ## + ## !< Pointer to corresponding esp-netif object + ip6_info* {.importc: "ip6_info".}: esp_netif_ip6_info_t ## + ## !< IPv6 address of the interface + ip_index* {.importc: "ip_index".}: cint + ## !< IPv6 address index + + + ip_event_add_ip6_t* {.importc: "ip_event_add_ip6_t", + header: hdr, bycopy.} = object ## + ## Event structure for ADD_IP6 event + `addr`* {.importc: "addr".}: esp_ip6_addr_t ## !< The address to be added to the interface + preferred* {.importc: "preferred".}: bool + ## !< The default preference of the address - ip_event_got_ip_t* {.importc: "ip_event_got_ip_t", header: hdr, - bycopy.} = object - if_index* {.importc: "if_index".}: cint ## !< Interface index for which the event is received (left for legacy compilation) - esp_netif* {.importc: "esp_netif".}: ptr esp_netif_t ## !< Pointer to corresponding esp-netif object - ip_info* {.importc: "ip_info".}: esp_netif_ip_info_t ## !< IP address, netmask, gatway IP address - ip_changed* {.importc: "ip_changed".}: bool ## !< Whether the assigned IP has changed or not + ip_event_ap_staipassigned_t* {.importc: "ip_event_ap_staipassigned_t", + header: hdr, bycopy.} = object ## + ## Event structure for IP_EVENT_AP_STAIPASSIGNED event + esp_netif* {.importc: "esp_netif".}: ptr esp_netif_t ## + ## !< Pointer to the associated netif handle + ip* {.importc: "ip".}: esp_ip4_addr_t ## !< IP address which was assigned to the station + mac* {.importc: "mac".}: array[6, uint8] + ## !< MAC address of the connected client -## * Event structure for IP_EVENT_GOT_IP6 event -type - ip_event_got_ip6_t* {.importc: "ip_event_got_ip6_t", header: hdr, - bycopy.} = object - if_index* {.importc: "if_index".}: cint ## !< Interface index for which the event is received (left for legacy compilation) - esp_netif* {.importc: "esp_netif".}: ptr esp_netif_t ## !< Pointer to corresponding esp-netif object - ip6_info* {.importc: "ip6_info".}: esp_netif_ip6_info_t ## !< IPv6 address of the interface + esp_netif_tx_rx_direction_t* {.size: sizeof(cint).} = enum + ESP_NETIF_TX = 0, ## Data is being transmitted. + ESP_NETIF_RX = 1 ## Data is being received. -## * Event structure for IP_EVENT_AP_STAIPASSIGNED event +when defined(CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC): + ## Event structure for IP_EVENT_TRANSMIT and IP_EVENT_RECEIVE + type + + ip_event_tx_rx_t* {.importc: "ip_event_tx_rx_t", + header: hdr, bycopy.} = object + esp_netif* {.importc: "esp_netif".}: ptr esp_netif_t ## + ## !< Pointer to the associated netif handle + len* {.importc: "len".}: csize_t ## !< Length of the data + dir* {.importc: "dir".}: esp_netif_tx_rx_direction_t + ## !< Directions for data transfer > type - ip_event_ap_staipassigned_t* {.importc: "ip_event_ap_staipassigned_t", - header: hdr, bycopy.} = object - ip* {.importc: "ip".}: esp_ip4_addr_t ## !< IP address which was assigned to the station esp_netif_flags_t* {.size: sizeof(cint).} = enum ESP_NETIF_DHCP_CLIENT = 1 shl 0, ESP_NETIF_DHCP_SERVER = 1 shl 1, ESP_NETIF_FLAG_AUTOUP = 1 shl 2, ESP_NETIF_FLAG_GARP = 1 shl 3, - ESP_NETIF_FLAG_EVENT_IP_MODIFIED = 1 shl 4, ESP_NETIF_FLAG_IS_PPP = 1 shl 5 + ESP_NETIF_FLAG_EVENT_IP_MODIFIED = 1 shl 4, ESP_NETIF_FLAG_IS_PPP = 1 shl 5, + ESP_NETIF_FLAG_IS_BRIDGE = 1 shl 6, ESP_NETIF_FLAG_MLDV6_REPORT = 1 shl 7, + ESP_NETIF_FLAG_IPV6_AUTOCONFIG_ENABLED = 1 shl 8 + esp_netif_ip_event_type_t* {.size: sizeof(cint).} = enum ESP_NETIF_IP_EVENT_GOT_IP = 1, ESP_NETIF_IP_EVENT_LOST_IP = 2 +type + + bridgeif_config_t* {.importc: "bridgeif_config_t", + header: hdr, bycopy.} = object ## + ## LwIP bridge configuration + max_fdb_dyn_entries* {.importc: "max_fdb_dyn_entries".}: uint16 ## + ## !< maximum number of entries in dynamic forwarding database + max_fdb_sta_entries* {.importc: "max_fdb_sta_entries".}: uint16 ## + ## !< maximum number of entries in static forwarding database + max_ports* {.importc: "max_ports".}: uint8 + ## !< maximum number of ports the bridge can consist of -## -## ESP-NETIF interface configuration: -## 1) general (behavioral) config (esp_netif_config_t) -## 2) (peripheral) driver specific config (esp_netif_driver_ifconfig_t) -## 3) network stack specific config (esp_netif_net_stack_ifconfig_t) -- no publicly available -## -type esp_netif_inherent_config_t* {.importc: "esp_netif_inherent_config_t", - header: hdr, bycopy.} = object - flags* {.importc: "flags".}: esp_netif_flags_t ## !< flags that define esp-netif behavior + header: hdr, bycopy.} = object ## + ## + ## ESP-NETIF interface configuration: + ## 1) general (behavioral) config (esp_netif_config_t) + ## 2) (peripheral) driver specific config (esp_netif_driver_ifconfig_t) + ## 3) network stack specific config (esp_netif_net_stack_ifconfig_t) -- no publicly available + ## + ## + ## @brief ESP-netif inherent config parameters + ## + ## + flags* {.importc: "flags".}: esp_netif_flags_t ## + ## !< flags that define esp-netif behavior mac* {.importc: "mac".}: array[6, uint8] ## !< initial mac address for this interface - ip_info* {.importc: "ip_info".}: ptr esp_netif_ip_info_t ## !< initial ip address for this interface - get_ip_event* {.importc: "get_ip_event".}: uint32 ## !< event id to be raised when interface gets an IP - lost_ip_event* {.importc: "lost_ip_event".}: uint32 ## !< event id to be raised when interface losts its IP + ip_info* {.importc: "ip_info".}: ptr esp_netif_ip_info_t ## + ## !< initial ip address for this interface + get_ip_event* {.importc: "get_ip_event".}: uint32 ## + ## !< event id to be raised when interface gets an IP + lost_ip_event* {.importc: "lost_ip_event".}: uint32 ## + ## !< event id to be raised when interface losts its IP if_key* {.importc: "if_key".}: cstring ## !< string identifier of the interface if_desc* {.importc: "if_desc".}: cstring ## !< textual description of the interface route_prio* {.importc: "route_prio".}: cint ## !< numeric priority of this interface to become a default - ## routing if (if other netifs are up) + ## routing if (if other netifs are up). + ## A higher value of route_prio indicates + ## a higher priority + bridge_info* {.importc: "bridge_info".}: ptr bridgeif_config_t + ## !< LwIP bridge configuration + + + esp_netif_config_t* = esp_netif_config - ## @brief IO driver handle type - esp_netif_iodriver_handle* = pointer + esp_netif_iodriver_handle* = pointer ## + ## @brief IO driver handle type + ## esp_netif_driver_base_t* {.importc: "esp_netif_driver_base_t", - header: hdr, bycopy.} = object + header: hdr, bycopy.} = object ## + ## + ## @brief ESP-netif driver base handle + ## + ## post_attach* {.importc: "post_attach".}: proc (netif: ptr esp_netif_t; - h: esp_netif_iodriver_handle): esp_err_t + h: esp_netif_iodriver_handle): esp_err_t {.cdecl.} ## + ## !< post attach function pointer netif* {.importc: "netif".}: ptr esp_netif_t - - ## @brief Specific IO driver configuration - esp_netif_driver_ifconfig_t* {.importc: "esp_netif_driver_ifconfig_t", - header: hdr, bycopy.} = object - handle* {.importc: "handle".}: esp_netif_iodriver_handle - transmit* {.importc: "transmit".}: proc (h: pointer; buffer: pointer; len: csize_t): esp_err_t - driver_free_rx_buffer* {.importc: "driver_free_rx_buffer".}: proc (h: pointer; - buffer: pointer) - - esp_netif_netstack_lwip_vanilla_config* {.bycopy.} = object - init_fn*: proc (a1: pointer): esp_err_t - input_fn*: proc (netif: pointer; buffer: pointer; len: csize_t; eb: pointer) - - esp_netif_netstack_config_t* {.importc: "$1", header: hdr, bycopy.} = object - lwip: esp_netif_netstack_lwip_vanilla_config - - ## @brief Generic esp_netif configuration - esp_netif_config_t* {.importc: "esp_netif_config_t", header: hdr, - bycopy.} = object - base* {.importc: "base".}: ptr esp_netif_inherent_config_t - driver* {.importc: "driver".}: ptr esp_netif_driver_ifconfig_t + ## !< netif handle + + + esp_netif_driver_ifconfig* {.importc: "esp_netif_driver_ifconfig", + header: hdr, bycopy.} = object ## + ## + ## @brief Specific IO driver configuration + ## + handle* {.importc: "handle".}: esp_netif_iodriver_handle ## + ## !< io-driver handle + transmit* {.importc: "transmit".}: proc (h: pointer; buffer: pointer; + len: csize_t): esp_err_t {.cdecl.} ## !< transmit function pointer + transmit_wrap* {.importc: "transmit_wrap".}: proc (h: pointer; + buffer: pointer; len: csize_t; netstack_buffer: pointer): esp_err_t {. + cdecl.} ## !< transmit wrap function pointer + driver_free_rx_buffer* {.importc: "driver_free_rx_buffer".}: proc ( + h: pointer; buffer: pointer) {.cdecl.} ## !< free rx buffer function pointer + driver_set_mac_filter* {.importc: "driver_set_mac_filter".}: proc ( + h: pointer; mac: ptr uint8; mac_len: csize_t; add: bool): esp_err_t {. + cdecl.} + ## !< set mac filter function pointer + + + esp_netif_driver_ifconfig_t* = esp_netif_driver_ifconfig + + esp_netif_netstack_config_t* = esp_netif_netstack_config ## + ## + ## @brief Specific L3 network stack configuration + ## + + esp_netif_config* {.importc: "esp_netif_config", header: hdr, + bycopy.} = object ## + ## @brief Generic esp_netif configuration + ## + base* {.importc: "base".}: ptr esp_netif_inherent_config_t ## + ## !< base config + driver* {.importc: "driver".}: ptr esp_netif_driver_ifconfig_t ## + ## !< driver config stack* {.importc: "stack".}: ptr esp_netif_netstack_config_t + ## !< stack config + esp_netif_pair_mac_ip_t* {.importc: "esp_netif_pair_mac_ip_t", + header: hdr, bycopy.} = object ## + ## + ## @brief DHCP client's addr info (pair of MAC and IP address) + ## + mac* {.importc: "mac".}: array[6, uint8] ## < Clients MAC address + ip* {.importc: "ip".}: esp_ip4_addr_t + ## < Clients IP address - ## @brief Specific L3 network stack configuration - # esp_netif_config_t* = esp_netif_config - - -type - ## @brief ESP-NETIF Receive function type esp_netif_receive_t* = proc (esp_netif: ptr esp_netif_t; buffer: pointer; - len: csize_t; eb: pointer): esp_err_t + len: csize_t; eb: pointer): esp_err_t {.cdecl.} ## + ## + ## @brief ESP-NETIF Receive function type + ## From 36616c360e9d70297baf0cb200a3698c07f4d594 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 19:02:39 -0600 Subject: [PATCH 003/142] adding net_ppp --- src/nesper/esp/net/esp_netif_net_stack.nim | 23 +++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/nesper/esp/net/esp_netif_net_stack.nim b/src/nesper/esp/net/esp_netif_net_stack.nim index 56f7e127..ef551212 100644 --- a/src/nesper/esp/net/esp_netif_net_stack.nim +++ b/src/nesper/esp/net/esp_netif_net_stack.nim @@ -4,6 +4,8 @@ ## SPDX-License-Identifier: Apache-2.0 ## +const hdr = "lwip/esp_netif_net_stack.h" + when defined(CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS): type esp_netif_recv_ret_t* = esp_err_t @@ -13,6 +15,9 @@ else: type + err_t* = distinct int8 + net_if* {.importc: "netif", header: hdr, bycopy.} = object + init_fn_t* = proc (a1: ptr netif): err_t {.cdecl.} input_fn_t* = proc (netif: pointer; buffer: pointer; len: csize_t; eb: pointer): esp_netif_recv_ret_t {. @@ -20,19 +25,19 @@ type esp_netif_netstack_lwip_vanilla_config* {. importc: "esp_netif_netstack_lwip_vanilla_config", - header: "esp_netif_net_stack.h", bycopy.} = object + header: hdr, bycopy.} = object init_fn* {.importc: "init_fn".}: init_fn_t input_fn* {.importc: "input_fn".}: input_fn_t esp_netif_netstack_lwip_ppp_config* {.importc: "esp_netif_netstack_lwip_ppp_config", - header: "esp_netif_net_stack.h", bycopy.} = object + header: hdr, bycopy.} = object input_fn* {.importc: "input_fn".}: input_fn_t ppp_events* {.importc: "ppp_events".}: esp_netif_ppp_config_t esp_netif_netstack_config* {.importc: "esp_netif_netstack_config", - header: "esp_netif_net_stack.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## LWIP netif specific network stack configuration lwip* {.importc: "lwip".}: esp_netif_netstack_lwip_vanilla_config lwip_ppp* {.importc: "lwip_ppp".}: esp_netif_netstack_lwip_ppp_config @@ -40,7 +45,7 @@ type proc ethernetif_init*(netif: ptr netif): err_t {.cdecl, - importc: "ethernetif_init", header: "esp_netif_net_stack.h".} + importc: "ethernetif_init", header: hdr.} ## ## ## @brief LWIP's network stack init function for Ethernet @@ -50,7 +55,7 @@ proc ethernetif_init*(netif: ptr netif): err_t {.cdecl, proc ethernetif_input*(h: pointer; buffer: pointer; len: csize_t; l2_buff: pointer): esp_netif_recv_ret_t {.cdecl, - importc: "ethernetif_input", header: "esp_netif_net_stack.h".} + importc: "ethernetif_input", header: hdr.} ## ## ## @brief LWIP's network stack input packet function for Ethernet @@ -61,7 +66,7 @@ proc ethernetif_input*(h: pointer; buffer: pointer; len: csize_t; ## proc wlanif_init_ap*(netif: ptr netif): err_t {.cdecl, - importc: "wlanif_init_ap", header: "esp_netif_net_stack.h".} + importc: "wlanif_init_ap", header: hdr.} ## ## ## @brief LWIP's network stack init function for WiFi (AP) @@ -70,7 +75,7 @@ proc wlanif_init_ap*(netif: ptr netif): err_t {.cdecl, ## proc wlanif_init_sta*(netif: ptr netif): err_t {.cdecl, - importc: "wlanif_init_sta", header: "esp_netif_net_stack.h".} + importc: "wlanif_init_sta", header: hdr.} ## ## ## @brief LWIP's network stack init function for WiFi (Station) @@ -79,7 +84,7 @@ proc wlanif_init_sta*(netif: ptr netif): err_t {.cdecl, ## proc wlanif_init_nan*(netif: ptr netif): err_t {.cdecl, - importc: "wlanif_init_nan", header: "esp_netif_net_stack.h".} + importc: "wlanif_init_nan", header: hdr.} ## ## ## @brief LWIP's network stack init function for WiFi Aware interface (NAN) @@ -88,7 +93,7 @@ proc wlanif_init_nan*(netif: ptr netif): err_t {.cdecl, ## proc wlanif_input*(h: pointer; buffer: pointer; len: csize_t; l2_buff: pointer): esp_netif_recv_ret_t {. - cdecl, importc: "wlanif_input", header: "esp_netif_net_stack.h".} + cdecl, importc: "wlanif_input", header: hdr.} ## ## ## @brief LWIP's network stack input packet function for WiFi (both STA/AP) From 62d17a32b4c5139e520a28c1cb3d186457f9fab3 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 19:08:43 -0600 Subject: [PATCH 004/142] adding net_ppp --- src/nesper/esp/net/esp_netif_net_stack.nim | 42 ++------------- src/nesper/esp/net/esp_netif_ppp.nim | 34 ++---------- src/nesper/esp/net/esp_netif_types.nim | 60 ++++++++++++++++++++++ 3 files changed, 67 insertions(+), 69 deletions(-) diff --git a/src/nesper/esp/net/esp_netif_net_stack.nim b/src/nesper/esp/net/esp_netif_net_stack.nim index ef551212..415a6f9c 100644 --- a/src/nesper/esp/net/esp_netif_net_stack.nim +++ b/src/nesper/esp/net/esp_netif_net_stack.nim @@ -4,48 +4,12 @@ ## SPDX-License-Identifier: Apache-2.0 ## -const hdr = "lwip/esp_netif_net_stack.h" - -when defined(CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS): - type - esp_netif_recv_ret_t* = esp_err_t -else: - type - esp_netif_recv_ret_t* = void - -type - - err_t* = distinct int8 - net_if* {.importc: "netif", header: hdr, bycopy.} = object - - init_fn_t* = proc (a1: ptr netif): err_t {.cdecl.} - - input_fn_t* = proc (netif: pointer; buffer: pointer; len: csize_t; eb: pointer): esp_netif_recv_ret_t {. - cdecl.} - - esp_netif_netstack_lwip_vanilla_config* {. - importc: "esp_netif_netstack_lwip_vanilla_config", - header: hdr, bycopy.} = object - init_fn* {.importc: "init_fn".}: init_fn_t - input_fn* {.importc: "input_fn".}: input_fn_t - - - esp_netif_netstack_lwip_ppp_config* {.importc: "esp_netif_netstack_lwip_ppp_config", - header: hdr, bycopy.} = object - input_fn* {.importc: "input_fn".}: input_fn_t - ppp_events* {.importc: "ppp_events".}: esp_netif_ppp_config_t - - - esp_netif_netstack_config* {.importc: "esp_netif_netstack_config", - header: hdr, bycopy.} = object ## - ## LWIP netif specific network stack configuration - lwip* {.importc: "lwip".}: esp_netif_netstack_lwip_vanilla_config - lwip_ppp* {.importc: "lwip_ppp".}: esp_netif_netstack_lwip_ppp_config - +const hdr = "esp_netif_net_stack.h" +import esp_netif_types proc ethernetif_init*(netif: ptr netif): err_t {.cdecl, - importc: "ethernetif_init", header: hdr.} + importc, header: hdr.} ## ## ## @brief LWIP's network stack init function for Ethernet diff --git a/src/nesper/esp/net/esp_netif_ppp.nim b/src/nesper/esp/net/esp_netif_ppp.nim index 2aecaef6..3c18648c 100644 --- a/src/nesper/esp/net/esp_netif_ppp.nim +++ b/src/nesper/esp/net/esp_netif_ppp.nim @@ -9,33 +9,7 @@ import ../../consts import esp_netif_types -type - - esp_netif_ppp_config_t* {.importc: "esp_netif_ppp_config_t", - header: "esp_netif_ppp.h", bycopy.} = object ## - ## @brief Configuration structure for PPP network interface - ## - ## - ppp_phase_event_enabled* {.importc: "ppp_phase_event_enabled".}: bool ## - ## < Enables events coming from PPP PHASE change - ppp_error_event_enabled* {.importc: "ppp_error_event_enabled".}: bool ## - ## < Enables events from main PPP state machine producing errors - when defined(CONFIG_LWIP_ENABLE_LCP_ECHO): - ppp_lcp_echo_disabled* {.importc: "ppp_lcp_echo_disabled".}: bool ## - ## #ifdef CONFIG_LWIP_ENABLE_LCP_ECHO - ## - when defined(CONFIG_LWIP_PPP_SERVER_SUPPORT): - ppp_our_ip4_addr* {.importc: "ppp_our_ip4_addr".}: esp_ip4_addr_t ## - ## #endif // CONFIG_LWIP_ENABLE_LCP_ECHO - ## #ifdef CONFIG_LWIP_PPP_SERVER_SUPPORT - ppp_their_ip4_addr* {.importc: "ppp_their_ip4_addr".}: esp_ip4_addr_t ## - ## < Set our preferred address, typically used when we're the PPP server - ppp_dns1_addr* {.importc: "ppp_dns1_addr".}: esp_ip4_addr_t ## - ## < DNS to provide if peer asks for it, typically used when we're the PPP server - ppp_dns2_addr* {.importc: "ppp_dns2_addr".}: esp_ip4_addr_t ## - ## < DNS to provide if peer asks for it, typically used when we're the PPP server - ppp_passive* {.importc: "ppp_passive".}: bool ## < Try once to initiate connection, stay silent if it fails, typically used when we're the PPP server - ## #endif // CONFIG_LWIP_PPP_SERVER_SUPPORT +const hdr = "esp_netif_ppp.h" const NETIF_PP_PHASE_OFFSET* = (0x100) ## @brief event id offset for PHASE related events @@ -101,7 +75,7 @@ type proc esp_netif_ppp_set_auth*(netif: ptr esp_netif_t; authtype: esp_netif_auth_type_t; user: cstring; passwd: cstring): esp_err_t {.cdecl, - importc: "esp_netif_ppp_set_auth", header: "esp_netif_ppp.h".} + importc: "esp_netif_ppp_set_auth", header: hdr.} ## ## @brief Sets the auth parameters for the supplied esp-netif. ## @@ -116,7 +90,7 @@ proc esp_netif_ppp_set_auth*(netif: ptr esp_netif_t; proc esp_netif_ppp_set_params*(netif: ptr esp_netif_t; config: ptr esp_netif_ppp_config_t): esp_err_t {. - cdecl, importc: "esp_netif_ppp_set_params", header: "esp_netif_ppp.h".} + cdecl, importc: "esp_netif_ppp_set_params", header: hdr.} ## ## @brief Sets common parameters for the supplied esp-netif. ## @@ -129,7 +103,7 @@ proc esp_netif_ppp_set_params*(netif: ptr esp_netif_t; proc esp_netif_ppp_get_params*(netif: ptr esp_netif_t; config: ptr esp_netif_ppp_config_t): esp_err_t {. - cdecl, importc: "esp_netif_ppp_get_params", header: "esp_netif_ppp.h".} + cdecl, importc: "esp_netif_ppp_get_params", header: hdr.} ## ## @brief Gets parameters configured in the supplied esp-netif. ## diff --git a/src/nesper/esp/net/esp_netif_types.nim b/src/nesper/esp/net/esp_netif_types.nim index 89818c72..9f2211c4 100644 --- a/src/nesper/esp/net/esp_netif_types.nim +++ b/src/nesper/esp/net/esp_netif_types.nim @@ -199,9 +199,69 @@ type esp_netif_ip_event_type_t* {.size: sizeof(cint).} = enum ESP_NETIF_IP_EVENT_GOT_IP = 1, ESP_NETIF_IP_EVENT_LOST_IP = 2 +when defined(CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS): + type + esp_netif_recv_ret_t* = esp_err_t +else: + type + esp_netif_recv_ret_t* = void + type + err_t* = distinct int8 + net_if* {.importc: "netif", header: hdr, bycopy.} = object + + init_fn_t* = proc (a1: ptr netif): err_t {.cdecl.} + + input_fn_t* = proc (netif: pointer; buffer: pointer; len: csize_t; eb: pointer): esp_netif_recv_ret_t {. + cdecl.} + + esp_netif_netstack_lwip_vanilla_config* {. + importc: "esp_netif_netstack_lwip_vanilla_config", + header: "esp_netif_net_stack.h", bycopy.} = object + init_fn* {.importc: "init_fn".}: init_fn_t + input_fn* {.importc: "input_fn".}: input_fn_t + + + esp_netif_netstack_lwip_ppp_config* {.importc: "esp_netif_netstack_lwip_ppp_config", + header: "esp_netif_net_stack.h", bycopy.} = object + input_fn* {.importc: "input_fn".}: input_fn_t + ppp_events* {.importc: "ppp_events".}: esp_netif_ppp_config_t + + + esp_netif_netstack_config* {.importc: "esp_netif_netstack_config", + header: "esp_netif_net_stack.h", bycopy.} = object ## + ## LWIP netif specific network stack configuration + lwip* {.importc: "lwip".}: esp_netif_netstack_lwip_vanilla_config + lwip_ppp* {.importc: "lwip_ppp".}: esp_netif_netstack_lwip_ppp_config + + esp_netif_ppp_config_t* {.importc: "esp_netif_ppp_config_t", + header: "esp_netif_ppp.h", bycopy.} = object ## + ## @brief Configuration structure for PPP network interface + ## + ## + ppp_phase_event_enabled* {.importc: "ppp_phase_event_enabled".}: bool ## + ## < Enables events coming from PPP PHASE change + ppp_error_event_enabled* {.importc: "ppp_error_event_enabled".}: bool ## + ## < Enables events from main PPP state machine producing errors + when defined(CONFIG_LWIP_ENABLE_LCP_ECHO): + ppp_lcp_echo_disabled* {.importc: "ppp_lcp_echo_disabled".}: bool ## + ## #ifdef CONFIG_LWIP_ENABLE_LCP_ECHO + ## + when defined(CONFIG_LWIP_PPP_SERVER_SUPPORT): + ppp_our_ip4_addr* {.importc: "ppp_our_ip4_addr".}: esp_ip4_addr_t ## + ## #endif // CONFIG_LWIP_ENABLE_LCP_ECHO + ## #ifdef CONFIG_LWIP_PPP_SERVER_SUPPORT + ppp_their_ip4_addr* {.importc: "ppp_their_ip4_addr".}: esp_ip4_addr_t ## + ## < Set our preferred address, typically used when we're the PPP server + ppp_dns1_addr* {.importc: "ppp_dns1_addr".}: esp_ip4_addr_t ## + ## < DNS to provide if peer asks for it, typically used when we're the PPP server + ppp_dns2_addr* {.importc: "ppp_dns2_addr".}: esp_ip4_addr_t ## + ## < DNS to provide if peer asks for it, typically used when we're the PPP server + ppp_passive* {.importc: "ppp_passive".}: bool ## < Try once to initiate connection, stay silent if it fails, typically used when we're the PPP server + ## #endif // CONFIG_LWIP_PPP_SERVER_SUPPORT + bridgeif_config_t* {.importc: "bridgeif_config_t", header: hdr, bycopy.} = object ## ## LwIP bridge configuration From 7f386c3922a850ebdb8b35e9db809d79b9577aa5 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 19:18:59 -0600 Subject: [PATCH 005/142] adding net_ppp --- src/nesper/esp/net/esp_netif_sntp.nim | 118 ++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/nesper/esp/net/esp_netif_sntp.nim diff --git a/src/nesper/esp/net/esp_netif_sntp.nim b/src/nesper/esp/net/esp_netif_sntp.nim new file mode 100644 index 00000000..c7fee0de --- /dev/null +++ b/src/nesper/esp/net/esp_netif_sntp.nim @@ -0,0 +1,118 @@ +## +## SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +## +## SPDX-License-Identifier: Apache-2.0 +## + +import std/posix +import ../../consts +import ./esp_netif_types + +type + + esp_sntp_time_cb_t* = proc (tv: ptr TimeVal) {.cdecl.} ## + ## + ## @defgroup ESP_NETIF_SNTP_API ESP-NETIF SNTP API + ## @brief SNTP API for underlying TCP/IP stack + ## + ## + ## @addtogroup ESP_NETIF_SNTP_API + ## @{ + ## + ## + ## @brief Time sync notification function + ## + +## +## @brief Utility macro for providing multiple servers in parentheses +## + +## +## @brief Default configuration to init SNTP with multiple servers +## @param servers_in_list Number of servers in the list +## @param list_of_servers List of servers (use ESP_SNTP_SERVER_LIST(...)) +## +## + +## +## @brief Default configuration with a single server +## + +type + + esp_sntp_config_t* {.importc: "esp_sntp_config_t", header: "esp_netif_sntp.h", + bycopy.} = object ## + ## @brief SNTP configuration struct + ## + smooth_sync* {.importc: "smooth_sync".}: bool ## < set to true if smooth sync required + server_from_dhcp* {.importc: "server_from_dhcp".}: bool ## + ## < set to true to request NTP server config from DHCP + wait_for_sync* {.importc: "wait_for_sync".}: bool ## + ## < if true, we create a semaphore to signal time sync event + start* {.importc: "start".}: bool ## < set to true to automatically start the SNTP service + sync_cb* {.importc: "sync_cb".}: esp_sntp_time_cb_t ## + ## < optionally sets callback function on time sync event + renew_servers_after_new_IP* {.importc: "renew_servers_after_new_IP".}: bool ## + ## < this is used to refresh server list if NTP provided by DHCP (which cleans other pre-configured servers) + ip_event_to_renew* {.importc: "ip_event_to_renew".}: ip_event_t ## + ## < set the IP event id on which we refresh server list (if renew_servers_after_new_IP=true) + index_of_first_server* {.importc: "index_of_first_server".}: csize_t ## + ## < refresh server list after this server (if renew_servers_after_new_IP=true) + num_of_servers* {.importc: "num_of_servers".}: csize_t ## + ## < number of preconfigured NTP servers + servers* {.importc: "servers".}: UncheckedArray[cstring] + ## < list of servers + + +proc esp_netif_sntp_init*(config: ptr esp_sntp_config_t): esp_err_t {.cdecl, + importc: "esp_netif_sntp_init", header: "esp_netif_sntp.h".} + ## + ## + ## @brief Initialize SNTP with supplied config struct + ## @param config Config struct + ## @return ESP_OK on success + ## + +proc esp_netif_sntp_start*(): esp_err_t {.cdecl, + importc: "esp_netif_sntp_start", header: "esp_netif_sntp.h".} + ## + ## + ## @brief Start SNTP service + ## if it wasn't started during init (config.start = false) + ## or restart it if already started + ## @return ESP_OK on success + ## + +proc esp_netif_sntp_deinit*() {.cdecl, importc: "esp_netif_sntp_deinit", + header: "esp_netif_sntp.h".} + ## + ## + ## @brief Deinitialize esp_netif SNTP module + ## + +proc esp_netif_sntp_sync_wait*(tout: TickType_t): esp_err_t {.cdecl, + importc: "esp_netif_sntp_sync_wait", header: "esp_netif_sntp.h".} + ## + ## + ## @brief Wait for time sync event + ## @param tout Specified timeout in RTOS ticks + ## @return ESP_TIMEOUT if sync event didn't came within the timeout + ## ESP_ERR_NOT_FINISHED if the sync event came, but we're in smooth update mode and still in progress (SNTP_SYNC_STATUS_IN_PROGRESS) + ## ESP_OK if time sync'ed + ## + +proc esp_netif_sntp_reachability*(index: cuint; reachability: ptr cuint): esp_err_t {. + cdecl, importc: "esp_netif_sntp_reachability", header: "esp_netif_sntp.h".} + ## + ## + ## @brief Returns SNTP server's reachability shift register as described in RFC 5905. + ## + ## @param index Index of the SERVER + ## @param reachability reachability shift register + ## @return ESP_OK on success, + ## ESP_ERR_INVALID_STATE if SNTP not initialized + ## ESP_ERR_INVALID_ARG if invalid arguments + ## +## +## @} +## From 1fce3f4d664c5ff79c31fbe1f9a52997aaa4b334 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 19:49:33 -0600 Subject: [PATCH 006/142] update defaults --- src/nesper/esp/net/esp_netif_defaults.nim | 142 ++++++++++------------ 1 file changed, 61 insertions(+), 81 deletions(-) diff --git a/src/nesper/esp/net/esp_netif_defaults.nim b/src/nesper/esp/net/esp_netif_defaults.nim index eaa22603..8f2935ad 100644 --- a/src/nesper/esp/net/esp_netif_defaults.nim +++ b/src/nesper/esp/net/esp_netif_defaults.nim @@ -1,92 +1,72 @@ -## Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD ## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## http://www.apache.org/licenses/LICENSE-2.0 +## SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD +## +## SPDX-License-Identifier: Apache-2.0 ## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. - -import esp_netif_types -const netif_def_headers = """#include "esp_netif.h" - #include "esp_netif_defaults.h" """ +const hdr = "esp_netif_defaults.h" -## @brief Default base config (esp-netif inherent) of WIFI STA -## +import ./esp_netif_types -var - ESP_NETIF_BASE_DEFAULT_WIFI_STA* {.importc: "$1", header: netif_def_headers.}: ptr esp_netif_inherent_config_t - ESP_NETIF_BASE_DEFAULT_WIFI_AP* {.importc: "$1", header: netif_def_headers.}: ptr esp_netif_inherent_config_t - ESP_NETIF_BASE_DEFAULT_ETH* {.importc: "$1", header: netif_def_headers.}: ptr esp_netif_inherent_config_t - ESP_NETIF_BASE_DEFAULT_PPP* {.importc: "$1", header: netif_def_headers.}: ptr esp_netif_inherent_config_t - ESP_NETIF_NETSTACK_DEFAULT_ETH* {.importc: "$1", header: netif_def_headers.}: ptr esp_netif_netstack_config_t - ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA* {.importc: "$1", header: netif_def_headers.}: ptr esp_netif_netstack_config_t - ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP* {.importc: "$1", header: netif_def_headers.}: ptr esp_netif_netstack_config_t - ESP_NETIF_NETSTACK_DEFAULT_PPP* {.importc: "$1", header: netif_def_headers.}: ptr esp_netif_netstack_config_t +let + ESP_NETIF_DEFAULT_ARP_FLAGS* {.importc: "ESP_NETIF_DEFAULT_ARP_FLAGS", header: hdr.}: cint ## + ## + ## Macros to assemble master configs with partial configs from netif, stack and driver + ## + ## If GARP enabled in menuconfig (default), make it also a default config for common netifs ## -## Macros to assemble master configs with partial configs from netif, stack and driver +## @brief Default configuration reference of ethernet interface ## -## /** -## * @brief Default configuration reference of ethernet interface -## */ -## #define ESP_NETIF_DEFAULT_ETH() \ -## { \ -## .base = ESP_NETIF_BASE_DEFAULT_ETH, \ -## .driver = NULL, \ -## .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH, \ -## } - -proc ESP_NETIF_DEFAULT_ETH*(): esp_netif_config_t = - return esp_netif_config_t( - base: ESP_NETIF_BASE_DEFAULT_ETH, - driver: nil, - stack: ESP_NETIF_NETSTACK_DEFAULT_ETH, - ) - -## /** -## * @brief Default configuration reference of WIFI AP -## */ -## #define ESP_NETIF_DEFAULT_WIFI_AP() \ -## { \ -## .base = ESP_NETIF_BASE_DEFAULT_WIFI_AP, \ -## .driver = NULL, \ -## .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP, \ -## } -## /** -## * @brief Default configuration reference of WIFI STA -## */ -## #define ESP_NETIF_DEFAULT_WIFI_STA() \ -## { \ -## .base = ESP_NETIF_BASE_DEFAULT_WIFI_STA, \ -## .driver = NULL, \ -## .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, \ -## } -## /** -## * @brief Default configuration reference of PPP client -## */ -## #define ESP_NETIF_DEFAULT_PPP() \ -## { \ -## .base = ESP_NETIF_BASE_DEFAULT_PPP, \ -## .driver = NULL, \ -## .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP, \ -## } -## * -## -## Include default network stacks configs -## - Network stack configurations are provided in a specific network stack -## implementation that is invisible to user API -## - Here referenced only as opaque pointers -## +proc ESP_NETIF_INHERENT_DEFAULT_WIFI_STA*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_STA", header: hdr.} -## -## * -## @brief Default base config (esp-netif inherent) of WIFI AP -## +let + ESP_NETIF_INHERENT_DEFAULT_WIFI_AP* {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_AP", header: hdr.}: esp_netif_inherent_config_t ## + + + ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN* {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN", header: hdr.}: esp_netif_inherent_config_t ## + + + ESP_NETIF_INHERENT_DEFAULT_ETH* {.importc: "ESP_NETIF_INHERENT_DEFAULT_ETH", header: hdr.}: esp_netif_inherent_config_t ## + + + ESP_NETIF_INHERENT_DEFAULT_PPP* {.importc: "ESP_NETIF_INHERENT_DEFAULT_PPP", header: hdr.}: esp_netif_inherent_config_t ## + + + ESP_NETIF_INHERENT_DEFAULT_BR* {.importc: "ESP_NETIF_INHERENT_DEFAULT_BR", header: hdr.}: esp_netif_inherent_config_t ## + + + ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS* {.importc: "ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS", header: hdr.}: esp_netif_inherent_config_t ## + + +let + ESP_NETIF_BASE_DEFAULT_WIFI_STA* {.importc: "ESP_NETIF_BASE_DEFAULT_WIFI_STA", header: hdr.}: ptr esp_netif_inherent_config_t ## + ## + ## @brief Default base config (esp-netif inherent) of WIFI STA + ## + ESP_NETIF_BASE_DEFAULT_WIFI_AP* {.importc: "ESP_NETIF_BASE_DEFAULT_WIFI_AP", header: hdr.}: ptr esp_netif_inherent_config_t ## + ## + ## @brief Default base config (esp-netif inherent) of WIFI AP + ## + ESP_NETIF_BASE_DEFAULT_WIFI_NAN* {.importc: "ESP_NETIF_BASE_DEFAULT_WIFI_NAN", header: hdr.}: ptr esp_netif_inherent_config_t ## + ## + ## @brief Default base config (esp-netif inherent) of WIFI NAN + ## + ESP_NETIF_BASE_DEFAULT_ETH* {.importc: "ESP_NETIF_BASE_DEFAULT_ETH", header: hdr.}: ptr esp_netif_inherent_config_t ## + ## + ## @brief Default base config (esp-netif inherent) of ethernet interface + ## + ESP_NETIF_BASE_DEFAULT_PPP* {.importc: "ESP_NETIF_BASE_DEFAULT_PPP", header: hdr.}: ptr esp_netif_inherent_config_t ## + ## + ## @brief Default base config (esp-netif inherent) of ppp interface + ## + +let + ESP_NETIF_NETSTACK_DEFAULT_ETH* {.importc: "ESP_NETIF_NETSTACK_DEFAULT_ETH", header: hdr.}: ptr esp_netif_netstack_config_t + ESP_NETIF_NETSTACK_DEFAULT_BR* {.importc: "ESP_NETIF_NETSTACK_DEFAULT_BR", header: hdr.}: ptr esp_netif_netstack_config_t + ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA* {.importc: "ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA", header: hdr.}: ptr esp_netif_netstack_config_t + ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP* {.importc: "ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP", header: hdr.}: ptr esp_netif_netstack_config_t + ESP_NETIF_NETSTACK_DEFAULT_WIFI_NAN* {.importc: "ESP_NETIF_NETSTACK_DEFAULT_WIFI_NAN", header: hdr.}: ptr esp_netif_netstack_config_t + ESP_NETIF_NETSTACK_DEFAULT_PPP* {.importc: "ESP_NETIF_NETSTACK_DEFAULT_PPP", header: hdr.}: ptr esp_netif_netstack_config_t From 8babdade27f00f7c886616ab33ed83e7f964e63f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 19:51:22 -0600 Subject: [PATCH 007/142] update defaults --- src/nesper/esp/net/esp_netif_defaults.nim | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/nesper/esp/net/esp_netif_defaults.nim b/src/nesper/esp/net/esp_netif_defaults.nim index 8f2935ad..5701bbd5 100644 --- a/src/nesper/esp/net/esp_netif_defaults.nim +++ b/src/nesper/esp/net/esp_netif_defaults.nim @@ -22,23 +22,17 @@ let proc ESP_NETIF_INHERENT_DEFAULT_WIFI_STA*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_STA", header: hdr.} -let - ESP_NETIF_INHERENT_DEFAULT_WIFI_AP* {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_AP", header: hdr.}: esp_netif_inherent_config_t ## - - - ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN* {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN", header: hdr.}: esp_netif_inherent_config_t ## - - - ESP_NETIF_INHERENT_DEFAULT_ETH* {.importc: "ESP_NETIF_INHERENT_DEFAULT_ETH", header: hdr.}: esp_netif_inherent_config_t ## - +proc ESP_NETIF_INHERENT_DEFAULT_WIFI_AP*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_AP", header: hdr.} - ESP_NETIF_INHERENT_DEFAULT_PPP* {.importc: "ESP_NETIF_INHERENT_DEFAULT_PPP", header: hdr.}: esp_netif_inherent_config_t ## +proc ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN", header: hdr.} +proc ESP_NETIF_INHERENT_DEFAULT_ETH*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_ETH", header: hdr.} - ESP_NETIF_INHERENT_DEFAULT_BR* {.importc: "ESP_NETIF_INHERENT_DEFAULT_BR", header: hdr.}: esp_netif_inherent_config_t ## +proc ESP_NETIF_INHERENT_DEFAULT_PPP*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_PPP", header: hdr.} +proc ESP_NETIF_INHERENT_DEFAULT_BR*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_BR", header: hdr.} - ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS* {.importc: "ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS", header: hdr.}: esp_netif_inherent_config_t ## +proc ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS", header: hdr.} let From 673c965364643a41b95dc7ba44b5f2367bdf1366 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 19:52:01 -0600 Subject: [PATCH 008/142] update defaults --- src/nesper/esp/net/esp_netif_defaults.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/src/nesper/esp/net/esp_netif_defaults.nim b/src/nesper/esp/net/esp_netif_defaults.nim index 5701bbd5..12c4f276 100644 --- a/src/nesper/esp/net/esp_netif_defaults.nim +++ b/src/nesper/esp/net/esp_netif_defaults.nim @@ -8,7 +8,6 @@ const hdr = "esp_netif_defaults.h" import ./esp_netif_types - let ESP_NETIF_DEFAULT_ARP_FLAGS* {.importc: "ESP_NETIF_DEFAULT_ARP_FLAGS", header: hdr.}: cint ## ## From ced706e7f5b87f313f12b1fe3ac313fcd52997fa Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 21:12:20 -0600 Subject: [PATCH 009/142] ppp connect example --- tests/ppp_connect.nim | 160 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 tests/ppp_connect.nim diff --git a/tests/ppp_connect.nim b/tests/ppp_connect.nim new file mode 100644 index 00000000..cf24f095 --- /dev/null +++ b/tests/ppp_connect.nim @@ -0,0 +1,160 @@ +import nesper/general +import nesper/esp/event_groups +import nesper/esp/esp_event +import nesper/esp/net/esp_netif +import nesper/esp/net/esp_netif_ppp +import nesper/esp/net/esp_netif_defaults +import nesper/esp/net/esp_netif_impl +import nesper/esp/net/esp_netif_types +import nesper/esp/driver/uart +import nesper/uarts + +when defined(ESP_IDF_V4_0): + import nesper/esp/net/tcpip_adapter +else: + var IP_EVENT* {.importc: "IP_EVENT", header: "esp_netif_types.h".}: esp_event_base_t + +export esp_event +export esp_netif +export esp_netif_ppp + +const + TAG: cstring = "example_connect_ppp" + EXAMPLE_NETIF_DESC_PPP* = "example_netif_ppp" + + GOT_IPV4 = EventBits_t(BIT(0)) + CONNECTION_FAILED = EventBits_t(BIT(1)) +when defined(CONFIG_EXAMPLE_CONNECT_IPV6): + const GOT_IPV6 = EventBits_t(BIT(2)) + +when defined(CONFIG_EXAMPLE_CONNECT_IPV6): + const CONNECT_BITS = GOT_IPV4 or GOT_IPV6 or CONNECTION_FAILED +else: + const CONNECT_BITS = GOT_IPV4 or CONNECTION_FAILED + +const + DefaultBufSize = 1024.SzBytes + +## Allow overriding at compile time: -d:PPP_CONN_MAX_RETRY=3 +const PPP_CONN_MAX_RETRY* {.intdefine.} = 5 + +var + sRetryNum: int = 0 + sEventGroup: EventGroupHandle_t + sNetif: ptr esp_netif_t + sStopTask: bool = false + gUartPort: uart_port_t = UART_NUM_1 + gUart: Uart + +proc pppTransmit(h: pointer; buffer: pointer; len: csize_t): esp_err_t {.cdecl.} = + # For UART device: write bytes out on the configured UART port + discard uart_write_bytes(gUartPort, cast[cstring](buffer), len) + return ESP_OK + +var driverCfg = esp_netif_driver_ifconfig_t( + handle: cast[pointer](1), # singleton driver, just != NULL + transmit: pppTransmit +) + +proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = + if event_id == ip_event_t.IP_EVENT_PPP_GOT_IP.ord: + let ev = cast[ptr ip_event_got_ip_t](event_data) + if ev.esp_netif != sNetif: + return + TAG.logi("PPP got IPv4") + var dnsInfo: esp_netif_dns_info_t + discard esp_netif_get_dns_info(sNetif, esp_netif_dns_type_t.ESP_NETIF_DNS_MAIN, addr dnsInfo) + discard xEventGroupSetBits(sEventGroup, GOT_IPV4) + elif event_id == ip_event_t.IP_EVENT_GOT_IP6.ord: + let ev6 = cast[ptr ip_event_got_ip6_t](event_data) + if ev6.esp_netif != sNetif: + return + TAG.logi("PPP got IPv6") + when defined(CONFIG_EXAMPLE_CONNECT_IPV6): + discard xEventGroupSetBits(sEventGroup, GOT_IPV6) + elif event_id == ip_event_t.IP_EVENT_PPP_LOST_IP.ord: + TAG.logi("PPP disconnected from server") + inc sRetryNum + if sRetryNum > PPP_CONN_MAX_RETRY: + TAG.loge("PPP Connection failed %d times, stop reconnecting.", sRetryNum.cint) + discard xEventGroupSetBits(sEventGroup, CONNECTION_FAILED) + else: + TAG.logi("PPP Connection failed %d times, reconnecting...", sRetryNum.cint) + esp_netif_action_start(sNetif, nil, 0, nil) + esp_netif_action_connected(sNetif, nil, 0, nil) + +proc pppUartTask(arg: pointer) {.cdecl.} = + while not sStopTask: + let data = gUart.read(size = DefaultBufSize, wait = 1.Millis) + if data.len > 0: + discard esp_netif_receive(sNetif, unsafeAddr data[0], data.len.csize_t, nil) + vTaskDelete(nil) + +proc examplePppConnect*( + uartNum: uart_port_t = UART_NUM_1, + txPin: gpio_num_t, + rxPin: gpio_num_t, + baudrate: int = 115_200, + stackSize: uint32 = 4096, + taskPrio: UBaseType_t = 5 + ): esp_err_t = + + TAG.logi("Start example_connect (PPP over UART)") + + sEventGroup = xEventGroupCreate() + if sEventGroup.isNil: + TAG.loge("Failed to create event group") + return ESP_FAIL + + check: esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, onIpEvent, nil) + + var baseCfg = ESP_NETIF_INHERENT_DEFAULT_PPP() + baseCfg.if_desc = EXAMPLE_NETIF_DESC_PPP + var netifCfg = esp_netif_config_t( + base: addr baseCfg, + driver: addr driverCfg, + stack: ESP_NETIF_NETSTACK_DEFAULT_PPP + ) + + sNetif = esp_netif_new(addr netifCfg) + if sNetif.isNil: + TAG.loge("Failed to create PPP netif") + return ESP_FAIL + + # Initialize UART for PPPoS framing + gUartPort = uartNum + var ucfg = newUartConfig(baud_rate = baudrate) + gUart = newUart(ucfg, uartNum, txPin, rxPin, buffer = DefaultBufSize, event_size = 0) + + sStopTask = false + if xTaskCreate(pppUartTask, "ppp connect", stackSize, nil, taskPrio, nil) != pdTRUE: + TAG.loge("Failed to create PPP task") + return ESP_FAIL + + # Bring the netif up (start + connected) + esp_netif_action_start(sNetif, nil, 0, nil) + esp_netif_action_connected(sNetif, nil, 0, nil) + + TAG.logi("Waiting for IP address") + let bits = xEventGroupWaitBits(sEventGroup, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY) + if (bits and CONNECTION_FAILED) != 0: + TAG.loge("PPP connection failed") + return ESP_FAIL + + TAG.logi("PPP connected!") + return ESP_OK + +proc examplePppShutdown*() = + discard esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, onIpEvent) + + sStopTask = true + vTaskDelay(pdMS_TO_TICKS(1000)) # wait for the PPP task to stop + + esp_netif_action_disconnected(sNetif, nil, 0, nil) + + vEventGroupDelete(sEventGroup) + esp_netif_action_stop(sNetif, nil, 0, nil) + esp_netif_destroy(sNetif) + sNetif = nil + sEventGroup = nil + From 53d2a0068da17c8572a822a5ad4afbaec565d368 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 21:27:27 -0600 Subject: [PATCH 010/142] ppp --- src/nesper/esp/net/esp_netif_defaults.nim | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/nesper/esp/net/esp_netif_defaults.nim b/src/nesper/esp/net/esp_netif_defaults.nim index 12c4f276..4845888e 100644 --- a/src/nesper/esp/net/esp_netif_defaults.nim +++ b/src/nesper/esp/net/esp_netif_defaults.nim @@ -33,6 +33,16 @@ proc ESP_NETIF_INHERENT_DEFAULT_BR*(): esp_netif_inherent_config_t {.importc: "E proc ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS", header: hdr.} +proc ESP_NETIF_DEFAULT_ETH*(): esp_netif_config_t {.importc: "ESP_NETIF_DEFAULT_ETH", header: hdr.} + +proc ESP_NETIF_DEFAULT_WIFI_AP*(): esp_netif_config_t {.importc: "ESP_NETIF_DEFAULT_WIFI_AP", header: hdr.} + +proc ESP_NETIF_DEFAULT_WIFI_NAN*(): esp_netif_config_t {.importc: "ESP_NETIF_DEFAULT_WIFI_NAN", header: hdr.} + +proc ESP_NETIF_DEFAULT_WIFI_STA*(): esp_netif_config_t {.importc: "ESP_NETIF_DEFAULT_WIFI_STA", header: hdr.} + +proc ESP_NETIF_DEFAULT_PPP*(): esp_netif_config_t {.importc: "ESP_NETIF_DEFAULT_PPP", header: hdr.} + let ESP_NETIF_BASE_DEFAULT_WIFI_STA* {.importc: "ESP_NETIF_BASE_DEFAULT_WIFI_STA", header: hdr.}: ptr esp_netif_inherent_config_t ## From 16ec25810aaf7d8aeb75ed529416d5e9ff8daf5b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 22:34:38 -0600 Subject: [PATCH 011/142] usb --- tests/c_headers/idf-usb/README.md | 28 + .../CMakeLists.txt | 11 + .../tusb_composite_msc_serialdevice/README.md | 81 +++ .../main/CMakeLists.txt | 5 + .../main/idf_component.yml | 4 + .../main/tusb_composite_main.c | 207 ++++++ .../partitions.csv | 6 + .../pytest_usb_device_composite.py | 33 + .../sdkconfig.defaults | 15 + .../device/tusb_console/CMakeLists.txt | 9 + .../idf-usb/device/tusb_console/README.md | 88 +++ .../device/tusb_console/main/CMakeLists.txt | 2 + .../tusb_console/main/idf_component.yml | 4 + .../tusb_console/main/tusb_console_main.c | 66 ++ .../tusb_console/pytest_usb_device_console.py | 37 ++ .../device/tusb_console/sdkconfig.defaults | 1 + .../idf-usb/device/tusb_hid/CMakeLists.txt | 10 + .../idf-usb/device/tusb_hid/README.md | 80 +++ .../device/tusb_hid/main/CMakeLists.txt | 5 + .../device/tusb_hid/main/idf_component.yml | 4 + .../tusb_hid/main/tusb_hid_example_main.c | 194 ++++++ .../device/tusb_hid/pytest_usb_device_hid.py | 14 + .../device/tusb_hid/sdkconfig.defaults | 4 + .../idf-usb/device/tusb_midi/CMakeLists.txt | 8 + .../idf-usb/device/tusb_midi/README.md | 83 +++ .../device/tusb_midi/main/CMakeLists.txt | 4 + .../device/tusb_midi/main/idf_component.yml | 4 + .../device/tusb_midi/main/tusb_midi_main.c | 185 ++++++ .../tusb_midi/pytest_usb_device_midi.py | 15 + .../device/tusb_midi/sdkconfig.defaults | 1 + .../idf-usb/device/tusb_msc/CMakeLists.txt | 10 + .../idf-usb/device/tusb_msc/README.md | 203 ++++++ .../device/tusb_msc/main/CMakeLists.txt | 11 + .../device/tusb_msc/main/Kconfig.projbuild | 100 +++ .../device/tusb_msc/main/idf_component.yml | 4 + .../device/tusb_msc/main/tusb_msc_main.c | 491 ++++++++++++++ .../idf-usb/device/tusb_msc/partitions.csv | 6 + .../device/tusb_msc/pytest_usb_device_msc.py | 17 + .../idf-usb/device/tusb_msc/sdkconfig.ci | 0 .../tusb_msc/sdkconfig.ci.esp32s3_sdmmc | 2 + .../device/tusb_msc/sdkconfig.defaults | 16 + .../idf-usb/device/tusb_ncm/CMakeLists.txt | 8 + .../idf-usb/device/tusb_ncm/README.md | 103 +++ .../device/tusb_ncm/main/CMakeLists.txt | 4 + .../device/tusb_ncm/main/Kconfig.projbuild | 15 + .../device/tusb_ncm/main/idf_component.yml | 5 + .../device/tusb_ncm/main/tusb_ncm_main.c | 126 ++++ .../device/tusb_ncm/pytest_usb_device_ncm.py | 31 + .../device/tusb_ncm/sdkconfig.defaults | 1 + .../tusb_ncm/sdkconfig.defaults.esp32s3 | 3 + .../device/tusb_serial_device/CMakeLists.txt | 9 + .../device/tusb_serial_device/README.md | 85 +++ .../tusb_serial_device/main/CMakeLists.txt | 2 + .../tusb_serial_device/main/idf_component.yml | 4 + .../main/tusb_serial_device_main.c | 140 ++++ .../pytest_usb_device_serial.py | 31 + .../device/tusb_serial_device/sdkconfig.ci | 0 .../sdkconfig.ci.dualchannel | 1 + .../tusb_serial_device/sdkconfig.defaults | 1 + .../host/cdc/cdc_acm_host/CMakeLists.txt | 10 + .../idf-usb/host/cdc/cdc_acm_host/README.md | 57 ++ .../host/cdc/cdc_acm_host/main/CMakeLists.txt | 4 + .../cdc/cdc_acm_host/main/idf_component.yml | 4 + .../cdc_acm_host/main/usb_cdc_example_main.c | 179 +++++ .../host/cdc/cdc_acm_vcp/CMakeLists.txt | 10 + .../idf-usb/host/cdc/cdc_acm_vcp/README.md | 41 ++ .../host/cdc/cdc_acm_vcp/main/CMakeLists.txt | 5 + .../main/cdc_acm_vcp_example_main.cpp | 177 +++++ .../cdc/cdc_acm_vcp/main/idf_component.yml | 7 + .../host/cdc/cdc_acm_vcp/sdkconfig.defaults | 5 + .../c_headers/idf-usb/host/hid/CMakeLists.txt | 10 + tests/c_headers/idf-usb/host/hid/README.md | 61 ++ .../idf-usb/host/hid/main/CMakeLists.txt | 4 + .../idf-usb/host/hid/main/hid_host_example.c | 616 ++++++++++++++++++ .../idf-usb/host/hid/main/idf_component.yml | 4 + .../idf-usb/host/hid/sdkconfig.defaults | 4 + .../c_headers/idf-usb/host/msc/CMakeLists.txt | 8 + tests/c_headers/idf-usb/host/msc/README.md | 139 ++++ .../idf-usb/host/msc/main/CMakeLists.txt | 4 + .../idf-usb/host/msc/main/idf_component.yml | 4 + .../idf-usb/host/msc/main/msc_example_main.c | 560 ++++++++++++++++ .../idf-usb/host/msc/pytest_usb_host_msc.py | 45 ++ tests/c_headers/idf-usb/host/msc/sdkconfig.ci | 0 .../host/msc/sdkconfig.ci.esp32p4_psram | 11 + .../idf-usb/host/msc/sdkconfig.defaults | 4 + .../idf-usb/host/usb_host_lib/CMakeLists.txt | 8 + .../idf-usb/host/usb_host_lib/README.md | 193 ++++++ .../host/usb_host_lib/main/CMakeLists.txt | 4 + .../host/usb_host_lib/main/Kconfig.projbuild | 12 + .../host/usb_host_lib/main/class_driver.c | 279 ++++++++ .../usb_host_lib/main/usb_host_lib_main.c | 226 +++++++ .../host/usb_host_lib/pytest_usb_host_lib.py | 25 + .../host/usb_host_lib/sdkconfig.defaults | 4 + .../c_headers/idf-usb/host/uvc/CMakeLists.txt | 8 + tests/c_headers/idf-usb/host/uvc/README.md | 96 +++ .../idf-usb/host/uvc/main/CMakeLists.txt | 5 + .../idf-usb/host/uvc/main/idf_component.yml | 4 + tests/c_headers/idf-usb/host/uvc/main/main.c | 233 +++++++ .../idf-usb/host/uvc/sdkconfig.defaults | 13 + .../host/uvc/sdkconfig.defaults.esp32p4 | 2 + .../host/uvc/sdkconfig.defaults.esp32s2 | 9 + .../host/uvc/sdkconfig.defaults.esp32s3 | 9 + tests/c_headers/ppp_connect_uart.c | 179 +++++ tests/c_headers/ppp_connect_usb.c | 186 ++++++ tests/ppp_connect.nim | 160 ----- 105 files changed, 6105 insertions(+), 160 deletions(-) create mode 100644 tests/c_headers/idf-usb/README.md create mode 100644 tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/README.md create mode 100644 tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/tusb_composite_main.c create mode 100644 tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/partitions.csv create mode 100644 tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py create mode 100644 tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/device/tusb_console/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_console/README.md create mode 100644 tests/c_headers/idf-usb/device/tusb_console/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_console/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/device/tusb_console/main/tusb_console_main.c create mode 100644 tests/c_headers/idf-usb/device/tusb_console/pytest_usb_device_console.py create mode 100644 tests/c_headers/idf-usb/device/tusb_console/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/device/tusb_hid/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_hid/README.md create mode 100644 tests/c_headers/idf-usb/device/tusb_hid/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_hid/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/device/tusb_hid/main/tusb_hid_example_main.c create mode 100644 tests/c_headers/idf-usb/device/tusb_hid/pytest_usb_device_hid.py create mode 100644 tests/c_headers/idf-usb/device/tusb_hid/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/device/tusb_midi/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_midi/README.md create mode 100644 tests/c_headers/idf-usb/device/tusb_midi/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_midi/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/device/tusb_midi/main/tusb_midi_main.c create mode 100644 tests/c_headers/idf-usb/device/tusb_midi/pytest_usb_device_midi.py create mode 100644 tests/c_headers/idf-usb/device/tusb_midi/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/README.md create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/main/Kconfig.projbuild create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/main/tusb_msc_main.c create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/partitions.csv create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/pytest_usb_device_msc.py create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.ci create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.ci.esp32s3_sdmmc create mode 100644 tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/device/tusb_ncm/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_ncm/README.md create mode 100644 tests/c_headers/idf-usb/device/tusb_ncm/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_ncm/main/Kconfig.projbuild create mode 100644 tests/c_headers/idf-usb/device/tusb_ncm/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/device/tusb_ncm/main/tusb_ncm_main.c create mode 100644 tests/c_headers/idf-usb/device/tusb_ncm/pytest_usb_device_ncm.py create mode 100644 tests/c_headers/idf-usb/device/tusb_ncm/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/device/tusb_ncm/sdkconfig.defaults.esp32s3 create mode 100644 tests/c_headers/idf-usb/device/tusb_serial_device/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_serial_device/README.md create mode 100644 tests/c_headers/idf-usb/device/tusb_serial_device/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/device/tusb_serial_device/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/device/tusb_serial_device/main/tusb_serial_device_main.c create mode 100644 tests/c_headers/idf-usb/device/tusb_serial_device/pytest_usb_device_serial.py create mode 100644 tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.ci create mode 100644 tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.ci.dualchannel create mode 100644 tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_host/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_host/README.md create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/usb_cdc_example_main.c create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/README.md create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/cdc_acm_vcp_example_main.cpp create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/host/hid/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/hid/README.md create mode 100644 tests/c_headers/idf-usb/host/hid/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/hid/main/hid_host_example.c create mode 100644 tests/c_headers/idf-usb/host/hid/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/host/hid/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/host/msc/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/msc/README.md create mode 100644 tests/c_headers/idf-usb/host/msc/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/msc/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/host/msc/main/msc_example_main.c create mode 100644 tests/c_headers/idf-usb/host/msc/pytest_usb_host_msc.py create mode 100644 tests/c_headers/idf-usb/host/msc/sdkconfig.ci create mode 100644 tests/c_headers/idf-usb/host/msc/sdkconfig.ci.esp32p4_psram create mode 100644 tests/c_headers/idf-usb/host/msc/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/host/usb_host_lib/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/usb_host_lib/README.md create mode 100644 tests/c_headers/idf-usb/host/usb_host_lib/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/usb_host_lib/main/Kconfig.projbuild create mode 100644 tests/c_headers/idf-usb/host/usb_host_lib/main/class_driver.c create mode 100644 tests/c_headers/idf-usb/host/usb_host_lib/main/usb_host_lib_main.c create mode 100644 tests/c_headers/idf-usb/host/usb_host_lib/pytest_usb_host_lib.py create mode 100644 tests/c_headers/idf-usb/host/usb_host_lib/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/host/uvc/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/uvc/README.md create mode 100644 tests/c_headers/idf-usb/host/uvc/main/CMakeLists.txt create mode 100644 tests/c_headers/idf-usb/host/uvc/main/idf_component.yml create mode 100644 tests/c_headers/idf-usb/host/uvc/main/main.c create mode 100644 tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults create mode 100644 tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32p4 create mode 100644 tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32s2 create mode 100644 tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32s3 create mode 100644 tests/c_headers/ppp_connect_uart.c create mode 100644 tests/c_headers/ppp_connect_usb.c delete mode 100644 tests/ppp_connect.nim diff --git a/tests/c_headers/idf-usb/README.md b/tests/c_headers/idf-usb/README.md new file mode 100644 index 00000000..30a6320f --- /dev/null +++ b/tests/c_headers/idf-usb/README.md @@ -0,0 +1,28 @@ +# USB-OTG Examples + +See the [README.md](../../README.md) file in the upper level [examples](../../) directory for more information about examples. + +## Common Pin Assignments + +Pin assignment is only needed for ESP chips that have a USB-OTG peripheral. +If your board doesn't have a USB connector connected to the USB-OTG dedicated GPIOs, you may have to DIY a cable and connect **D+** and **D-** to the pins listed below. + +``` +ESP BOARD USB CONNECTOR (type A) + -- + | || VBUS (5V) +[USB_DM] ------> | || D- +[USB_DP] ------> | || D+ + | || GND + -- +``` + +### USB PHY pin mapping + +| | USB_DP | USB_DM | +| ------------ | ------ | ------ | +| ESP32-S2/S3 | GPIO20 | GPIO19 | +| ESP32-P4 2.0 | pin 50 | pin 49 | +| ESP32-P4 1.1 | GPIO27 | GPIO26 | + +> Note: On the ESP32-P4, the USB 2.0 PHY pins are dedicated to USB-OTG functionality and cannot be used as general-purpose GPIOs. diff --git a/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/CMakeLists.txt new file mode 100644 index 00000000..ac369a25 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/CMakeLists.txt @@ -0,0 +1,11 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +add_compile_options(-w) # Turn off warnings until esp_tinyusb is updated IEC-86 +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(tusb_composite) diff --git a/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/README.md b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/README.md new file mode 100644 index 00000000..a7a32c45 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/README.md @@ -0,0 +1,81 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# TinyUSB Composite Device (MSC + Serial) Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +A USB device can provide multiple functions that are active simultaneously. Such multi-function devices are also known as composite devices. This example shows how to set up ESP chip to work as a USB Serial Device as well as MSC device (Storage media as SPI-Flash). + +As a USB stack, a TinyUSB component is used. + +## How to use example + +### Hardware Required + +Any ESP board that supports the USB-OTG peripheral. + +### Pin Assignment + +_Note:_ In case your board doesn't have micro-USB connector connected to USB-OTG peripheral, you may have to DIY a cable and connect **D+** and **D-** to the pins listed below. + +See common pin assignments for USB Device examples from [upper level](../../README.md#common-pin-assignments). + +Next, for Self-Powered Devices with VBUS monitoring, user must set ``self_powered`` to ``true`` and ``vbus_monitor_io`` to GPIO number (``VBUS_MONITORING_GPIO_NUM``) that will be used for VBUS monitoring. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +```bash +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +After the flashing you should see the output at idf monitor: + +``` +I (344) main_task: Calling app_main() +I (344) example_main: USB Composite initialization +W (354) TinyUSB: The device's configuration descriptor is not provided by user, using default. +W (364) TinyUSB: The device's string descriptor is not provided by user, using default. +W (374) TinyUSB: The device's device descriptor is not provided by user, using default. +I (384) tusb_desc: +┌─────────────────────────────────┐ +│ USB Device Descriptor Summary │ +├───────────────────┬─────────────┤ +│bDeviceClass │ 239 │ +├───────────────────┼─────────────┤ +│bDeviceSubClass │ 2 │ +├───────────────────┼─────────────┤ +│bDeviceProtocol │ 1 │ +├───────────────────┼─────────────┤ +│bMaxPacketSize0 │ 64 │ +├───────────────────┼─────────────┤ +│idVendor │ 0x303a │ +├───────────────────┼─────────────┤ +│idProduct │ 0x4001 │ +├───────────────────┼─────────────┤ +│bcdDevice │ 0x100 │ +├───────────────────┼─────────────┤ +│iManufacturer │ 0x1 │ +├───────────────────┼─────────────┤ +│iProduct │ 0x2 │ +├───────────────────┼─────────────┤ +│iSerialNumber │ 0x3 │ +├───────────────────┼─────────────┤ +│bNumConfigurations │ 0x1 │ +└───────────────────┴─────────────┘ +I (544) TinyUSB: TinyUSB Driver installed +I (554) example_main: Initializing storage... +I (554) example_main: Initializing wear levelling +I (584) example_main: USB Composite initialization DONE +I (584) main_task: Returned from app_main() +``` diff --git a/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/CMakeLists.txt new file mode 100644 index 00000000..b8dc619b --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS tusb_composite_main.c + INCLUDE_DIRS . + PRIV_REQUIRES fatfs wear_levelling esp_partition +) diff --git a/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/idf_component.yml b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/idf_component.yml new file mode 100644 index 00000000..06b047d6 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_tinyusb: "^1.2" + idf: "^5.0" diff --git a/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/tusb_composite_main.c b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/tusb_composite_main.c new file mode 100644 index 00000000..87474afb --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/main/tusb_composite_main.c @@ -0,0 +1,207 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include "esp_partition.h" +#include "esp_check.h" +#include "tinyusb.h" +#include "tusb_msc_storage.h" +#include "tusb_cdc_acm.h" + +#define BASE_PATH "/usb" // base path to mount the partition + +static const char *TAG = "example_main"; +static uint8_t rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; + +/** + * @brief Application Queue + */ +static QueueHandle_t app_queue; +typedef struct { + uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; // Data buffer + size_t buf_len; // Number of bytes received + uint8_t itf; // Index of CDC device interface +} app_message_t; + +/** + * @brief CDC device RX callback + * + * CDC device signals, that new data were received + * + * @param[in] itf CDC device index + * @param[in] event CDC event type + */ +void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event) +{ + /* initialization */ + size_t rx_size = 0; + + /* read */ + esp_err_t ret = tinyusb_cdcacm_read(itf, rx_buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); + if (ret == ESP_OK) { + + app_message_t tx_msg = { + .buf_len = rx_size, + .itf = itf, + }; + + /* Copy received message to application queue buffer */ + memcpy(tx_msg.buf, rx_buf, rx_size); + xQueueSend(app_queue, &tx_msg, 0); + } else { + ESP_LOGE(TAG, "Read Error"); + } +} + +/** + * @brief CDC device line change callback + * + * CDC device signals, that the DTR, RTS states changed + * + * @param[in] itf CDC device index + * @param[in] event CDC event type + */ +void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event) +{ + int dtr = event->line_state_changed_data.dtr; + int rts = event->line_state_changed_data.rts; + ESP_LOGI(TAG, "Line state changed on channel %d: DTR:%d, RTS:%d", itf, dtr, rts); +} + +static bool file_exists(const char *file_path) +{ + struct stat buffer; + return stat(file_path, &buffer) == 0; +} + +static void file_operations(void) +{ + const char *directory = "/usb/esp"; + const char *file_path = "/usb/esp/test.txt"; + + struct stat s = {0}; + bool directory_exists = stat(directory, &s) == 0; + if (!directory_exists) { + if (mkdir(directory, 0775) != 0) { + ESP_LOGE(TAG, "mkdir failed with errno: %s", strerror(errno)); + } + } + + if (!file_exists(file_path)) { + ESP_LOGI(TAG, "Creating file"); + FILE *f = fopen(file_path, "w"); + if (f == NULL) { + ESP_LOGE(TAG, "Failed to open file for writing"); + return; + } + fprintf(f, "Hello World!\n"); + fclose(f); + } + + FILE *f; + ESP_LOGI(TAG, "Reading file"); + f = fopen(file_path, "r"); + if (f == NULL) { + ESP_LOGE(TAG, "Failed to open file for reading"); + return; + } + char line[64]; + fgets(line, sizeof(line), f); + fclose(f); + // strip newline + char *pos = strchr(line, '\n'); + if (pos) { + *pos = '\0'; + } + ESP_LOGI(TAG, "Read from file: '%s'", line); +} + +static esp_err_t storage_init_spiflash(wl_handle_t *wl_handle) +{ + ESP_LOGI(TAG, "Initializing wear levelling"); + + const esp_partition_t *data_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL); + if (data_partition == NULL) { + ESP_LOGE(TAG, "Failed to find FATFS partition. Check the partition table."); + return ESP_ERR_NOT_FOUND; + } + + return wl_mount(data_partition, wl_handle); +} + +void app_main(void) +{ + // Create FreeRTOS primitives + app_queue = xQueueCreate(5, sizeof(app_message_t)); + assert(app_queue); + app_message_t msg; + + ESP_LOGI(TAG, "Initializing storage..."); + + static wl_handle_t wl_handle = WL_INVALID_HANDLE; + ESP_ERROR_CHECK(storage_init_spiflash(&wl_handle)); + + const tinyusb_msc_spiflash_config_t config_spi = { + .wl_handle = wl_handle + }; + ESP_ERROR_CHECK(tinyusb_msc_storage_init_spiflash(&config_spi)); + ESP_ERROR_CHECK(tinyusb_msc_storage_mount(BASE_PATH)); + file_operations(); + + ESP_LOGI(TAG, "USB Composite initialization"); + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .string_descriptor_count = 0, + .external_phy = false, +#if (TUD_OPT_HIGH_SPEED) + .fs_configuration_descriptor = NULL, + .hs_configuration_descriptor = NULL, + .qualifier_descriptor = NULL, +#else + .configuration_descriptor = NULL, +#endif // TUD_OPT_HIGH_SPEED + }; + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + tinyusb_config_cdcacm_t acm_cfg = { + .usb_dev = TINYUSB_USBDEV_0, + .cdc_port = TINYUSB_CDC_ACM_0, + .rx_unread_buf_sz = 64, + .callback_rx = &tinyusb_cdc_rx_callback, // the first way to register a callback + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = NULL, + .callback_line_coding_changed = NULL + }; + + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); + /* the second way to register a callback */ + ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( + TINYUSB_CDC_ACM_0, + CDC_EVENT_LINE_STATE_CHANGED, + &tinyusb_cdc_line_state_changed_callback)); + + ESP_LOGI(TAG, "USB Composite initialization DONE"); + while (1) { + if (xQueueReceive(app_queue, &msg, portMAX_DELAY)) { + if (msg.buf_len) { + + /* Print received data*/ + ESP_LOGI(TAG, "Data from channel %d:", msg.itf); + ESP_LOG_BUFFER_HEXDUMP(TAG, msg.buf, msg.buf_len, ESP_LOG_INFO); + + /* write back */ + tinyusb_cdcacm_write_queue(msg.itf, msg.buf, msg.buf_len); + esp_err_t err = tinyusb_cdcacm_write_flush(msg.itf, 0); + if (err != ESP_OK) { + ESP_LOGE(TAG, "CDC ACM write flush error: %s", esp_err_to_name(err)); + } + } + } + } +} diff --git a/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/partitions.csv b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/partitions.csv new file mode 100644 index 00000000..1c79321a --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/partitions.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +storage, data, fat, , 1M, diff --git a/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py new file mode 100644 index 00000000..2c42a923 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py @@ -0,0 +1,33 @@ +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +from time import sleep + +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize +from serial import Serial +from serial.tools.list_ports import comports + + +@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') +@pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) +def test_usb_composite_device_serial_example(dut: Dut) -> None: + dut.expect_exact('Hello World!') + dut.expect_exact('USB Composite initialization') + dut.expect_exact('USB Composite initialization DONE') + sleep(2) # Some time for the OS to enumerate our USB device + + # Find device with Espressif TinyUSB VID/PID + ports = comports() + for port, _, hwid in ports: + if '303A:4001' in hwid: + with Serial(port) as s: + s.write('text\r\n'.encode()) # Write dummy text to COM port + dut.expect_exact('Data from channel 0:') # Check ESP log + dut.expect_exact('|text..|') + res = s.readline() # Check COM echo + assert b'text\r\n' in res + return + + raise Exception('TinyUSB COM port not found') diff --git a/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/sdkconfig.defaults b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/sdkconfig.defaults new file mode 100644 index 00000000..087e74a6 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_composite_msc_serialdevice/sdkconfig.defaults @@ -0,0 +1,15 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_TINYUSB_MSC_ENABLED=y + +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_WL_SECTOR_SIZE_512=y +CONFIG_WL_SECTOR_MODE_PERF=y + +CONFIG_TINYUSB_CDC_ENABLED=y +# CONFIG_TINYUSB_DESC_USE_DEFAULT_PID is not set +CONFIG_TINYUSB_DESC_CUSTOM_PID=0x4001 diff --git a/tests/c_headers/idf-usb/device/tusb_console/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_console/CMakeLists.txt new file mode 100644 index 00000000..c8353934 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_console/CMakeLists.txt @@ -0,0 +1,9 @@ +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +add_compile_options(-w) # Turn off warnings until esp_tinyusb is updated IEC-86 +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(tusb_console) diff --git a/tests/c_headers/idf-usb/device/tusb_console/README.md b/tests/c_headers/idf-usb/device/tusb_console/README.md new file mode 100644 index 00000000..aeccaab2 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_console/README.md @@ -0,0 +1,88 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# TinyUSB Sample Descriptor + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example shows how to set up ESP chip to get log output via Serial Device connection. + +As a USB stack, a TinyUSB component is used. + +## How to use example + +### Hardware Required + +Any ESP boards that have USB-OTG supported. + +#### Pin Assignment + +See common pin assignments for USB Device examples from [upper level](../../README.md#common-pin-assignments). + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +```bash +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Serial Connection + +After program's start and getting of the message of readiness (`Serial device is ready to connect`) you can connect to the board using any serial port terminal application (e.g. CoolTerm). + +Note: if you want to send data to the target see how to implement it via `tud_cdc_rx_cb` at the `tusb_serial_device` example. + +## Example Output + +After the flashing you should see the output at idf monitor: + +``` +I (288) example: USB initialization +I (288) tusb_desc: +┌─────────────────────────────────┐ +│ USB Device Descriptor Summary │ +├───────────────────┬─────────────┤ +│bDeviceClass │ 239 │ +├───────────────────┼─────────────┤ +│bDeviceSubClass │ 2 │ +├───────────────────┼─────────────┤ +│bDeviceProtocol │ 1 │ +├───────────────────┼─────────────┤ +│bMaxPacketSize0 │ 64 │ +├───────────────────┼─────────────┤ +│idVendor │ 0x303a │ +├───────────────────┼─────────────┤ +│idProduct │ 0x4001 │ +├───────────────────┼─────────────┤ +│bcdDevice │ 0x100 │ +├───────────────────┼─────────────┤ +│iManufacturer │ 0x1 │ +├───────────────────┼─────────────┤ +│iProduct │ 0x2 │ +├───────────────────┼─────────────┤ +│iSerialNumber │ 0x3 │ +├───────────────────┼─────────────┤ +│bNumConfigurations │ 0x1 │ +└───────────────────┴─────────────┘ +I (458) TinyUSB: TinyUSB Driver installed +I (468) example: USB initialization DONE +I (468) example: log -> UART +example: print -> stdout +example: print -> stderr +... + +``` + +Other log will be printed to USB: +``` +I (3478) example: log -> USB +example: print -> stdout +example: print -> stderr +``` diff --git a/tests/c_headers/idf-usb/device/tusb_console/main/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_console/main/CMakeLists.txt new file mode 100644 index 00000000..f1ad99b5 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_console/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "tusb_console_main.c" + INCLUDE_DIRS .) diff --git a/tests/c_headers/idf-usb/device/tusb_console/main/idf_component.yml b/tests/c_headers/idf-usb/device/tusb_console/main/idf_component.yml new file mode 100644 index 00000000..ff67b5da --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_console/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_tinyusb: "^1" + idf: "^5.0" diff --git a/tests/c_headers/idf-usb/device/tusb_console/main/tusb_console_main.c b/tests/c_headers/idf-usb/device/tusb_console/main/tusb_console_main.c new file mode 100644 index 00000000..5b16591c --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_console/main/tusb_console_main.c @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +// DESCRIPTION: +// This example contains minimal code to make ESP32-S2 based device +// recognizable by USB-host devices as a USB Serial Device printing output from +// the application. + +#include +#include +#include +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "tinyusb.h" +#include "tusb_cdc_acm.h" +#include "tusb_console.h" +#include "sdkconfig.h" + +static const char *TAG = "example"; + +void app_main(void) +{ + /* Setting TinyUSB up */ + ESP_LOGI(TAG, "USB initialization"); + + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .external_phy = false, // In the most cases you need to use a `false` value +#if (TUD_OPT_HIGH_SPEED) + .fs_configuration_descriptor = NULL, + .hs_configuration_descriptor = NULL, + .qualifier_descriptor = NULL, +#else + .configuration_descriptor = NULL, +#endif // TUD_OPT_HIGH_SPEED + }; + + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + tinyusb_config_cdcacm_t acm_cfg = { 0 }; // the configuration uses default values + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); + + ESP_LOGI(TAG, "USB initialization DONE"); + while (1) { + ESP_LOGI(TAG, "log -> UART"); + vTaskDelay(1000 / portTICK_PERIOD_MS); + fprintf(stdout, "example: print -> stdout\n"); + vTaskDelay(1000 / portTICK_PERIOD_MS); + fprintf(stderr, "example: print -> stderr\n"); + vTaskDelay(1000 / portTICK_PERIOD_MS); + + esp_tusb_init_console(TINYUSB_CDC_ACM_0); // log to usb + ESP_LOGI(TAG, "log -> USB"); + vTaskDelay(1000 / portTICK_PERIOD_MS); + fprintf(stdout, "example: print -> stdout\n"); + vTaskDelay(1000 / portTICK_PERIOD_MS); + fprintf(stderr, "example: print -> stderr\n"); + vTaskDelay(1000 / portTICK_PERIOD_MS); + esp_tusb_deinit_console(TINYUSB_CDC_ACM_0); // log to uart + } +} diff --git a/tests/c_headers/idf-usb/device/tusb_console/pytest_usb_device_console.py b/tests/c_headers/idf-usb/device/tusb_console/pytest_usb_device_console.py new file mode 100644 index 00000000..8860dbff --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_console/pytest_usb_device_console.py @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +from time import sleep + +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize +from serial import Serial +from serial.tools.list_ports import comports + + +@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') +@pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) +def test_usb_device_console_example(dut: Dut) -> None: + dut.expect_exact('USB initialization DONE') + dut.expect_exact('example: log -> UART') + dut.expect_exact('example: print -> stdout') + dut.expect_exact('example: print -> stderr') + + # Find device with Espressif TinyUSB VID/PID + sleep(2) # Some time for the OS to enumerate our USB device + ports = comports() + for port, _, hwid in ports: + if '303A:4001' in hwid: + with Serial(port) as s: + # Assert TinyUSB output: Read 3 lines and check their content + serial_output = list() + serial_output.append(s.readline()) + serial_output.append(s.readline()) + serial_output.append(s.readline()) + assert any(b'example: log -> USB' in out for out in serial_output) + assert any(b'example: print -> stdout' in out for out in serial_output) + assert any(b'example: print -> stderr' in out for out in serial_output) + return + + raise Exception('TinyUSB COM port not found') diff --git a/tests/c_headers/idf-usb/device/tusb_console/sdkconfig.defaults b/tests/c_headers/idf-usb/device/tusb_console/sdkconfig.defaults new file mode 100644 index 00000000..afec5843 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_console/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_TINYUSB_CDC_ENABLED=y diff --git a/tests/c_headers/idf-usb/device/tusb_hid/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_hid/CMakeLists.txt new file mode 100644 index 00000000..258a4dce --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_hid/CMakeLists.txt @@ -0,0 +1,10 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(tusb_hid) diff --git a/tests/c_headers/idf-usb/device/tusb_hid/README.md b/tests/c_headers/idf-usb/device/tusb_hid/README.md new file mode 100644 index 00000000..e7847425 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_hid/README.md @@ -0,0 +1,80 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# TinyUSB Human Interface Device Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +Human interface devices (HID) are one of the most common USB devices, it is implemented in various devices such as keyboards, mice, game controllers, sensors and alphanumeric display devices. +In this example, we implement USB keyboard and mouse. +Upon connection to USB host (PC), the example application will sent 'key a/A pressed & released' events and move mouse in a square trajectory. To send these HID reports again, press the BOOT button, that is present on most ESP development boards (GPIO0). + +As a USB stack, a TinyUSB component is used. + +## How to use example + +### Hardware Required + +Any ESP board that have USB-OTG supported. + +#### Pin Assignment + +_Note:_ In case your board doesn't have micro-USB connector connected to USB-OTG peripheral, you may have to DIY a cable and connect **D+** and **D-** to the pins listed below. + +See common pin assignments for USB Device examples from [upper level](../../README.md#common-pin-assignments). + +Boot signal (GPIO0) is used to send HID reports to USB host. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +```bash +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +After the flashing you should see the output at idf monitor: + +``` +I (290) cpu_start: Starting scheduler on PRO CPU. +I (0) cpu_start: Starting scheduler on APP CPU. +I (310) example: USB initialization +I (310) tusb_desc: +┌─────────────────────────────────┐ +│ USB Device Descriptor Summary │ +├───────────────────┬─────────────┤ +│bDeviceClass │ 0 │ +├───────────────────┼─────────────┤ +│bDeviceSubClass │ 0 │ +├───────────────────┼─────────────┤ +│bDeviceProtocol │ 0 │ +├───────────────────┼─────────────┤ +│bMaxPacketSize0 │ 64 │ +├───────────────────┼─────────────┤ +│idVendor │ 0x303a │ +├───────────────────┼─────────────┤ +│idProduct │ 0x4004 │ +├───────────────────┼─────────────┤ +│bcdDevice │ 0x100 │ +├───────────────────┼─────────────┤ +│iManufacturer │ 0x1 │ +├───────────────────┼─────────────┤ +│iProduct │ 0x2 │ +├───────────────────┼─────────────┤ +│iSerialNumber │ 0x3 │ +├───────────────────┼─────────────┤ +│bNumConfigurations │ 0x1 │ +└───────────────────┴─────────────┘ +I (480) TinyUSB: TinyUSB Driver installed +I (480) example: USB initialization DONE +I (2490) example: Sending Keyboard report +I (3040) example: Sending Mouse report +``` diff --git a/tests/c_headers/idf-usb/device/tusb_hid/main/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_hid/main/CMakeLists.txt new file mode 100644 index 00000000..ed6a4b2d --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_hid/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS "tusb_hid_example_main.c" + INCLUDE_DIRS "." + PRIV_REQUIRES esp_driver_gpio + ) diff --git a/tests/c_headers/idf-usb/device/tusb_hid/main/idf_component.yml b/tests/c_headers/idf-usb/device/tusb_hid/main/idf_component.yml new file mode 100644 index 00000000..b60893c8 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_hid/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_tinyusb: "^1.1" + idf: "^5.0" diff --git a/tests/c_headers/idf-usb/device/tusb_hid/main/tusb_hid_example_main.c b/tests/c_headers/idf-usb/device/tusb_hid/main/tusb_hid_example_main.c new file mode 100644 index 00000000..6ac29716 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_hid/main/tusb_hid_example_main.c @@ -0,0 +1,194 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "tinyusb.h" +#include "class/hid/hid_device.h" +#include "driver/gpio.h" + +#define APP_BUTTON (GPIO_NUM_0) // Use BOOT signal by default +static const char *TAG = "example"; + +/************* TinyUSB descriptors ****************/ + +#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_HID * TUD_HID_DESC_LEN) + +/** + * @brief HID report descriptor + * + * In this example we implement Keyboard + Mouse HID device, + * so we must define both report descriptors + */ +const uint8_t hid_report_descriptor[] = { + TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(HID_ITF_PROTOCOL_KEYBOARD)), + TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(HID_ITF_PROTOCOL_MOUSE)) +}; + +/** + * @brief String descriptor + */ +const char* hid_string_descriptor[5] = { + // array of pointer to string descriptors + (char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + "123456", // 3: Serials, should use chip ID + "Example HID interface", // 4: HID +}; + +/** + * @brief Configuration descriptor + * + * This is a simple configuration descriptor that defines 1 configuration and 1 HID interface + */ +static const uint8_t hid_configuration_descriptor[] = { + // Configuration number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, 1, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + + // Interface number, string index, boot protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(0, 4, false, sizeof(hid_report_descriptor), 0x81, 16, 10), +}; + +/********* TinyUSB HID callbacks ***************/ + +// Invoked when received GET HID REPORT DESCRIPTOR request +// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete +uint8_t const *tud_hid_descriptor_report_cb(uint8_t instance) +{ + // We use only one interface and one HID report descriptor, so we can ignore parameter 'instance' + return hid_report_descriptor; +} + +// Invoked when received GET_REPORT control request +// Application must fill buffer report's content and return its length. +// Return zero will cause the stack to STALL request +uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) +{ + (void) instance; + (void) report_id; + (void) report_type; + (void) buffer; + (void) reqlen; + + return 0; +} + +// Invoked when received SET_REPORT control request or +// received data on OUT endpoint ( Report ID = 0, Type = 0 ) +void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) +{ +} + +/********* Application ***************/ + +typedef enum { + MOUSE_DIR_RIGHT, + MOUSE_DIR_DOWN, + MOUSE_DIR_LEFT, + MOUSE_DIR_UP, + MOUSE_DIR_MAX, +} mouse_dir_t; + +#define DISTANCE_MAX 125 +#define DELTA_SCALAR 5 + +static void mouse_draw_square_next_delta(int8_t *delta_x_ret, int8_t *delta_y_ret) +{ + static mouse_dir_t cur_dir = MOUSE_DIR_RIGHT; + static uint32_t distance = 0; + + // Calculate next delta + if (cur_dir == MOUSE_DIR_RIGHT) { + *delta_x_ret = DELTA_SCALAR; + *delta_y_ret = 0; + } else if (cur_dir == MOUSE_DIR_DOWN) { + *delta_x_ret = 0; + *delta_y_ret = DELTA_SCALAR; + } else if (cur_dir == MOUSE_DIR_LEFT) { + *delta_x_ret = -DELTA_SCALAR; + *delta_y_ret = 0; + } else if (cur_dir == MOUSE_DIR_UP) { + *delta_x_ret = 0; + *delta_y_ret = -DELTA_SCALAR; + } + + // Update cumulative distance for current direction + distance += DELTA_SCALAR; + // Check if we need to change direction + if (distance >= DISTANCE_MAX) { + distance = 0; + cur_dir++; + if (cur_dir == MOUSE_DIR_MAX) { + cur_dir = 0; + } + } +} + +static void app_send_hid_demo(void) +{ + // Keyboard output: Send key 'a/A' pressed and released + ESP_LOGI(TAG, "Sending Keyboard report"); + uint8_t keycode[6] = {HID_KEY_A}; + tud_hid_keyboard_report(HID_ITF_PROTOCOL_KEYBOARD, 0, keycode); + vTaskDelay(pdMS_TO_TICKS(50)); + tud_hid_keyboard_report(HID_ITF_PROTOCOL_KEYBOARD, 0, NULL); + + // Mouse output: Move mouse cursor in square trajectory + ESP_LOGI(TAG, "Sending Mouse report"); + int8_t delta_x; + int8_t delta_y; + for (int i = 0; i < (DISTANCE_MAX / DELTA_SCALAR) * 4; i++) { + // Get the next x and y delta in the draw square pattern + mouse_draw_square_next_delta(&delta_x, &delta_y); + tud_hid_mouse_report(HID_ITF_PROTOCOL_MOUSE, 0x00, delta_x, delta_y, 0, 0); + vTaskDelay(pdMS_TO_TICKS(20)); + } +} + +void app_main(void) +{ + // Initialize button that will trigger HID reports + const gpio_config_t boot_button_config = { + .pin_bit_mask = BIT64(APP_BUTTON), + .mode = GPIO_MODE_INPUT, + .intr_type = GPIO_INTR_DISABLE, + .pull_up_en = true, + .pull_down_en = false, + }; + ESP_ERROR_CHECK(gpio_config(&boot_button_config)); + + ESP_LOGI(TAG, "USB initialization"); + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = hid_string_descriptor, + .string_descriptor_count = sizeof(hid_string_descriptor) / sizeof(hid_string_descriptor[0]), + .external_phy = false, +#if (TUD_OPT_HIGH_SPEED) + .fs_configuration_descriptor = hid_configuration_descriptor, // HID configuration descriptor for full-speed and high-speed are the same + .hs_configuration_descriptor = hid_configuration_descriptor, + .qualifier_descriptor = NULL, +#else + .configuration_descriptor = hid_configuration_descriptor, +#endif // TUD_OPT_HIGH_SPEED + }; + + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + ESP_LOGI(TAG, "USB initialization DONE"); + + while (1) { + if (tud_mounted()) { + static bool send_hid_data = true; + if (send_hid_data) { + app_send_hid_demo(); + } + send_hid_data = !gpio_get_level(APP_BUTTON); + } + vTaskDelay(pdMS_TO_TICKS(100)); + } +} diff --git a/tests/c_headers/idf-usb/device/tusb_hid/pytest_usb_device_hid.py b/tests/c_headers/idf-usb/device/tusb_hid/pytest_usb_device_hid.py new file mode 100644 index 00000000..986b293f --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_hid/pytest_usb_device_hid.py @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize + + +@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') +@pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) +def test_usb_device_hid_example(dut: Dut) -> None: + dut.expect_exact('USB initialization DONE') + dut.expect_exact('Sending Keyboard report') + dut.expect_exact('Sending Mouse report') diff --git a/tests/c_headers/idf-usb/device/tusb_hid/sdkconfig.defaults b/tests/c_headers/idf-usb/device/tusb_hid/sdkconfig.defaults new file mode 100644 index 00000000..0dc3a98d --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_hid/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_TINYUSB_HID_COUNT=1 diff --git a/tests/c_headers/idf-usb/device/tusb_midi/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_midi/CMakeLists.txt new file mode 100644 index 00000000..91e90baa --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_midi/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(tusb_midi) diff --git a/tests/c_headers/idf-usb/device/tusb_midi/README.md b/tests/c_headers/idf-usb/device/tusb_midi/README.md new file mode 100644 index 00000000..7007230d --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_midi/README.md @@ -0,0 +1,83 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# TinyUSB MIDI Device Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example shows how to set up ESP chip to work as a USB MIDI Device. +It outputs a MIDI note sequence via the native USB port. + +As a USB stack, a TinyUSB component is used. + +## How to use example + +### Hardware Required + +Any ESP board that have USB-OTG supported. + +#### Pin Assignment + +_Note:_ In case your board doesn't have micro-USB connector connected to USB-OTG peripheral, you may have to DIY a cable and connect **D+** and **D-** to the pins listed below. + +See common pin assignments for USB Device examples from [upper level](../../README.md#common-pin-assignments). + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +```bash +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## MIDI output + +You can use several programs on your computer to listen to the ESP's MIDI output depending on your operating system, e.g.: + +* Windows: `MIDI-OX` +* Linux: `qsynth` with `qjackctl` +* macOS: `SimpleSynth` + +## Example Output + +After the flashing you should see the output at idf monitor: + +``` +I (285) example: USB initialization +I (285) tusb_desc: +┌─────────────────────────────────┐ +│ USB Device Descriptor Summary │ +├───────────────────┬─────────────┤ +│bDeviceClass │ 0 │ +├───────────────────┼─────────────┤ +│bDeviceSubClass │ 0 │ +├───────────────────┼─────────────┤ +│bDeviceProtocol │ 0 │ +├───────────────────┼─────────────┤ +│bMaxPacketSize0 │ 64 │ +├───────────────────┼─────────────┤ +│idVendor │ 0x303a │ +├───────────────────┼─────────────┤ +│idProduct │ 0x4008 │ +├───────────────────┼─────────────┤ +│bcdDevice │ 0x100 │ +├───────────────────┼─────────────┤ +│iManufacturer │ 0x1 │ +├───────────────────┼─────────────┤ +│iProduct │ 0x2 │ +├───────────────────┼─────────────┤ +│iSerialNumber │ 0x3 │ +├───────────────────┼─────────────┤ +│bNumConfigurations │ 0x1 │ +└───────────────────┴─────────────┘ +I (455) TinyUSB: TinyUSB Driver installed +I (465) example: USB initialization DONE +``` + +Disconnect UART-to-USB port and connect the native USB port to a computer then the device should show up as a USB MIDI Device while outputting notes. diff --git a/tests/c_headers/idf-usb/device/tusb_midi/main/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_midi/main/CMakeLists.txt new file mode 100644 index 00000000..01775bf6 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_midi/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "tusb_midi_main.c" + INCLUDE_DIRS "." + PRIV_REQUIRES esp_timer + ) diff --git a/tests/c_headers/idf-usb/device/tusb_midi/main/idf_component.yml b/tests/c_headers/idf-usb/device/tusb_midi/main/idf_component.yml new file mode 100644 index 00000000..b60893c8 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_midi/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_tinyusb: "^1.1" + idf: "^5.0" diff --git a/tests/c_headers/idf-usb/device/tusb_midi/main/tusb_midi_main.c b/tests/c_headers/idf-usb/device/tusb_midi/main/tusb_midi_main.c new file mode 100644 index 00000000..04fe850b --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_midi/main/tusb_midi_main.c @@ -0,0 +1,185 @@ +/* + * SPDX-FileCopyrightText: 2019 Ha Thach (tinyusb.org) + * + * SPDX-License-Identifier: MIT + * + * SPDX-FileContributor: 2022-2024 Espressif Systems (Shanghai) CO LTD + */ + +#include +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "tinyusb.h" +#include "esp_timer.h" + +static const char *TAG = "example"; + +/** Helper defines **/ + +// Interface counter +enum interface_count { +#if CFG_TUD_MIDI + ITF_NUM_MIDI = 0, + ITF_NUM_MIDI_STREAMING, +#endif + ITF_COUNT +}; + +// USB Endpoint numbers +enum usb_endpoints { + // Available USB Endpoints: 5 IN/OUT EPs and 1 IN EP + EP_EMPTY = 0, +#if CFG_TUD_MIDI + EPNUM_MIDI, +#endif +}; + +/** TinyUSB descriptors **/ + +#define TUSB_DESCRIPTOR_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_MIDI * TUD_MIDI_DESC_LEN) + +/** + * @brief String descriptor + */ +static const char* s_str_desc[5] = { + // array of pointer to string descriptors + (char[]){0x09, 0x04}, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + "123456", // 3: Serials, should use chip ID + "Example MIDI device", // 4: MIDI +}; + +/** + * @brief Configuration descriptor + * + * This is a simple configuration descriptor that defines 1 configuration and a MIDI interface + */ +static const uint8_t s_midi_cfg_desc[] = { + // Configuration number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_COUNT, 0, TUSB_DESCRIPTOR_TOTAL_LEN, 0, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 4, EPNUM_MIDI, (0x80 | EPNUM_MIDI), 64), +}; + +#if (TUD_OPT_HIGH_SPEED) +/** + * @brief High Speed configuration descriptor + * + * This is a simple configuration descriptor that defines 1 configuration and a MIDI interface + */ +static const uint8_t s_midi_hs_cfg_desc[] = { + // Configuration number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_COUNT, 0, TUSB_DESCRIPTOR_TOTAL_LEN, 0, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 4, EPNUM_MIDI, (0x80 | EPNUM_MIDI), 512), +}; +#endif // TUD_OPT_HIGH_SPEED + +static void midi_task_read_example(void *arg) +{ + // The MIDI interface always creates input and output port/jack descriptors + // regardless of these being used or not. Therefore incoming traffic should be read + // (possibly just discarded) to avoid the sender blocking in IO + uint8_t packet[4]; + bool read = false; + for (;;) { + vTaskDelay(1); + while (tud_midi_available()) { + read = tud_midi_packet_read(packet); + if (read) { + ESP_LOGI(TAG, "Read - Time (ms since boot): %lld, Data: %02hhX %02hhX %02hhX %02hhX", + esp_timer_get_time(), packet[0], packet[1], packet[2], packet[3]); + } + } + } +} + +// Basic MIDI Messages +#define NOTE_OFF 0x80 +#define NOTE_ON 0x90 + +static void periodic_midi_write_example_cb(void *arg) +{ + // Example melody stored as an array of note values + uint8_t const note_sequence[] = { + 74, 78, 81, 86, 90, 93, 98, 102, 57, 61, 66, 69, 73, 78, 81, 85, 88, 92, 97, 100, 97, 92, 88, 85, 81, 78, + 74, 69, 66, 62, 57, 62, 66, 69, 74, 78, 81, 86, 90, 93, 97, 102, 97, 93, 90, 85, 81, 78, 73, 68, 64, 61, + 56, 61, 64, 68, 74, 78, 81, 86, 90, 93, 98, 102 + }; + + static uint8_t const cable_num = 0; // MIDI jack associated with USB endpoint + static uint8_t const channel = 0; // 0 for channel 1 + static uint32_t note_pos = 0; + + // Previous positions in the note sequence. + int previous = note_pos - 1; + + // If we currently are at position 0, set the + // previous position to the last note in the sequence. + if (previous < 0) { + previous = sizeof(note_sequence) - 1; + } + + // Send Note On for current position at full velocity (127) on channel 1. + ESP_LOGI(TAG, "Writing MIDI data %d", note_sequence[note_pos]); + + if (tud_midi_mounted()) { + uint8_t note_on[3] = {NOTE_ON | channel, note_sequence[note_pos], 127}; + tud_midi_stream_write(cable_num, note_on, 3); + + // Send Note Off for previous note. + uint8_t note_off[3] = {NOTE_OFF | channel, note_sequence[previous], 0}; + tud_midi_stream_write(cable_num, note_off, 3); + } + + // Increment position + note_pos++; + + // If we are at the end of the sequence, start over. + if (note_pos >= sizeof(note_sequence)) { + note_pos = 0; + } +} + +void app_main(void) +{ + ESP_LOGI(TAG, "USB initialization"); + + tinyusb_config_t const tusb_cfg = { + .device_descriptor = NULL, // If device_descriptor is NULL, tinyusb_driver_install() will use Kconfig + .string_descriptor = s_str_desc, + .string_descriptor_count = sizeof(s_str_desc) / sizeof(s_str_desc[0]), + .external_phy = false, +#if (TUD_OPT_HIGH_SPEED) + .fs_configuration_descriptor = s_midi_cfg_desc, // HID configuration descriptor for full-speed and high-speed are the same + .hs_configuration_descriptor = s_midi_hs_cfg_desc, + .qualifier_descriptor = NULL, +#else + .configuration_descriptor = s_midi_cfg_desc, +#endif // TUD_OPT_HIGH_SPEED + }; + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + ESP_LOGI(TAG, "USB initialization DONE"); + + // Periodically send MIDI packets + int const tempo = 286; + const esp_timer_create_args_t periodic_midi_args = { + .callback = &periodic_midi_write_example_cb, + /* name is optional, but may help identify the timer when debugging */ + .name = "periodic_midi" + }; + + ESP_LOGI(TAG, "MIDI write task init"); + esp_timer_handle_t periodic_midi_timer; + ESP_ERROR_CHECK(esp_timer_create(&periodic_midi_args, &periodic_midi_timer)); + ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_midi_timer, tempo * 1000)); + + // Read received MIDI packets + ESP_LOGI(TAG, "MIDI read task init"); + xTaskCreate(midi_task_read_example, "midi_task_read_example", 4 * 1024, NULL, 5, NULL); +} diff --git a/tests/c_headers/idf-usb/device/tusb_midi/pytest_usb_device_midi.py b/tests/c_headers/idf-usb/device/tusb_midi/pytest_usb_device_midi.py new file mode 100644 index 00000000..9c6a5762 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_midi/pytest_usb_device_midi.py @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize + + +@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') +@pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) +def test_usb_device_midi_example(dut: Dut) -> None: + dut.expect_exact('USB initialization DONE') + dut.expect_exact('MIDI write task init') + dut.expect_exact('MIDI read task init') + dut.expect_exact('Writing MIDI data 74') diff --git a/tests/c_headers/idf-usb/device/tusb_midi/sdkconfig.defaults b/tests/c_headers/idf-usb/device/tusb_midi/sdkconfig.defaults new file mode 100644 index 00000000..4708b2ac --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_midi/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_TINYUSB_MIDI_COUNT=1 diff --git a/tests/c_headers/idf-usb/device/tusb_msc/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_msc/CMakeLists.txt new file mode 100644 index 00000000..0863d423 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_msc/CMakeLists.txt @@ -0,0 +1,10 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(tusb_msc) diff --git a/tests/c_headers/idf-usb/device/tusb_msc/README.md b/tests/c_headers/idf-usb/device/tusb_msc/README.md new file mode 100644 index 00000000..134b2ecb --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_msc/README.md @@ -0,0 +1,203 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# TinyUSB Mass Storage Device Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +Mass Storage Devices are one of the most common USB devices. It use Mass Storage Class (MSC) that allow access to their internal data storage. +This example contains code to make ESP based device recognizable by USB-hosts as a USB Mass Storage Device. +It either allows the embedded application i.e. example to access the partition or Host PC accesses the partition over USB MSC. +They can't be allowed to access the partition at the same time. + +This example supports storage media of two types: +1. SPI Flash +2. SD MMC Card + +Data is read/written from/to SPI Flash through wear-levelling APIs. Wear leveling is a technique that helps to distribute wear and tear among sectors more evenly without requiring any attention from the user. As a result, it helps in extending the life of each sector of the Flash memory. + +As a USB stack, a TinyUSB component is used. + +## How to use example + +### Scenarios +1. USB which accesses the ESP MSC Partition is unplugged initially and the board is powered-on. + - Result: Host PC can't access the partition over USB MSC. Application example can perform operations (read, write) on partition. +2. USB which accesses the ESP MSC Partition is already plugged-in at boot time. + - Result: Host PC recongnize it as removable device and can access the partition over USB MSC. Application example can't perform any operation on partition. +3. USB which accesses the ESP MSC Partition is plugged-in at boot-up. After boot-up, it is ejected on Host PC manually by user. + - Result: Host PC can't access the partition over USB MSC. Application example can perform operations (read, write) on partition. +4. USB which accesses the ESP MSC Partition is plugged-in at boot-up. It is then unplugged(removed) from Host PC manually by user. + - Result: The behaviour is different for bus-powered devices and self-powered devices + - (a) Bus-Powered devices - Both Host PC as well as application example can't access the partition over USB MSC. Here, the device will be Powered-off. + - (b) Self-Powered devices - Here, the device can be powered-on even after unplugging the device from Host PC. These behaviour can be further categorize in two ways: + - (i) Self-Powered Devices without VBUS monitoring - Both Host PC as well as application example can't access the partition over USB MSC. + - (ii) Self-Powered Devices with VBUS monitoring - Host PC can't access the partition over USB MSC. Application example can perform operations (read, write) on partition. Here, in ``tinyusb_config_t`` user must set ``self_powered`` to ``true`` and ``vbus_monitor_io`` to GPIO number (``VBUS_MONITORING_GPIO_NUM``) that will be used for VBUS monitoring. + +### Hardware Required + +1. If the storage media is SPI Flash, any ESP board that have USB-OTG is supported. +2. If the storage media is SD MMC Card, any ESP board with SD MMC card slot and an SD card is required. For Ex - ESP32-S3-USB-OTG + +### Pin Assignment + +_Note:_ In case your board doesn't have micro-USB connector connected to USB-OTG peripheral, you may have to DIY a cable and connect **D+** and **D-** to the pins listed below. + +See common pin assignments for USB Device examples from [upper level](../../README.md#common-pin-assignments). + +Next, for Self-Powered Devices with VBUS monitoring, user must set ``self_powered`` to ``true`` and ``vbus_monitor_io`` to GPIO number (``VBUS_MONITORING_GPIO_NUM``) that will be used for VBUS monitoring. + +### Additional Pin assignments for ESP32-S3 for accessing SD MMC Card + +On ESP32-S3, SDMMC peripheral is connected to GPIO pins using GPIO matrix. This allows arbitrary GPIOs to be used to connect an SD card. In this example, GPIOs can be configured in two ways: + +1. Using menuconfig: Run `idf.py menuconfig` in the project directory, open "USB DEV MSC Example Configuration" and select "SDMMC CARD" for "Storage Media Used". +2. In the source code: See the initialization of ``sdmmc_slot_config_t slot_config`` structure in the example code. + +The table below lists the default pin assignments. + +When using an ESP32-S3-USB-OTG board, this example runs without any extra modifications required. Only an SD card needs to be inserted into the slot. + +ESP32-S3 pin | SD card pin | Notes +--------------|-------------|------------ +GPIO36 | CLK | 10k pullup +GPIO35 | CMD | 10k pullup +GPIO37 | D0 | 10k pullup +GPIO38 | D1 | not used in 1-line SD mode; 10k pullup in 4-line mode +GPIO33 | D2 | not used in 1-line SD mode; 10k pullup in 4-line mode +GPIO34 | D3 | not used in 1-line SD mode, but card's D3 pin must have a 10k pullup + +By default, this example uses 4 line SD mode, utilizing 6 pins: CLK, CMD, D0 - D3. It is possible to use 1-line mode (CLK, CMD, D0) by changing "SD/MMC bus width" in the example configuration menu (see `CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_1`). + +Note that even if card's D3 line is not connected to the ESP chip, it still has to be pulled up, otherwise the card will go into SPI protocol mode. + +### Build and Flash + +1. By default, the example will compile to access SPI Flash as storage media. Here, SPI Flash Wear Levelling WL_SECTOR_SIZE is set to 512 and WL_SECTOR_MODE is set to PERF in Menuconfig. +2. In order to access SD MMC card as storage media, configuration has to be changed using `idf.py menuconfig`: + - i. Open "USB Dev MSC Example Configuration" and select "SDMMC CARD" for "Storage Media Used" + - ii. Open "SD/MMC bus width" and select between "4 lines (D0 - D3)" or "1 line (D0)" + - iii. Select the GPIO Pin numbers for SD Card Pin. + - iv. Save the configuration. + +Build the project and flash it to the board, then run monitor tool to view serial output: + +```bash +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +After the flashing you should see the output at idf monitor: + +``` +I (329) app_start: Starting scheduler on CPU0 +I (334) app_start: Starting scheduler on CPU1 +I (334) main_task: Started on CPU0 +I (344) main_task: Calling app_main() +I (344) gpio: GPIO[4]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (354) example_main: Initializing storage... +I (364) example_main: Initializing wear levelling +I (374) example_main: Mount storage... +I (374) example_main: +ls command output: +.fseventsd +_pic.jpg +.__pic.jpg +README.MD +I (384) example_main: USB MSC initialization +I (384) tusb_desc: +┌─────────────────────────────────┐ +│ USB Device Descriptor Summary │ +├───────────────────┬─────────────┤ +│bDeviceClass │ 239 │ +├───────────────────┼─────────────┤ +│bDeviceSubClass │ 2 │ +├───────────────────┼─────────────┤ +│bDeviceProtocol │ 1 │ +├───────────────────┼─────────────┤ +│bMaxPacketSize0 │ 64 │ +├───────────────────┼─────────────┤ +│idVendor │ 0x303a │ +├───────────────────┼─────────────┤ +│idProduct │ 0x4002 │ +├───────────────────┼─────────────┤ +│bcdDevice │ 0x100 │ +├───────────────────┼─────────────┤ +│iManufacturer │ 0x1 │ +├───────────────────┼─────────────┤ +│iProduct │ 0x2 │ +├───────────────────┼─────────────┤ +│iSerialNumber │ 0x3 │ +├───────────────────┼─────────────┤ +│bNumConfigurations │ 0x1 │ +└───────────────────┴─────────────┘ +I (554) TinyUSB: TinyUSB Driver installed +I (564) example_main: USB MSC initialization DONE + +Type 'help' to get the list of commands. +Use UP/DOWN arrows to navigate through command history. +Press TAB when typing command name to auto-complete. +I (724) main_task: Returned from app_main() +esp32s3> +esp32s3> help +help + Print the list of registered commands + +read + read BASE_PATH/README.MD and print its contents + +write + create file BASE_PATH/README.MD if it does not exist + +size + show storage size and sector size + +expose + Expose Storage to Host + +status + Status of storage exposure over USB + +exit + exit from application + +esp32s3> +esp32s3> read +E (80054) example_main: storage exposed over USB. Application can't read from storage. +Command returned non-zero error code: 0xffffffff (ESP_FAIL) +esp32s3> write +E (83134) example_main: storage exposed over USB. Application can't write to storage. +Command returned non-zero error code: 0xffffffff (ESP_FAIL) +esp32s3> size +E (85354) example_main: storage exposed over USB. Application can't access storage +Command returned non-zero error code: 0xffffffff (ESP_FAIL) +esp32s3> status +storage exposed over USB: Yes +esp32s3> expose +E (108344) example_main: storage is already exposed +Command returned non-zero error code: 0xffffffff (ESP_FAIL) +esp32s3> +esp32s3> +esp32s3> read +Mass Storage Devices are one of the most common USB devices. It use Mass Storage Class (MSC) that allow access to their internal data storage. +In this example, ESP chip will be recognised by host (PC) as Mass Storage Device. +Upon connection to USB host (PC), the example application will initialize the storage module and then the storage will be seen as removable device on PC. +esp32s3> write +esp32s3> size +Storage Capacity 0MB +esp32s3> status +storage exposed over USB: No +esp32s3> expose +I (181224) example_main: Unmount storage... +esp32s3> status +storage exposed over USB: Yes +esp32s3> +esp32s3> +``` diff --git a/tests/c_headers/idf-usb/device/tusb_msc/main/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_msc/main/CMakeLists.txt new file mode 100644 index 00000000..7c7438e1 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_msc/main/CMakeLists.txt @@ -0,0 +1,11 @@ +set(priv_requires fatfs console) + +if(CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH) + list(APPEND priv_requires wear_levelling esp_partition) +endif() + +idf_component_register( + SRCS "tusb_msc_main.c" + INCLUDE_DIRS . + PRIV_REQUIRES "${priv_requires}" +) diff --git a/tests/c_headers/idf-usb/device/tusb_msc/main/Kconfig.projbuild b/tests/c_headers/idf-usb/device/tusb_msc/main/Kconfig.projbuild new file mode 100644 index 00000000..a43bb71a --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_msc/main/Kconfig.projbuild @@ -0,0 +1,100 @@ +menu "TinyUSB MSC Example Configuration" + + orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" + + choice EXAMPLE_STORAGE_MEDIA + prompt "Storage Media Used" + default EXAMPLE_STORAGE_MEDIA_SPIFLASH + help + Select the storage media that is exposed to USB host. + + config EXAMPLE_STORAGE_MEDIA_SPIFLASH + bool "SPI FLASH" + + config EXAMPLE_STORAGE_MEDIA_SDMMC + bool "SDMMC CARD" + depends on IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32P4 + endchoice + + if EXAMPLE_STORAGE_MEDIA_SDMMC + + choice EXAMPLE_SDMMC_BUS_WIDTH + prompt "SD/MMC bus width" + default EXAMPLE_SDMMC_BUS_WIDTH_4 + help + Select the bus width of SD or MMC interface. + Note that even if 1 line mode is used, D3 pin of the SD card must + have a pull-up resistor connected. Otherwise the card may enter + SPI mode, the only way to recover from which is to cycle power to the card. + + config EXAMPLE_SDMMC_BUS_WIDTH_4 + bool "4 lines (D0 - D3)" + + config EXAMPLE_SDMMC_BUS_WIDTH_1 + bool "1 line (D0)" + endchoice + + if SOC_SDMMC_USE_GPIO_MATRIX + + config EXAMPLE_PIN_CMD + int "CMD GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 35 if IDF_TARGET_ESP32S3 + default 44 if IDF_TARGET_ESP32P4 + + config EXAMPLE_PIN_CLK + int "CLK GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX + default 36 if IDF_TARGET_ESP32S3 + default 43 if IDF_TARGET_ESP32P4 + + config EXAMPLE_PIN_D0 + int "D0 GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 37 if IDF_TARGET_ESP32S3 + default 39 if IDF_TARGET_ESP32P4 + + if EXAMPLE_SDMMC_BUS_WIDTH_4 + + config EXAMPLE_PIN_D1 + int "D1 GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 38 if IDF_TARGET_ESP32S3 + default 40 if IDF_TARGET_ESP32P4 + + config EXAMPLE_PIN_D2 + int "D2 GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 33 if IDF_TARGET_ESP32S3 + default 41 if IDF_TARGET_ESP32P4 + + config EXAMPLE_PIN_D3 + int "D3 GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 34 if IDF_TARGET_ESP32S3 + default 42 if IDF_TARGET_ESP32P4 + + endif # EXAMPLE_SDMMC_BUS_WIDTH_4 + + endif # SOC_SDMMC_USE_GPIO_MATRIX + + config EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + depends on SOC_SDMMC_IO_POWER_EXTERNAL + bool "SDMMC powered by internal LDO" + default y + help + Enable when internal LDO of ESP32-P4 is used as a power supply for SD card. Specify the LDO IO. + Disable when external power supply is used as a power supply for SD card. + + config EXAMPLE_SD_PWR_CTRL_LDO_IO_ID + depends on SOC_SDMMC_IO_POWER_EXTERNAL && EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + int "LDO IO" + default 4 if IDF_TARGET_ESP32P4 + help + There are several IOs in ESP32-P4 which are in "SD card IO" power domain. + Power has to be supplied to this power domain externally (from outside the chip) via one of the pins. + Based on the schematic, specify the LDO IO pin. + + endif # EXAMPLE_STORAGE_MEDIA_SDMMC + +endmenu diff --git a/tests/c_headers/idf-usb/device/tusb_msc/main/idf_component.yml b/tests/c_headers/idf-usb/device/tusb_msc/main/idf_component.yml new file mode 100644 index 00000000..1659a1eb --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_msc/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_tinyusb: "^1.4.2" + idf: "^5.0" diff --git a/tests/c_headers/idf-usb/device/tusb_msc/main/tusb_msc_main.c b/tests/c_headers/idf-usb/device/tusb_msc/main/tusb_msc_main.c new file mode 100644 index 00000000..ccea2ba6 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_msc/main/tusb_msc_main.c @@ -0,0 +1,491 @@ +/* + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +/* DESCRIPTION: + * This example contains code to make ESP32 based device recognizable by USB-hosts as a USB Mass Storage Device. + * It either allows the embedded application i.e. example to access the partition or Host PC accesses the partition over USB MSC. + * They can't be allowed to access the partition at the same time. + * For different scenarios and behaviour, Refer to README of this example. + */ + +#include +#include +#include +#include "sdkconfig.h" +#include "esp_console.h" +#include "esp_check.h" +#include "esp_partition.h" +#include "driver/gpio.h" +#include "tinyusb.h" +#include "tusb_msc_storage.h" +#ifdef CONFIG_EXAMPLE_STORAGE_MEDIA_SDMMC +#include "sdmmc_cmd.h" +#include "diskio_impl.h" +#include "diskio_sdmmc.h" +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO +#include "sd_pwr_ctrl_by_on_chip_ldo.h" +#endif // CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO +#endif + +/* + * We warn if a secondary serial console is enabled. A secondary serial console is always output-only and + * hence not very useful for interactive console applications. If you encounter this warning, consider disabling + * the secondary serial console in menuconfig unless you know what you are doing. + */ +#if SOC_USB_SERIAL_JTAG_SUPPORTED +#if !CONFIG_ESP_CONSOLE_SECONDARY_NONE +#warning "A secondary serial console is not useful when using the console component. Please disable it in menuconfig." +#endif +#endif + +static const char *TAG = "example_main"; +static esp_console_repl_t *repl = NULL; + +static SemaphoreHandle_t _wait_console_smp = NULL; + +/* TinyUSB descriptors + ********************************************************************* */ +#define EPNUM_MSC 1 +#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_MSC_DESC_LEN) + +enum { + ITF_NUM_MSC = 0, + ITF_NUM_TOTAL +}; + +enum { + EDPT_CTRL_OUT = 0x00, + EDPT_CTRL_IN = 0x80, + + EDPT_MSC_OUT = 0x01, + EDPT_MSC_IN = 0x81, +}; + +static tusb_desc_device_t descriptor_config = { + .bLength = sizeof(descriptor_config), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .idVendor = 0x303A, // This is Espressif VID. This needs to be changed according to Users / Customers + .idProduct = 0x4002, + .bcdDevice = 0x100, + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + .bNumConfigurations = 0x01 +}; + +static uint8_t const msc_fs_configuration_desc[] = { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, 64), +}; + +#if (TUD_OPT_HIGH_SPEED) +static const tusb_desc_device_qualifier_t device_qualifier = { + .bLength = sizeof(tusb_desc_device_qualifier_t), + .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER, + .bcdUSB = 0x0200, + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bNumConfigurations = 0x01, + .bReserved = 0 +}; + +static uint8_t const msc_hs_configuration_desc[] = { + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EDPT_MSC_OUT, EDPT_MSC_IN, 512), +}; +#endif // TUD_OPT_HIGH_SPEED + +static char const *string_desc_arr[] = { + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + "123456", // 3: Serials + "Example MSC", // 4. MSC +}; +/*********************************************************************** TinyUSB descriptors*/ + +#define BASE_PATH "/data" // base path to mount the partition + +#define PROMPT_STR CONFIG_IDF_TARGET +static int console_unmount(int argc, char **argv); +static int console_read(int argc, char **argv); +static int console_write(int argc, char **argv); +static int console_size(int argc, char **argv); +static int console_status(int argc, char **argv); +static int console_exit(int argc, char **argv); +const esp_console_cmd_t cmds[] = { + { + .command = "read", + .help = "read BASE_PATH/README.MD and print its contents", + .hint = NULL, + .func = &console_read, + }, + { + .command = "write", + .help = "create file BASE_PATH/README.MD if it does not exist", + .hint = NULL, + .func = &console_write, + }, + { + .command = "size", + .help = "show storage size and sector size", + .hint = NULL, + .func = &console_size, + }, + { + .command = "expose", + .help = "Expose Storage to Host", + .hint = NULL, + .func = &console_unmount, + }, + { + .command = "status", + .help = "Status of storage exposure over USB", + .hint = NULL, + .func = &console_status, + }, + { + .command = "exit", + .help = "exit from application", + .hint = NULL, + .func = &console_exit, + } +}; + +// mount the partition and show all the files in BASE_PATH +static void _mount(void) +{ + ESP_LOGI(TAG, "Mount storage..."); + ESP_ERROR_CHECK(tinyusb_msc_storage_mount(BASE_PATH)); + + // List all the files in this directory + ESP_LOGI(TAG, "\nls command output:"); + struct dirent *d; + DIR *dh = opendir(BASE_PATH); + if (!dh) { + if (errno == ENOENT) { + //If the directory is not found + ESP_LOGE(TAG, "Directory doesn't exist %s", BASE_PATH); + } else { + //If the directory is not readable then throw error and exit + ESP_LOGE(TAG, "Unable to read directory %s", BASE_PATH); + } + return; + } + //While the next entry is not readable we will print directory files + while ((d = readdir(dh)) != NULL) { + printf("%s\n", d->d_name); + } + return; +} + +// unmount storage +static int console_unmount(int argc, char **argv) +{ + if (tinyusb_msc_storage_in_use_by_usb_host()) { + ESP_LOGE(TAG, "storage is already exposed"); + return -1; + } + ESP_LOGI(TAG, "Unmount storage..."); + ESP_ERROR_CHECK(tinyusb_msc_storage_unmount()); + return 0; +} + +// read BASE_PATH/README.MD and print its contents +static int console_read(int argc, char **argv) +{ + if (tinyusb_msc_storage_in_use_by_usb_host()) { + ESP_LOGE(TAG, "storage exposed over USB. Application can't read from storage."); + return -1; + } + ESP_LOGD(TAG, "read from storage:"); + const char *filename = BASE_PATH "/README.MD"; + FILE *ptr = fopen(filename, "r"); + if (ptr == NULL) { + ESP_LOGE(TAG, "Filename not present - %s", filename); + return -1; + } + char buf[1024]; + while (fgets(buf, 1000, ptr) != NULL) { + printf("%s", buf); + } + fclose(ptr); + return 0; +} + +// create file BASE_PATH/README.MD if it does not exist +static int console_write(int argc, char **argv) +{ + if (tinyusb_msc_storage_in_use_by_usb_host()) { + ESP_LOGE(TAG, "storage exposed over USB. Application can't write to storage."); + return -1; + } + ESP_LOGD(TAG, "write to storage:"); + const char *filename = BASE_PATH "/README.MD"; + FILE *fd = fopen(filename, "r"); + if (!fd) { + ESP_LOGW(TAG, "README.MD doesn't exist yet, creating"); + fd = fopen(filename, "w"); + fprintf(fd, "Mass Storage Devices are one of the most common USB devices. It use Mass Storage Class (MSC) that allow access to their internal data storage.\n"); + fprintf(fd, "In this example, ESP chip will be recognised by host (PC) as Mass Storage Device.\n"); + fprintf(fd, "Upon connection to USB host (PC), the example application will initialize the storage module and then the storage will be seen as removable device on PC.\n"); + fclose(fd); + } + return 0; +} + +// Show storage size and sector size +static int console_size(int argc, char **argv) +{ + if (tinyusb_msc_storage_in_use_by_usb_host()) { + ESP_LOGE(TAG, "storage exposed over USB. Application can't access storage"); + return -1; + } + uint32_t sec_count = tinyusb_msc_storage_get_sector_count(); + uint32_t sec_size = tinyusb_msc_storage_get_sector_size(); + printf("Storage Capacity %lluMB\n", ((uint64_t) sec_count) * sec_size / (1024 * 1024)); + return 0; +} + +// Show storage status +static int console_status(int argc, char **argv) +{ + printf("storage exposed over USB: %s\n", tinyusb_msc_storage_in_use_by_usb_host() ? "Yes" : "No"); + return 0; +} + +// Exit from application +static int console_exit(int argc, char **argv) +{ + tinyusb_msc_unregister_callback(TINYUSB_MSC_EVENT_MOUNT_CHANGED); + tinyusb_msc_storage_deinit(); + tinyusb_driver_uninstall(); + + xSemaphoreGive(_wait_console_smp); + + printf("Application Exit\n"); + + return 0; +} + +// callback that is delivered when storage is mounted/unmounted by application. +static void storage_mount_changed_cb(tinyusb_msc_event_t *event) +{ + ESP_LOGI(TAG, "Storage mounted to application: %s", event->mount_changed_data.is_mounted ? "Yes" : "No"); +} + +#ifdef CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH +static esp_err_t storage_init_spiflash(wl_handle_t *wl_handle) +{ + ESP_LOGI(TAG, "Initializing wear levelling"); + + const esp_partition_t *data_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL); + if (data_partition == NULL) { + ESP_LOGE(TAG, "Failed to find FATFS partition. Check the partition table."); + return ESP_ERR_NOT_FOUND; + } + + return wl_mount(data_partition, wl_handle); +} +#else // CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH +static esp_err_t storage_init_sdmmc(sdmmc_card_t **card) +{ + esp_err_t ret = ESP_OK; + bool host_init = false; + sdmmc_card_t *sd_card; + + ESP_LOGI(TAG, "Initializing SDCard"); + + // By default, SD card frequency is initialized to SDMMC_FREQ_DEFAULT (20MHz) + // For setting a specific frequency, use host.max_freq_khz (range 400kHz - 40MHz for SDMMC) + // Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000; + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + + // For SoCs where the SD power can be supplied both via an internal or external (e.g. on-board LDO) power supply. + // When using specific IO pins (which can be used for ultra high-speed SDMMC) to connect to the SD card + // and the internal LDO power supply, we need to initialize the power supply first. +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + sd_pwr_ctrl_ldo_config_t ldo_config = { + .ldo_chan_id = CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_IO_ID, + }; + sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; + + ret = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to create a new on-chip LDO power control driver"); + return ret; + } + host.pwr_ctrl_handle = pwr_ctrl_handle; +#endif + + // This initializes the slot without card detect (CD) and write protect (WP) signals. + // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + + // For SD Card, set bus width to use +#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4 + slot_config.width = 4; +#else + slot_config.width = 1; +#endif // CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4 + + // On chips where the GPIOs used for SD card can be configured, set the user defined values +#ifdef CONFIG_SOC_SDMMC_USE_GPIO_MATRIX + slot_config.clk = CONFIG_EXAMPLE_PIN_CLK; + slot_config.cmd = CONFIG_EXAMPLE_PIN_CMD; + slot_config.d0 = CONFIG_EXAMPLE_PIN_D0; +#ifdef CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4 + slot_config.d1 = CONFIG_EXAMPLE_PIN_D1; + slot_config.d2 = CONFIG_EXAMPLE_PIN_D2; + slot_config.d3 = CONFIG_EXAMPLE_PIN_D3; +#endif // CONFIG_EXAMPLE_SDMMC_BUS_WIDTH_4 + +#endif // CONFIG_SOC_SDMMC_USE_GPIO_MATRIX + + // Enable internal pullups on enabled pins. The internal pullups + // are insufficient however, please make sure 10k external pullups are + // connected on the bus. This is for debug / example purpose only. + slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP; + + // not using ff_memalloc here, as allocation in internal RAM is preferred + sd_card = (sdmmc_card_t *)malloc(sizeof(sdmmc_card_t)); + ESP_GOTO_ON_FALSE(sd_card, ESP_ERR_NO_MEM, clean, TAG, "could not allocate new sdmmc_card_t"); + + ESP_GOTO_ON_ERROR((*host.init)(), clean, TAG, "Host Config Init fail"); + host_init = true; + + ESP_GOTO_ON_ERROR(sdmmc_host_init_slot(host.slot, (const sdmmc_slot_config_t *) &slot_config), + clean, TAG, "Host init slot fail"); + + while (sdmmc_card_init(&host, sd_card)) { + ESP_LOGE(TAG, "The detection pin of the slot is disconnected(Insert uSD card). Retrying..."); + vTaskDelay(pdMS_TO_TICKS(3000)); + } + + // Card has been initialized, print its properties + sdmmc_card_print_info(stdout, sd_card); + *card = sd_card; + + return ESP_OK; + +clean: + if (host_init) { + if (host.flags & SDMMC_HOST_FLAG_DEINIT_ARG) { + host.deinit_p(host.slot); + } else { + (*host.deinit)(); + } + } + if (sd_card) { + free(sd_card); + sd_card = NULL; + } +#if CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + // We don't need to duplicate error here as all error messages are handled via sd_pwr_* call + sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle); +#endif // CONFIG_EXAMPLE_SD_PWR_CTRL_LDO_INTERNAL_IO + return ret; +} +#endif // CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH + +void app_main(void) +{ + ESP_LOGI(TAG, "Initializing storage..."); + + _wait_console_smp = xSemaphoreCreateBinary(); + if (_wait_console_smp == NULL) { + ESP_LOGE(TAG, "Failed to create semaphore"); + return; + } + +#ifdef CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH + static wl_handle_t wl_handle = WL_INVALID_HANDLE; + ESP_ERROR_CHECK(storage_init_spiflash(&wl_handle)); + + const tinyusb_msc_spiflash_config_t config_spi = { + .wl_handle = wl_handle, + .callback_mount_changed = storage_mount_changed_cb, /* First way to register the callback. This is while initializing the storage. */ + .mount_config.max_files = 5, + }; + ESP_ERROR_CHECK(tinyusb_msc_storage_init_spiflash(&config_spi)); + ESP_ERROR_CHECK(tinyusb_msc_register_callback(TINYUSB_MSC_EVENT_MOUNT_CHANGED, storage_mount_changed_cb)); /* Other way to register the callback i.e. registering using separate API. If the callback had been already registered, it will be overwritten. */ +#else // CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH + static sdmmc_card_t *card = NULL; + ESP_ERROR_CHECK(storage_init_sdmmc(&card)); + + const tinyusb_msc_sdmmc_config_t config_sdmmc = { + .card = card, + .callback_mount_changed = storage_mount_changed_cb, /* First way to register the callback. This is while initializing the storage. */ + .mount_config.max_files = 5, + }; + ESP_ERROR_CHECK(tinyusb_msc_storage_init_sdmmc(&config_sdmmc)); + ESP_ERROR_CHECK(tinyusb_msc_register_callback(TINYUSB_MSC_EVENT_MOUNT_CHANGED, storage_mount_changed_cb)); /* Other way to register the callback i.e. registering using separate API. If the callback had been already registered, it will be overwritten. */ +#endif // CONFIG_EXAMPLE_STORAGE_MEDIA_SPIFLASH + + //mounted in the app by default + _mount(); + + ESP_LOGI(TAG, "USB MSC initialization"); + const tinyusb_config_t tusb_cfg = { + .device_descriptor = &descriptor_config, + .string_descriptor = string_desc_arr, + .string_descriptor_count = sizeof(string_desc_arr) / sizeof(string_desc_arr[0]), + .external_phy = false, +#if (TUD_OPT_HIGH_SPEED) + .fs_configuration_descriptor = msc_fs_configuration_desc, + .hs_configuration_descriptor = msc_hs_configuration_desc, + .qualifier_descriptor = &device_qualifier, +#else + .configuration_descriptor = msc_fs_configuration_desc, +#endif // TUD_OPT_HIGH_SPEED + }; + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + ESP_LOGI(TAG, "USB MSC initialization DONE"); + + esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + /* Prompt to be printed before each line. + * This can be customized, made dynamic, etc. + */ + repl_config.prompt = PROMPT_STR ">"; + repl_config.max_cmdline_length = 64; + + // Init console based on menuconfig settings +#if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) || defined(CONFIG_ESP_CONSOLE_UART_CUSTOM) + esp_console_dev_uart_config_t hw_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_uart(&hw_config, &repl_config, &repl)); + + // USJ console can be set only on esp32p4, having separate USB PHYs for USB_OTG and USJ +#elif defined(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG) && defined(CONFIG_IDF_TARGET_ESP32P4) + esp_console_dev_usb_serial_jtag_config_t hw_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&hw_config, &repl_config, &repl)); + +#else +#error Unsupported console type +#endif + + for (int count = 0; count < sizeof(cmds) / sizeof(esp_console_cmd_t); count++) { + ESP_ERROR_CHECK(esp_console_cmd_register(&cmds[count])); + } + + ESP_ERROR_CHECK(esp_console_start_repl(repl)); + + xSemaphoreTake(_wait_console_smp, portMAX_DELAY); + ESP_ERROR_CHECK(esp_console_stop_repl(repl)); + vSemaphoreDelete(_wait_console_smp); +} diff --git a/tests/c_headers/idf-usb/device/tusb_msc/partitions.csv b/tests/c_headers/idf-usb/device/tusb_msc/partitions.csv new file mode 100644 index 00000000..1c79321a --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_msc/partitions.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +storage, data, fat, , 1M, diff --git a/tests/c_headers/idf-usb/device/tusb_msc/pytest_usb_device_msc.py b/tests/c_headers/idf-usb/device/tusb_msc/pytest_usb_device_msc.py new file mode 100644 index 00000000..3503b0e6 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_msc/pytest_usb_device_msc.py @@ -0,0 +1,17 @@ +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize + + +@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') +@pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) +def test_usb_device_msc_example(dut: Dut) -> None: + dut.expect('Mount storage') + dut.expect('TinyUSB Driver installed') + dut.expect('USB MSC initialization DONE') + dut.expect(dut.target + '>') + dut.write('status') + dut.expect('storage exposed over USB') diff --git a/tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.ci b/tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.ci new file mode 100644 index 00000000..e69de29b diff --git a/tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.ci.esp32s3_sdmmc b/tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.ci.esp32s3_sdmmc new file mode 100644 index 00000000..47f8df9f --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.ci.esp32s3_sdmmc @@ -0,0 +1,2 @@ +CONFIG_IDF_TARGET="esp32s3" +CONFIG_EXAMPLE_STORAGE_MEDIA_SDMMC=y diff --git a/tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.defaults b/tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.defaults new file mode 100644 index 00000000..cf5dd194 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_msc/sdkconfig.defaults @@ -0,0 +1,16 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_TINYUSB_MSC_ENABLED=y + +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_WL_SECTOR_SIZE_512=y +CONFIG_WL_SECTOR_MODE_PERF=y + +CONFIG_FATFS_LFN_HEAP=y + +# On chips with USB Serial JTAG, disable secondary console which does not make sense when using console component +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y diff --git a/tests/c_headers/idf-usb/device/tusb_ncm/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_ncm/CMakeLists.txt new file mode 100644 index 00000000..9772549e --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_ncm/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(tusb_ncm) diff --git a/tests/c_headers/idf-usb/device/tusb_ncm/README.md b/tests/c_headers/idf-usb/device/tusb_ncm/README.md new file mode 100644 index 00000000..66e6d6b2 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_ncm/README.md @@ -0,0 +1,103 @@ +| Supported Targets | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | + +# TinyUSB Network Control Model Device Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +Network Control Model (NCM) is a sub-class of Communication Device Class (CDC) USB Device for Ethernet-over-USB applications. + +In this example, we implemented the ESP development board to transmit WiFi data to the Linux or Windows host via USB, so that the host could access the Internet. + +As a USB stack, a TinyUSB component is used. + +## How to use example + +### Hardware Required + +Any ESP board that have USB-OTG supported. + +#### Pin Assignment + +_Note:_ In case your board doesn't have micro-USB connector connected to USB-OTG peripheral, you may have to DIY a cable and connect **D+** and **D-** to the pins listed below. + +See common pin assignments for USB Device examples from [upper level](../../README.md#common-pin-assignments). + +### Configure the project + +Open the project configuration menu (`idf.py menuconfig`). + +In the `Example Configuration` menu: + +* Set the Wi-Fi configuration. + * Set `WiFi SSID`. + * Set `WiFi Password`. + +### Build, Flash, and Run + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT build flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +After the flashing you should see the output at idf monitor: + +``` +I (399) main_task: Calling app_main() +I (429) USB_NCM: USB NCM device initialization +W (429) TinyUSB: The device's configuration descriptor is not provided by user, using default. +W (429) TinyUSB: The device's string descriptor is not provided by user, using default. +W (439) TinyUSB: The device's device descriptor is not provided by user, using default. +I (449) tusb_desc: +┌─────────────────────────────────┐ +│ USB Device Descriptor Summary │ +├───────────────────┬─────────────┤ +│bDeviceClass │ 239 │ +├───────────────────┼─────────────┤ +│bDeviceSubClass │ 2 │ +├───────────────────┼─────────────┤ +│bDeviceProtocol │ 1 │ +├───────────────────┼─────────────┤ +│bMaxPacketSize0 │ 64 │ +├───────────────────┼─────────────┤ +│idVendor │ 0x303a │ +├───────────────────┼─────────────┤ +│idProduct │ 0x4001 │ +├───────────────────┼─────────────┤ +│bcdDevice │ 0x100 │ +├───────────────────┼─────────────┤ +│iManufacturer │ 0x1 │ +├───────────────────┼─────────────┤ +│iProduct │ 0x2 │ +├───────────────────┼─────────────┤ +│iSerialNumber │ 0x3 │ +├───────────────────┼─────────────┤ +│bNumConfigurations │ 0x1 │ +└───────────────────┴─────────────┘ +I (619) TinyUSB: TinyUSB Driver installed +I (619) USB_NCM: WiFi initialization +I (619) pp: pp rom version: e7ae62f +I (629) net80211: net80211 rom version: e7ae62f +I (689) wifi_init: rx ba win: 6 +I (699) wifi_init: tcpip mbox: 32 +I (699) wifi_init: udp mbox: 6 +I (699) wifi_init: tcp mbox: 6 +I (709) wifi_init: tcp tx win: 5744 +I (709) wifi_init: tcp rx win: 5744 +I (719) wifi_init: tcp mss: 1440 +I (719) wifi_init: WiFi IRAM OP enabled +I (719) wifi_init: WiFi RX IRAM OP enabled +I (729) phy_init: phy_version 600,8dd0147,Mar 31 2023,16:34:12 +I (779) USB_NCM: USB NCM and WiFi initialized and started +I (779) main_task: Returned from app_main() +I (849) USB_NCM: WiFi STA connected +``` diff --git a/tests/c_headers/idf-usb/device/tusb_ncm/main/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_ncm/main/CMakeLists.txt new file mode 100644 index 00000000..cb3fe664 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_ncm/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "tusb_ncm_main.c" + INCLUDE_DIRS "" + PRIV_REQUIRES esp_wifi nvs_flash + ) diff --git a/tests/c_headers/idf-usb/device/tusb_ncm/main/Kconfig.projbuild b/tests/c_headers/idf-usb/device/tusb_ncm/main/Kconfig.projbuild new file mode 100644 index 00000000..dd0b5e41 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_ncm/main/Kconfig.projbuild @@ -0,0 +1,15 @@ +menu "Example Configuration" + + config ESP_WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + + config ESP_WIFI_PASSWORD + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + +endmenu diff --git a/tests/c_headers/idf-usb/device/tusb_ncm/main/idf_component.yml b/tests/c_headers/idf-usb/device/tusb_ncm/main/idf_component.yml new file mode 100644 index 00000000..2576181c --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_ncm/main/idf_component.yml @@ -0,0 +1,5 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_tinyusb: + version: "^1.3.0" + idf: "^5.0" diff --git a/tests/c_headers/idf-usb/device/tusb_ncm/main/tusb_ncm_main.c b/tests/c_headers/idf-usb/device/tusb_ncm/main/tusb_ncm_main.c new file mode 100644 index 00000000..79efe53a --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_ncm/main/tusb_ncm_main.c @@ -0,0 +1,126 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +/* DESCRIPTION: + * This example demonstrates using ESP32-S2/S3 as a USB network device. It initializes WiFi in station mode, + * connects and bridges the WiFi and USB networks, so the USB device acts as a standard network interface that + * acquires an IP address from the AP/router which the WiFi station connects to. + */ + +#include + +#include "esp_log.h" +#include "esp_event.h" +#include "esp_check.h" +#include "nvs_flash.h" +#include "esp_mac.h" + +#include "esp_wifi.h" +#include "esp_private/wifi.h" + +#include "tinyusb.h" +#include "tinyusb_net.h" + +static const char *TAG = "USB_NCM"; + +static esp_err_t usb_recv_callback(void *buffer, uint16_t len, void *ctx) +{ + bool *is_wifi_connected = ctx; + if (*is_wifi_connected) { + esp_wifi_internal_tx(ESP_IF_WIFI_STA, buffer, len); + } + return ESP_OK; +} + +static void wifi_pkt_free(void *eb, void *ctx) +{ + esp_wifi_internal_free_rx_buffer(eb); +} + +static esp_err_t pkt_wifi2usb(void *buffer, uint16_t len, void *eb) +{ + if (tinyusb_net_send_sync(buffer, len, eb, portMAX_DELAY) != ESP_OK) { + esp_wifi_internal_free_rx_buffer(eb); + } + return ESP_OK; +} + +static void wifi_event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + bool *is_connected = arg; + + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + ESP_LOGI(TAG, "WiFi STA disconnected"); + *is_connected = false; + esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, NULL); + esp_wifi_connect(); + } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) { + ESP_LOGI(TAG, "WiFi STA connected"); + esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, pkt_wifi2usb); + *is_connected = true; + } +} + +static esp_err_t start_wifi(bool *is_connected) +{ + ESP_RETURN_ON_ERROR(esp_event_loop_create_default(), TAG, "Cannot initialize event loop"); + + wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_RETURN_ON_ERROR(esp_wifi_init(&wifi_cfg), TAG, "Failed to initialize WiFi library"); + ESP_RETURN_ON_ERROR(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, is_connected), + TAG, "Failed to register handler for wifi events"); + ESP_RETURN_ON_ERROR(esp_wifi_set_mode(WIFI_MODE_STA), TAG, "Failed to set WiFi station mode"); + ESP_RETURN_ON_ERROR(esp_wifi_start(), TAG, "Failed to start WiFi library"); + + wifi_config_t wifi_config = { + .sta = { + .ssid = CONFIG_ESP_WIFI_SSID, + .password = CONFIG_ESP_WIFI_PASSWORD, + }, + }; + + ESP_RETURN_ON_ERROR(esp_wifi_set_config(WIFI_IF_STA, &wifi_config), TAG, "Failed to set WiFi config"); + return esp_wifi_connect(); +} + +void app_main(void) +{ + static bool s_is_wifi_connected = false; // needs to be static as it's used after we exit app_main() + + /* Initialize NVS — it is used to store PHY calibration data */ + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ESP_LOGI(TAG, "USB NCM device initialization"); + const tinyusb_config_t tusb_cfg = { + .external_phy = false, + }; + ESP_GOTO_ON_ERROR(tinyusb_driver_install(&tusb_cfg), err, TAG, "Failed to install TinyUSB driver"); + + tinyusb_net_config_t net_config = { + .on_recv_callback = usb_recv_callback, + .free_tx_buffer = wifi_pkt_free, + .user_context = &s_is_wifi_connected + }; + esp_read_mac(net_config.mac_addr, ESP_MAC_WIFI_STA); + uint8_t *mac = net_config.mac_addr; + ESP_LOGI(TAG, "Network interface HW address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + ESP_GOTO_ON_ERROR(tinyusb_net_init(TINYUSB_USBDEV_0, &net_config), err, TAG, "Failed to initialize TinyUSB NCM device class"); + + ESP_LOGI(TAG, "WiFi initialization"); + ESP_GOTO_ON_ERROR(start_wifi(&s_is_wifi_connected), err, TAG, "Failed to init and start WiFi"); + + ESP_LOGI(TAG, "USB NCM and WiFi initialized and started"); + return; + +err: + ESP_LOGE(TAG, "USB-WiFi bridge example failed!"); +} diff --git a/tests/c_headers/idf-usb/device/tusb_ncm/pytest_usb_device_ncm.py b/tests/c_headers/idf-usb/device/tusb_ncm/pytest_usb_device_ncm.py new file mode 100644 index 00000000..c3828531 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_ncm/pytest_usb_device_ncm.py @@ -0,0 +1,31 @@ +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import subprocess +import time + +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize + + +@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') +@pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) +def test_usb_device_ncm_example(dut: Dut) -> None: + netif_mac = dut.expect( + r'Network interface HW address: ' + r'([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:' + r'[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})' + ) + netif_mac = netif_mac.group(1).decode('utf-8') + dut.expect_exact('USB NCM and WiFi initialized and started') + dut.expect_exact('Returned from app_main()') + time.sleep(2) # Wait 2s for the network interface to appear + out_bytes = subprocess.check_output('ifconfig', shell=True, timeout=5) + out_str = out_bytes.decode('utf-8') + print('expected network interface HW address: ', netif_mac) + print('ifconfig command output:\n', out_str) + if netif_mac in out_str: + print("NCM device's MAC address {} was found in system network interfaces".format(netif_mac)) + else: + raise AssertionError('NCM device not found in network interface list') diff --git a/tests/c_headers/idf-usb/device/tusb_ncm/sdkconfig.defaults b/tests/c_headers/idf-usb/device/tusb_ncm/sdkconfig.defaults new file mode 100644 index 00000000..65730e3e --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_ncm/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_TINYUSB_NET_MODE_NCM=y diff --git a/tests/c_headers/idf-usb/device/tusb_ncm/sdkconfig.defaults.esp32s3 b/tests/c_headers/idf-usb/device/tusb_ncm/sdkconfig.defaults.esp32s3 new file mode 100644 index 00000000..0776bebd --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_ncm/sdkconfig.defaults.esp32s3 @@ -0,0 +1,3 @@ +CONFIG_TINYUSB_TASK_AFFINITY_CPU0=y +CONFIG_TINYUSB_INIT_IN_DEFAULT_TASK=y +CONFIG_TINYUSB_NET_MODE_NCM=y diff --git a/tests/c_headers/idf-usb/device/tusb_serial_device/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_serial_device/CMakeLists.txt new file mode 100644 index 00000000..c2897f72 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_serial_device/CMakeLists.txt @@ -0,0 +1,9 @@ +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +add_compile_options(-w) # Turn off warnings until esp_tinyusb is updated IEC-86 +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(tusb_serial_device) diff --git a/tests/c_headers/idf-usb/device/tusb_serial_device/README.md b/tests/c_headers/idf-usb/device/tusb_serial_device/README.md new file mode 100644 index 00000000..60ef9a9b --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_serial_device/README.md @@ -0,0 +1,85 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# TinyUSB Serial Device Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example shows how to set up ESP chip to work as a USB Serial Device. + +As a USB stack, a TinyUSB component is used. + +## How to use example + +This example can also be configured to act as double serial device. +Run `idf.py menuconfig` and in `Component config → TinyUSB Stack → Communication Device Class (CDC) → CDC Channel Count` select number of serial devices you want to implement. + +### Hardware Required + +Any ESP board that have USB-OTG supported. + +#### Pin Assignment + +_Note:_ In case your board doesn't have micro-USB connector connected to USB-OTG peripheral, you may have to DIY a cable and connect **D+** and **D-** to the pins listed below. + +See common pin assignments for USB Device examples from [upper level](../../README.md#common-pin-assignments). + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +```bash +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +After the flashing you should see this output (for single CDC channel): + +``` +I (285) example: USB initialization +I (285) tusb_desc: +┌─────────────────────────────────┐ +│ USB Device Descriptor Summary │ +├───────────────────┬─────────────┤ +│bDeviceClass │ 239 │ +├───────────────────┼─────────────┤ +│bDeviceSubClass │ 2 │ +├───────────────────┼─────────────┤ +│bDeviceProtocol │ 1 │ +├───────────────────┼─────────────┤ +│bMaxPacketSize0 │ 64 │ +├───────────────────┼─────────────┤ +│idVendor │ 0x303a │ +├───────────────────┼─────────────┤ +│idProduct │ 0x4001 │ +├───────────────────┼─────────────┤ +│bcdDevice │ 0x100 │ +├───────────────────┼─────────────┤ +│iManufacturer │ 0x1 │ +├───────────────────┼─────────────┤ +│iProduct │ 0x2 │ +├───────────────────┼─────────────┤ +│iSerialNumber │ 0x3 │ +├───────────────────┼─────────────┤ +│bNumConfigurations │ 0x1 │ +└───────────────────┴─────────────┘ +I (455) TinyUSB: TinyUSB Driver installed +I (465) example: USB initialization DONE +``` + +Connect to the serial port (e.g. on Linux, it should be `/dev/ttyACM0`) by any terminal application (e.g. `picocom /dev/ttyACM0`). +Now you can send data strings to the device, the device will echo back the same data string. + +The monitor tool will also print the communication process: + +``` +I (12438) example: Data from channel 0: +I (12438) example: 0x3ffbfea0 45 73 70 72 65 73 73 69 66 0d |Espressif.| +``` diff --git a/tests/c_headers/idf-usb/device/tusb_serial_device/main/CMakeLists.txt b/tests/c_headers/idf-usb/device/tusb_serial_device/main/CMakeLists.txt new file mode 100644 index 00000000..a3d8eb60 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_serial_device/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "tusb_serial_device_main.c" + INCLUDE_DIRS .) diff --git a/tests/c_headers/idf-usb/device/tusb_serial_device/main/idf_component.yml b/tests/c_headers/idf-usb/device/tusb_serial_device/main/idf_component.yml new file mode 100644 index 00000000..ff67b5da --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_serial_device/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_tinyusb: "^1" + idf: "^5.0" diff --git a/tests/c_headers/idf-usb/device/tusb_serial_device/main/tusb_serial_device_main.c b/tests/c_headers/idf-usb/device/tusb_serial_device/main/tusb_serial_device_main.c new file mode 100644 index 00000000..cc111189 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_serial_device/main/tusb_serial_device_main.c @@ -0,0 +1,140 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "tinyusb.h" +#include "tusb_cdc_acm.h" +#include "sdkconfig.h" + +static const char *TAG = "example"; +static uint8_t rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; + +/** + * @brief Application Queue + */ +static QueueHandle_t app_queue; +typedef struct { + uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; // Data buffer + size_t buf_len; // Number of bytes received + uint8_t itf; // Index of CDC device interface +} app_message_t; + +/** + * @brief CDC device RX callback + * + * CDC device signals, that new data were received + * + * @param[in] itf CDC device index + * @param[in] event CDC event type + */ +void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event) +{ + /* initialization */ + size_t rx_size = 0; + + /* read */ + esp_err_t ret = tinyusb_cdcacm_read(itf, rx_buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); + if (ret == ESP_OK) { + + app_message_t tx_msg = { + .buf_len = rx_size, + .itf = itf, + }; + + memcpy(tx_msg.buf, rx_buf, rx_size); + xQueueSend(app_queue, &tx_msg, 0); + } else { + ESP_LOGE(TAG, "Read Error"); + } +} + +/** + * @brief CDC device line change callback + * + * CDC device signals, that the DTR, RTS states changed + * + * @param[in] itf CDC device index + * @param[in] event CDC event type + */ +void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event) +{ + int dtr = event->line_state_changed_data.dtr; + int rts = event->line_state_changed_data.rts; + ESP_LOGI(TAG, "Line state changed on channel %d: DTR:%d, RTS:%d", itf, dtr, rts); +} + +void app_main(void) +{ + // Create FreeRTOS primitives + app_queue = xQueueCreate(5, sizeof(app_message_t)); + assert(app_queue); + app_message_t msg; + + ESP_LOGI(TAG, "USB initialization"); + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .external_phy = false, +#if (TUD_OPT_HIGH_SPEED) + .fs_configuration_descriptor = NULL, + .hs_configuration_descriptor = NULL, + .qualifier_descriptor = NULL, +#else + .configuration_descriptor = NULL, +#endif // TUD_OPT_HIGH_SPEED + }; + + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + tinyusb_config_cdcacm_t acm_cfg = { + .usb_dev = TINYUSB_USBDEV_0, + .cdc_port = TINYUSB_CDC_ACM_0, + .rx_unread_buf_sz = 64, + .callback_rx = &tinyusb_cdc_rx_callback, // the first way to register a callback + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = NULL, + .callback_line_coding_changed = NULL + }; + + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); + /* the second way to register a callback */ + ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( + TINYUSB_CDC_ACM_0, + CDC_EVENT_LINE_STATE_CHANGED, + &tinyusb_cdc_line_state_changed_callback)); + +#if (CONFIG_TINYUSB_CDC_COUNT > 1) + acm_cfg.cdc_port = TINYUSB_CDC_ACM_1; + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); + ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( + TINYUSB_CDC_ACM_1, + CDC_EVENT_LINE_STATE_CHANGED, + &tinyusb_cdc_line_state_changed_callback)); +#endif + + ESP_LOGI(TAG, "USB initialization DONE"); + while (1) { + if (xQueueReceive(app_queue, &msg, portMAX_DELAY)) { + if (msg.buf_len) { + + /* Print received data*/ + ESP_LOGI(TAG, "Data from channel %d:", msg.itf); + ESP_LOG_BUFFER_HEXDUMP(TAG, msg.buf, msg.buf_len, ESP_LOG_INFO); + + /* write back */ + tinyusb_cdcacm_write_queue(msg.itf, msg.buf, msg.buf_len); + esp_err_t err = tinyusb_cdcacm_write_flush(msg.itf, 0); + if (err != ESP_OK) { + ESP_LOGE(TAG, "CDC ACM write flush error: %s", esp_err_to_name(err)); + } + } + } + } +} diff --git a/tests/c_headers/idf-usb/device/tusb_serial_device/pytest_usb_device_serial.py b/tests/c_headers/idf-usb/device/tusb_serial_device/pytest_usb_device_serial.py new file mode 100644 index 00000000..f1dd71ef --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_serial_device/pytest_usb_device_serial.py @@ -0,0 +1,31 @@ +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +from time import sleep + +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize +from serial import Serial +from serial.tools.list_ports import comports + + +@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') +@pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) +def test_usb_device_serial_example(dut: Dut) -> None: + dut.expect_exact('USB initialization DONE') + sleep(2) # Some time for the OS to enumerate our USB device + + # Find device with Espressif TinyUSB VID/PID + ports = comports() + for port, _, hwid in ports: + if '303A:4001' in hwid: + with Serial(port) as s: + s.write('text\r\n'.encode()) # Write dummy text to COM port + dut.expect_exact('Data from channel 0:') # Check ESP log + dut.expect_exact('|text..|') + res = s.readline() # Check COM echo + assert b'text\r\n' in res + return + + raise Exception('TinyUSB COM port not found') diff --git a/tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.ci b/tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.ci new file mode 100644 index 00000000..e69de29b diff --git a/tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.ci.dualchannel b/tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.ci.dualchannel new file mode 100644 index 00000000..909dd48c --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.ci.dualchannel @@ -0,0 +1 @@ +CONFIG_TINYUSB_CDC_COUNT=2 diff --git a/tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.defaults b/tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.defaults new file mode 100644 index 00000000..afec5843 --- /dev/null +++ b/tests/c_headers/idf-usb/device/tusb_serial_device/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_TINYUSB_CDC_ENABLED=y diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/CMakeLists.txt b/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/CMakeLists.txt new file mode 100644 index 00000000..dd45c278 --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/CMakeLists.txt @@ -0,0 +1,10 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(cdc_acm_host) diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/README.md b/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/README.md new file mode 100644 index 00000000..504c16e5 --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/README.md @@ -0,0 +1,57 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# USB CDC-ACM Host Driver Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example shows how to use the CDC-ACM Host Driver to allow an ESP chip to communicate with a USB CDC-ACM device. + +## How to use example + +### Hardware Required + +Two development boards with USB-OTG support. One will act as USB host and the other as USB device. + +#### Pin Assignment + +Follow instruction in [examples/usb/README.md](../../../README.md) for specific hardware setup. + +### Build and Flash + +1. Build and flash [tusb_serial_device example](../../../device/tusb_serial_device) to USB device board. +2. Build this project and flash it to the USB host board, then run monitor tool to view serial output: + +```bash +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +After the flashing you should see the output at idf monitor: + +``` +... +I (256) USB-CDC: USB Host installed +I (256) USB-CDC: Opening CDC ACM device 0x303A:0x4001 +... +Device descriptor is printed here +... +I (1666) USB-CDC: Data received +I (1666) USB-CDC: 0x3ffc4c20 41 54 0d |AT.| +I (2666) USB-CDC: Data received +I (2666) USB-CDC: 0x3ffc4c20 41 54 2b 47 53 4e 0d |AT+GSN.| +I (3666) USB-CDC: Setting up line coding +I (3666) USB-CDC: Line Get: Rate: 115200, Stop bits: 0, Parity: 0, Databits: 8 +I (3666) USB-CDC: Line Set: Rate: 9600, Stop bits: 1, Parity: 1, Databits: 7 +I (3666) USB-CDC: Line Get: Rate: 9600, Stop bits: 1, Parity: 1, Databits: 7 +I (3676) Example finished successfully! +... + +``` diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/CMakeLists.txt b/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/CMakeLists.txt new file mode 100644 index 00000000..3b0d7035 --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "usb_cdc_example_main.c" + INCLUDE_DIRS "." + PRIV_REQUIRES usb + ) diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/idf_component.yml b/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/idf_component.yml new file mode 100644 index 00000000..7865f535 --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + usb_host_cdc_acm: "2.*" + idf: ">=4.4" diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/usb_cdc_example_main.c b/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/usb_cdc_example_main.c new file mode 100644 index 00000000..f8c548e0 --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_host/main/usb_cdc_example_main.c @@ -0,0 +1,179 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#include +#include "esp_system.h" +#include "esp_log.h" +#include "esp_err.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" + +#include "usb/usb_host.h" +#include "usb/cdc_acm_host.h" + +#define EXAMPLE_USB_HOST_PRIORITY (20) +#define EXAMPLE_USB_DEVICE_VID (0x303A) +#define EXAMPLE_USB_DEVICE_PID (0x4001) // 0x303A:0x4001 (TinyUSB CDC device) +#define EXAMPLE_USB_DEVICE_DUAL_PID (0x4002) // 0x303A:0x4002 (TinyUSB Dual CDC device) +#define EXAMPLE_TX_STRING ("CDC test string!") +#define EXAMPLE_TX_TIMEOUT_MS (1000) + +static const char *TAG = "USB-CDC"; +static SemaphoreHandle_t device_disconnected_sem; + +/** + * @brief Data received callback + * + * @param[in] data Pointer to received data + * @param[in] data_len Length of received data in bytes + * @param[in] arg Argument we passed to the device open function + * @return + * true: We have processed the received data + * false: We expect more data + */ +static bool handle_rx(const uint8_t *data, size_t data_len, void *arg) +{ + ESP_LOGI(TAG, "Data received"); + ESP_LOG_BUFFER_HEXDUMP(TAG, data, data_len, ESP_LOG_INFO); + return true; +} + +/** + * @brief Device event callback + * + * Apart from handling device disconnection it doesn't do anything useful + * + * @param[in] event Device event type and data + * @param[in] user_ctx Argument we passed to the device open function + */ +static void handle_event(const cdc_acm_host_dev_event_data_t *event, void *user_ctx) +{ + switch (event->type) { + case CDC_ACM_HOST_ERROR: + ESP_LOGE(TAG, "CDC-ACM error has occurred, err_no = %i", event->data.error); + break; + case CDC_ACM_HOST_DEVICE_DISCONNECTED: + ESP_LOGI(TAG, "Device suddenly disconnected"); + ESP_ERROR_CHECK(cdc_acm_host_close(event->data.cdc_hdl)); + xSemaphoreGive(device_disconnected_sem); + break; + case CDC_ACM_HOST_SERIAL_STATE: + ESP_LOGI(TAG, "Serial state notif 0x%04X", event->data.serial_state.val); + break; + case CDC_ACM_HOST_NETWORK_CONNECTION: + default: + ESP_LOGW(TAG, "Unsupported CDC event: %i", event->type); + break; + } +} + +/** + * @brief USB Host library handling task + * + * @param arg Unused + */ +static void usb_lib_task(void *arg) +{ + while (1) { + // Start handling system events + uint32_t event_flags; + usb_host_lib_handle_events(portMAX_DELAY, &event_flags); + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + ESP_ERROR_CHECK(usb_host_device_free_all()); + } + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + ESP_LOGI(TAG, "USB: All devices freed"); + // Continue handling USB events to allow device reconnection + } + } +} + +/** + * @brief Main application + * + * Here we open a USB CDC device and send some data to it + */ +void app_main(void) +{ + device_disconnected_sem = xSemaphoreCreateBinary(); + assert(device_disconnected_sem); + + // Install USB Host driver. Should only be called once in entire application + ESP_LOGI(TAG, "Installing USB Host"); + const usb_host_config_t host_config = { + .skip_phy_setup = false, + .intr_flags = ESP_INTR_FLAG_LEVEL1, + }; + ESP_ERROR_CHECK(usb_host_install(&host_config)); + + // Create a task that will handle USB library events + BaseType_t task_created = xTaskCreate(usb_lib_task, "usb_lib", 4096, xTaskGetCurrentTaskHandle(), EXAMPLE_USB_HOST_PRIORITY, NULL); + assert(task_created == pdTRUE); + + ESP_LOGI(TAG, "Installing CDC-ACM driver"); + ESP_ERROR_CHECK(cdc_acm_host_install(NULL)); + + const cdc_acm_host_device_config_t dev_config = { + .connection_timeout_ms = 1000, + .out_buffer_size = 512, + .in_buffer_size = 512, + .user_arg = NULL, + .event_cb = handle_event, + .data_cb = handle_rx + }; + + while (true) { + cdc_acm_dev_hdl_t cdc_dev = NULL; + + // Open USB device from tusb_serial_device example example. Either single or dual port configuration. + ESP_LOGI(TAG, "Opening CDC ACM device 0x%04X:0x%04X...", EXAMPLE_USB_DEVICE_VID, EXAMPLE_USB_DEVICE_PID); + esp_err_t err = cdc_acm_host_open(EXAMPLE_USB_DEVICE_VID, EXAMPLE_USB_DEVICE_PID, 0, &dev_config, &cdc_dev); + if (ESP_OK != err) { + ESP_LOGI(TAG, "Opening CDC ACM device 0x%04X:0x%04X...", EXAMPLE_USB_DEVICE_VID, EXAMPLE_USB_DEVICE_DUAL_PID); + err = cdc_acm_host_open(EXAMPLE_USB_DEVICE_VID, EXAMPLE_USB_DEVICE_DUAL_PID, 0, &dev_config, &cdc_dev); + if (ESP_OK != err) { + ESP_LOGI(TAG, "Failed to open device"); + continue; + } + } + cdc_acm_host_desc_print(cdc_dev); + vTaskDelay(pdMS_TO_TICKS(100)); + + // Test sending and receiving: responses are handled in handle_rx callback + ESP_ERROR_CHECK(cdc_acm_host_data_tx_blocking(cdc_dev, (const uint8_t *)EXAMPLE_TX_STRING, strlen(EXAMPLE_TX_STRING), EXAMPLE_TX_TIMEOUT_MS)); + vTaskDelay(pdMS_TO_TICKS(100)); + + // Test Line Coding commands: Get current line coding, change it 9600 7N1 and read again + ESP_LOGI(TAG, "Setting up line coding"); + + cdc_acm_line_coding_t line_coding; + ESP_ERROR_CHECK(cdc_acm_host_line_coding_get(cdc_dev, &line_coding)); + ESP_LOGI(TAG, "Line Get: Rate: %"PRIu32", Stop bits: %"PRIu8", Parity: %"PRIu8", Databits: %"PRIu8"", + line_coding.dwDTERate, line_coding.bCharFormat, line_coding.bParityType, line_coding.bDataBits); + + line_coding.dwDTERate = 9600; + line_coding.bDataBits = 7; + line_coding.bParityType = 1; + line_coding.bCharFormat = 1; + ESP_ERROR_CHECK(cdc_acm_host_line_coding_set(cdc_dev, &line_coding)); + ESP_LOGI(TAG, "Line Set: Rate: %"PRIu32", Stop bits: %"PRIu8", Parity: %"PRIu8", Databits: %"PRIu8"", + line_coding.dwDTERate, line_coding.bCharFormat, line_coding.bParityType, line_coding.bDataBits); + + ESP_ERROR_CHECK(cdc_acm_host_line_coding_get(cdc_dev, &line_coding)); + ESP_LOGI(TAG, "Line Get: Rate: %"PRIu32", Stop bits: %"PRIu8", Parity: %"PRIu8", Databits: %"PRIu8"", + line_coding.dwDTERate, line_coding.bCharFormat, line_coding.bParityType, line_coding.bDataBits); + + ESP_ERROR_CHECK(cdc_acm_host_set_control_line_state(cdc_dev, true, false)); + + // We are done. Wait for device disconnection and start over + ESP_LOGI(TAG, "Example finished successfully! You can reconnect the device to run again."); + xSemaphoreTake(device_disconnected_sem, portMAX_DELAY); + } +} diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/CMakeLists.txt b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/CMakeLists.txt new file mode 100644 index 00000000..a4d34e3f --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/CMakeLists.txt @@ -0,0 +1,10 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(cdc_acm_vcp) diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/README.md b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/README.md new file mode 100644 index 00000000..2883ef06 --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/README.md @@ -0,0 +1,41 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# USB CDC-ACM Virtual COM Port example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example shows how to extend CDC-ACM driver for Virtual Communication Port (VCP) devices, such as CP210x, FTDI FT23x or CH34x devices. + +The drivers are fetched from [ESP Component Registry](https://components.espressif.com/) together with VCP service that automatically loads correct driver for plugged-in device. + +## How to use example + +1. Connect your USB<->UART converter to ESP board, the device will be automatically enumerated and correct driver will be loaded +2. Change baudrate and other line coding parameters in [cdc_acm_vcp_example_main.cpp](main/cdc_acm_vcp_example_main.cpp) to match your needs +3. Now you can use the usual CDC-ACM API to control the device and send data. Data are received in `handle_rx` callback +4. Try disconnecting and then reconnecting of the USB device to experiment with USB hotplugging + +### Hardware Required + +* Development board with USB-OTG support +* A USB cable for Power supply and programming +* Silicon Labs CP210x, FTDI FT23x or CP34x USB to UART converter + +#### Pin Assignment + +Follow instruction in [examples/usb/README.md](../../../README.md) for specific hardware setup. + +### Build and Flash + +Build this project and flash it to the USB host board, then run monitor tool to view serial output: + +```bash +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/CMakeLists.txt b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/CMakeLists.txt new file mode 100644 index 00000000..e52dfe2b --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS "cdc_acm_vcp_example_main.cpp" + INCLUDE_DIRS "." + PRIV_REQUIRES usb + ) diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/cdc_acm_vcp_example_main.cpp b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/cdc_acm_vcp_example_main.cpp new file mode 100644 index 00000000..32d2fee7 --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/cdc_acm_vcp_example_main.cpp @@ -0,0 +1,177 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include + +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" + +#include "usb/cdc_acm_host.h" +#include "usb/vcp_ch34x.hpp" +#include "usb/vcp_cp210x.hpp" +#include "usb/vcp_ftdi.hpp" +#include "usb/vcp.hpp" +#include "usb/usb_host.h" + +using namespace esp_usb; + +// Change these values to match your needs +#define EXAMPLE_BAUDRATE (115200) +#define EXAMPLE_STOP_BITS (0) // 0: 1 stopbit, 1: 1.5 stopbits, 2: 2 stopbits +#define EXAMPLE_PARITY (0) // 0: None, 1: Odd, 2: Even, 3: Mark, 4: Space +#define EXAMPLE_DATA_BITS (8) + +namespace { +static const char *TAG = "VCP example"; +static SemaphoreHandle_t device_disconnected_sem; + +/** + * @brief Data received callback + * + * Just pass received data to stdout + * + * @param[in] data Pointer to received data + * @param[in] data_len Length of received data in bytes + * @param[in] arg Argument we passed to the device open function + * @return + * true: We have processed the received data + * false: We expect more data + */ +static bool handle_rx(const uint8_t *data, size_t data_len, void *arg) +{ + printf("%.*s", data_len, data); + return true; +} + +/** + * @brief Device event callback + * + * Apart from handling device disconnection it doesn't do anything useful + * + * @param[in] event Device event type and data + * @param[in] user_ctx Argument we passed to the device open function + */ +static void handle_event(const cdc_acm_host_dev_event_data_t *event, void *user_ctx) +{ + switch (event->type) { + case CDC_ACM_HOST_ERROR: + ESP_LOGE(TAG, "CDC-ACM error has occurred, err_no = %d", event->data.error); + break; + case CDC_ACM_HOST_DEVICE_DISCONNECTED: + ESP_LOGI(TAG, "Device suddenly disconnected"); + xSemaphoreGive(device_disconnected_sem); + break; + case CDC_ACM_HOST_SERIAL_STATE: + ESP_LOGI(TAG, "Serial state notif 0x%04X", event->data.serial_state.val); + break; + case CDC_ACM_HOST_NETWORK_CONNECTION: + default: break; + } +} + +/** + * @brief USB Host library handling task + * + * @param arg Unused + */ +static void usb_lib_task(void *arg) +{ + while (1) { + // Start handling system events + uint32_t event_flags; + usb_host_lib_handle_events(portMAX_DELAY, &event_flags); + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + ESP_ERROR_CHECK(usb_host_device_free_all()); + } + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + ESP_LOGI(TAG, "USB: All devices freed"); + // Continue handling USB events to allow device reconnection + } + } +} +} + +/** + * @brief Main application + * + * This function shows how you can use Virtual COM Port drivers + */ +extern "C" void app_main(void) +{ + device_disconnected_sem = xSemaphoreCreateBinary(); + assert(device_disconnected_sem); + + // Install USB Host driver. Should only be called once in entire application + ESP_LOGI(TAG, "Installing USB Host"); + usb_host_config_t host_config = {}; + host_config.skip_phy_setup = false; + host_config.intr_flags = ESP_INTR_FLAG_LEVEL1; + ESP_ERROR_CHECK(usb_host_install(&host_config)); + + // Create a task that will handle USB library events + BaseType_t task_created = xTaskCreate(usb_lib_task, "usb_lib", 4096, NULL, 10, NULL); + assert(task_created == pdTRUE); + + ESP_LOGI(TAG, "Installing CDC-ACM driver"); + ESP_ERROR_CHECK(cdc_acm_host_install(NULL)); + + // Register VCP drivers to VCP service + VCP::register_driver(); + VCP::register_driver(); + VCP::register_driver(); + + // Do everything else in a loop, so we can demonstrate USB device reconnections + while (true) { + const cdc_acm_host_device_config_t dev_config = { + .connection_timeout_ms = 5000, // 5 seconds, enough time to plug the device in or experiment with timeout + .out_buffer_size = 512, + .in_buffer_size = 512, + .event_cb = handle_event, + .data_cb = handle_rx, + .user_arg = NULL, + }; + + // You don't need to know the device's VID and PID. Just plug in any device and the VCP service will load correct (already registered) driver for the device + ESP_LOGI(TAG, "Opening any VCP device..."); + auto vcp = std::unique_ptr(VCP::open(&dev_config)); + + if (vcp == nullptr) { + ESP_LOGI(TAG, "Failed to open VCP device"); + continue; + } + vTaskDelay(10); + + ESP_LOGI(TAG, "Setting up line coding"); + cdc_acm_line_coding_t line_coding = { + .dwDTERate = EXAMPLE_BAUDRATE, + .bCharFormat = EXAMPLE_STOP_BITS, + .bParityType = EXAMPLE_PARITY, + .bDataBits = EXAMPLE_DATA_BITS, + }; + ESP_ERROR_CHECK(vcp->line_coding_set(&line_coding)); + + /* + Now the USB-to-UART converter is configured and receiving data. + You can use standard CDC-ACM API to interact with it. E.g. + + ESP_ERROR_CHECK(vcp->set_control_line_state(false, true)); + ESP_ERROR_CHECK(vcp->tx_blocking((uint8_t *)"Test string", 12)); + */ + + // Send some dummy data + ESP_LOGI(TAG, "Sending data through CdcAcmDevice"); + uint8_t data[] = "test_string"; + ESP_ERROR_CHECK(vcp->tx_blocking(data, sizeof(data))); + ESP_ERROR_CHECK(vcp->set_control_line_state(true, true)); + + // We are done. Wait for device disconnection and start over + ESP_LOGI(TAG, "Done. You can reconnect the VCP device to run again."); + xSemaphoreTake(device_disconnected_sem, portMAX_DELAY); + } +} diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/idf_component.yml b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/idf_component.yml new file mode 100644 index 00000000..d8f31492 --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/main/idf_component.yml @@ -0,0 +1,7 @@ +## IDF Component Manager Manifest File +dependencies: + usb_host_ch34x_vcp: "^2" + usb_host_cp210x_vcp: "^2" + usb_host_ftdi_vcp: "^2" + usb_host_vcp: "^1" + idf: ">=5.1.0" diff --git a/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/sdkconfig.defaults b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/sdkconfig.defaults new file mode 100644 index 00000000..a3e635c9 --- /dev/null +++ b/tests/c_headers/idf-usb/host/cdc/cdc_acm_vcp/sdkconfig.defaults @@ -0,0 +1,5 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_COMPILER_CXX_EXCEPTIONS=y +CONFIG_USB_HOST_HUBS_SUPPORTED=y diff --git a/tests/c_headers/idf-usb/host/hid/CMakeLists.txt b/tests/c_headers/idf-usb/host/hid/CMakeLists.txt new file mode 100644 index 00000000..ad1d49fc --- /dev/null +++ b/tests/c_headers/idf-usb/host/hid/CMakeLists.txt @@ -0,0 +1,10 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +get_filename_component(ProjectId ${CMAKE_CURRENT_LIST_DIR} NAME) +string(REPLACE " " "_" ProjectId ${ProjectId}) +project(${ProjectId}) diff --git a/tests/c_headers/idf-usb/host/hid/README.md b/tests/c_headers/idf-usb/host/hid/README.md new file mode 100644 index 00000000..9c52850e --- /dev/null +++ b/tests/c_headers/idf-usb/host/hid/README.md @@ -0,0 +1,61 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# USB HID Class example +This example implements a basic USB Host HID Class Driver, and demonstrates how to use the driver to communicate with USB HID devices (such as Keyboard and Mouse or both) on the ESP32-S2/S3. Currently, the example only supports the HID boot protocol which should be present on most USB Mouse and Keyboards. The example will continuously scan for the connection of any HID Mouse or Keyboard, and attempt to fetch HID reports from those devices once connected. To quit the example (and shut down the HID driver), users can GPIO0 to low (i.e., pressing the "Boot" button on most ESP dev kits). + + +### Hardware Required +* Development board with USB-OTG support +* A USB cable for Power supply and programming +* USB OTG Cable + +### Common Pin Assignments + +Follow instructions in [examples/usb/README.md](../../README.md) for specific hardware setup. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +The example serial output will be the following: + +``` +I (198) example: HID HOST example +I (598) example: Interface number 0, protocol Mouse +I (598) example: Interface number 1, protocol Keyboard + +Mouse +X: 000883 Y: 000058 |o| | +Keyboard +qwertyuiop[]\asdfghjkl;'zxcvbnm,./ +Mouse +X: 000883 Y: 000058 | |o| +``` + +Where every keyboard key printed as char symbol if it is possible and a Hex value for any other key. + +#### Keyboard input data +Keyboard input data starts with the word "Keyboard" and every pressed key is printed to the serial debug. +Left or right Shift modifier is also supported. + +``` +Keyboard +Hello, ESP32 USB HID Keyboard is here! +``` + +#### Mouse input data +Mouse input data starts with the word "Mouse" and has the following structure. +``` +Mouse +X: -00343 Y: 000183 | |o| + | | | | + | | | +- Right mouse button pressed status ("o" - pressed, " " - not pressed) + | | +--- Left mouse button pressed status ("o" - pressed, " " - not pressed) + | +---------- Y relative coordinate of the cursor + +----------------------- X relative coordinate of the cursor +``` diff --git a/tests/c_headers/idf-usb/host/hid/main/CMakeLists.txt b/tests/c_headers/idf-usb/host/hid/main/CMakeLists.txt new file mode 100644 index 00000000..0bf44fb7 --- /dev/null +++ b/tests/c_headers/idf-usb/host/hid/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "hid_host_example.c" + INCLUDE_DIRS "." + PRIV_REQUIRES usb esp_driver_gpio + ) diff --git a/tests/c_headers/idf-usb/host/hid/main/hid_host_example.c b/tests/c_headers/idf-usb/host/hid/main/hid_host_example.c new file mode 100644 index 00000000..fde9f95d --- /dev/null +++ b/tests/c_headers/idf-usb/host/hid/main/hid_host_example.c @@ -0,0 +1,616 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "esp_log.h" +#include "usb/usb_host.h" +#include "errno.h" +#include "driver/gpio.h" + +#include "usb/hid_host.h" +#include "usb/hid_usage_keyboard.h" +#include "usb/hid_usage_mouse.h" + +/* GPIO Pin number for quit from example logic */ +#define APP_QUIT_PIN GPIO_NUM_0 + +static const char *TAG = "example"; + +QueueHandle_t app_event_queue = NULL; + +/** + * @brief APP event group + * + * Application logic can be different. There is a one among other ways to distinguish the + * event by application event group. + * In this example we have two event groups: + * APP_EVENT - General event, which is APP_QUIT_PIN press event (Generally, it is IO0). + * APP_EVENT_HID_HOST - HID Host Driver event, such as device connection/disconnection or input report. + */ +typedef enum { + APP_EVENT = 0, + APP_EVENT_HID_HOST +} app_event_group_t; + +/** + * @brief APP event queue + * + * This event is used for delivering the HID Host event from callback to a task. + */ +typedef struct { + app_event_group_t event_group; + /* HID Host - Device related info */ + struct { + hid_host_device_handle_t handle; + hid_host_driver_event_t event; + void *arg; + } hid_host_device; +} app_event_queue_t; + +/** + * @brief HID Protocol string names + */ +static const char *hid_proto_name_str[] = { + "NONE", + "KEYBOARD", + "MOUSE" +}; + +/** + * @brief Key event + */ +typedef struct { + enum key_state { + KEY_STATE_PRESSED = 0x00, + KEY_STATE_RELEASED = 0x01 + } state; + uint8_t modifier; + uint8_t key_code; +} key_event_t; + +/* Main char symbol for ENTER key */ +#define KEYBOARD_ENTER_MAIN_CHAR '\r' +/* When set to 1 pressing ENTER will be extending with LineFeed during serial debug output */ +#define KEYBOARD_ENTER_LF_EXTEND 1 + +/** + * @brief Scancode to ascii table + */ +const uint8_t keycode2ascii [57][2] = { + {0, 0}, /* HID_KEY_NO_PRESS */ + {0, 0}, /* HID_KEY_ROLLOVER */ + {0, 0}, /* HID_KEY_POST_FAIL */ + {0, 0}, /* HID_KEY_ERROR_UNDEFINED */ + {'a', 'A'}, /* HID_KEY_A */ + {'b', 'B'}, /* HID_KEY_B */ + {'c', 'C'}, /* HID_KEY_C */ + {'d', 'D'}, /* HID_KEY_D */ + {'e', 'E'}, /* HID_KEY_E */ + {'f', 'F'}, /* HID_KEY_F */ + {'g', 'G'}, /* HID_KEY_G */ + {'h', 'H'}, /* HID_KEY_H */ + {'i', 'I'}, /* HID_KEY_I */ + {'j', 'J'}, /* HID_KEY_J */ + {'k', 'K'}, /* HID_KEY_K */ + {'l', 'L'}, /* HID_KEY_L */ + {'m', 'M'}, /* HID_KEY_M */ + {'n', 'N'}, /* HID_KEY_N */ + {'o', 'O'}, /* HID_KEY_O */ + {'p', 'P'}, /* HID_KEY_P */ + {'q', 'Q'}, /* HID_KEY_Q */ + {'r', 'R'}, /* HID_KEY_R */ + {'s', 'S'}, /* HID_KEY_S */ + {'t', 'T'}, /* HID_KEY_T */ + {'u', 'U'}, /* HID_KEY_U */ + {'v', 'V'}, /* HID_KEY_V */ + {'w', 'W'}, /* HID_KEY_W */ + {'x', 'X'}, /* HID_KEY_X */ + {'y', 'Y'}, /* HID_KEY_Y */ + {'z', 'Z'}, /* HID_KEY_Z */ + {'1', '!'}, /* HID_KEY_1 */ + {'2', '@'}, /* HID_KEY_2 */ + {'3', '#'}, /* HID_KEY_3 */ + {'4', '$'}, /* HID_KEY_4 */ + {'5', '%'}, /* HID_KEY_5 */ + {'6', '^'}, /* HID_KEY_6 */ + {'7', '&'}, /* HID_KEY_7 */ + {'8', '*'}, /* HID_KEY_8 */ + {'9', '('}, /* HID_KEY_9 */ + {'0', ')'}, /* HID_KEY_0 */ + {KEYBOARD_ENTER_MAIN_CHAR, KEYBOARD_ENTER_MAIN_CHAR}, /* HID_KEY_ENTER */ + {0, 0}, /* HID_KEY_ESC */ + {'\b', 0}, /* HID_KEY_DEL */ + {0, 0}, /* HID_KEY_TAB */ + {' ', ' '}, /* HID_KEY_SPACE */ + {'-', '_'}, /* HID_KEY_MINUS */ + {'=', '+'}, /* HID_KEY_EQUAL */ + {'[', '{'}, /* HID_KEY_OPEN_BRACKET */ + {']', '}'}, /* HID_KEY_CLOSE_BRACKET */ + {'\\', '|'}, /* HID_KEY_BACK_SLASH */ + {'\\', '|'}, /* HID_KEY_SHARP */ // HOTFIX: for NonUS Keyboards repeat HID_KEY_BACK_SLASH + {';', ':'}, /* HID_KEY_COLON */ + {'\'', '"'}, /* HID_KEY_QUOTE */ + {'`', '~'}, /* HID_KEY_TILDE */ + {',', '<'}, /* HID_KEY_LESS */ + {'.', '>'}, /* HID_KEY_GREATER */ + {'/', '?'} /* HID_KEY_SLASH */ +}; + +/** + * @brief Makes new line depending on report output protocol type + * + * @param[in] proto Current protocol to output + */ +static void hid_print_new_device_report_header(hid_protocol_t proto) +{ + static hid_protocol_t prev_proto_output = -1; + + if (prev_proto_output != proto) { + prev_proto_output = proto; + printf("\r\n"); + if (proto == HID_PROTOCOL_MOUSE) { + printf("Mouse\r\n"); + } else if (proto == HID_PROTOCOL_KEYBOARD) { + printf("Keyboard\r\n"); + } else { + printf("Generic\r\n"); + } + fflush(stdout); + } +} + +/** + * @brief HID Keyboard modifier verification for capitalization application (right or left shift) + * + * @param[in] modifier + * @return true Modifier was pressed (left or right shift) + * @return false Modifier was not pressed (left or right shift) + * + */ +static inline bool hid_keyboard_is_modifier_shift(uint8_t modifier) +{ + if (((modifier & HID_LEFT_SHIFT) == HID_LEFT_SHIFT) || + ((modifier & HID_RIGHT_SHIFT) == HID_RIGHT_SHIFT)) { + return true; + } + return false; +} + +/** + * @brief HID Keyboard get char symbol from key code + * + * @param[in] modifier Keyboard modifier data + * @param[in] key_code Keyboard key code + * @param[in] key_char Pointer to key char data + * + * @return true Key scancode converted successfully + * @return false Key scancode unknown + */ +static inline bool hid_keyboard_get_char(uint8_t modifier, + uint8_t key_code, + unsigned char *key_char) +{ + uint8_t mod = (hid_keyboard_is_modifier_shift(modifier)) ? 1 : 0; + + if ((key_code >= HID_KEY_A) && (key_code <= HID_KEY_SLASH)) { + *key_char = keycode2ascii[key_code][mod]; + } else { + // All other key pressed + return false; + } + + return true; +} + +/** + * @brief HID Keyboard print char symbol + * + * @param[in] key_char Keyboard char to stdout + */ +static inline void hid_keyboard_print_char(unsigned int key_char) +{ + if (!!key_char) { + putchar(key_char); +#if (KEYBOARD_ENTER_LF_EXTEND) + if (KEYBOARD_ENTER_MAIN_CHAR == key_char) { + putchar('\n'); + } +#endif // KEYBOARD_ENTER_LF_EXTEND + fflush(stdout); + } +} + +/** + * @brief Key Event. Key event with the key code, state and modifier. + * + * @param[in] key_event Pointer to Key Event structure + * + */ +static void key_event_callback(key_event_t *key_event) +{ + unsigned char key_char; + + hid_print_new_device_report_header(HID_PROTOCOL_KEYBOARD); + + if (KEY_STATE_PRESSED == key_event->state) { + if (hid_keyboard_get_char(key_event->modifier, + key_event->key_code, &key_char)) { + + hid_keyboard_print_char(key_char); + + } + } +} + +/** + * @brief Key buffer scan code search. + * + * @param[in] src Pointer to source buffer where to search + * @param[in] key Key scancode to search + * @param[in] length Size of the source buffer + */ +static inline bool key_found(const uint8_t *const src, + uint8_t key, + unsigned int length) +{ + for (unsigned int i = 0; i < length; i++) { + if (src[i] == key) { + return true; + } + } + return false; +} + +/** + * @brief USB HID Host Keyboard Interface report callback handler + * + * @param[in] data Pointer to input report data buffer + * @param[in] length Length of input report data buffer + */ +static void hid_host_keyboard_report_callback(const uint8_t *const data, const int length) +{ + hid_keyboard_input_report_boot_t *kb_report = (hid_keyboard_input_report_boot_t *)data; + + if (length < sizeof(hid_keyboard_input_report_boot_t)) { + return; + } + + static uint8_t prev_keys[HID_KEYBOARD_KEY_MAX] = { 0 }; + key_event_t key_event; + + for (int i = 0; i < HID_KEYBOARD_KEY_MAX; i++) { + + // key has been released verification + if (prev_keys[i] > HID_KEY_ERROR_UNDEFINED && + !key_found(kb_report->key, prev_keys[i], HID_KEYBOARD_KEY_MAX)) { + key_event.key_code = prev_keys[i]; + key_event.modifier = 0; + key_event.state = KEY_STATE_RELEASED; + key_event_callback(&key_event); + } + + // key has been pressed verification + if (kb_report->key[i] > HID_KEY_ERROR_UNDEFINED && + !key_found(prev_keys, kb_report->key[i], HID_KEYBOARD_KEY_MAX)) { + key_event.key_code = kb_report->key[i]; + key_event.modifier = kb_report->modifier.val; + key_event.state = KEY_STATE_PRESSED; + key_event_callback(&key_event); + } + } + + memcpy(prev_keys, &kb_report->key, HID_KEYBOARD_KEY_MAX); +} + +/** + * @brief USB HID Host Mouse Interface report callback handler + * + * @param[in] data Pointer to input report data buffer + * @param[in] length Length of input report data buffer + */ +static void hid_host_mouse_report_callback(const uint8_t *const data, const int length) +{ + hid_mouse_input_report_boot_t *mouse_report = (hid_mouse_input_report_boot_t *)data; + + if (length < sizeof(hid_mouse_input_report_boot_t)) { + return; + } + + static int x_pos = 0; + static int y_pos = 0; + + // Calculate absolute position from displacement + x_pos += mouse_report->x_displacement; + y_pos += mouse_report->y_displacement; + + hid_print_new_device_report_header(HID_PROTOCOL_MOUSE); + + printf("X: %06d\tY: %06d\t|%c|%c|\r", + x_pos, y_pos, + (mouse_report->buttons.button1 ? 'o' : ' '), + (mouse_report->buttons.button2 ? 'o' : ' ')); + fflush(stdout); +} + +/** + * @brief USB HID Host Generic Interface report callback handler + * + * 'generic' means anything else than mouse or keyboard + * + * @param[in] data Pointer to input report data buffer + * @param[in] length Length of input report data buffer + */ +static void hid_host_generic_report_callback(const uint8_t *const data, const int length) +{ + hid_print_new_device_report_header(HID_PROTOCOL_NONE); + for (int i = 0; i < length; i++) { + printf("%02X", data[i]); + } + putchar('\r'); +} + +/** + * @brief USB HID Host interface callback + * + * @param[in] hid_device_handle HID Device handle + * @param[in] event HID Host interface event + * @param[in] arg Pointer to arguments, does not used + */ +void hid_host_interface_callback(hid_host_device_handle_t hid_device_handle, + const hid_host_interface_event_t event, + void *arg) +{ + uint8_t data[64] = { 0 }; + size_t data_length = 0; + hid_host_dev_params_t dev_params; + ESP_ERROR_CHECK(hid_host_device_get_params(hid_device_handle, &dev_params)); + + switch (event) { + case HID_HOST_INTERFACE_EVENT_INPUT_REPORT: + ESP_ERROR_CHECK(hid_host_device_get_raw_input_report_data(hid_device_handle, + data, + 64, + &data_length)); + + if (HID_SUBCLASS_BOOT_INTERFACE == dev_params.sub_class) { + if (HID_PROTOCOL_KEYBOARD == dev_params.proto) { + hid_host_keyboard_report_callback(data, data_length); + } else if (HID_PROTOCOL_MOUSE == dev_params.proto) { + hid_host_mouse_report_callback(data, data_length); + } + } else { + hid_host_generic_report_callback(data, data_length); + } + + break; + case HID_HOST_INTERFACE_EVENT_DISCONNECTED: + ESP_LOGI(TAG, "HID Device, protocol '%s' DISCONNECTED", + hid_proto_name_str[dev_params.proto]); + ESP_ERROR_CHECK(hid_host_device_close(hid_device_handle)); + break; + case HID_HOST_INTERFACE_EVENT_TRANSFER_ERROR: + ESP_LOGI(TAG, "HID Device, protocol '%s' TRANSFER_ERROR", + hid_proto_name_str[dev_params.proto]); + break; + default: + ESP_LOGE(TAG, "HID Device, protocol '%s' Unhandled event", + hid_proto_name_str[dev_params.proto]); + break; + } +} + +/** + * @brief USB HID Host Device event + * + * @param[in] hid_device_handle HID Device handle + * @param[in] event HID Host Device event + * @param[in] arg Pointer to arguments, does not used + */ +void hid_host_device_event(hid_host_device_handle_t hid_device_handle, + const hid_host_driver_event_t event, + void *arg) +{ + hid_host_dev_params_t dev_params; + ESP_ERROR_CHECK(hid_host_device_get_params(hid_device_handle, &dev_params)); + + switch (event) { + case HID_HOST_DRIVER_EVENT_CONNECTED: + ESP_LOGI(TAG, "HID Device, protocol '%s' CONNECTED", + hid_proto_name_str[dev_params.proto]); + + const hid_host_device_config_t dev_config = { + .callback = hid_host_interface_callback, + .callback_arg = NULL + }; + + ESP_ERROR_CHECK(hid_host_device_open(hid_device_handle, &dev_config)); + if (HID_SUBCLASS_BOOT_INTERFACE == dev_params.sub_class) { + ESP_ERROR_CHECK(hid_class_request_set_protocol(hid_device_handle, HID_REPORT_PROTOCOL_BOOT)); + if (HID_PROTOCOL_KEYBOARD == dev_params.proto) { + ESP_ERROR_CHECK(hid_class_request_set_idle(hid_device_handle, 0, 0)); + } + } + ESP_ERROR_CHECK(hid_host_device_start(hid_device_handle)); + break; + default: + break; + } +} + +/** + * @brief Start USB Host install and handle common USB host library events while app pin not low + * + * @param[in] arg Not used + */ +static void usb_lib_task(void *arg) +{ + const usb_host_config_t host_config = { + .skip_phy_setup = false, + .intr_flags = ESP_INTR_FLAG_LEVEL1, + }; + + ESP_ERROR_CHECK(usb_host_install(&host_config)); + xTaskNotifyGive(arg); + + while (true) { + uint32_t event_flags; + usb_host_lib_handle_events(portMAX_DELAY, &event_flags); + // In this example, there is only one client registered + // So, once we deregister the client, this call must succeed with ESP_OK + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + ESP_ERROR_CHECK(usb_host_device_free_all()); + break; + } + } + + ESP_LOGI(TAG, "USB shutdown"); + // Clean up USB Host + vTaskDelay(10); // Short delay to allow clients clean-up + ESP_ERROR_CHECK(usb_host_uninstall()); + vTaskDelete(NULL); +} + +/** + * @brief BOOT button pressed callback + * + * Signal application to exit the HID Host task + * + * @param[in] arg Unused + */ +static void gpio_isr_cb(void *arg) +{ + BaseType_t xTaskWoken = pdFALSE; + const app_event_queue_t evt_queue = { + .event_group = APP_EVENT, + }; + + if (app_event_queue) { + xQueueSendFromISR(app_event_queue, &evt_queue, &xTaskWoken); + } + + if (xTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} + +/** + * @brief HID Host Device callback + * + * Puts new HID Device event to the queue + * + * @param[in] hid_device_handle HID Device handle + * @param[in] event HID Device event + * @param[in] arg Not used + */ +void hid_host_device_callback(hid_host_device_handle_t hid_device_handle, + const hid_host_driver_event_t event, + void *arg) +{ + const app_event_queue_t evt_queue = { + .event_group = APP_EVENT_HID_HOST, + // HID Host Device related info + .hid_host_device.handle = hid_device_handle, + .hid_host_device.event = event, + .hid_host_device.arg = arg + }; + + if (app_event_queue) { + xQueueSend(app_event_queue, &evt_queue, 0); + } +} + +void app_main(void) +{ + BaseType_t task_created; + app_event_queue_t evt_queue; + ESP_LOGI(TAG, "HID Host example"); + + // Init BOOT button: Pressing the button simulates app request to exit + // It will disconnect the USB device and uninstall the HID driver and USB Host Lib + const gpio_config_t input_pin = { + .pin_bit_mask = BIT64(APP_QUIT_PIN), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .intr_type = GPIO_INTR_NEGEDGE, + }; + ESP_ERROR_CHECK(gpio_config(&input_pin)); + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1)); + ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_isr_cb, NULL)); + + /* + * Create usb_lib_task to: + * - initialize USB Host library + * - Handle USB Host events while APP pin in in HIGH state + */ + task_created = xTaskCreatePinnedToCore(usb_lib_task, + "usb_events", + 4096, + xTaskGetCurrentTaskHandle(), + 2, NULL, 0); + assert(task_created == pdTRUE); + + // Wait for notification from usb_lib_task to proceed + ulTaskNotifyTake(false, 1000); + + /* + * HID host driver configuration + * - create background task for handling low level event inside the HID driver + * - provide the device callback to get new HID Device connection event + */ + const hid_host_driver_config_t hid_host_driver_config = { + .create_background_task = true, + .task_priority = 5, + .stack_size = 4096, + .core_id = 0, + .callback = hid_host_device_callback, + .callback_arg = NULL + }; + + ESP_ERROR_CHECK(hid_host_install(&hid_host_driver_config)); + + // Create queue + app_event_queue = xQueueCreate(10, sizeof(app_event_queue_t)); + + ESP_LOGI(TAG, "Waiting for HID Device to be connected"); + + while (1) { + // Wait queue + if (xQueueReceive(app_event_queue, &evt_queue, portMAX_DELAY)) { + if (APP_EVENT == evt_queue.event_group) { + // User pressed button + usb_host_lib_info_t lib_info; + ESP_ERROR_CHECK(usb_host_lib_info(&lib_info)); + if (lib_info.num_devices == 0) { + // End while cycle + break; + } else { + ESP_LOGW(TAG, "To shutdown example, remove all USB devices and press button again."); + // Keep polling + } + } + + if (APP_EVENT_HID_HOST == evt_queue.event_group) { + hid_host_device_event(evt_queue.hid_host_device.handle, + evt_queue.hid_host_device.event, + evt_queue.hid_host_device.arg); + } + } + } + + ESP_LOGI(TAG, "HID Driver uninstall"); + ESP_ERROR_CHECK(hid_host_uninstall()); + gpio_isr_handler_remove(APP_QUIT_PIN); + xQueueReset(app_event_queue); + vQueueDelete(app_event_queue); +} diff --git a/tests/c_headers/idf-usb/host/hid/main/idf_component.yml b/tests/c_headers/idf-usb/host/hid/main/idf_component.yml new file mode 100644 index 00000000..0c3620e3 --- /dev/null +++ b/tests/c_headers/idf-usb/host/hid/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + idf: ">=4.4" + usb_host_hid: "^1.0.1" diff --git a/tests/c_headers/idf-usb/host/hid/sdkconfig.defaults b/tests/c_headers/idf-usb/host/hid/sdkconfig.defaults new file mode 100644 index 00000000..bf1b553b --- /dev/null +++ b/tests/c_headers/idf-usb/host/hid/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_USB_HOST_HUBS_SUPPORTED=y diff --git a/tests/c_headers/idf-usb/host/msc/CMakeLists.txt b/tests/c_headers/idf-usb/host/msc/CMakeLists.txt new file mode 100644 index 00000000..f00f0d98 --- /dev/null +++ b/tests/c_headers/idf-usb/host/msc/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(usb-msc) diff --git a/tests/c_headers/idf-usb/host/msc/README.md b/tests/c_headers/idf-usb/host/msc/README.md new file mode 100644 index 00000000..46a8cc00 --- /dev/null +++ b/tests/c_headers/idf-usb/host/msc/README.md @@ -0,0 +1,139 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# USB Mass Storage Class example + +## Overview + +This example demonstrates usage of the MSC (Mass Storage Class) to access storage on a USB flash drive. Upon connection of the flash drive, it is mounted to the Virtual filesystem. The following example operations are then performed: + +1. Print device info (capacity, sectors size, and count...). +2. List all folders and files in the root directory of the USB flash drive. +3. Create `esp` subdirectory (if not present already), as well as a `test.txt` file. +4. Run read/write benchmarks by transferring 1 MB of data to a `dummy` file. + +> Note: This example currently supports only FAT-formatted drives. Other file systems, such as exFAT or NTFS, are not compatible with this example. Please ensure that your USB drive is formatted as FAT to avoid compatibility issues. + +### USB Reconnections + +The example is run in a loop so that it can demonstrate USB connection and reconnection handling. If you want to deinitialize the entire USB Host Stack, you can short GPIO0 to GND. GPIO0 is usually mapped to a BOOT button, thus pressing the button will deinitialize the stack. + +### Hardware Required + +* Development board with USB-OTG support +* A USB cable for power supply and programming +* A USB flash drive + +### USB Host Limitations + +#### ESP32-S2 & ESP32-S3 +The USB OTG peripheral on ESP32-S2 and ESP32-S3 in host mode supports **up to 8 bidirectional endpoints**. Each of these endpoints can be configured as either IN or OUT. + +Since each USB Mass Storage Class (MSC) device typically requires **3 endpoints** (Control, BULK IN, and BULK OUT), and USB hubs also consume endpoints (Control, INTERRUPT IN), this limits the theoretical maximum number of connected MSC devices to **2**. + +#### ESP32-P4 +ESP32-P4 features a more advanced USB 2.0 OTG controller with **up to 16 bidirectional endpoints** in host mode. Given the same endpoint requirements per device, the theoretical maximum number of connected MSC devices is **4**. + +### Example Limitations +The number of simultaneously connected MSC devices is now **determined by `CONFIG_FATFS_VOLUME_COUNT`**. This ensures consistency with the FAT filesystem configuration and prevents misalignment between the MSC device count and the available FAT volumes. + +By default, `CONFIG_FATFS_VOLUME_COUNT` is set to **2**, meaning that up to **2 MSC devices** can be connected at the same time. If your application requires more devices, you can increase `CONFIG_FATFS_VOLUME_COUNT` accordingly, while keeping in mind **endpoint and memory constraints**. + +#### How to configure `CONFIG_FATFS_VOLUME_COUNT` in menuconfig: +To change the maximum number of MSC devices, adjust `CONFIG_FATFS_VOLUME_COUNT` in **menuconfig**: +idf.py menuconfig → Component config → FAT Filesystem support → Number of FATFS volumes +Set this value to the desired number of MSC devices, ensuring it aligns with USB endpoint availability. + +### Common Pin Assignments + +Follow instructions in [examples/usb/README.md](../../README.md) for specific hardware setup. + +Additionally, GPIO0 can be shorted to ground in order to deinitialize the USB stack. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` +... +I (323) example: Waiting for USB flash drive to be connected +I (3353) example: MSC device connected (usb_addr=3) +*** Device descriptor *** +bLength 18 +bDescriptorType 1 +bcdUSB 2.00 +bDeviceClass 0x0 +bDeviceSubClass 0x0 +bDeviceProtocol 0x0 +bMaxPacketSize0 64 +idVendor 0xabcd +idProduct 0x1234 +bcdDevice 1.00 +iManufacturer 1 +iProduct 2 +iSerialNumber 3 +bNumConfigurations 1 +*** Configuration descriptor *** +bLength 9 +bDescriptorType 2 +wTotalLength 32 +bNumInterfaces 1 +bConfigurationValue 1 +iConfiguration 0 +bmAttributes 0x80 +bMaxPower 100mA + *** Interface descriptor *** + bLength 9 + bDescriptorType 4 + bInterfaceNumber 0 + bAlternateSetting 0 + bNumEndpoints 2 + bInterfaceClass 0x8 + bInterfaceSubClass 0x6 + bInterfaceProtocol 0x50 + iInterface 0 + *** Endpoint descriptor *** + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x1 EP 1 OUT + bmAttributes 0x2 BULK + wMaxPacketSize 512 + bInterval 0 + *** Endpoint descriptor *** + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x81 EP 1 IN + bmAttributes 0x2 BULK + wMaxPacketSize 512 + bInterval 0 +Device info: + Capacity: 3839 MB + Sector size: 512 + Sector count: 7864319 + PID: 0x1234 + VID: 0xABCD + iProduct: UDisk + iManufacturer: General + iSerialNumber: +I (3763) example: ls command output for all connected devices: +I (3763) example: Listing contents of /usb0 +/usb0/SYSTEM~1 +/usb0/ESP +I (3773) example: Reading file +I (3773) example: Read from file '/usb0/esp/test.txt': 'Hello World!' +I (3803) example: Writing to file /usb0/esp/dummy +I (3943) example: Write speed 7.16 MiB/s +I (3953) example: Reading from file /usb0/esp/dummy +I (4093) example: Read speed 7.16 MiB/s +I (4103) example: Example finished, you can disconnect the USB flash drive (or connect another USB flash drive) +``` diff --git a/tests/c_headers/idf-usb/host/msc/main/CMakeLists.txt b/tests/c_headers/idf-usb/host/msc/main/CMakeLists.txt new file mode 100644 index 00000000..cf7d18b3 --- /dev/null +++ b/tests/c_headers/idf-usb/host/msc/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "msc_example_main.c" + INCLUDE_DIRS "" + PRIV_REQUIRES usb fatfs esp_driver_gpio esp_timer + ) diff --git a/tests/c_headers/idf-usb/host/msc/main/idf_component.yml b/tests/c_headers/idf-usb/host/msc/main/idf_component.yml new file mode 100644 index 00000000..198a93bb --- /dev/null +++ b/tests/c_headers/idf-usb/host/msc/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + idf: ">=4.4" + usb_host_msc: "^1.1.1" diff --git a/tests/c_headers/idf-usb/host/msc/main/msc_example_main.c b/tests/c_headers/idf-usb/host/msc/main/msc_example_main.c new file mode 100644 index 00000000..690fb82d --- /dev/null +++ b/tests/c_headers/idf-usb/host/msc/main/msc_example_main.c @@ -0,0 +1,560 @@ +/* + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_timer.h" +#include "esp_err.h" +#include "esp_log.h" +#include "usb/usb_host.h" +#include "usb/msc_host_vfs.h" +#include "ffconf.h" +#include "errno.h" +#include "driver/gpio.h" + +static const char *TAG = "example"; + +#define MNT_PATH "/usb" // Base mount path prefix, devices will be mounted as /usb0, /usb1, /usb2... +#define APP_QUIT_PIN GPIO_NUM_0 // BOOT button on most boards +#define BUFFER_SIZE 4096 // The read/write performance can be improved with larger buffer for the cost of RAM, 4kB is enough for most usecases +#define MAX_MSC_DEVICES CONFIG_FATFS_VOLUME_COUNT /*!< Maximum number of simultaneously connected MSC (Mass Storage Class) devices. + Adjust this value based on available system resources and expected use cases. */ + +/** + * @brief MSC Device Entry + * + * This structure holds information about a connected MSC device, + * including the USB address, MSC device handle, VFS handle, and assigned mount point. + */ +typedef struct { + uint8_t usb_addr; /*!< USB device address */ + msc_host_device_handle_t msc_device; /*!< Handle of the MSC device */ + msc_host_vfs_handle_t vfs_handle; /*!< VFS handle assigned to the MSC device */ +} msc_dev_entry_t; + +static msc_dev_entry_t *msc_devices[MAX_MSC_DEVICES] = {0}; + +/** + * @brief Application Queue and its messages ID + */ +static QueueHandle_t app_queue; +typedef struct { + enum { + APP_QUIT, // Signals request to exit the application + APP_DEVICE_CONNECTED, // USB device connect event + APP_DEVICE_DISCONNECTED, // USB device disconnect event + } id; + union { + uint8_t new_dev_address; // Address of new USB device for APP_DEVICE_CONNECTED event + msc_host_device_handle_t device_handle; // Handle of removed USB device for APP_DEVICE_DISCONNECTED event + } data; +} app_message_t; + +/** + * @brief Find a free slot in the device table. + * + * @return Index of the free slot, or -1 if no free slot is available. + */ +static inline int find_free_slot(void) +{ + for (int i = 0; i < MAX_MSC_DEVICES; i++) { + if (msc_devices[i] == NULL) { + return i; + } + } + return -1; +} + +/** + * @brief Allocates a new MSC device entry and mounts it to VFS. + * + * This function finds a free slot for a new MSC device, allocates memory for the device entry, + * installs the MSC device, and mounts it to the virtual file system (VFS). + * + * If any step fails, the function ensures proper cleanup of allocated resources before returning an error. + * + * @param[in] msg Message containing the address of the new USB device. + * @param[out] out_slot Pointer to store the allocated slot index on success. + * + * @return + * - ESP_OK on success. + * - ESP_ERR_NOT_FOUND if no free slot is available. + * - ESP_ERR_NO_MEM if memory allocation fails. + * - Other esp_err_t codes if device installation or VFS registration fails. + */ +static esp_err_t allocate_new_msc_device(const app_message_t *msg, int *out_slot) +{ + int slot = find_free_slot(); + if (slot < 0) { + ESP_LOGW(TAG, "No free slots for new MSC device (max %d)", MAX_MSC_DEVICES); + return ESP_ERR_NOT_FOUND; + } + + msc_devices[slot] = calloc(1, sizeof(msc_dev_entry_t)); + if (!msc_devices[slot]) { + ESP_LOGE(TAG, "Failed to allocate memory for new MSC device entry"); + return ESP_ERR_NO_MEM; + } + esp_err_t err = msc_host_install_device(msg->data.new_dev_address, &msc_devices[slot]->msc_device); + if (err != ESP_OK) { + ESP_LOGE(TAG, "msc_host_install_device failed: %s", esp_err_to_name(err)); + free(msc_devices[slot]); + msc_devices[slot] = NULL; + return err; + } + + msc_devices[slot]->usb_addr = msg->data.new_dev_address; + + const esp_vfs_fat_mount_config_t mount_config = { + .format_if_mount_failed = false, + .max_files = 3, + .allocation_unit_size = 8192, + }; + + char mount_path[16]; + snprintf(mount_path, sizeof(mount_path), MNT_PATH "%d", slot); + + err = msc_host_vfs_register(msc_devices[slot]->msc_device, mount_path, &mount_config, &msc_devices[slot]->vfs_handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "msc_host_vfs_register failed: %s", esp_err_to_name(err)); + ESP_ERROR_CHECK(msc_host_uninstall_device(msc_devices[slot]->msc_device)); + free(msc_devices[slot]); + msc_devices[slot] = NULL; + return err; + } + + *out_slot = slot; + return ESP_OK; +} + +/** + * @brief Find a slot by MSC device handle. + * + * This function searches for the slot corresponding to a given MSC device handle. + * + * @param handle MSC device handle to search for. + * @return Index of the slot if found, otherwise -1. + */ +static int find_slot_by_handle(msc_host_device_handle_t handle) +{ + for (int i = 0; i < MAX_MSC_DEVICES; i++) { + if (msc_devices[i] && msc_devices[i]->msc_device == handle) { + return i; + } + } + return -1; +} + +/** + * @brief Free resources associated with a specific MSC device by slot index. + * + * This function releases all resources associated with a device identified by its slot index. + * It unmounts the VFS, uninstalls the MSC device, and frees the allocated memory. + * + * @param slot Index of the MSC device in the device array. + */ +static void free_msc_device(int slot) +{ + if (slot < 0 || slot >= MAX_MSC_DEVICES || !msc_devices[slot]) { + ESP_LOGE(TAG, "Invalid slot index for MSC device deallocation"); + return; + } + + if (msc_devices[slot]->vfs_handle) { + ESP_ERROR_CHECK(msc_host_vfs_unregister(msc_devices[slot]->vfs_handle)); + } + if (msc_devices[slot]->msc_device) { + ESP_ERROR_CHECK(msc_host_uninstall_device(msc_devices[slot]->msc_device)); + } + + free(msc_devices[slot]); + msc_devices[slot] = NULL; +} + +/** + * @brief Free all connected MSC devices. + * + * Iterates over all allocated MSC devices, unmounts them from VFS, and frees their memory. + */ +static void free_all_msc_devices(void) +{ + for (int i = 0; i < MAX_MSC_DEVICES; i++) { + if (msc_devices[i]) { + free_msc_device(i); + } + } +} + +/** + * @brief BOOT button pressed callback + * + * Signal application to exit the main task + * + * @param[in] arg Unused + */ +static void gpio_cb(void *arg) +{ + BaseType_t xTaskWoken = pdFALSE; + app_message_t message = { + .id = APP_QUIT, + }; + + if (app_queue) { + xQueueSendFromISR(app_queue, &message, &xTaskWoken); + } + + if (xTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} + +/** + * @brief Find a USB addr by MSC device handle. + * + * @param handle MSC device handle + * @return USB addr, or -1 if not found. + */ +static inline int8_t find_usb_addr_by_handle(msc_host_device_handle_t handle) +{ + for (int8_t i = 0; i < MAX_MSC_DEVICES; i++) { + if (msc_devices[i] && msc_devices[i]->msc_device == handle) { + return msc_devices[i]->usb_addr; + } + } + return -1; +} + +/** + * @brief MSC driver callback + * + * Signal device connection/disconnection to the main task + * + * @param[in] event MSC event + * @param[in] arg MSC event data + */ +static void msc_event_cb(const msc_host_event_t *event, void *arg) +{ + if (event->event == MSC_DEVICE_CONNECTED) { + ESP_LOGI(TAG, "MSC device connected (usb_addr=%d)", event->device.address); + app_message_t message = { + .id = APP_DEVICE_CONNECTED, + .data.new_dev_address = event->device.address, + }; + xQueueSend(app_queue, &message, portMAX_DELAY); + } else if (event->event == MSC_DEVICE_DISCONNECTED) { + int usb_addr = find_usb_addr_by_handle(event->device.handle); + if (usb_addr >= 0) { + ESP_LOGI(TAG, "MSC device disconnected (usb_addr=%d)", usb_addr); + } else { + ESP_LOGW(TAG, "MSC device disconnected, but failed to retrieve USB address"); + } + app_message_t message = { + .id = APP_DEVICE_DISCONNECTED, + .data.device_handle = event->device.handle, + }; + xQueueSend(app_queue, &message, portMAX_DELAY); + } +} + +/** + * @brief Print information about the connected MSC device. + * + * This function prints detailed information about the connected USB MSC device, + * such as capacity, sector size, PID, VID, and string descriptors. + * + * @param[in] info Pointer to MSC device information structure. + */ +static void print_device_info(msc_host_device_info_t *info) +{ + const size_t megabyte = 1024 * 1024; + uint64_t capacity = ((uint64_t)info->sector_size * info->sector_count) / megabyte; + + printf("Device info:\n"); + printf("\t Capacity: %llu MB\n", capacity); + printf("\t Sector size: %"PRIu32"\n", info->sector_size); + printf("\t Sector count: %"PRIu32"\n", info->sector_count); + printf("\t PID: 0x%04X \n", info->idProduct); + printf("\t VID: 0x%04X \n", info->idVendor); +#ifndef CONFIG_NEWLIB_NANO_FORMAT + wprintf(L"\t iProduct: %S \n", info->iProduct); + wprintf(L"\t iManufacturer: %S \n", info->iManufacturer); + wprintf(L"\t iSerialNumber: %S \n", info->iSerialNumber); +#endif +} + +/** + * @brief Perform basic file operations on the mounted USB storage device. + * + * This function demonstrates basic file I/O operations: + * - Create a directory `/usb/esp` if it does not exist. + * - Create a file `test.txt` in the directory with sample content if it does not exist. + * - Read the content of the `test.txt` file and print it to the console. + * + * @param[in] slot Index of the mounted USB device (0 to MAX_MSC_DEVICES-1). + */ +static void file_operations(int slot) +{ + char directory[32]; + char file_path[32]; + snprintf(directory, sizeof(directory), MNT_PATH "%d/esp", slot); + snprintf(file_path, sizeof(file_path), MNT_PATH "%d/esp/test.txt", slot); + + // Create /usb/esp directory + struct stat s = {0}; + bool directory_exists = stat(directory, &s) == 0; + if (!directory_exists) { + if (mkdir(directory, 0775) != 0) { + ESP_LOGE(TAG, "mkdir failed with errno: %s", strerror(errno)); + } + } + + // Create /usb/esp/test.txt file, if it doesn't exist + if (stat(file_path, &s) != 0) { + ESP_LOGI(TAG, "Creating file"); + FILE *f = fopen(file_path, "w"); + if (f == NULL) { + ESP_LOGE(TAG, "Failed to open file for writing"); + return; + } + fprintf(f, "Hello World!\n"); + fclose(f); + } + + // Read back the file + FILE *f; + ESP_LOGI(TAG, "Reading file"); + f = fopen(file_path, "r"); + if (f == NULL) { + ESP_LOGE(TAG, "Failed to open file for reading"); + return; + } + char line[64]; + fgets(line, sizeof(line), f); + fclose(f); + // strip newline + char *pos = strchr(line, '\n'); + if (pos) { + *pos = '\0'; + } + ESP_LOGI(TAG, "Read from file '%s': '%s'", file_path, line); +} + +/** + * @brief Perform sequential write and read speed test on the mounted USB storage device. + * + * This function performs: + * - A write speed test by writing a series of 4KB blocks to a test file. + * - A read speed test by reading the same number of 4KB blocks from the file. + * + * The results (in MiB/s) are printed to the console. + * + * @param[in] slot Index of the mounted USB device (0 to MAX_MSC_DEVICES-1). + */ +static void speed_test(int slot) +{ +#define ITERATIONS 256 // 256 * 4kb = 1MB + int64_t test_start, test_end; + char test_file[32]; + snprintf(test_file, sizeof(test_file), MNT_PATH "%d/esp/dummy", slot); + + FILE *f = fopen(test_file, "wb+"); + if (f == NULL) { + ESP_LOGE(TAG, "Failed to open file for writing"); + return; + } + // Set larger buffer for this file. It results in larger and more effective USB transfers + setvbuf(f, NULL, _IOFBF, BUFFER_SIZE); + + // Allocate application buffer used for read/write + uint8_t *data = malloc(BUFFER_SIZE); + assert(data); + + ESP_LOGI(TAG, "Writing to file %s", test_file); + test_start = esp_timer_get_time(); + for (int i = 0; i < ITERATIONS; i++) { + if (fwrite(data, BUFFER_SIZE, 1, f) == 0) { + ESP_LOGE(TAG, "Write error"); + fclose(f); + free(data); + return; + } + } + test_end = esp_timer_get_time(); + ESP_LOGI(TAG, "Write speed %1.2f MiB/s", (BUFFER_SIZE * ITERATIONS) / (float)(test_end - test_start)); + rewind(f); + + ESP_LOGI(TAG, "Reading from file %s", test_file); + test_start = esp_timer_get_time(); + for (int i = 0; i < ITERATIONS; i++) { + if (0 == fread(data, BUFFER_SIZE, 1, f)) { + ESP_LOGE(TAG, "Read error"); + fclose(f); + free(data); + return; + } + } + test_end = esp_timer_get_time(); + ESP_LOGI(TAG, "Read speed %1.2f MiB/s", (BUFFER_SIZE * ITERATIONS) / (float)(test_end - test_start)); + + fclose(f); + free(data); +} + +/** + * @brief USB task + * + * Install USB Host Library and MSC driver. + * Handle USB Host Library events + * + * @param[in] args Unused + */ +static void usb_task(void *args) +{ + const usb_host_config_t host_config = { .intr_flags = ESP_INTR_FLAG_LEVEL1 }; + ESP_ERROR_CHECK(usb_host_install(&host_config)); + + const msc_host_driver_config_t msc_config = { + .create_backround_task = true, + .task_priority = 5, + .stack_size = 4096, + .callback = msc_event_cb, + }; + ESP_ERROR_CHECK(msc_host_install(&msc_config)); + + bool has_clients = true; + while (true) { + uint32_t event_flags; + usb_host_lib_handle_events(portMAX_DELAY, &event_flags); + + // Release devices once all clients has deregistered + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + has_clients = false; + if (usb_host_device_free_all() == ESP_OK) { + break; + }; + } + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE && !has_clients) { + break; + } + } + + vTaskDelay(10); // Give clients some time to uninstall + ESP_LOGI(TAG, "Deinitializing USB"); + ESP_ERROR_CHECK(usb_host_uninstall()); + vTaskDelete(NULL); +} + +/** + * @brief List contents of the root directories of all mounted USB storage devices. + * + * This function iterates over all mounted MSC devices and lists the contents + * of their root directories. It is intended for debugging and demonstration purposes. + * + * For each connected and mounted device, the function attempts to open the root directory + * `/usb` and print the names of all files and directories contained within. + * + * If opening the directory fails, an error is logged. + */ +static inline void show_list_files_all_devices(void) +{ + ESP_LOGI(TAG, "ls command output for all connected devices:"); + for (int i = 0; i < MAX_MSC_DEVICES; i++) { + if (msc_devices[i]) { + char mount_path[16]; + snprintf(mount_path, sizeof(mount_path), MNT_PATH "%d", i); + + ESP_LOGI(TAG, "Listing contents of %s", mount_path); + struct dirent *d; + DIR *dh = opendir(mount_path); + if (!dh) { + ESP_LOGE(TAG, "Failed to open directory: %s", mount_path); + continue; + } + + while ((d = readdir(dh)) != NULL) { + printf("%s/%s\n", mount_path, d->d_name); + } + closedir(dh); + } + } +} + +void app_main(void) +{ + // Create FreeRTOS primitives + app_queue = xQueueCreate(5, sizeof(app_message_t)); + assert(app_queue); + + BaseType_t task_created = xTaskCreate(usb_task, "usb_task", 4096, NULL, 2, NULL); + assert(task_created); + + // Init BOOT button: Pressing the button simulates app request to exit + // It will disconnect the USB device and uninstall the MSC drivers and USB Host Lib + const gpio_config_t input_pin = { + .pin_bit_mask = BIT64(APP_QUIT_PIN), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .intr_type = GPIO_INTR_NEGEDGE, + }; + ESP_ERROR_CHECK(gpio_config(&input_pin)); + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1)); + ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_cb, NULL)); + + ESP_LOGI(TAG, "Waiting for USB flash drive to be connected"); + + // Perform all example operations in a loop to allow USB reconnections + while (1) { + app_message_t msg; + xQueueReceive(app_queue, &msg, portMAX_DELAY); + + if (msg.id == APP_DEVICE_CONNECTED) { + int slot; + esp_err_t res = allocate_new_msc_device(&msg, &slot); + if (res != ESP_OK) { + continue; + } + // 2. Print information about the connected disk + msc_host_device_info_t info; + ESP_ERROR_CHECK(msc_host_get_device_info(msc_devices[slot]->msc_device, &info)); + msc_host_print_descriptors(msc_devices[slot]->msc_device); + print_device_info(&info); + + // 3. List all the files in root directory from all connected msc devices + show_list_files_all_devices(); + + // 4. The disk is mounted to Virtual File System, perform some basic demo file operation + file_operations(slot); + // 5. Perform speed test + speed_test(slot); + + ESP_LOGI(TAG, "Example finished, you can disconnect the USB flash drive (or connect another USB flash drive)"); + } + if (msg.id == APP_DEVICE_DISCONNECTED) { + int slot = find_slot_by_handle(msg.data.device_handle); + if (slot >= 0) { + free_msc_device(slot); + } + } + if (msg.id == APP_QUIT) { + free_all_msc_devices(); + msc_host_uninstall(); + break; + } + } + + ESP_LOGI(TAG, "Done"); + gpio_isr_handler_remove(APP_QUIT_PIN); + gpio_uninstall_isr_service(); + vQueueDelete(app_queue); +} diff --git a/tests/c_headers/idf-usb/host/msc/pytest_usb_host_msc.py b/tests/c_headers/idf-usb/host/msc/pytest_usb_host_msc.py new file mode 100644 index 00000000..5a4fda39 --- /dev/null +++ b/tests/c_headers/idf-usb/host/msc/pytest_usb_host_msc.py @@ -0,0 +1,45 @@ +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize + + +@pytest.mark.temp_skip_ci(targets=['esp32s2'], reason='lack of runners with usb_host_flash_disk tag') +@pytest.mark.usb_host_flash_disk +@idf_parametrize( + 'config,target', + [('default', 'esp32s2'), ('default', 'esp32s3'), ('default', 'esp32p4'), ('esp32p4_psram', 'esp32p4')], + indirect=['config', 'target'], +) +def test_usb_host_msc_example(dut: Dut) -> None: + # Check whether the USB-DWC DMA capable memory is allocated in PSRAM + usb_dwc_in_psram = bool(dut.app.sdkconfig.get('USB_HOST_DWC_DMA_CAP_MEMORY_IN_PSRAM')) + + # Get wMaxPacketSize to get USB device speed + max_packet_size = int(dut.expect(r'wMaxPacketSize (\d{2,3})')[1].decode()) + + # Check result of file_operations() + dut.expect(r"example: Read from file '/usb[0-9]/esp/test.txt': 'Hello World!'") + + # Check result of speed_test() + write_throughput = float(dut.expect(r'example: Write speed ([0-9]*[.]?[0-9]+) MiB')[1].decode()) + read_throughput = float(dut.expect(r'example: Read speed ([0-9]*[.]?[0-9]+) MiB')[1].decode()) + + # Set write and read throughput limits + if max_packet_size == 512: # wMaxPacketSize = 512 for HS + write_throughput_limit = 3.5 if usb_dwc_in_psram else 4.9 + read_throughput_limit = 9.9 if usb_dwc_in_psram else 11.5 + else: # wMaxPacketSize = 64 for FS + write_throughput_limit = 0.9 + read_throughput_limit = 1.0 + + # Evaluate the speed measurements + if write_throughput > write_throughput_limit: + print('Write throughput put OK') + else: + print('write throughput too slow!') + if read_throughput > read_throughput_limit: + print('Read throughput put OK') + else: + print('Read throughput too slow!') diff --git a/tests/c_headers/idf-usb/host/msc/sdkconfig.ci b/tests/c_headers/idf-usb/host/msc/sdkconfig.ci new file mode 100644 index 00000000..e69de29b diff --git a/tests/c_headers/idf-usb/host/msc/sdkconfig.ci.esp32p4_psram b/tests/c_headers/idf-usb/host/msc/sdkconfig.ci.esp32p4_psram new file mode 100644 index 00000000..fa9e86ed --- /dev/null +++ b/tests/c_headers/idf-usb/host/msc/sdkconfig.ci.esp32p4_psram @@ -0,0 +1,11 @@ +CONFIG_IDF_TARGET="esp32p4" + +# Enable experimental features, to set PSRAM frequency to 200 MHz +CONFIG_IDF_EXPERIMENTAL_FEATURES=y + +# Enable PSRAM and set PSRAM frequency +CONFIG_SPIRAM=y +CONFIG_SPIRAM_SPEED_200M=y + +# Allocate USB_DWC DMA capable memory in PSRAM +CONFIG_USB_HOST_DWC_DMA_CAP_MEMORY_IN_PSRAM=y diff --git a/tests/c_headers/idf-usb/host/msc/sdkconfig.defaults b/tests/c_headers/idf-usb/host/msc/sdkconfig.defaults new file mode 100644 index 00000000..bf1b553b --- /dev/null +++ b/tests/c_headers/idf-usb/host/msc/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_USB_HOST_HUBS_SUPPORTED=y diff --git a/tests/c_headers/idf-usb/host/usb_host_lib/CMakeLists.txt b/tests/c_headers/idf-usb/host/usb_host_lib/CMakeLists.txt new file mode 100644 index 00000000..153b20d5 --- /dev/null +++ b/tests/c_headers/idf-usb/host/usb_host_lib/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(usb_host_lib_example) diff --git a/tests/c_headers/idf-usb/host/usb_host_lib/README.md b/tests/c_headers/idf-usb/host/usb_host_lib/README.md new file mode 100644 index 00000000..e7a2028e --- /dev/null +++ b/tests/c_headers/idf-usb/host/usb_host_lib/README.md @@ -0,0 +1,193 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# USB Host Library Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example demonstrates the basic usage of the [USB Host Library API](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/usb_host.html) by implementing a pseudo class driver and a Host Library task. The example does the following: + +1. Install Host Library and register a client +2. Waits for a device connection +3. Prints the device's information (such as device/configuration/string descriptors) +4. Waits for the device to disconnect +5. Repeats steps 2 to 4 until a user pressess a button, which quits the `app` +6. If the button has been pressed, while a USB device is still connected, the user will be prompted to remove the device and push the button again to quit the `app` +7. Deregister the client, uninstall the Host Library and quit the `app` + +The example demonstrates the following aspects of the USB Host Library API: + +- How to use the Library API to: + - Install and uninstall the USB Host Library + - Run the library event handler function and usb host library task + - How to handle library events +- How to use the Client API from a client task to: + - Register and deregister a client of the USB Host Library + - Run the client event handler functions + - How to handle client events via various callbacks + - Open and close a device + - Get a device's descriptors + +## How to use example + +### Hardware Required + +* Development board with USB-OTG support. +* Follow instruction in [examples/usb/README.md](../../README.md) for specific hardware setup. + +### Configure the project + +``` +idf.py menuconfig +``` + +* The USB Host Stack has a maximum supported transfer size for control transfer during device enumeration. This size is specified via the USB_HOST_CONTROL_TRANSFER_MAX_SIZE configuration option and has a default value of 256 bytes. Therefore, if devices with length config/string descriptors are used, users may want to increase the size of this configuration. +* Push button GPIO selection + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` +I (305) main_task: Started on CPU0 +I (315) main_task: Calling app_main() +I (315) USB host lib: USB host library example +I (315) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2 +I (325) USB host lib: Installing USB Host Library +I (365) CLASS: Registering Client +I (745) CLASS: Opening device at address 1 +I (745) CLASS: Getting device information +I (745) CLASS: Full speed +I (745) CLASS: bConfigurationValue 1 +I (745) CLASS: Getting device descriptor +*** Device descriptor *** +bLength 18 +bDescriptorType 1 +bcdUSB 2.00 +bDeviceClass 0xef +bDeviceSubClass 0x2 +bDeviceProtocol 0x1 +bMaxPacketSize0 64 +idVendor 0x303a +idProduct 0x1001 +bcdDevice 1.00 +iManufacturer 1 +iProduct 2 +iSerialNumber 3 +bNumConfigurations 1 +I (775) CLASS: Getting config descriptor +*** Configuration descriptor *** +bLength 9 +bDescriptorType 2 +wTotalLength 98 +bNumInterfaces 3 +bConfigurationValue 1 +iConfiguration 0 +bmAttributes 0xc0 +bMaxPower 500mA + *** Interface descriptor *** + bLength 9 + bDescriptorType 4 + bInterfaceNumber 0 + bAlternateSetting 0 + bNumEndpoints 1 + bInterfaceClass 0x0 + iInterface 0 + *** Endpoint descriptor *** + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x82 EP 2 IN + bmAttributes 0x3 INT + wMaxPacketSize 64 + bInterval 1 + *** Interface descriptor *** + bLength 9 + bDescriptorType 4 + bInterfaceNumber 1 + bAlternateSetting 0 + bNumEndpoints 2 + bInterfaceClass 0x0 + iInterface 0 + *** Endpoint descriptor *** + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x1 EP 1 OUT + bmAttributes 0x2 BULK + wMaxPacketSize 64 + bInterval 1 + *** Endpoint descriptor *** + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x81 EP 1 IN + bmAttributes 0x2 BULK + wMaxPacketSize 64 + bInterval 1 + *** Interface descriptor *** + bLength 9 + bDescriptorType 4 + bInterfaceNumber 2 + bAlternateSetting 0 + bNumEndpoints 2 + bInterfaceClass 0x1 + iInterface 0 + *** Endpoint descriptor *** + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x2 EP 2 OUT + bmAttributes 0x2 BULK + wMaxPacketSize 64 + bInterval 1 + *** Endpoint descriptor *** + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x83 EP 3 IN + bmAttributes 0x2 BULK + wMaxPacketSize 64 + bInterval 1 +I (855) CLASS: Getting Manufacturer string descriptor +Espressif +I (855) CLASS: Getting Product string descriptor +USB JTAG/serial debug unit +I (865) CLASS: Getting Serial Number string descriptor +7C:DF:A1:E0:10:50 +W (2855) USB host lib: To shutdown example, remove all USB devices and press button again. +E (6135) USBH: Device 1 gone +I (9545) CLASS: Deregistering Client +I (9545) USB host lib: No more clients +I (9545) USB host lib: All devices marked as free +I (9545) USB host lib: No more clients and devices +I (9645) USB host lib: End of the example +I (9645) main_task: Returned from app_main() +``` + +## Troubleshooting + +To obtain more debug, users should set the [log level](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/system/log.html) to debug via menuconfig. + +### Failing Enumeration + +``` +I (262) cpu_start: Starting scheduler on PRO CPU. +I (268) DAEMON: Installing USB Host Library +I (298) CLASS: Registering Client +E (2748) HUB: Short string desc corrupt +E (2748) HUB: Stage failed: CHECK_SHORT_MANU_STR_DESC +``` + +The log output demonstrates a device that has failed. The Hub Driver will output some error logs indicating which stage of enumeration has failed. + +### Blank String Descriptors + +The current USB Host Library will automatically cache the Manufacturer, Product, and Serial Number string descriptors of the device during enumeration. However, when fetching the string descriptors, the USB Host Library will only fetch those strings descriptors of they of LANGID code 0x0409 (i.e., English - United States). Therefore, if the example does not print a particular descriptor, it is likely that the string descriptor was not cached during enumeration. diff --git a/tests/c_headers/idf-usb/host/usb_host_lib/main/CMakeLists.txt b/tests/c_headers/idf-usb/host/usb_host_lib/main/CMakeLists.txt new file mode 100644 index 00000000..8e8817d5 --- /dev/null +++ b/tests/c_headers/idf-usb/host/usb_host_lib/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "usb_host_lib_main.c" "class_driver.c" + INCLUDE_DIRS "." + PRIV_REQUIRES usb esp_driver_gpio + ) diff --git a/tests/c_headers/idf-usb/host/usb_host_lib/main/Kconfig.projbuild b/tests/c_headers/idf-usb/host/usb_host_lib/main/Kconfig.projbuild new file mode 100644 index 00000000..680b0cc3 --- /dev/null +++ b/tests/c_headers/idf-usb/host/usb_host_lib/main/Kconfig.projbuild @@ -0,0 +1,12 @@ +menu "Example Configuration" + + orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" + + config APP_QUIT_PIN + int "APP Quit button GPIO pin" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 0 + help + GPIO pin number to be used as APP_QUIT button. + +endmenu diff --git a/tests/c_headers/idf-usb/host/usb_host_lib/main/class_driver.c b/tests/c_headers/idf-usb/host/usb_host_lib/main/class_driver.c new file mode 100644 index 00000000..5a89e40d --- /dev/null +++ b/tests/c_headers/idf-usb/host/usb_host_lib/main/class_driver.c @@ -0,0 +1,279 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "esp_log.h" +#include "usb/usb_host.h" + +#define CLIENT_NUM_EVENT_MSG 5 + +typedef enum { + ACTION_OPEN_DEV = (1 << 0), + ACTION_GET_DEV_INFO = (1 << 1), + ACTION_GET_DEV_DESC = (1 << 2), + ACTION_GET_CONFIG_DESC = (1 << 3), + ACTION_GET_STR_DESC = (1 << 4), + ACTION_CLOSE_DEV = (1 << 5), +} action_t; + +#define DEV_MAX_COUNT 128 + +typedef struct { + usb_host_client_handle_t client_hdl; + uint8_t dev_addr; + usb_device_handle_t dev_hdl; + action_t actions; +} usb_device_t; + +typedef struct { + struct { + union { + struct { + uint8_t unhandled_devices: 1; /**< Device has unhandled devices */ + uint8_t shutdown: 1; /**< */ + uint8_t reserved6: 6; /**< Reserved */ + }; + uint8_t val; /**< Class drivers' flags value */ + } flags; /**< Class drivers' flags */ + usb_device_t device[DEV_MAX_COUNT]; /**< Class drivers' static array of devices */ + } mux_protected; /**< Mutex protected members. Must be protected by the Class mux_lock when accessed */ + + struct { + usb_host_client_handle_t client_hdl; + SemaphoreHandle_t mux_lock; /**< Mutex for protected members */ + } constant; /**< Constant members. Do not change after installation thus do not require a critical section or mutex */ +} class_driver_t; + +static const char *TAG = "CLASS"; +static class_driver_t *s_driver_obj; + +static void client_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg) +{ + class_driver_t *driver_obj = (class_driver_t *)arg; + switch (event_msg->event) { + case USB_HOST_CLIENT_EVENT_NEW_DEV: + // Save the device address + xSemaphoreTake(driver_obj->constant.mux_lock, portMAX_DELAY); + driver_obj->mux_protected.device[event_msg->new_dev.address].dev_addr = event_msg->new_dev.address; + driver_obj->mux_protected.device[event_msg->new_dev.address].dev_hdl = NULL; + // Open the device next + driver_obj->mux_protected.device[event_msg->new_dev.address].actions |= ACTION_OPEN_DEV; + // Set flag + driver_obj->mux_protected.flags.unhandled_devices = 1; + xSemaphoreGive(driver_obj->constant.mux_lock); + break; + case USB_HOST_CLIENT_EVENT_DEV_GONE: + // Cancel any other actions and close the device next + xSemaphoreTake(driver_obj->constant.mux_lock, portMAX_DELAY); + for (uint8_t i = 0; i < DEV_MAX_COUNT; i++) { + if (driver_obj->mux_protected.device[i].dev_hdl == event_msg->dev_gone.dev_hdl) { + driver_obj->mux_protected.device[i].actions = ACTION_CLOSE_DEV; + // Set flag + driver_obj->mux_protected.flags.unhandled_devices = 1; + } + } + xSemaphoreGive(driver_obj->constant.mux_lock); + break; + default: + // Should never occur + abort(); + } +} + +static void action_open_dev(usb_device_t *device_obj) +{ + assert(device_obj->dev_addr != 0); + ESP_LOGI(TAG, "Opening device at address %d", device_obj->dev_addr); + ESP_ERROR_CHECK(usb_host_device_open(device_obj->client_hdl, device_obj->dev_addr, &device_obj->dev_hdl)); + // Get the device's information next + device_obj->actions |= ACTION_GET_DEV_INFO; +} + +static void action_get_info(usb_device_t *device_obj) +{ + assert(device_obj->dev_hdl != NULL); + ESP_LOGI(TAG, "Getting device information"); + usb_device_info_t dev_info; + ESP_ERROR_CHECK(usb_host_device_info(device_obj->dev_hdl, &dev_info)); + ESP_LOGI(TAG, "\t%s speed", (char *[]) { + "Low", "Full", "High" + }[dev_info.speed]); + ESP_LOGI(TAG, "\tParent info:"); + if (dev_info.parent.dev_hdl) { + usb_device_info_t parent_dev_info; + ESP_ERROR_CHECK(usb_host_device_info(dev_info.parent.dev_hdl, &parent_dev_info)); + ESP_LOGI(TAG, "\t\tBus addr: %d", parent_dev_info.dev_addr); + ESP_LOGI(TAG, "\t\tPort: %d", dev_info.parent.port_num); + + } else { + ESP_LOGI(TAG, "\t\tPort: ROOT"); + } + ESP_LOGI(TAG, "\tbConfigurationValue %d", dev_info.bConfigurationValue); + // Get the device descriptor next + device_obj->actions |= ACTION_GET_DEV_DESC; +} + +static void action_get_dev_desc(usb_device_t *device_obj) +{ + assert(device_obj->dev_hdl != NULL); + ESP_LOGI(TAG, "Getting device descriptor"); + const usb_device_desc_t *dev_desc; + ESP_ERROR_CHECK(usb_host_get_device_descriptor(device_obj->dev_hdl, &dev_desc)); + usb_print_device_descriptor(dev_desc); + // Get the device's config descriptor next + device_obj->actions |= ACTION_GET_CONFIG_DESC; +} + +static void action_get_config_desc(usb_device_t *device_obj) +{ + assert(device_obj->dev_hdl != NULL); + ESP_LOGI(TAG, "Getting config descriptor"); + const usb_config_desc_t *config_desc; + ESP_ERROR_CHECK(usb_host_get_active_config_descriptor(device_obj->dev_hdl, &config_desc)); + usb_print_config_descriptor(config_desc, NULL); + // Get the device's string descriptors next + device_obj->actions |= ACTION_GET_STR_DESC; +} + +static void action_get_str_desc(usb_device_t *device_obj) +{ + assert(device_obj->dev_hdl != NULL); + usb_device_info_t dev_info; + ESP_ERROR_CHECK(usb_host_device_info(device_obj->dev_hdl, &dev_info)); + if (dev_info.str_desc_manufacturer) { + ESP_LOGI(TAG, "Getting Manufacturer string descriptor"); + usb_print_string_descriptor(dev_info.str_desc_manufacturer); + } + if (dev_info.str_desc_product) { + ESP_LOGI(TAG, "Getting Product string descriptor"); + usb_print_string_descriptor(dev_info.str_desc_product); + } + if (dev_info.str_desc_serial_num) { + ESP_LOGI(TAG, "Getting Serial Number string descriptor"); + usb_print_string_descriptor(dev_info.str_desc_serial_num); + } +} + +static void action_close_dev(usb_device_t *device_obj) +{ + ESP_ERROR_CHECK(usb_host_device_close(device_obj->client_hdl, device_obj->dev_hdl)); + device_obj->dev_hdl = NULL; + device_obj->dev_addr = 0; +} + +static void class_driver_device_handle(usb_device_t *device_obj) +{ + uint8_t actions = device_obj->actions; + device_obj->actions = 0; + + while (actions) { + if (actions & ACTION_OPEN_DEV) { + action_open_dev(device_obj); + } + if (actions & ACTION_GET_DEV_INFO) { + action_get_info(device_obj); + } + if (actions & ACTION_GET_DEV_DESC) { + action_get_dev_desc(device_obj); + } + if (actions & ACTION_GET_CONFIG_DESC) { + action_get_config_desc(device_obj); + } + if (actions & ACTION_GET_STR_DESC) { + action_get_str_desc(device_obj); + } + if (actions & ACTION_CLOSE_DEV) { + action_close_dev(device_obj); + } + + actions = device_obj->actions; + device_obj->actions = 0; + } +} + +void class_driver_task(void *arg) +{ + class_driver_t driver_obj = {0}; + usb_host_client_handle_t class_driver_client_hdl = NULL; + + ESP_LOGI(TAG, "Registering Client"); + + SemaphoreHandle_t mux_lock = xSemaphoreCreateMutex(); + if (mux_lock == NULL) { + ESP_LOGE(TAG, "Unable to create class driver mutex"); + vTaskSuspend(NULL); + return; + } + + usb_host_client_config_t client_config = { + .is_synchronous = false, //Synchronous clients currently not supported. Set this to false + .max_num_event_msg = CLIENT_NUM_EVENT_MSG, + .async = { + .client_event_callback = client_event_cb, + .callback_arg = (void *) &driver_obj, + }, + }; + ESP_ERROR_CHECK(usb_host_client_register(&client_config, &class_driver_client_hdl)); + + driver_obj.constant.mux_lock = mux_lock; + driver_obj.constant.client_hdl = class_driver_client_hdl; + + for (uint8_t i = 0; i < DEV_MAX_COUNT; i++) { + driver_obj.mux_protected.device[i].client_hdl = class_driver_client_hdl; + } + + s_driver_obj = &driver_obj; + + while (1) { + // Driver has unhandled devices, handle all devices first + if (driver_obj.mux_protected.flags.unhandled_devices) { + xSemaphoreTake(driver_obj.constant.mux_lock, portMAX_DELAY); + for (uint8_t i = 0; i < DEV_MAX_COUNT; i++) { + if (driver_obj.mux_protected.device[i].actions) { + class_driver_device_handle(&driver_obj.mux_protected.device[i]); + } + } + driver_obj.mux_protected.flags.unhandled_devices = 0; + xSemaphoreGive(driver_obj.constant.mux_lock); + } else { + // Driver is active, handle client events + if (driver_obj.mux_protected.flags.shutdown == 0) { + usb_host_client_handle_events(class_driver_client_hdl, portMAX_DELAY); + } else { + // Shutdown the driver + break; + } + } + } + + ESP_LOGI(TAG, "Deregistering Class Client"); + ESP_ERROR_CHECK(usb_host_client_deregister(class_driver_client_hdl)); + if (mux_lock != NULL) { + vSemaphoreDelete(mux_lock); + } + vTaskSuspend(NULL); +} + +void class_driver_client_deregister(void) +{ + // Mark all opened devices + xSemaphoreTake(s_driver_obj->constant.mux_lock, portMAX_DELAY); + for (uint8_t i = 0; i < DEV_MAX_COUNT; i++) { + if (s_driver_obj->mux_protected.device[i].dev_hdl != NULL) { + // Mark device to close + s_driver_obj->mux_protected.device[i].actions |= ACTION_CLOSE_DEV; + // Set flag + s_driver_obj->mux_protected.flags.unhandled_devices = 1; + } + } + s_driver_obj->mux_protected.flags.shutdown = 1; + xSemaphoreGive(s_driver_obj->constant.mux_lock); + + // Unblock, exit the loop and proceed to deregister client + ESP_ERROR_CHECK(usb_host_client_unblock(s_driver_obj->constant.client_hdl)); +} diff --git a/tests/c_headers/idf-usb/host/usb_host_lib/main/usb_host_lib_main.c b/tests/c_headers/idf-usb/host/usb_host_lib/main/usb_host_lib_main.c new file mode 100644 index 00000000..8c804344 --- /dev/null +++ b/tests/c_headers/idf-usb/host/usb_host_lib/main/usb_host_lib_main.c @@ -0,0 +1,226 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" +#include "esp_log.h" +#include "esp_intr_alloc.h" +#include "usb/usb_host.h" +#include "driver/gpio.h" + +#define HOST_LIB_TASK_PRIORITY 2 +#define CLASS_TASK_PRIORITY 3 +#define APP_QUIT_PIN CONFIG_APP_QUIT_PIN + +#ifdef CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK +#define ENABLE_ENUM_FILTER_CALLBACK +#endif // CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK + +extern void class_driver_task(void *arg); +extern void class_driver_client_deregister(void); + +static const char *TAG = "USB host lib"; + +QueueHandle_t app_event_queue = NULL; + +/** + * @brief APP event group + * + * APP_EVENT - General event, which is APP_QUIT_PIN press event in this example. + */ +typedef enum { + APP_EVENT = 0, +} app_event_group_t; + +/** + * @brief APP event queue + * + * This event is used for delivering events from callback to a task. + */ +typedef struct { + app_event_group_t event_group; +} app_event_queue_t; + +/** + * @brief BOOT button pressed callback + * + * Signal application to exit the Host lib task + * + * @param[in] arg Unused + */ +static void gpio_cb(void *arg) +{ + const app_event_queue_t evt_queue = { + .event_group = APP_EVENT, + }; + + BaseType_t xTaskWoken = pdFALSE; + + if (app_event_queue) { + xQueueSendFromISR(app_event_queue, &evt_queue, &xTaskWoken); + } + + if (xTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} + +/** + * @brief Set configuration callback + * + * Set the USB device configuration during the enumeration process, must be enabled in the menuconfig + + * @note bConfigurationValue starts at index 1 + * + * @param[in] dev_desc device descriptor of the USB device currently being enumerated + * @param[out] bConfigurationValue configuration descriptor index, that will be user for enumeration + * + * @return bool + * - true: USB device will be enumerated + * - false: USB device will not be enumerated + */ +#ifdef ENABLE_ENUM_FILTER_CALLBACK +static bool set_config_cb(const usb_device_desc_t *dev_desc, uint8_t *bConfigurationValue) +{ + // If the USB device has more than one configuration, set the second configuration + if (dev_desc->bNumConfigurations > 1) { + *bConfigurationValue = 2; + } else { + *bConfigurationValue = 1; + } + + // Return true to enumerate the USB device + return true; +} +#endif // ENABLE_ENUM_FILTER_CALLBACK + +/** + * @brief Start USB Host install and handle common USB host library events while app pin not low + * + * @param[in] arg Not used + */ +static void usb_host_lib_task(void *arg) +{ + ESP_LOGI(TAG, "Installing USB Host Library"); + usb_host_config_t host_config = { + .skip_phy_setup = false, + .intr_flags = ESP_INTR_FLAG_LEVEL1, +# ifdef ENABLE_ENUM_FILTER_CALLBACK + .enum_filter_cb = set_config_cb, +# endif // ENABLE_ENUM_FILTER_CALLBACK + .peripheral_map = BIT0, + }; + ESP_ERROR_CHECK(usb_host_install(&host_config)); + ESP_LOGI(TAG, "USB Host installed with peripheral map 0x%x", host_config.peripheral_map); + + //Signalize the app_main, the USB host library has been installed + xTaskNotifyGive(arg); + + bool has_clients = true; + bool has_devices = false; + while (has_clients) { + uint32_t event_flags; + ESP_ERROR_CHECK(usb_host_lib_handle_events(portMAX_DELAY, &event_flags)); + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + ESP_LOGI(TAG, "Get FLAGS_NO_CLIENTS"); + if (ESP_OK == usb_host_device_free_all()) { + ESP_LOGI(TAG, "All devices marked as free, no need to wait FLAGS_ALL_FREE event"); + has_clients = false; + } else { + ESP_LOGI(TAG, "Wait for the FLAGS_ALL_FREE"); + has_devices = true; + } + } + if (has_devices && event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + ESP_LOGI(TAG, "Get FLAGS_ALL_FREE"); + has_clients = false; + } + } + ESP_LOGI(TAG, "No more clients and devices, uninstall USB Host library"); + + //Uninstall the USB Host Library + ESP_ERROR_CHECK(usb_host_uninstall()); + vTaskSuspend(NULL); +} + +void app_main(void) +{ + ESP_LOGI(TAG, "USB host library example"); + + // Init BOOT button: Pressing the button simulates app request to exit + // It will uninstall the class driver and USB Host Lib + const gpio_config_t input_pin = { + .pin_bit_mask = BIT64(APP_QUIT_PIN), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .intr_type = GPIO_INTR_NEGEDGE, + }; + ESP_ERROR_CHECK(gpio_config(&input_pin)); + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1)); + ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_cb, NULL)); + + app_event_queue = xQueueCreate(10, sizeof(app_event_queue_t)); + app_event_queue_t evt_queue; + + TaskHandle_t host_lib_task_hdl, class_driver_task_hdl; + + // Create usb host lib task + BaseType_t task_created; + task_created = xTaskCreatePinnedToCore(usb_host_lib_task, + "usb_host", + 4096, + xTaskGetCurrentTaskHandle(), + HOST_LIB_TASK_PRIORITY, + &host_lib_task_hdl, + 0); + assert(task_created == pdTRUE); + + // Wait until the USB host library is installed + ulTaskNotifyTake(false, 1000); + + // Create class driver task + task_created = xTaskCreatePinnedToCore(class_driver_task, + "class", + 5 * 1024, + NULL, + CLASS_TASK_PRIORITY, + &class_driver_task_hdl, + 0); + assert(task_created == pdTRUE); + // Add a short delay to let the tasks run + vTaskDelay(10); + + while (1) { + if (xQueueReceive(app_event_queue, &evt_queue, portMAX_DELAY)) { + if (APP_EVENT == evt_queue.event_group) { + // User pressed button + usb_host_lib_info_t lib_info; + ESP_ERROR_CHECK(usb_host_lib_info(&lib_info)); + if (lib_info.num_devices != 0) { + ESP_LOGW(TAG, "Shutdown with attached devices."); + } + // End while cycle + break; + } + } + } + + // Deregister client + class_driver_client_deregister(); + vTaskDelay(10); + + // Delete the tasks + vTaskDelete(class_driver_task_hdl); + vTaskDelete(host_lib_task_hdl); + + // Delete interrupt and queue + gpio_isr_handler_remove(APP_QUIT_PIN); + xQueueReset(app_event_queue); + vQueueDelete(app_event_queue); + ESP_LOGI(TAG, "End of the example"); +} diff --git a/tests/c_headers/idf-usb/host/usb_host_lib/pytest_usb_host_lib.py b/tests/c_headers/idf-usb/host/usb_host_lib/pytest_usb_host_lib.py new file mode 100644 index 00000000..b3907df7 --- /dev/null +++ b/tests/c_headers/idf-usb/host/usb_host_lib/pytest_usb_host_lib.py @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize + + +@pytest.mark.temp_skip_ci(targets=['esp32s2'], reason='lack of runners with usb_host_flash_disk tag') +@pytest.mark.usb_host_flash_disk +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) +def test_usb_host_lib_example(dut: Dut) -> None: + # register client + dut.expect_exact('CLASS: Registering Client') + + # expect device descriptor + dut.expect_exact('CLASS: Getting device descriptor') + + # confirm device descriptor + dut.expect_exact('*** Device descriptor ***') + + # expect configuration descriptor + dut.expect_exact('CLASS: Getting config descriptor') + + # confirm configuration descriptor + dut.expect_exact('*** Configuration descriptor ***') diff --git a/tests/c_headers/idf-usb/host/usb_host_lib/sdkconfig.defaults b/tests/c_headers/idf-usb/host/usb_host_lib/sdkconfig.defaults new file mode 100644 index 00000000..bf1b553b --- /dev/null +++ b/tests/c_headers/idf-usb/host/usb_host_lib/sdkconfig.defaults @@ -0,0 +1,4 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_USB_HOST_HUBS_SUPPORTED=y diff --git a/tests/c_headers/idf-usb/host/uvc/CMakeLists.txt b/tests/c_headers/idf-usb/host/uvc/CMakeLists.txt new file mode 100644 index 00000000..b54c6c14 --- /dev/null +++ b/tests/c_headers/idf-usb/host/uvc/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(usb-uvc) diff --git a/tests/c_headers/idf-usb/host/uvc/README.md b/tests/c_headers/idf-usb/host/uvc/README.md new file mode 100644 index 00000000..fb408d0d --- /dev/null +++ b/tests/c_headers/idf-usb/host/uvc/README.md @@ -0,0 +1,96 @@ +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | + +# USB Camera Example + +## Overview + +This example shows basic usage of [USB UVC host driver](https://components.espressif.com/components/espressif/usb_host_uvc). The example waits for USB camera connection, it then configures the camera and starts streaming video frames until the device is removed. + +More advanced examples can be found in [UVC host driver repository](https://github.com/espressif/esp-usb/tree/master/host/class/uvc/usb_host_uvc/examples). + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +## How to Use Example + +### Hardware Required + +* Development board with USB-OTG support and external PSRAM +* Exposed USB host connector +* USB camera + +Running this example on an **ESP module without external PSRAM will fail on initialization**. Please select your PSRAM configuration in menuconfig `Component config->ESP PSRAM`. If you manually disable PSRAM, the required frame buffers might not fit into DRAM (especially on ESP32-S2). If you absolutely must not use PSRAM, consider the following for minimizing RAM usage: +* Select smaller resolution (eg. 320x240) +* Select fewer frame buffers (eg. 2) +* Select smaller and fewer URBs (eg. 2x 2kB) + +Follow instructions in [examples/usb/README.md](../../README.md) for specific hardware setup. + +### Frame format + +You can select frame format in [main.c](./main/main.c) file in `stream_config` variable. Default is set to very common 640x480@15FPS, MJPEG encoded. + +This example will print supported formats on device connection - this can be disabled in menuconfig ` Component config → USB HOST UVC`. The frame format can also be changed in runtime by calling `uvc_host_stream_format_select()` function. + +### Build and Flash + +Build the project and flash it to the board, then run the monitor tool to view the serial output: + +Run `idf.py set-target esp32xx` to set target chip. + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects. + +## Known limitations + +On targets with Full Speed USB peripheral the MPS (maximum packet size) is limited to 512 bytes, the ESP32-S2/S3 is capable of reading data at approximately 0.5 MB/s. When connected to Full Speed USB host, cameras usually provide resolution no larger than 640x480 pixels. The following two formats are the most commonly supported at Full Speed : +* 320x240 30 FPS MJPEG +* 640x480 15 FPS MJPEG + +## Tested cameras +* Logitech C980 +* Logitech C270 +* Logitech C170 +* Logitech Brio 100 +* CANYON CNE-CWC2 +* Trust WebCam +* Anker Powerconf C200 +* Microsoft LifeCam HD-6000 +* Asus Webcam C3 + +## Example Output + +Output with USB camera already connected at program start: +``` +... +I (1460) main_task: Calling app_main() +I (1460) UVC example: Installing USB Host +I (1500) UVC example: Installing UVC driver +I (1500) UVC example: Opening UVC device 0x0000:0x0000 640x480@15.0FPS... +I (1500) main_task: Returned from app_main() +*** Configuration descriptor *** + +... +Here is rest of Configuration descriptor +... + +I (3140) UVC example: UVC Device OPENED! +I (3240) UVC example: Stream start. Iteration 0 +I (4410) UVC example: New frame! Len: 13392 +I (4470) UVC example: New frame! Len: 13392 +I (4530) UVC example: New frame! Len: 13392 + +... +More frames received +... + +I (8310) UVC example: New frame! Len: 18512 +I (8310) UVC example: Stream stop +I (10440) UVC example: Stream start. Iteration 1 + +... +Streaming continues here +``` diff --git a/tests/c_headers/idf-usb/host/uvc/main/CMakeLists.txt b/tests/c_headers/idf-usb/host/uvc/main/CMakeLists.txt new file mode 100644 index 00000000..f91cf7ce --- /dev/null +++ b/tests/c_headers/idf-usb/host/uvc/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register(SRCS "main.c" + PRIV_REQUIRES + usb + esp_psram # Required for CONFIG_SPIRAM + ) diff --git a/tests/c_headers/idf-usb/host/uvc/main/idf_component.yml b/tests/c_headers/idf-usb/host/uvc/main/idf_component.yml new file mode 100644 index 00000000..75713163 --- /dev/null +++ b/tests/c_headers/idf-usb/host/uvc/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + idf: ">=5.0" + usb_host_uvc: "^2.2.0" diff --git a/tests/c_headers/idf-usb/host/uvc/main/main.c b/tests/c_headers/idf-usb/host/uvc/main/main.c new file mode 100644 index 00000000..60edd732 --- /dev/null +++ b/tests/c_headers/idf-usb/host/uvc/main/main.c @@ -0,0 +1,233 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "sdkconfig.h" +#include "esp_system.h" +#include "esp_log.h" +#include "esp_err.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" + +#include "usb/usb_host.h" +#include "usb/uvc_host.h" + +#define EXAMPLE_USB_HOST_PRIORITY (15) +#define EXAMPLE_RECORDING_LENGTH_S (5) // This example will enable the stream, run it for EXAMPLE_RECORDING_LENGTH_S and then stop it + +// Private function prototypes +static bool frame_callback(const uvc_host_frame_t *frame, void *user_ctx); +static void stream_callback(const uvc_host_stream_event_data_t *event, void *user_ctx); + +// Private variables +static QueueHandle_t rx_frames_queue; +static bool dev_connected = false; +static const char *TAG = "UVC example"; + +/** + * @brief Configuration of the UVC stream + * + * Update the vs_format to match your camera's capabilities. + * The example will try to open the camera with the specified resolution and FPS. + */ +static const uvc_host_stream_config_t stream_config = { + .event_cb = stream_callback, + .frame_cb = frame_callback, + .user_ctx = &rx_frames_queue, + .usb = { + .vid = UVC_HOST_ANY_VID, // Set to 0 to match any VID + .pid = UVC_HOST_ANY_PID, // Set to 0 to match any PID + .uvc_stream_index = 0, /* Index of UVC function you want to use. Set to 0 to use first available UVC function. + Setting this to >= 1 will only work if the camera has multiple UVC functions (eg. multiple image sensors in one USB device) */ + }, + .vs_format = { + // Note: For Full-Speed targets, only limited set of formats might be supported by the camera. + // Check the camera's Configuration descriptor for supported formats and resolutions. +#if CONFIG_SPIRAM + .h_res = 640, + .v_res = 480, +#else + .h_res = 320, + .v_res = 240, +#endif + .fps = 15, + .format = UVC_VS_FORMAT_MJPEG, + }, + .advanced = { + .frame_size = 0, /* == 0: Use dwMaxVideoFrameSize from format negotiation result (might be too large) + >= 0: Use user provide frame size -> can save RAM, but occasionally a frame can overflow */ +#if CONFIG_SPIRAM + .number_of_frame_buffers = 3, // Use triple buffering scheme if SPIRAM is available + .number_of_urbs = 3, // 3x 10kB URBs is usually enough, even for higher resolutions + .urb_size = 10 * 1024, // Larger values result in less frequent interrupts at the cost of memory consumption + .frame_heap_caps = MALLOC_CAP_SPIRAM, // Use SPIRAM for frame buffers +#else + .number_of_frame_buffers = 2, // Use double buffering scheme if SPIRAM is not available + .number_of_urbs = 2, // 2x 2kB URBs for memory constrained applications + .urb_size = 2 * 1024, // Larger values result in less frequent interrupts at the cost of memory consumption +#endif + }, +}; + +static bool frame_callback(const uvc_host_frame_t *frame, void *user_ctx) +{ + assert(frame); + assert(user_ctx); + QueueHandle_t frame_q = *((QueueHandle_t *)user_ctx); + + // Send the received frame to queue for further processing + ESP_LOGD(TAG, "Frame callback! data len: %d", frame->data_len); + BaseType_t result = xQueueSendToBack(frame_q, &frame, 0); + if (pdPASS != result) { + ESP_LOGW(TAG, "Queue full, losing frame"); // This should never happen + return true; // We will not process this frame, return it immediately + } + return false; // We only passed the frame to Queue, so we must return false and call uvc_host_frame_return() later +} + +static void stream_callback(const uvc_host_stream_event_data_t *event, void *user_ctx) +{ + switch (event->type) { + case UVC_HOST_TRANSFER_ERROR: + ESP_LOGE(TAG, "USB error has occurred, err_no = %i", event->transfer_error.error); + break; + case UVC_HOST_DEVICE_DISCONNECTED: + ESP_LOGI(TAG, "Device suddenly disconnected"); + dev_connected = false; + ESP_ERROR_CHECK(uvc_host_stream_close(event->device_disconnected.stream_hdl)); + break; + case UVC_HOST_FRAME_BUFFER_OVERFLOW: + // The Frame was discarded because it exceeded the available frame buffer size. + // To resolve this, increase the `frame_size` parameter in `uvc_host_stream_config_t.advanced` to allocate a larger buffer. + ESP_LOGW(TAG, "Frame buffer overflow"); + break; + case UVC_HOST_FRAME_BUFFER_UNDERFLOW: + // The Frame was discarded because no available buffer was free for storage. + // To resolve this, either optimize your processing speed or increase the `number_of_frame_buffers` parameter in + // `uvc_host_stream_config_t.advanced` to allocate additional buffers. + ESP_LOGW(TAG, "Frame buffer underflow"); + break; + default: + abort(); + break; + } +} + +static void usb_lib_task(void *arg) +{ + while (1) { + // Start handling system events + uint32_t event_flags; + usb_host_lib_handle_events(portMAX_DELAY, &event_flags); + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + usb_host_device_free_all(); + } + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + ESP_LOGI(TAG, "USB: All devices freed"); + // Continue handling USB events to allow device reconnection + } + } +} + +static void frame_handling_task(void *arg) +{ + const uvc_host_stream_config_t *stream_config = (const uvc_host_stream_config_t *)arg; + QueueHandle_t frame_q = *((QueueHandle_t *)(stream_config->user_ctx)); + + // This is the main program loop, it tries to open the UVC device and start streaming + while (true) { + uvc_host_stream_hdl_t uvc_stream = NULL; + + ESP_LOGI(TAG, "Opening UVC device 0x%04X:0x%04X %dx%d@%2.1fFPS...", + stream_config->usb.vid, stream_config->usb.pid, stream_config->vs_format.h_res, stream_config->vs_format.v_res, stream_config->vs_format.fps); + esp_err_t err = uvc_host_stream_open(stream_config, pdMS_TO_TICKS(5000), &uvc_stream); + if (ESP_OK != err) { + ESP_LOGI(TAG, "Failed to open device"); + vTaskDelay(pdMS_TO_TICKS(5000)); + continue; + } + dev_connected = true; + ESP_LOGI(TAG, "UVC Device OPENED!"); + vTaskDelay(pdMS_TO_TICKS(100)); + unsigned count = 0; + + // This is the main processing loop. It enables the stream for EXAMPLE_RECORDING_LENGTH_S seconds and then closes it + while (true) { + ESP_LOGI(TAG, "Stream start. Iteration %u", count); + count++; + uvc_host_stream_start(uvc_stream); + TickType_t timeout_ticks = pdMS_TO_TICKS(EXAMPLE_RECORDING_LENGTH_S * 1000); + TimeOut_t stream_timeout; + vTaskSetTimeOutState(&stream_timeout); + + do { + uvc_host_frame_t *frame; + if (xQueueReceive(frame_q, &frame, pdMS_TO_TICKS(5000)) == pdPASS) { + ESP_LOGI(TAG, "New frame! Len: %d", frame->data_len); + + // Process the frame data here + // For example, you can: + // - Save the frame to a file + // - Send the frame over the network + // - Decode the frame (typically MJPEG encoded) + // - Display the frame on a screen + // - etc. + + uvc_host_frame_return(uvc_stream, frame); + } else { + ESP_LOGW(TAG, "Stream: Frame not received on time"); + break; + } + } while (xTaskCheckForTimeOut(&stream_timeout, &timeout_ticks) == pdFALSE); + + if (dev_connected) { + // Stop and wait 2 seconds + ESP_LOGI(TAG, "Stream stop"); + uvc_host_stream_stop(uvc_stream); + vTaskDelay(pdMS_TO_TICKS(2000)); + } else { + ESP_LOGI(TAG, "device disconnected, breaking"); + break; + } + } + } +} + +/** + * @brief Main application + */ +void app_main(void) +{ + rx_frames_queue = xQueueCreate(3, sizeof(uvc_host_frame_t *)); + assert(rx_frames_queue); + + // Install USB Host driver. Should only be called once in entire application + ESP_LOGI(TAG, "Installing USB Host"); + const usb_host_config_t host_config = { + .skip_phy_setup = false, + .intr_flags = ESP_INTR_FLAG_LEVEL1, + }; + ESP_ERROR_CHECK(usb_host_install(&host_config)); + + // Create a task that will handle USB library events + BaseType_t task_created = xTaskCreatePinnedToCore(usb_lib_task, "usb_lib", 4096, NULL, EXAMPLE_USB_HOST_PRIORITY, NULL, tskNO_AFFINITY); + assert(task_created == pdTRUE); + + ESP_LOGI(TAG, "Installing UVC driver"); + const uvc_host_driver_config_t uvc_driver_config = { + .driver_task_stack_size = 4 * 1024, + .driver_task_priority = EXAMPLE_USB_HOST_PRIORITY + 1, + .xCoreID = tskNO_AFFINITY, + .create_background_task = true, + }; + ESP_ERROR_CHECK(uvc_host_install(&uvc_driver_config)); + + task_created = xTaskCreatePinnedToCore(frame_handling_task, "frame_hdl", 4096, (void *)&stream_config, EXAMPLE_USB_HOST_PRIORITY - 2, NULL, tskNO_AFFINITY); + assert(task_created == pdTRUE); +} diff --git a/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults b/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults new file mode 100644 index 00000000..1248dbd1 --- /dev/null +++ b/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults @@ -0,0 +1,13 @@ +# +# SPIRAM +# +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=150000 +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y + +# +# USB +# +CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=3000 +CONFIG_USB_HOST_HW_BUFFER_BIAS_IN=y +CONFIG_PRINTF_UVC_CONFIGURATION_DESCRIPTOR=y diff --git a/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32p4 b/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32p4 new file mode 100644 index 00000000..b700e907 --- /dev/null +++ b/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32p4 @@ -0,0 +1,2 @@ +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM_SPEED_200M=y diff --git a/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32s2 b/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32s2 new file mode 100644 index 00000000..864fd356 --- /dev/null +++ b/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32s2 @@ -0,0 +1,9 @@ +# +# SPIRAM +# +CONFIG_SPIRAM_SPEED_80M=y + +# +# SYSTEM +# +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y diff --git a/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32s3 b/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32s3 new file mode 100644 index 00000000..864fd356 --- /dev/null +++ b/tests/c_headers/idf-usb/host/uvc/sdkconfig.defaults.esp32s3 @@ -0,0 +1,9 @@ +# +# SPIRAM +# +CONFIG_SPIRAM_SPEED_80M=y + +# +# SYSTEM +# +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y diff --git a/tests/c_headers/ppp_connect_uart.c b/tests/c_headers/ppp_connect_uart.c new file mode 100644 index 00000000..98db74d6 --- /dev/null +++ b/tests/c_headers/ppp_connect_uart.c @@ -0,0 +1,179 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "protocol_examples_common.h" +#include "example_common_private.h" + +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_netif_ppp.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "driver/uart.h" +#define BUF_SIZE (1024) +static bool s_stop_task = false; + + +static const char *TAG = "example_connect_ppp"; +static int s_retry_num = 0; +static EventGroupHandle_t s_event_group = NULL; +static esp_netif_t *s_netif; +static const int GOT_IPV4 = BIT0; +static const int CONNECTION_FAILED = BIT1; +#if CONFIG_EXAMPLE_CONNECT_IPV6 +static const int GOT_IPV6 = BIT2; +#define CONNECT_BITS (GOT_IPV4|GOT_IPV6|CONNECTION_FAILED) +#else +#define CONNECT_BITS (GOT_IPV4|CONNECTION_FAILED) +#endif + +static esp_err_t transmit(void *h, void *buffer, size_t len) +{ + ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); + uart_write_bytes(UART_NUM_1, buffer, len); + return ESP_OK; +} + +static esp_netif_driver_ifconfig_t driver_cfg = { + .handle = (void *)1, // singleton driver, just to != NULL + .transmit = transmit, +}; +const esp_netif_driver_ifconfig_t *ppp_driver_cfg = &driver_cfg; + +static void on_ip_event(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + + if (event_id == IP_EVENT_PPP_GOT_IP) { + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_netif_t *netif = event->esp_netif; + esp_netif_dns_info_t dns_info; + ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); + esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info); + ESP_LOGI(TAG, "Main DNS server : " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); + xEventGroupSetBits(s_event_group, GOT_IPV4); + } else if (event_id == IP_EVENT_GOT_IP6) { + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), + IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { + xEventGroupSetBits(s_event_group, GOT_IPV6); + } + } else if (event_id == IP_EVENT_PPP_LOST_IP) { + ESP_LOGI(TAG, "Disconnect from PPP Server"); + s_retry_num++; + if (s_retry_num > CONFIG_EXAMPLE_PPP_CONN_MAX_RETRY) { + ESP_LOGE(TAG, "PPP Connection failed %d times, stop reconnecting.", s_retry_num); + xEventGroupSetBits(s_event_group, CONNECTION_FAILED); + } else { + ESP_LOGI(TAG, "PPP Connection failed %d times, try to reconnect.", s_retry_num); + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + } + + } +} + + +static void ppp_task(void *args) +{ + uart_config_t uart_config = {}; + uart_config.baud_rate = CONFIG_EXAMPLE_CONNECT_UART_BAUDRATE; + uart_config.data_bits = UART_DATA_8_BITS; + uart_config.parity = UART_PARITY_DISABLE; + uart_config.stop_bits = UART_STOP_BITS_1; + uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; + uart_config.source_clk = UART_SCLK_DEFAULT; + + QueueHandle_t event_queue; + ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, BUF_SIZE, 0, 16, &event_queue, 0)); + ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, CONFIG_EXAMPLE_CONNECT_UART_TX_PIN, CONFIG_EXAMPLE_CONNECT_UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + ESP_ERROR_CHECK(uart_set_rx_timeout(UART_NUM_1, 1)); + + char *buffer = (char*)malloc(BUF_SIZE); + uart_event_t event; + esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_GOT_IP, esp_netif_action_connected, s_netif); + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + while (!s_stop_task) { + xQueueReceive(event_queue, &event, pdMS_TO_TICKS(1000)); + if (event.type == UART_DATA) { + size_t len; + uart_get_buffered_data_len(UART_NUM_1, &len); + if (len) { + len = uart_read_bytes(UART_NUM_1, buffer, BUF_SIZE, 0); + ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); + esp_netif_receive(s_netif, buffer, len, NULL); + } + } else { + ESP_LOGW(TAG, "Received UART event: %d", event.type); + } + } + free(buffer); + vTaskDelete(NULL); +} + + +esp_err_t example_ppp_connect(void) +{ + ESP_LOGI(TAG, "Start example_connect."); + + s_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL)); + + esp_netif_inherent_config_t base_netif_cfg = ESP_NETIF_INHERENT_DEFAULT_PPP(); + base_netif_cfg.if_desc = EXAMPLE_NETIF_DESC_PPP; + esp_netif_config_t netif_ppp_config = { .base = &base_netif_cfg, + .driver = ppp_driver_cfg, + .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP + }; + + s_netif = esp_netif_new(&netif_ppp_config); + assert(s_netif); + s_stop_task = false; + if (xTaskCreate(ppp_task, "ppp connect", 4096, NULL, 5, NULL) != pdTRUE) { + ESP_LOGE(TAG, "Failed to create a ppp connection task"); + return ESP_FAIL; + } + + ESP_LOGI(TAG, "Waiting for IP address"); + EventBits_t bits = xEventGroupWaitBits(s_event_group, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY); + if (bits & CONNECTION_FAILED) { + ESP_LOGE(TAG, "Connection failed!"); + return ESP_FAIL; + } + ESP_LOGI(TAG, "Connected!"); + + return ESP_OK; +} + +void example_ppp_shutdown(void) +{ + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event)); + s_stop_task = true; + vTaskDelay(pdMS_TO_TICKS(1000)); // wait for the ppp task to stop + + esp_netif_action_disconnected(s_netif, 0, 0, 0); + + vEventGroupDelete(s_event_group); + esp_netif_action_stop(s_netif, 0, 0, 0); + esp_netif_destroy(s_netif); + s_netif = NULL; + s_event_group = NULL; +} diff --git a/tests/c_headers/ppp_connect_usb.c b/tests/c_headers/ppp_connect_usb.c new file mode 100644 index 00000000..97c0902d --- /dev/null +++ b/tests/c_headers/ppp_connect_usb.c @@ -0,0 +1,186 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "protocol_examples_common.h" +#include "example_common_private.h" + +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_netif_ppp.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#define CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB 1 + +#include "tinyusb.h" +#include "tusb_cdc_acm.h" + +static int s_itf; +static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE]; + + +static const char *TAG = "example_connect_ppp"; +static int s_retry_num = 0; +static EventGroupHandle_t s_event_group = NULL; +static esp_netif_t *s_netif; +static const int GOT_IPV4 = BIT0; +static const int CONNECTION_FAILED = BIT1; +static const int GOT_IPV6 = BIT2; +#define CONNECT_BITS (GOT_IPV4|GOT_IPV6|CONNECTION_FAILED) + +static esp_err_t transmit(void *h, void *buffer, size_t len) +{ + ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); + + tinyusb_cdcacm_write_queue(s_itf, buffer, len); + tinyusb_cdcacm_write_flush(s_itf, 0); + + return ESP_OK; +} + +static esp_netif_driver_ifconfig_t driver_cfg = { + .handle = (void *)1, // singleton driver, just to != NULL + .transmit = transmit, +}; +const esp_netif_driver_ifconfig_t *ppp_driver_cfg = &driver_cfg; + +static void on_ip_event(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + + if (event_id == IP_EVENT_PPP_GOT_IP) { + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_netif_t *netif = event->esp_netif; + esp_netif_dns_info_t dns_info; + ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); + esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info); + ESP_LOGI(TAG, "Main DNS server : " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); + xEventGroupSetBits(s_event_group, GOT_IPV4); + } else if (event_id == IP_EVENT_GOT_IP6) { + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), + IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { + xEventGroupSetBits(s_event_group, GOT_IPV6); + } + } else if (event_id == IP_EVENT_PPP_LOST_IP) { + ESP_LOGI(TAG, "Disconnect from PPP Server"); + s_retry_num++; + if (s_retry_num > CONFIG_EXAMPLE_PPP_CONN_MAX_RETRY) { + ESP_LOGE(TAG, "PPP Connection failed %d times, stop reconnecting.", s_retry_num); + xEventGroupSetBits(s_event_group, CONNECTION_FAILED); + } else { + ESP_LOGI(TAG, "PPP Connection failed %d times, try to reconnect.", s_retry_num); + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + } + + } +} + +static void cdc_rx_callback(int itf, cdcacm_event_t *event) +{ + size_t rx_size = 0; + if (itf != s_itf) { + // Not our channel + return; + } + esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); + if (ret == ESP_OK) { + ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_VERBOSE); + // pass the received data to the network interface + esp_netif_receive(s_netif, buf, rx_size, NULL); + } else { + ESP_LOGE(TAG, "Read error"); + } +} + +static void line_state_changed(int itf, cdcacm_event_t *event) +{ + s_itf = itf; // use this channel for the netif communication + ESP_LOGI(TAG, "Line state changed on channel %d", itf); +} + +esp_err_t example_ppp_connect(void) +{ + ESP_LOGI(TAG, "Start example_connect."); + + ESP_LOGI(TAG, "USB initialization"); + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .external_phy = false, + .configuration_descriptor = NULL, + }; + + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + tinyusb_config_cdcacm_t acm_cfg = { + .usb_dev = TINYUSB_USBDEV_0, + .cdc_port = TINYUSB_CDC_ACM_0, + .callback_rx = &cdc_rx_callback, + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = NULL, + .callback_line_coding_changed = NULL + }; + + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); + /* the second way to register a callback */ + ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( + TINYUSB_CDC_ACM_0, + CDC_EVENT_LINE_STATE_CHANGED, + &line_state_changed)); + + s_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL)); + + esp_netif_inherent_config_t base_netif_cfg = ESP_NETIF_INHERENT_DEFAULT_PPP(); + base_netif_cfg.if_desc = EXAMPLE_NETIF_DESC_PPP; + esp_netif_config_t netif_ppp_config = { .base = &base_netif_cfg, + .driver = ppp_driver_cfg, + .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP + }; + + s_netif = esp_netif_new(&netif_ppp_config); + assert(s_netif); + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + + ESP_LOGI(TAG, "Waiting for IP address"); + EventBits_t bits = xEventGroupWaitBits(s_event_group, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY); + if (bits & CONNECTION_FAILED) { + ESP_LOGE(TAG, "Connection failed!"); + return ESP_FAIL; + } + ESP_LOGI(TAG, "Connected!"); + + return ESP_OK; +} + +void example_ppp_shutdown(void) +{ + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event)); + + esp_netif_action_disconnected(s_netif, 0, 0, 0); + + vEventGroupDelete(s_event_group); + esp_netif_action_stop(s_netif, 0, 0, 0); + esp_netif_destroy(s_netif); + s_netif = NULL; + s_event_group = NULL; +} + diff --git a/tests/ppp_connect.nim b/tests/ppp_connect.nim deleted file mode 100644 index cf24f095..00000000 --- a/tests/ppp_connect.nim +++ /dev/null @@ -1,160 +0,0 @@ -import nesper/general -import nesper/esp/event_groups -import nesper/esp/esp_event -import nesper/esp/net/esp_netif -import nesper/esp/net/esp_netif_ppp -import nesper/esp/net/esp_netif_defaults -import nesper/esp/net/esp_netif_impl -import nesper/esp/net/esp_netif_types -import nesper/esp/driver/uart -import nesper/uarts - -when defined(ESP_IDF_V4_0): - import nesper/esp/net/tcpip_adapter -else: - var IP_EVENT* {.importc: "IP_EVENT", header: "esp_netif_types.h".}: esp_event_base_t - -export esp_event -export esp_netif -export esp_netif_ppp - -const - TAG: cstring = "example_connect_ppp" - EXAMPLE_NETIF_DESC_PPP* = "example_netif_ppp" - - GOT_IPV4 = EventBits_t(BIT(0)) - CONNECTION_FAILED = EventBits_t(BIT(1)) -when defined(CONFIG_EXAMPLE_CONNECT_IPV6): - const GOT_IPV6 = EventBits_t(BIT(2)) - -when defined(CONFIG_EXAMPLE_CONNECT_IPV6): - const CONNECT_BITS = GOT_IPV4 or GOT_IPV6 or CONNECTION_FAILED -else: - const CONNECT_BITS = GOT_IPV4 or CONNECTION_FAILED - -const - DefaultBufSize = 1024.SzBytes - -## Allow overriding at compile time: -d:PPP_CONN_MAX_RETRY=3 -const PPP_CONN_MAX_RETRY* {.intdefine.} = 5 - -var - sRetryNum: int = 0 - sEventGroup: EventGroupHandle_t - sNetif: ptr esp_netif_t - sStopTask: bool = false - gUartPort: uart_port_t = UART_NUM_1 - gUart: Uart - -proc pppTransmit(h: pointer; buffer: pointer; len: csize_t): esp_err_t {.cdecl.} = - # For UART device: write bytes out on the configured UART port - discard uart_write_bytes(gUartPort, cast[cstring](buffer), len) - return ESP_OK - -var driverCfg = esp_netif_driver_ifconfig_t( - handle: cast[pointer](1), # singleton driver, just != NULL - transmit: pppTransmit -) - -proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = - if event_id == ip_event_t.IP_EVENT_PPP_GOT_IP.ord: - let ev = cast[ptr ip_event_got_ip_t](event_data) - if ev.esp_netif != sNetif: - return - TAG.logi("PPP got IPv4") - var dnsInfo: esp_netif_dns_info_t - discard esp_netif_get_dns_info(sNetif, esp_netif_dns_type_t.ESP_NETIF_DNS_MAIN, addr dnsInfo) - discard xEventGroupSetBits(sEventGroup, GOT_IPV4) - elif event_id == ip_event_t.IP_EVENT_GOT_IP6.ord: - let ev6 = cast[ptr ip_event_got_ip6_t](event_data) - if ev6.esp_netif != sNetif: - return - TAG.logi("PPP got IPv6") - when defined(CONFIG_EXAMPLE_CONNECT_IPV6): - discard xEventGroupSetBits(sEventGroup, GOT_IPV6) - elif event_id == ip_event_t.IP_EVENT_PPP_LOST_IP.ord: - TAG.logi("PPP disconnected from server") - inc sRetryNum - if sRetryNum > PPP_CONN_MAX_RETRY: - TAG.loge("PPP Connection failed %d times, stop reconnecting.", sRetryNum.cint) - discard xEventGroupSetBits(sEventGroup, CONNECTION_FAILED) - else: - TAG.logi("PPP Connection failed %d times, reconnecting...", sRetryNum.cint) - esp_netif_action_start(sNetif, nil, 0, nil) - esp_netif_action_connected(sNetif, nil, 0, nil) - -proc pppUartTask(arg: pointer) {.cdecl.} = - while not sStopTask: - let data = gUart.read(size = DefaultBufSize, wait = 1.Millis) - if data.len > 0: - discard esp_netif_receive(sNetif, unsafeAddr data[0], data.len.csize_t, nil) - vTaskDelete(nil) - -proc examplePppConnect*( - uartNum: uart_port_t = UART_NUM_1, - txPin: gpio_num_t, - rxPin: gpio_num_t, - baudrate: int = 115_200, - stackSize: uint32 = 4096, - taskPrio: UBaseType_t = 5 - ): esp_err_t = - - TAG.logi("Start example_connect (PPP over UART)") - - sEventGroup = xEventGroupCreate() - if sEventGroup.isNil: - TAG.loge("Failed to create event group") - return ESP_FAIL - - check: esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, onIpEvent, nil) - - var baseCfg = ESP_NETIF_INHERENT_DEFAULT_PPP() - baseCfg.if_desc = EXAMPLE_NETIF_DESC_PPP - var netifCfg = esp_netif_config_t( - base: addr baseCfg, - driver: addr driverCfg, - stack: ESP_NETIF_NETSTACK_DEFAULT_PPP - ) - - sNetif = esp_netif_new(addr netifCfg) - if sNetif.isNil: - TAG.loge("Failed to create PPP netif") - return ESP_FAIL - - # Initialize UART for PPPoS framing - gUartPort = uartNum - var ucfg = newUartConfig(baud_rate = baudrate) - gUart = newUart(ucfg, uartNum, txPin, rxPin, buffer = DefaultBufSize, event_size = 0) - - sStopTask = false - if xTaskCreate(pppUartTask, "ppp connect", stackSize, nil, taskPrio, nil) != pdTRUE: - TAG.loge("Failed to create PPP task") - return ESP_FAIL - - # Bring the netif up (start + connected) - esp_netif_action_start(sNetif, nil, 0, nil) - esp_netif_action_connected(sNetif, nil, 0, nil) - - TAG.logi("Waiting for IP address") - let bits = xEventGroupWaitBits(sEventGroup, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY) - if (bits and CONNECTION_FAILED) != 0: - TAG.loge("PPP connection failed") - return ESP_FAIL - - TAG.logi("PPP connected!") - return ESP_OK - -proc examplePppShutdown*() = - discard esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, onIpEvent) - - sStopTask = true - vTaskDelay(pdMS_TO_TICKS(1000)) # wait for the PPP task to stop - - esp_netif_action_disconnected(sNetif, nil, 0, nil) - - vEventGroupDelete(sEventGroup) - esp_netif_action_stop(sNetif, nil, 0, nil) - esp_netif_destroy(sNetif) - sNetif = nil - sEventGroup = nil - From 450cc8592250949f79880f7d20978862b18bc2c6 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 22:39:10 -0600 Subject: [PATCH 012/142] tests --- tests/c_headers/esp_netif_defaults.h | 231 ++++++++ .../protocol_examples_common/CMakeLists.txt | 52 ++ .../Kconfig.projbuild | 504 ++++++++++++++++++ .../protocol_examples_common/README.md | 66 +++ .../addr_from_stdin.c | 69 +++ .../protocol_examples_common/connect.c | 148 +++++ .../protocol_examples_common/console_cmd.c | 87 +++ .../protocol_examples_common/eth_connect.c | 245 +++++++++ .../include/addr_from_stdin.h | 44 ++ .../include/example_common_private.h | 58 ++ .../include/protocol_examples_common.h | 154 ++++++ .../include/protocol_examples_thread_config.h | 115 ++++ .../include/protocol_examples_utils.h | 49 ++ .../protocol_examples_common/ppp_connect.c | 258 +++++++++ .../protocol_examples_utils.c | 388 ++++++++++++++ .../protocol_examples_common/stdin_out.c | 32 ++ .../protocol_examples_common/thread_connect.c | 130 +++++ .../protocol_examples_common/wifi_connect.c | 247 +++++++++ 18 files changed, 2877 insertions(+) create mode 100644 tests/c_headers/esp_netif_defaults.h create mode 100644 tests/c_headers/protocol_examples_common/CMakeLists.txt create mode 100644 tests/c_headers/protocol_examples_common/Kconfig.projbuild create mode 100644 tests/c_headers/protocol_examples_common/README.md create mode 100644 tests/c_headers/protocol_examples_common/addr_from_stdin.c create mode 100644 tests/c_headers/protocol_examples_common/connect.c create mode 100644 tests/c_headers/protocol_examples_common/console_cmd.c create mode 100644 tests/c_headers/protocol_examples_common/eth_connect.c create mode 100644 tests/c_headers/protocol_examples_common/include/addr_from_stdin.h create mode 100644 tests/c_headers/protocol_examples_common/include/example_common_private.h create mode 100644 tests/c_headers/protocol_examples_common/include/protocol_examples_common.h create mode 100644 tests/c_headers/protocol_examples_common/include/protocol_examples_thread_config.h create mode 100644 tests/c_headers/protocol_examples_common/include/protocol_examples_utils.h create mode 100644 tests/c_headers/protocol_examples_common/ppp_connect.c create mode 100644 tests/c_headers/protocol_examples_common/protocol_examples_utils.c create mode 100644 tests/c_headers/protocol_examples_common/stdin_out.c create mode 100644 tests/c_headers/protocol_examples_common/thread_connect.c create mode 100644 tests/c_headers/protocol_examples_common/wifi_connect.c diff --git a/tests/c_headers/esp_netif_defaults.h b/tests/c_headers/esp_netif_defaults.h new file mode 100644 index 00000000..1036d543 --- /dev/null +++ b/tests/c_headers/esp_netif_defaults.h @@ -0,0 +1,231 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ESP_NETIF_DEFAULTS_H +#define _ESP_NETIF_DEFAULTS_H + +#include "esp_compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// +// Macros to assemble master configs with partial configs from netif, stack and driver +// + +// If GARP enabled in menuconfig (default), make it also a default config for common netifs +#define ESP_NETIF_DEFAULT_ARP_FLAGS (ESP_NETIF_FLAG_GARP) + +#define ESP_NETIF_IPV4_ONLY_FLAGS(flags) (flags) + +#define ESP_NETIF_DEFAULT_MLDV6_REPORT_FLAGS (ESP_NETIF_FLAG_MLDV6_REPORT) + +#define ESP_NETIF_DEFAULT_IPV6_AUTOCONFIG_FLAGS (ESP_NETIF_FLAG_IPV6_AUTOCONFIG_ENABLED) + +#define ESP_NETIF_INHERENT_DEFAULT_WIFI_STA() \ + { \ + .flags = (esp_netif_flags_t)(ESP_NETIF_IPV4_ONLY_FLAGS(ESP_NETIF_DHCP_CLIENT) | ESP_NETIF_DEFAULT_ARP_FLAGS | ESP_NETIF_DEFAULT_MLDV6_REPORT_FLAGS | ESP_NETIF_FLAG_EVENT_IP_MODIFIED | ESP_NETIF_DEFAULT_IPV6_AUTOCONFIG_FLAGS), \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \ + .get_ip_event = IP_EVENT_STA_GOT_IP, \ + .lost_ip_event = IP_EVENT_STA_LOST_IP, \ + .if_key = "WIFI_STA_DEF", \ + .if_desc = "sta", \ + .route_prio = 100, \ + .bridge_info = NULL \ + } \ + +#define ESP_NETIF_INHERENT_DEFAULT_WIFI_AP() \ + { \ + .flags = (esp_netif_flags_t)(ESP_NETIF_IPV4_ONLY_FLAGS(ESP_NETIF_DHCP_SERVER) | ESP_NETIF_FLAG_AUTOUP), \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ + .ip_info = &_g_esp_netif_soft_ap_ip, \ + .get_ip_event = 0, \ + .lost_ip_event = 0, \ + .if_key = "WIFI_AP_DEF", \ + .if_desc = "ap", \ + .route_prio = 10, \ + .bridge_info = NULL \ + } + +#define ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN() \ + { \ + .flags = 0, \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \ + .get_ip_event = 0, \ + .lost_ip_event = 0, \ + .if_key = "WIFI_NAN_DEF", \ + .if_desc = "nan", \ + .route_prio = 10 \ + }; + +#define ESP_NETIF_INHERENT_DEFAULT_ETH() \ + { \ + .flags = (esp_netif_flags_t)(ESP_NETIF_IPV4_ONLY_FLAGS(ESP_NETIF_DHCP_CLIENT) | ESP_NETIF_DEFAULT_ARP_FLAGS | ESP_NETIF_FLAG_EVENT_IP_MODIFIED | ESP_NETIF_DEFAULT_IPV6_AUTOCONFIG_FLAGS), \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \ + .get_ip_event = IP_EVENT_ETH_GOT_IP, \ + .lost_ip_event = IP_EVENT_ETH_LOST_IP, \ + .if_key = "ETH_DEF", \ + .if_desc = "eth", \ + .route_prio = 50, \ + .bridge_info = NULL \ + } + +#define ESP_NETIF_INHERENT_DEFAULT_PPP() \ + { \ + .flags = (esp_netif_flags_t)(ESP_NETIF_FLAG_IS_PPP | ESP_NETIF_DEFAULT_IPV6_AUTOCONFIG_FLAGS), \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \ + .get_ip_event = IP_EVENT_PPP_GOT_IP, \ + .lost_ip_event = IP_EVENT_PPP_LOST_IP, \ + .if_key = "PPP_DEF", \ + .if_desc = "ppp", \ + .route_prio = 20, \ + .bridge_info = NULL \ + } + +#define ESP_NETIF_INHERENT_DEFAULT_BR() \ + { \ + .flags = (esp_netif_flags_t)(ESP_NETIF_DHCP_CLIENT | ESP_NETIF_DEFAULT_ARP_FLAGS | ESP_NETIF_FLAG_EVENT_IP_MODIFIED | ESP_NETIF_FLAG_IS_BRIDGE), \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(ip_info) \ + .get_ip_event = IP_EVENT_ETH_GOT_IP, \ + .lost_ip_event = IP_EVENT_ETH_LOST_IP, \ + .if_key = "BR0", \ + .if_desc = "br0", \ + .route_prio = 70, \ + .bridge_info = NULL \ + } + +#define ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS() \ + { \ + .flags = (esp_netif_flags_t)(ESP_NETIF_DHCP_SERVER | ESP_NETIF_FLAG_IS_BRIDGE), \ + ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_EMPTY(mac) \ + .ip_info = &_g_esp_netif_soft_ap_ip, \ + .get_ip_event = 0, \ + .lost_ip_event = 0, \ + .if_key = "BR1", \ + .if_desc = "br1", \ + .route_prio = 70, \ + .bridge_info = NULL \ + } + +/** + * @brief Default configuration reference of ethernet interface + */ +#define ESP_NETIF_DEFAULT_ETH() \ + { \ + .base = ESP_NETIF_BASE_DEFAULT_ETH, \ + .driver = NULL, \ + .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH, \ + } + +/** + * @brief Default configuration reference of WIFI AP + */ +#define ESP_NETIF_DEFAULT_WIFI_AP() \ + { \ + .base = ESP_NETIF_BASE_DEFAULT_WIFI_AP, \ + .driver = NULL, \ + .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP, \ + } + +/** +* @brief Default configuration reference of WIFI NAN +*/ +#define ESP_NETIF_DEFAULT_WIFI_NAN() \ + { \ + .base = ESP_NETIF_BASE_DEFAULT_WIFI_NAN, \ + .driver = NULL, \ + .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_NAN, \ + } + +/** +* @brief Default configuration reference of WIFI STA +*/ +#define ESP_NETIF_DEFAULT_WIFI_STA() \ + { \ + .base = ESP_NETIF_BASE_DEFAULT_WIFI_STA, \ + .driver = NULL, \ + .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, \ + } + +/** +* @brief Default configuration reference of PPP client +*/ +#define ESP_NETIF_DEFAULT_PPP() \ + { \ + .base = ESP_NETIF_BASE_DEFAULT_PPP, \ + .driver = NULL, \ + .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP, \ + } + +/** + * @brief Default base config (esp-netif inherent) of WIFI STA + */ +#define ESP_NETIF_BASE_DEFAULT_WIFI_STA &_g_esp_netif_inherent_sta_config + +/** + * @brief Default base config (esp-netif inherent) of WIFI AP + */ +#define ESP_NETIF_BASE_DEFAULT_WIFI_AP &_g_esp_netif_inherent_ap_config + +/** + * @brief Default base config (esp-netif inherent) of WIFI NAN + */ +#define ESP_NETIF_BASE_DEFAULT_WIFI_NAN &_g_esp_netif_inherent_nan_config + +/** + * @brief Default base config (esp-netif inherent) of ethernet interface + */ +#define ESP_NETIF_BASE_DEFAULT_ETH &_g_esp_netif_inherent_eth_config + +/** + * @brief Default base config (esp-netif inherent) of ppp interface + */ +#define ESP_NETIF_BASE_DEFAULT_PPP &_g_esp_netif_inherent_ppp_config + + +#define ESP_NETIF_NETSTACK_DEFAULT_ETH _g_esp_netif_netstack_default_eth +#define ESP_NETIF_NETSTACK_DEFAULT_BR _g_esp_netif_netstack_default_br +#define ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA _g_esp_netif_netstack_default_wifi_sta + +#define ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP _g_esp_netif_netstack_default_wifi_ap +#define ESP_NETIF_NETSTACK_DEFAULT_WIFI_NAN _g_esp_netif_netstack_default_wifi_nan +#define ESP_NETIF_NETSTACK_DEFAULT_PPP _g_esp_netif_netstack_default_ppp + +// +// Include default network stacks configs +// - Network stack configurations are provided in a specific network stack +// implementation that is invisible to user API +// - Here referenced only as opaque pointers +// +extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_eth; +extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_br; +extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_sta; +extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_ap; +extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_nan; +extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_ppp; +// +// Include default common configs inherent to esp-netif +// - These inherent configs are defined in esp_netif_defaults.c and describe +// common behavioural patterns for common interfaces such as STA, AP, ETH, PPP +// +extern const esp_netif_inherent_config_t _g_esp_netif_inherent_sta_config; +extern const esp_netif_inherent_config_t _g_esp_netif_inherent_ap_config; +extern const esp_netif_inherent_config_t _g_esp_netif_inherent_nan_config; +extern const esp_netif_inherent_config_t _g_esp_netif_inherent_eth_config; +extern const esp_netif_inherent_config_t _g_esp_netif_inherent_ppp_config; +extern const esp_netif_ip_info_t _g_esp_netif_soft_ap_ip; + +#ifdef __cplusplus +} +#endif + +#endif //_ESP_NETIF_DEFAULTS_H diff --git a/tests/c_headers/protocol_examples_common/CMakeLists.txt b/tests/c_headers/protocol_examples_common/CMakeLists.txt new file mode 100644 index 00000000..8d0501a9 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/CMakeLists.txt @@ -0,0 +1,52 @@ +idf_build_get_property(target IDF_TARGET) + +if(${target} STREQUAL "linux") + # Header only library for linux + + idf_component_register(INCLUDE_DIRS include + SRCS protocol_examples_utils.c) + return() +endif() + +set(srcs "stdin_out.c" + "addr_from_stdin.c" + "connect.c" + "wifi_connect.c" + "protocol_examples_utils.c") + +if(CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD) + list(APPEND srcs "console_cmd.c") +endif() + +if(CONFIG_EXAMPLE_CONNECT_ETHERNET) + list(APPEND srcs "eth_connect.c") +endif() + +if(CONFIG_EXAMPLE_CONNECT_THREAD) + list(APPEND srcs "thread_connect.c") +endif() + +if(CONFIG_EXAMPLE_CONNECT_PPP) + list(APPEND srcs "ppp_connect.c") +endif() + + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "include" + PRIV_REQUIRES esp_netif esp_driver_gpio esp_driver_uart esp_wifi vfs console esp_eth openthread) + +if(CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD) + idf_component_optional_requires(PRIVATE console) +endif() + +if(CONFIG_EXAMPLE_CONNECT_ETHERNET) + idf_component_optional_requires(PUBLIC esp_eth) +endif() + +if(CONFIG_EXAMPLE_CONNECT_THREAD) + idf_component_optional_requires(PRIVATE openthread) +endif() + +if(CONFIG_EXAMPLE_CONNECT_PPP) + idf_component_optional_requires(PRIVATE esp_tinyusb espressif__esp_tinyusb) +endif() diff --git a/tests/c_headers/protocol_examples_common/Kconfig.projbuild b/tests/c_headers/protocol_examples_common/Kconfig.projbuild new file mode 100644 index 00000000..f9ccbfb5 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/Kconfig.projbuild @@ -0,0 +1,504 @@ +menu "Example Connection Configuration" + + orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" + + config EXAMPLE_CONNECT_WIFI + bool "connect using WiFi interface" + depends on !IDF_TARGET_LINUX && (SOC_WIFI_SUPPORTED || ESP_WIFI_REMOTE_ENABLED || ESP_HOST_WIFI_ENABLED) + default y if SOC_WIFI_SUPPORTED + help + Protocol examples can use Wi-Fi, Ethernet and/or Thread to connect to the network. + Choose this option to connect with WiFi + + if EXAMPLE_CONNECT_WIFI + config EXAMPLE_WIFI_SSID_PWD_FROM_STDIN + bool "Get ssid and password from stdin" + default n + help + Give the WiFi SSID and password from stdin. + + config EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD + depends on !EXAMPLE_WIFI_SSID_PWD_FROM_STDIN + bool "Provide wifi connect commands" + default y + help + Provide wifi connect commands for esp_console. + Please use `example_register_wifi_connect_commands` to register them. + + config EXAMPLE_WIFI_SSID + depends on !EXAMPLE_WIFI_SSID_PWD_FROM_STDIN + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + + config EXAMPLE_WIFI_PASSWORD + depends on !EXAMPLE_WIFI_SSID_PWD_FROM_STDIN + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + Can be left blank if the network has no security set. + + config EXAMPLE_WIFI_CONN_MAX_RETRY + int "Maximum retry" + default 6 + help + Set the Maximum retry to avoid station reconnecting to the AP unlimited, + in case the AP is really inexistent. + + choice EXAMPLE_WIFI_SCAN_METHOD + prompt "WiFi Scan Method" + default EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL + help + WiFi scan method: + + If "Fast" is selected, scan will end after find SSID match AP. + + If "All Channel" is selected, scan will end after scan all the channel. + + config EXAMPLE_WIFI_SCAN_METHOD_FAST + bool "Fast" + config EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL + bool "All Channel" + endchoice + + menu "WiFi Scan threshold" + config EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD + int "WiFi minimum rssi" + range -127 0 + + default -127 + help + The minimum rssi to accept in the scan mode. + + choice EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD + prompt "WiFi Scan auth mode threshold" + default EXAMPLE_WIFI_AUTH_OPEN + help + The weakest authmode to accept in the scan mode. + + config EXAMPLE_WIFI_AUTH_OPEN + bool "OPEN" + config EXAMPLE_WIFI_AUTH_WEP + bool "WEP" + config EXAMPLE_WIFI_AUTH_WPA_PSK + bool "WPA PSK" + config EXAMPLE_WIFI_AUTH_WPA2_PSK + bool "WPA2 PSK" + config EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK + bool "WPA WPA2 PSK" + config EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE + bool "WPA2 ENTERPRISE" + config EXAMPLE_WIFI_AUTH_WPA3_PSK + bool "WPA3 PSK" + config EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK + bool "WPA2 WPA3 PSK" + config EXAMPLE_WIFI_AUTH_WAPI_PSK + bool "WAPI PSK" + endchoice + endmenu + + choice EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD + prompt "WiFi Connect AP Sort Method" + default EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL + help + WiFi connect AP sort method: + + If "Signal" is selected, Sort matched APs in scan list by RSSI. + + If "Security" is selected, Sort matched APs in scan list by security mode. + + config EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL + bool "Signal" + config EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY + bool "Security" + endchoice + endif + + config EXAMPLE_CONNECT_ETHERNET + bool "connect using Ethernet interface" + depends on !IDF_TARGET_LINUX + default y if !EXAMPLE_CONNECT_WIFI && !EXAMPLE_CONNECT_THREAD + help + Protocol examples can use Wi-Fi, Ethernet and/or Thread to connect to the network. + Choose this option to connect with Ethernet + + if EXAMPLE_CONNECT_ETHERNET + config EXAMPLE_ETHERNET_EMAC_TASK_STACK_SIZE + int "emac_rx task stack size" + default 2048 + help + This set stack size for emac_rx task + + config EXAMPLE_USE_SPI_ETHERNET + bool + + choice EXAMPLE_ETHERNET_TYPE + prompt "Ethernet Type" + default EXAMPLE_USE_INTERNAL_ETHERNET if SOC_EMAC_SUPPORTED + default EXAMPLE_USE_W5500 + help + Select which kind of Ethernet will be used in the example. + + config EXAMPLE_USE_INTERNAL_ETHERNET + depends on SOC_EMAC_SUPPORTED + select ETH_USE_ESP32_EMAC + bool "Internal EMAC" + help + Select internal Ethernet MAC controller. + + config EXAMPLE_USE_DM9051 + bool "DM9051 Module" + select EXAMPLE_USE_SPI_ETHERNET + select ETH_USE_SPI_ETHERNET + select ETH_SPI_ETHERNET_DM9051 + help + Select external SPI-Ethernet module. + + config EXAMPLE_USE_W5500 + bool "W5500 Module" + select EXAMPLE_USE_SPI_ETHERNET + select ETH_USE_SPI_ETHERNET + select ETH_SPI_ETHERNET_W5500 + help + Select external SPI-Ethernet module (W5500). + + config EXAMPLE_USE_OPENETH + bool "OpenCores Ethernet MAC (EXPERIMENTAL)" + select ETH_USE_OPENETH + help + When this option is enabled, the example is built with support for + OpenCores Ethernet MAC, which allows testing the example in QEMU. + Note that this option is used for internal testing purposes, and + not officially supported. Examples built with this option enabled + will not run on a real ESP32 chip. + + endchoice # EXAMPLE_ETHERNET_TYPE + + if EXAMPLE_USE_INTERNAL_ETHERNET + choice EXAMPLE_ETH_PHY_MODEL + prompt "Ethernet PHY Device" + default EXAMPLE_ETH_PHY_IP101 + help + Select the Ethernet PHY device to use in the example. + + config EXAMPLE_ETH_PHY_GENERIC + bool "Generic 802.3 PHY" + help + Any Ethernet PHY chip compliant with IEEE 802.3 can be used. However, while + basic functionality should always work, some specific features might be limited, + even if the PHY meets IEEE 802.3 standard. A typical example is loopback + functionality, where certain PHYs may require setting a specific speed mode to + operate correctly. + + config EXAMPLE_ETH_PHY_IP101 + bool "IP101" + help + IP101 is a single port 10/100 MII/RMII/TP/Fiber Fast Ethernet Transceiver. + Goto http://www.icplus.com.tw/pp-IP101G.html for more information about it. + + config EXAMPLE_ETH_PHY_RTL8201 + bool "RTL8201/SR8201" + help + RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX. + Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it. + + config EXAMPLE_ETH_PHY_LAN87XX + bool "LAN87xx" + help + Below chips are supported: + LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and + flexPWR® Technology. + LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support. + LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver + with HP Auto-MDIX and flexPWR® Technology. + LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and + flexPWR® Technology. + Goto https://www.microchip.com for more information about them. + + config EXAMPLE_ETH_PHY_DP83848 + bool "DP83848" + help + DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver. + Goto http://www.ti.com/product/DP83848J for more information about it. + + config EXAMPLE_ETH_PHY_KSZ80XX + bool "KSZ80xx" + help + With the KSZ80xx series, Microchip offers single-chip 10BASE-T/100BASE-TX + Ethernet Physical Layer Transceivers (PHY). + The following chips are supported: KSZ8001, KSZ8021, KSZ8031, KSZ8041, + KSZ8051, KSZ8061, KSZ8081, KSZ8091 + Goto https://www.microchip.com for more information about them. + endchoice + + config EXAMPLE_ETH_MDC_GPIO + int "SMI MDC GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX + default 23 if IDF_TARGET_ESP32 + default 31 if IDF_TARGET_ESP32P4 + help + Set the GPIO number used by SMI MDC. + + config EXAMPLE_ETH_MDIO_GPIO + int "SMI MDIO GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX + default 18 if IDF_TARGET_ESP32 + default 52 if IDF_TARGET_ESP32P4 + help + Set the GPIO number used by SMI MDIO. + endif + + if EXAMPLE_USE_SPI_ETHERNET + config EXAMPLE_ETH_SPI_HOST + int "SPI Host Number" + range 0 2 + default 1 + help + Set the SPI host used to communicate with the SPI Ethernet Controller. + + config EXAMPLE_ETH_SPI_SCLK_GPIO + int "SPI SCLK GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX + default 14 + help + Set the GPIO number used by SPI SCLK. + + config EXAMPLE_ETH_SPI_MOSI_GPIO + int "SPI MOSI GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX + default 13 + help + Set the GPIO number used by SPI MOSI. + + config EXAMPLE_ETH_SPI_MISO_GPIO + int "SPI MISO GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 12 + help + Set the GPIO number used by SPI MISO. + + config EXAMPLE_ETH_SPI_CS_GPIO + int "SPI CS GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX + default 15 + help + Set the GPIO number used by SPI CS. + + config EXAMPLE_ETH_SPI_CLOCK_MHZ + int "SPI clock speed (MHz)" + range 5 80 + default 36 + help + Set the clock speed (MHz) of SPI interface. + + config EXAMPLE_ETH_SPI_INT_GPIO + int "Interrupt GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 4 + help + Set the GPIO number used by the SPI Ethernet module interrupt line. + endif # EXAMPLE_USE_SPI_ETHERNET + + config EXAMPLE_ETH_PHY_RST_GPIO + int "PHY Reset GPIO number" + range -1 ENV_GPIO_OUT_RANGE_MAX + default 51 if IDF_TARGET_ESP32P4 + default 5 + help + Set the GPIO number used to reset PHY chip. + Set to -1 to disable PHY chip hardware reset. + + config EXAMPLE_ETH_PHY_ADDR + int "PHY Address" + range 0 31 if EXAMPLE_USE_INTERNAL_ETHERNET + default 1 + help + Set PHY address according your board schematic. + endif # EXAMPLE_CONNECT_ETHERNET + + config EXAMPLE_CONNECT_PPP + bool "connect using Point to Point interface" + select LWIP_PPP_SUPPORT + help + Protocol examples can use PPP connection over serial line. + Choose this option to connect to the ppp server running + on your laptop over a serial line (either UART or USB ACM) + + if EXAMPLE_CONNECT_PPP + choice EXAMPLE_CONNECT_PPP_DEVICE + prompt "Choose PPP device" + default EXAMPLE_CONNECT_PPP_DEVICE_USB + help + Select which peripheral to use to connect to the PPP server. + + config EXAMPLE_CONNECT_PPP_DEVICE_USB + bool "USB" + depends on SOC_USB_OTG_SUPPORTED + select TINYUSB_CDC_ENABLED + help + Use USB ACM device. + + config EXAMPLE_CONNECT_PPP_DEVICE_UART + bool "UART" + help + Use UART. + + endchoice + + menu "UART Configuration" + depends on EXAMPLE_CONNECT_PPP_DEVICE_UART + config EXAMPLE_CONNECT_UART_TX_PIN + int "TXD Pin Number" + default 4 + range 0 31 + help + Pin number of UART TX. + + config EXAMPLE_CONNECT_UART_RX_PIN + int "RXD Pin Number" + default 5 + range 0 31 + help + Pin number of UART RX. + + config EXAMPLE_CONNECT_UART_BAUDRATE + int "UART Baudrate" + default 115200 + range 9600 3000000 + help + Baudrate of the UART device + + endmenu + + config EXAMPLE_PPP_CONN_MAX_RETRY + int "Maximum retry" + default 6 + help + Set the Maximum retry to avoid station reconnecting if the pppd + is not available + + endif # EXAMPLE_CONNECT_PPP + + config EXAMPLE_CONNECT_THREAD + bool "Connect using Thread interface" + depends on !IDF_TARGET_LINUX && OPENTHREAD_ENABLED + default y if SOC_IEEE802154_SUPPORTED + select EXAMPLE_CONNECT_IPV6 + help + Protocol examples can use Wi-Fi, Ethernet and/or Thread to connect to the network. + Choose this option to connect with Thread. + The operational active dataset of the Thread network can be configured in openthread + component at '->Components->OpenThread->Thread Core Features->Thread Operational Dataset' + + if EXAMPLE_CONNECT_THREAD + config EXAMPLE_THREAD_TASK_STACK_SIZE + int "Example Thread task stack size" + default 8192 + help + Thread task stack size + + menu "Radio Spinel Options" + depends on OPENTHREAD_RADIO_SPINEL_UART || OPENTHREAD_RADIO_SPINEL_SPI + + config EXAMPLE_THREAD_UART_RX_PIN + depends on OPENTHREAD_RADIO_SPINEL_UART + int "Uart Rx Pin" + default 17 + + config EXAMPLE_THREAD_UART_TX_PIN + depends on OPENTHREAD_RADIO_SPINEL_UART + int "Uart Tx pin" + default 18 + + config EXAMPLE_THREAD_UART_BAUD + depends on OPENTHREAD_RADIO_SPINEL_UART + int "Uart baud rate" + default 460800 + + config EXAMPLE_THREAD_UART_PORT + depends on OPENTHREAD_RADIO_SPINEL_UART + int "Uart port" + default 1 + + config EXAMPLE_THREAD_SPI_CS_PIN + depends on OPENTHREAD_RADIO_SPINEL_SPI + int "SPI CS Pin" + default 10 + + config EXAMPLE_THREAD_SPI_SCLK_PIN + depends on OPENTHREAD_RADIO_SPINEL_SPI + int "SPI SCLK Pin" + default 12 + + config EXAMPLE_THREAD_SPI_MISO_PIN + depends on OPENTHREAD_RADIO_SPINEL_SPI + int "SPI MISO Pin" + default 13 + + config EXAMPLE_THREAD_SPI_MOSI_PIN + depends on OPENTHREAD_RADIO_SPINEL_SPI + int "SPI MOSI Pin" + default 11 + + config EXAMPLE_THREAD_SPI_INTR_PIN + depends on OPENTHREAD_RADIO_SPINEL_SPI + int "SPI Interrupt Pin" + default 8 + endmenu + + endif + + config EXAMPLE_CONNECT_IPV4 + bool + depends on LWIP_IPV4 + default n if EXAMPLE_CONNECT_THREAD + default y + + config EXAMPLE_CONNECT_IPV6 + depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET || EXAMPLE_CONNECT_PPP || EXAMPLE_CONNECT_THREAD + bool "Obtain IPv6 address" + default y + select LWIP_IPV6 + select LWIP_PPP_ENABLE_IPV6 if EXAMPLE_CONNECT_PPP + help + By default, examples will wait until IPv4 and IPv6 local link addresses are obtained. + Disable this option if the network does not support IPv6. + Choose the preferred IPv6 address type if the connection code should wait until other than + the local link address gets assigned. + Consider enabling IPv6 stateless address autoconfiguration (SLAAC) in the LWIP component. + + if EXAMPLE_CONNECT_IPV6 + choice EXAMPLE_CONNECT_PREFERRED_IPV6 + prompt "Preferred IPv6 Type" + default EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK + help + Select which kind of IPv6 address the connect logic waits for. + + config EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK + bool "Local Link Address" + help + Blocks until Local link address assigned. + + config EXAMPLE_CONNECT_IPV6_PREF_GLOBAL + bool "Global Address" + help + Blocks until Global address assigned. + + config EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL + bool "Site Local Address" + help + Blocks until Site link address assigned. + + config EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL + bool "Unique Local Link Address" + help + Blocks until Unique local address assigned. + + endchoice + + endif + + +endmenu diff --git a/tests/c_headers/protocol_examples_common/README.md b/tests/c_headers/protocol_examples_common/README.md new file mode 100644 index 00000000..00111dbf --- /dev/null +++ b/tests/c_headers/protocol_examples_common/README.md @@ -0,0 +1,66 @@ +# protocol_example_connect + +This component implements the most common connection methods for ESP32 boards. It should be used mainly in examples of ESP-IDF to demonstrate functionality of network protocols and other libraries, that need the connection step as a prerequisite. + +## How to use this component + +Choose the preferred interface (WiFi, Ethernet, Thread, PPPoS) to connect to the network and configure the interface. + +It is possible to enable multiple interfaces simultaneously making the connection phase to block until all the chosen interfaces acquire IP addresses. +It is also possible to disable all interfaces, skipping the connection phase altogether. + +### WiFi + +Choose WiFi connection method (for chipsets that support it) and configure basic WiFi connection properties: +* WiFi SSID +* WiFI password +* Maximum connection retry (connection would be aborted if it doesn't succeed after specified number of retries) +* WiFi scan method (including RSSI and authorization mode threshold) + + + +### Ethernet + +Choose Ethernet connection if your board supports it. The most common settings is using Espressif Ethernet Kit, which is also the recommended HW for this selection. You can also select an SPI ethernet device (if your chipset doesn't support internal EMAC or if you prefer). It is also possible to use OpenCores Ethernet MAC if you're running the example under QEMU. + +### Thread + +Choose Thread connection if your board supports IEEE802.15.4 native radio or works with [OpenThread RCP](../../openthread/ot_rcp/README.md). You can configure the Thread network at menuconfig '->Components->OpenThread->Thread Core Features->Thread Operational Dataset'. + +If the Thread end-device joins a Thread network with a Thread Border Router that has the NAT64 feature enabled, the end-device can access the Internet with the standard DNS APIs after configuring the following properties: +* Enable DNS64 client ('->Components->OpenThread->Thread Core Features->Enable DNS64 client') +* Enable custom DNS external resolve Hook ('->Components->LWIP->Hooks->DNS external resolve Hook->Custom implementation') + +### PPP + +Point to point connection method creates a simple IP tunnel to the counterpart device (running PPP server), typically a Linux machine with pppd service. We currently support only PPP over Serial (using UART or USB CDC). This is useful for simple testing of networking layers, but with some additional configuration on the server side, we could simulate standard model of internet connectivity. The PPP server could be also represented by a cellular modem device with pre-configured connectivity and already switched to PPP mode (this setup is not very flexible though, so we suggest using a standard modem library implementing commands and modes, e.g. [esp_modem](https://components.espressif.com/component/espressif/esp_modem) ). + +> [!Note] +> Note that if you choose USB device, you have to manually add a dependency on `esp_tinyusb` component. This step is necessary to keep the `protocol_example_connect` component simple and dependency free. Please run this command from your project location to add the dependency: +> ```bash +> idf.py add-dependency espressif/esp_tinyusb^1 +> ``` + +#### Setup a PPP server + +Connect the board using UART or USB and note the device name, which would be typically: +* `/dev/ttyACMx` for USB devices +* `/dev/ttyUSBx` for UART devices + +Run the pppd server: + +```bash +sudo pppd /dev/ttyACM0 115200 192.168.11.1:192.168.11.2 ms-dns 8.8.8.8 modem local noauth debug nocrtscts nodetach +ipv6 +``` + +Please update the parameters with the correct serial device, baud rate, IP addresses, DNS server, use `+ipv6` if `EXAMPLE_CONNECT_IPV6=y`. + +#### Connection to outside + +In order to access other network endpoints, we have to configure some IP/translation rules. The easiest method is to setup a masquerade of the PPPD created interface (`ppp0`) to your default networking interface (`${ETH0}`). Here is an example of such rule: + +```bash +sudo iptables -t nat -A POSTROUTING -o ${ETH0} -j MASQUERADE +sudo iptables -A FORWARD -i ${ETH0} -o ppp0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i ppp0 -o ${ETH0} -j ACCEPT +``` diff --git a/tests/c_headers/protocol_examples_common/addr_from_stdin.c b/tests/c_headers/protocol_examples_common/addr_from_stdin.c new file mode 100644 index 00000000..e4c94b1a --- /dev/null +++ b/tests/c_headers/protocol_examples_common/addr_from_stdin.c @@ -0,0 +1,69 @@ +#include +#include "esp_system.h" +#include "esp_log.h" +#include "esp_netif.h" +#include "protocol_examples_common.h" + +#include "lwip/sockets.h" +#include +#include + +#define HOST_IP_SIZE 128 + +esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *addr_family, struct sockaddr_storage *dest_addr) +{ + char host_ip[HOST_IP_SIZE]; + int len; + static bool already_init = false; + + // this function could be called multiple times -> make sure UART init runs only once + if (!already_init) { + example_configure_stdin_stdout(); + already_init = true; + } + + // ignore empty or LF only string (could receive from DUT class) + do { + fgets(host_ip, HOST_IP_SIZE, stdin); + len = strlen(host_ip); + } while (len<=1 && host_ip[0] == '\n'); + host_ip[len - 1] = '\0'; + + struct addrinfo hints, *addr_list, *cur; + memset( &hints, 0, sizeof( hints ) ); + + // run getaddrinfo() to decide on the IP protocol + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = sock_type; + hints.ai_protocol = IPPROTO_TCP; + if( getaddrinfo( host_ip, NULL, &hints, &addr_list ) != 0 ) { + return ESP_FAIL; + } + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) { + memcpy(dest_addr, cur->ai_addr, sizeof(*dest_addr)); +#if CONFIG_EXAMPLE_CONNECT_IPV4 + if (cur->ai_family == AF_INET) { + *ip_protocol = IPPROTO_IP; + *addr_family = AF_INET; + // add port number and return on first IPv4 match + ((struct sockaddr_in*)dest_addr)->sin_port = htons(port); + freeaddrinfo( addr_list ); + return ESP_OK; + } +#endif // IPV4 +#if CONFIG_EXAMPLE_CONNECT_IPV6 + if (cur->ai_family == AF_INET6) { + *ip_protocol = IPPROTO_IPV6; + *addr_family = AF_INET6; + // add port and interface number and return on first IPv6 match + ((struct sockaddr_in6*)dest_addr)->sin6_port = htons(port); + ((struct sockaddr_in6*)dest_addr)->sin6_scope_id = esp_netif_get_netif_impl_index(EXAMPLE_INTERFACE); + freeaddrinfo( addr_list ); + return ESP_OK; + } +#endif // IPV6 + } + // no match found + freeaddrinfo( addr_list ); + return ESP_FAIL; +} diff --git a/tests/c_headers/protocol_examples_common/connect.c b/tests/c_headers/protocol_examples_common/connect.c new file mode 100644 index 00000000..65fa2b85 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/connect.c @@ -0,0 +1,148 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include "protocol_examples_common.h" +#include "example_common_private.h" +#include "sdkconfig.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_wifi_default.h" +#include "esp_log.h" +#include "esp_netif.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "lwip/err.h" +#include "lwip/sys.h" + +static const char *TAG = "example_common"; + +#if CONFIG_EXAMPLE_CONNECT_IPV6 +/* types of ipv6 addresses to be displayed on ipv6 events */ +const char *example_ipv6_addr_types_to_str[6] = { + "ESP_IP6_ADDR_IS_UNKNOWN", + "ESP_IP6_ADDR_IS_GLOBAL", + "ESP_IP6_ADDR_IS_LINK_LOCAL", + "ESP_IP6_ADDR_IS_SITE_LOCAL", + "ESP_IP6_ADDR_IS_UNIQUE_LOCAL", + "ESP_IP6_ADDR_IS_IPV4_MAPPED_IPV6" +}; +#endif + +/** + * @brief Checks the netif description if it contains specified prefix. + * All netifs created within common connect component are prefixed with the module TAG, + * so it returns true if the specified netif is owned by this module + */ +bool example_is_our_netif(const char *prefix, esp_netif_t *netif) +{ + return strncmp(prefix, esp_netif_get_desc(netif), strlen(prefix) - 1) == 0; +} + +static bool netif_desc_matches_with(esp_netif_t *netif, void *ctx) +{ + return strcmp(ctx, esp_netif_get_desc(netif)) == 0; +} + +esp_netif_t *get_example_netif_from_desc(const char *desc) +{ + return esp_netif_find_if(netif_desc_matches_with, (void*)desc); +} + +static esp_err_t print_all_ips_tcpip(void* ctx) +{ + const char *prefix = ctx; + // iterate over active interfaces, and print out IPs of "our" netifs + esp_netif_t *netif = NULL; + while ((netif = esp_netif_next_unsafe(netif)) != NULL) { + if (example_is_our_netif(prefix, netif)) { + ESP_LOGI(TAG, "Connected to %s", esp_netif_get_desc(netif)); +#if CONFIG_EXAMPLE_CONNECT_IPV4 + esp_netif_ip_info_t ip; + ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip)); + + ESP_LOGI(TAG, "- IPv4 address: " IPSTR ",", IP2STR(&ip.ip)); +#endif +#if CONFIG_EXAMPLE_CONNECT_IPV6 + esp_ip6_addr_t ip6[MAX_IP6_ADDRS_PER_NETIF]; + int ip6_addrs = esp_netif_get_all_ip6(netif, ip6); + for (int j = 0; j < ip6_addrs; ++j) { + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&(ip6[j])); + ESP_LOGI(TAG, "- IPv6 address: " IPV6STR ", type: %s", IPV62STR(ip6[j]), example_ipv6_addr_types_to_str[ipv6_type]); + } +#endif + } + } + return ESP_OK; +} + +void example_print_all_netif_ips(const char *prefix) +{ + // Print all IPs in TCPIP context to avoid potential races of removing/adding netifs when iterating over the list + esp_netif_tcpip_exec(print_all_ips_tcpip, (void*) prefix); +} + + +esp_err_t example_connect(void) +{ +#if CONFIG_EXAMPLE_CONNECT_ETHERNET + if (example_ethernet_connect() != ESP_OK) { + return ESP_FAIL; + } + ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_ethernet_shutdown)); +#endif +#if CONFIG_EXAMPLE_CONNECT_WIFI + if (example_wifi_connect() != ESP_OK) { + return ESP_FAIL; + } + ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_wifi_shutdown)); +#endif +#if CONFIG_EXAMPLE_CONNECT_THREAD + if (example_thread_connect() != ESP_OK) { + return ESP_FAIL; + } + ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_thread_shutdown)); +#endif +#if CONFIG_EXAMPLE_CONNECT_PPP + if (example_ppp_connect() != ESP_OK) { + return ESP_FAIL; + } + ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_ppp_shutdown)); +#endif + +#if CONFIG_EXAMPLE_CONNECT_ETHERNET + example_print_all_netif_ips(EXAMPLE_NETIF_DESC_ETH); +#endif + +#if CONFIG_EXAMPLE_CONNECT_WIFI + example_print_all_netif_ips(EXAMPLE_NETIF_DESC_STA); +#endif + +#if CONFIG_EXAMPLE_CONNECT_THREAD + example_print_all_netif_ips(EXAMPLE_NETIF_DESC_THREAD); +#endif + +#if CONFIG_EXAMPLE_CONNECT_PPP + example_print_all_netif_ips(EXAMPLE_NETIF_DESC_PPP); +#endif + + return ESP_OK; +} + + +esp_err_t example_disconnect(void) +{ +#if CONFIG_EXAMPLE_CONNECT_ETHERNET + example_ethernet_shutdown(); + ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&example_ethernet_shutdown)); +#endif +#if CONFIG_EXAMPLE_CONNECT_WIFI + example_wifi_shutdown(); + ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&example_wifi_shutdown)); +#endif + return ESP_OK; +} diff --git a/tests/c_headers/protocol_examples_common/console_cmd.c b/tests/c_headers/protocol_examples_common/console_cmd.c new file mode 100644 index 00000000..342a92c7 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/console_cmd.c @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + +#include +#include "protocol_examples_common.h" +#include "example_common_private.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "esp_console.h" +#include "argtable3/argtable3.h" + + +static const char *TAG = "example_console"; + +typedef struct { + struct arg_str *ssid; + struct arg_str *password; + struct arg_int *channel; + struct arg_end *end; +} wifi_connect_args_t; +static wifi_connect_args_t connect_args; + +static int cmd_do_wifi_connect(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &connect_args); + + if (nerrors != 0) { + arg_print_errors(stderr, connect_args.end, argv[0]); + return 1; + } + + wifi_config_t wifi_config = { + .sta = { + .scan_method = WIFI_ALL_CHANNEL_SCAN, + .sort_method = WIFI_CONNECT_AP_BY_SIGNAL, + }, + }; + if (connect_args.channel->count > 0) { + wifi_config.sta.channel = (uint8_t)(connect_args.channel->ival[0]); + } + const char *ssid = connect_args.ssid->sval[0]; + const char *pass = connect_args.password->sval[0]; + strlcpy((char *) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid)); + if (pass) { + strlcpy((char *) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password)); + } + example_wifi_sta_do_connect(wifi_config, false); + return 0; +} + +static int cmd_do_wifi_disconnect(int argc, char **argv) +{ + example_wifi_sta_do_disconnect(); + return 0; +} + +void example_register_wifi_connect_commands(void) +{ + ESP_LOGI(TAG, "Registering WiFi connect commands."); + example_wifi_start(); + + connect_args.ssid = arg_str1(NULL, NULL, "", "SSID of AP"); + connect_args.password = arg_str0(NULL, NULL, "", "password of AP"); + connect_args.channel = arg_int0("n", "channel", "", "channel of AP"); + connect_args.end = arg_end(2); + const esp_console_cmd_t wifi_connect_cmd = { + .command = "wifi_connect", + .help = "WiFi is station mode, join specified soft-AP", + .hint = NULL, + .func = &cmd_do_wifi_connect, + .argtable = &connect_args + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&wifi_connect_cmd) ); + + + const esp_console_cmd_t wifi_disconnect_cmd = { + .command = "wifi_disconnect", + .help = "Do wifi disconnect", + .hint = NULL, + .func = &cmd_do_wifi_disconnect, + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&wifi_disconnect_cmd) ); +} diff --git a/tests/c_headers/protocol_examples_common/eth_connect.c b/tests/c_headers/protocol_examples_common/eth_connect.c new file mode 100644 index 00000000..ad480690 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/eth_connect.c @@ -0,0 +1,245 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include "protocol_examples_common.h" +#include "example_common_private.h" +#include "esp_event.h" +#include "esp_eth.h" +#if CONFIG_ETH_USE_SPI_ETHERNET +#include "driver/spi_master.h" +#endif // CONFIG_ETH_USE_SPI_ETHERNET +#include "esp_log.h" +#include "esp_mac.h" +#include "driver/gpio.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" + + +static const char *TAG = "ethernet_connect"; +static SemaphoreHandle_t s_semph_get_ip_addrs = NULL; +#if CONFIG_EXAMPLE_CONNECT_IPV6 +static SemaphoreHandle_t s_semph_get_ip6_addrs = NULL; +#endif + +static esp_netif_t *eth_start(void); +static void eth_stop(void); + + +/** Event handler for Ethernet events */ + +static void eth_on_got_ip(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_ETH, event->esp_netif)) { + return; + } + ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); + xSemaphoreGive(s_semph_get_ip_addrs); +} + +#if CONFIG_EXAMPLE_CONNECT_IPV6 + +static void eth_on_got_ipv6(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_ETH, event->esp_netif)) { + return; + } + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), + IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { + xSemaphoreGive(s_semph_get_ip6_addrs); + } +} + +static void on_eth_event(void *esp_netif, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + switch (event_id) { + case ETHERNET_EVENT_CONNECTED: + ESP_LOGI(TAG, "Ethernet Link Up"); + ESP_ERROR_CHECK(esp_netif_create_ip6_linklocal(esp_netif)); + break; + default: + break; + } +} + +#endif // CONFIG_EXAMPLE_CONNECT_IPV6 + +static esp_eth_handle_t s_eth_handle = NULL; +static esp_eth_mac_t *s_mac = NULL; +static esp_eth_phy_t *s_phy = NULL; +static esp_eth_netif_glue_handle_t s_eth_glue = NULL; + +static esp_netif_t *eth_start(void) +{ + esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH(); + // Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask) + esp_netif_config.if_desc = EXAMPLE_NETIF_DESC_ETH; + esp_netif_config.route_prio = 64; + esp_netif_config_t netif_config = { + .base = &esp_netif_config, + .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH + }; + esp_netif_t *netif = esp_netif_new(&netif_config); + assert(netif); + + eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); + mac_config.rx_task_stack_size = CONFIG_EXAMPLE_ETHERNET_EMAC_TASK_STACK_SIZE; + eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); + phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; + phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; +#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET + eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); + esp32_emac_config.smi_gpio.mdc_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; + esp32_emac_config.smi_gpio.mdio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; + s_mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); +#if CONFIG_EXAMPLE_ETH_PHY_GENERIC + s_phy = esp_eth_phy_new_generic(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_IP101 + s_phy = esp_eth_phy_new_ip101(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201 + s_phy = esp_eth_phy_new_rtl8201(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX + s_phy = esp_eth_phy_new_lan87xx(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_DP83848 + s_phy = esp_eth_phy_new_dp83848(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX + s_phy = esp_eth_phy_new_ksz80xx(&phy_config); +#endif +#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET + gpio_install_isr_service(0); + spi_bus_config_t buscfg = { + .miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO, + .mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO, + .sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + }; + ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO)); + spi_device_interface_config_t spi_devcfg = { + .mode = 0, + .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000, + .spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO, + .queue_size = 20 + }; +#if CONFIG_EXAMPLE_USE_DM9051 + /* dm9051 ethernet driver is based on spi driver */ + eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg); + dm9051_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO; + s_mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config); + s_phy = esp_eth_phy_new_dm9051(&phy_config); +#elif CONFIG_EXAMPLE_USE_W5500 + /* w5500 ethernet driver is based on spi driver */ + eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg); + w5500_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO; + s_mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config); + s_phy = esp_eth_phy_new_w5500(&phy_config); +#endif +#elif CONFIG_EXAMPLE_USE_OPENETH + phy_config.autonego_timeout_ms = 100; + s_mac = esp_eth_mac_new_openeth(&mac_config); + s_phy = esp_eth_phy_new_dp83848(&phy_config); +#endif + + // Install Ethernet driver + esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy); + ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle)); + +#if CONFIG_EXAMPLE_USE_SPI_ETHERNET + /* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually. + We set the ESP_MAC_ETH mac address as the default, if you want to use ESP_MAC_EFUSE_CUSTOM mac address, please enable the + configuration: `ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC` + */ + uint8_t eth_mac[6] = {0}; + ESP_ERROR_CHECK(esp_read_mac(eth_mac, ESP_MAC_ETH)); + ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_MAC_ADDR, eth_mac)); +#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET + + // combine driver with netif + s_eth_glue = esp_eth_new_netif_glue(s_eth_handle); + esp_netif_attach(netif, s_eth_glue); + + // Register user defined event handlers + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, ð_on_got_ip, NULL)); +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, netif)); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, ð_on_got_ipv6, NULL)); +#endif + + esp_eth_start(s_eth_handle); + return netif; +} + +static void eth_stop(void) +{ + esp_netif_t *eth_netif = get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH); + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, ð_on_got_ip)); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, ð_on_got_ipv6)); + ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event)); +#endif + ESP_ERROR_CHECK(esp_eth_stop(s_eth_handle)); + ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue)); + ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle)); + s_eth_handle = NULL; + ESP_ERROR_CHECK(s_phy->del(s_phy)); + ESP_ERROR_CHECK(s_mac->del(s_mac)); + + esp_netif_destroy(eth_netif); +} + +esp_eth_handle_t get_example_eth_handle(void) +{ + return s_eth_handle; +} + +/* tear down connection, release resources */ +void example_ethernet_shutdown(void) +{ + if (s_semph_get_ip_addrs == NULL) { + return; + } + vSemaphoreDelete(s_semph_get_ip_addrs); + s_semph_get_ip_addrs = NULL; +#if CONFIG_EXAMPLE_CONNECT_IPV6 + vSemaphoreDelete(s_semph_get_ip6_addrs); + s_semph_get_ip6_addrs = NULL; +#endif + eth_stop(); +} + +esp_err_t example_ethernet_connect(void) +{ +#if CONFIG_EXAMPLE_CONNECT_IPV4 + s_semph_get_ip_addrs = xSemaphoreCreateBinary(); + if (s_semph_get_ip_addrs == NULL) { + return ESP_ERR_NO_MEM; + } +#endif +#if CONFIG_EXAMPLE_CONNECT_IPV6 + s_semph_get_ip6_addrs = xSemaphoreCreateBinary(); + if (s_semph_get_ip6_addrs == NULL) { + vSemaphoreDelete(s_semph_get_ip_addrs); + return ESP_ERR_NO_MEM; + } +#endif + eth_start(); + ESP_LOGI(TAG, "Waiting for IP(s)."); +#if CONFIG_EXAMPLE_CONNECT_IPV4 + xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY); +#endif +#if CONFIG_EXAMPLE_CONNECT_IPV6 + xSemaphoreTake(s_semph_get_ip6_addrs, portMAX_DELAY); +#endif + return ESP_OK; +} diff --git a/tests/c_headers/protocol_examples_common/include/addr_from_stdin.h b/tests/c_headers/protocol_examples_common/include/addr_from_stdin.h new file mode 100644 index 00000000..827f8c25 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/include/addr_from_stdin.h @@ -0,0 +1,44 @@ +/* Common utilities for socket address input interface: + The API get_addr_from_stdin() is mainly used by socket client examples which read IP address from stdin (if configured). + This option is typically used in the CI, but could be enabled in the project configuration. + In that case this component is used to receive a string that is evaluated and processed to output + socket structures to open a connectio + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + */ + +#pragma once + +#include "lwip/sys.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Read and evaluate IP address from stdin + * + * This API reads stdin and parses the input address using getaddrinfo() + * to fill in struct sockaddr_storage (for both IPv4 and IPv6) used to open + * a socket. IP protocol is guessed from the IP address string. + * + * @param[in] port port number of expected connection + * @param[in] sock_type expected protocol: SOCK_STREAM or SOCK_DGRAM + * @param[out] ip_protocol resultant IP protocol: IPPROTO_IP or IPPROTO_IP6 + * @param[out] addr_family resultant address family: AF_INET or AF_INET6 + * @param[out] dest_addr sockaddr_storage structure (for both IPv4 and IPv6) + * @return ESP_OK on success, ESP_FAIL otherwise + */ +esp_err_t get_addr_from_stdin(int port, int sock_type, + int *ip_protocol, + int *addr_family, + struct sockaddr_storage *dest_addr); + +#ifdef __cplusplus +} +#endif diff --git a/tests/c_headers/protocol_examples_common/include/example_common_private.h b/tests/c_headers/protocol_examples_common/include/example_common_private.h new file mode 100644 index 00000000..ad6ef537 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/include/example_common_private.h @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Private Functions of protocol example common */ + +#pragma once + +#include "esp_err.h" +#include "esp_wifi.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_EXAMPLE_CONNECT_IPV6 +#define MAX_IP6_ADDRS_PER_NETIF (5) + +#if defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK) +#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_LINK_LOCAL +#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL) +#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_GLOBAL +#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL) +#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_SITE_LOCAL +#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL) +#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_UNIQUE_LOCAL +#endif // if-elif CONFIG_EXAMPLE_CONNECT_IPV6_PREF_... + +#endif + + +#if CONFIG_EXAMPLE_CONNECT_IPV6 +extern const char *example_ipv6_addr_types_to_str[6]; +#endif + +void example_wifi_start(void); +void example_wifi_stop(void); +esp_err_t example_wifi_sta_do_connect(wifi_config_t wifi_config, bool wait); +esp_err_t example_wifi_sta_do_disconnect(void); +bool example_is_our_netif(const char *prefix, esp_netif_t *netif); +void example_print_all_netif_ips(const char *prefix); +void example_wifi_shutdown(void); +esp_err_t example_wifi_connect(void); +void example_ethernet_shutdown(void); +esp_err_t example_ethernet_connect(void); +void example_thread_shutdown(void); +esp_err_t example_thread_connect(void); +esp_err_t example_ppp_connect(void); +void example_ppp_start(void); +void example_ppp_shutdown(void); + + + +#ifdef __cplusplus +} +#endif diff --git a/tests/c_headers/protocol_examples_common/include/protocol_examples_common.h b/tests/c_headers/protocol_examples_common/include/protocol_examples_common.h new file mode 100644 index 00000000..54e2c07a --- /dev/null +++ b/tests/c_headers/protocol_examples_common/include/protocol_examples_common.h @@ -0,0 +1,154 @@ +/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection. + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + */ + +#pragma once + +#include "sdkconfig.h" +#include "esp_err.h" +#if !CONFIG_IDF_TARGET_LINUX +#include "esp_netif.h" +#if CONFIG_EXAMPLE_CONNECT_ETHERNET +#include "esp_eth.h" +#endif +#endif // !CONFIG_IDF_TARGET_LINUX + +#ifdef __cplusplus +extern "C" { +#endif + +#if !CONFIG_IDF_TARGET_LINUX +#if CONFIG_EXAMPLE_CONNECT_WIFI +#define EXAMPLE_NETIF_DESC_STA "example_netif_sta" +#endif + +#if CONFIG_EXAMPLE_CONNECT_ETHERNET +#define EXAMPLE_NETIF_DESC_ETH "example_netif_eth" +#endif + +#if CONFIG_EXAMPLE_CONNECT_THREAD +#define EXAMPLE_NETIF_DESC_THREAD "example_netif_thread" +#endif + +#if CONFIG_EXAMPLE_CONNECT_PPP +#define EXAMPLE_NETIF_DESC_PPP "example_netif_ppp" +#endif + +#if CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST +#define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN +#elif CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL +#define EXAMPLE_WIFI_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN +#endif + +#if CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL +#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL +#elif CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY +#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY +#endif + +#if CONFIG_EXAMPLE_WIFI_AUTH_OPEN +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN +#elif CONFIG_EXAMPLE_WIFI_AUTH_WEP +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_ENTERPRISE +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK +#endif + +/* Example default interface, prefer the ethernet one if running in example-test (CI) configuration */ +#if CONFIG_EXAMPLE_CONNECT_ETHERNET +#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH) +#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH) +#elif CONFIG_EXAMPLE_CONNECT_WIFI +#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_STA) +#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_STA) +#elif CONFIG_EXAMPLE_CONNECT_THREAD +#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_THREAD) +#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_THREAD) +#elif CONFIG_EXAMPLE_CONNECT_PPP +#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_PPP) +#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_PPP) +#endif + +/** + * @brief Configure Wi-Fi or Ethernet, connect, wait for IP + * + * This all-in-one helper function is used in protocols examples to + * reduce the amount of boilerplate in the example. + * + * It is not intended to be used in real world applications. + * See examples under examples/wifi/getting_started/ and examples/ethernet/ + * for more complete Wi-Fi or Ethernet initialization code. + * + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + * + * @return ESP_OK on successful connection + */ +esp_err_t example_connect(void); + +/** + * Counterpart to example_connect, de-initializes Wi-Fi or Ethernet + */ +esp_err_t example_disconnect(void); + +/** + * @brief Configure stdin and stdout to use blocking I/O + * + * This helper function is used in ASIO examples. It wraps installing the + * UART driver and configuring VFS layer to use UART driver for console I/O. + */ +esp_err_t example_configure_stdin_stdout(void); + +/** + * @brief Returns esp-netif pointer created by example_connect() described by + * the supplied desc field + * + * @param desc Textual interface of created network interface, for example "sta" + * indicate default WiFi station, "eth" default Ethernet interface. + * + */ +esp_netif_t *get_example_netif_from_desc(const char *desc); + +#if CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD +/** + * @brief Register wifi connect commands + * + * Provide a simple wifi_connect command in esp_console. + * This function can be used after esp_console is initialized. + */ +void example_register_wifi_connect_commands(void); +#endif + +#if CONFIG_EXAMPLE_CONNECT_ETHERNET +/** + * @brief Get the example Ethernet driver handle + * + * @return esp_eth_handle_t + */ +esp_eth_handle_t get_example_eth_handle(void); +#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET + +#else +static inline esp_err_t example_connect(void) {return ESP_OK;} +#endif // !CONFIG_IDF_TARGET_LINUX + +#ifdef __cplusplus +} +#endif diff --git a/tests/c_headers/protocol_examples_common/include/protocol_examples_thread_config.h b/tests/c_headers/protocol_examples_common/include/protocol_examples_thread_config.h new file mode 100644 index 00000000..532f828b --- /dev/null +++ b/tests/c_headers/protocol_examples_common/include/protocol_examples_thread_config.h @@ -0,0 +1,115 @@ +/* + * Thread configurations for protocol examples + * + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#pragma once + +#include + +#include + +#ifdef CONFIG_OPENTHREAD_RADIO_NATIVE +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_NATIVE, \ + } + +#elif defined(CONFIG_OPENTHREAD_RADIO_SPINEL_UART) +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_UART_RCP, \ + .radio_uart_config = \ + { \ + .port = CONFIG_EXAMPLE_THREAD_UART_PORT, \ + .uart_config = \ + { \ + .baud_rate = CONFIG_EXAMPLE_THREAD_UART_BAUD, \ + .data_bits = UART_DATA_8_BITS, \ + .parity = UART_PARITY_DISABLE, \ + .stop_bits = UART_STOP_BITS_1, \ + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \ + .rx_flow_ctrl_thresh = 0, \ + .source_clk = UART_SCLK_DEFAULT, \ + }, \ + .rx_pin = CONFIG_EXAMPLE_THREAD_UART_RX_PIN, \ + .tx_pin = CONFIG_EXAMPLE_THREAD_UART_TX_PIN, \ + }, \ + } +#elif defined(CONFIG_OPENTHREAD_RADIO_SPINEL_SPI) +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_SPI_RCP, \ + .radio_spi_config = \ + { \ + .host_device = SPI2_HOST, \ + .dma_channel = 2, \ + .spi_interface = \ + { \ + .mosi_io_num = CONFIG_EXAMPLE_THREAD_SPI_MOSI_PIN, \ + .miso_io_num = CONFIG_EXAMPLE_THREAD_SPI_MISO_PIN, \ + .sclk_io_num = CONFIG_EXAMPLE_THREAD_SPI_SCLK_PIN, \ + .quadwp_io_num = -1, \ + .quadhd_io_num = -1, \ + }, \ + .spi_device = \ + { \ + .cs_ena_pretrans = 2, \ + .input_delay_ns = 100, \ + .mode = 0, \ + .clock_speed_hz = 2500 * 1000, \ + .spics_io_num = CONFIG_EXAMPLE_THREAD_SPI_CS_PIN, \ + .queue_size = 5, \ + }, \ + .intr_pin = CONFIG_EXAMPLE_THREAD_SPI_INTR_PIN, \ + }, \ + } +#else +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_TREL, \ + } +#endif + +#if CONFIG_OPENTHREAD_CONSOLE_TYPE_UART +#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \ + { \ + .host_connection_mode = HOST_CONNECTION_MODE_CLI_UART, \ + .host_uart_config = \ + { \ + .port = 0, \ + .uart_config = \ + { \ + .baud_rate = 115200, \ + .data_bits = UART_DATA_8_BITS, \ + .parity = UART_PARITY_DISABLE, \ + .stop_bits = UART_STOP_BITS_1, \ + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \ + .rx_flow_ctrl_thresh = 0, \ + .source_clk = UART_SCLK_DEFAULT, \ + }, \ + .rx_pin = UART_PIN_NO_CHANGE, \ + .tx_pin = UART_PIN_NO_CHANGE, \ + }, \ + } +#elif CONFIG_OPENTHREAD_CONSOLE_TYPE_USB_SERIAL_JTAG +#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \ + { \ + .host_connection_mode = HOST_CONNECTION_MODE_CLI_USB, \ + .host_usb_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT(), \ + } +#else +#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \ + { \ + .host_connection_mode = HOST_CONNECTION_MODE_NONE, \ + } +#endif + +#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \ + { \ + .storage_partition_name = "nvs", \ + .netif_queue_size = 10, \ + .task_queue_size = 10, \ + } diff --git a/tests/c_headers/protocol_examples_common/include/protocol_examples_utils.h b/tests/c_headers/protocol_examples_common/include/protocol_examples_utils.h new file mode 100644 index 00000000..79031171 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/include/protocol_examples_utils.h @@ -0,0 +1,49 @@ +/* + * Utility functions for protocol examples + * + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Encode an URI + * + * @param dest a destination memory location + * @param src the source string + * @param len the length of the source string + * @return uint32_t the count of escaped characters + * + * @note Please allocate the destination buffer keeping in mind that encoding a + * special character will take up 3 bytes (for '%' and two hex digits). + * In the worst-case scenario, the destination buffer will have to be 3 times + * that of the source string. + */ +uint32_t example_uri_encode(char *dest, const char *src, size_t len); + +/** + * @brief Decode an URI + * + * @param dest a destination memory location + * @param src the source string + * @param len the length of the source string + * + * @note Please allocate the destination buffer keeping in mind that a decoded + * special character will take up 2 less bytes than its encoded form. + * In the worst-case scenario, the destination buffer will have to be + * the same size that of the source string. + */ +void example_uri_decode(char *dest, const char *src, size_t len); + +#ifdef __cplusplus +} +#endif diff --git a/tests/c_headers/protocol_examples_common/ppp_connect.c b/tests/c_headers/protocol_examples_common/ppp_connect.c new file mode 100644 index 00000000..34c0aaf9 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/ppp_connect.c @@ -0,0 +1,258 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "protocol_examples_common.h" +#include "example_common_private.h" + +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_netif_ppp.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB +#include "tinyusb.h" +#include "tusb_cdc_acm.h" + +static int s_itf; +static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE]; + +#else // DEVICE is UART + +#include "driver/uart.h" +#define BUF_SIZE (1024) +static bool s_stop_task = false; + +#endif // CONNECT_PPP_DEVICE + + +static const char *TAG = "example_connect_ppp"; +static int s_retry_num = 0; +static EventGroupHandle_t s_event_group = NULL; +static esp_netif_t *s_netif; +static const int GOT_IPV4 = BIT0; +static const int CONNECTION_FAILED = BIT1; +#if CONFIG_EXAMPLE_CONNECT_IPV6 +static const int GOT_IPV6 = BIT2; +#define CONNECT_BITS (GOT_IPV4|GOT_IPV6|CONNECTION_FAILED) +#else +#define CONNECT_BITS (GOT_IPV4|CONNECTION_FAILED) +#endif + +static esp_err_t transmit(void *h, void *buffer, size_t len) +{ + ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + tinyusb_cdcacm_write_queue(s_itf, buffer, len); + tinyusb_cdcacm_write_flush(s_itf, 0); +#else // DEVICE_UART + uart_write_bytes(UART_NUM_1, buffer, len); +#endif // CONNECT_PPP_DEVICE + return ESP_OK; +} + +static esp_netif_driver_ifconfig_t driver_cfg = { + .handle = (void *)1, // singleton driver, just to != NULL + .transmit = transmit, +}; +const esp_netif_driver_ifconfig_t *ppp_driver_cfg = &driver_cfg; + +static void on_ip_event(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + + if (event_id == IP_EVENT_PPP_GOT_IP) { + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_netif_t *netif = event->esp_netif; + esp_netif_dns_info_t dns_info; + ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); + esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info); + ESP_LOGI(TAG, "Main DNS server : " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); + xEventGroupSetBits(s_event_group, GOT_IPV4); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + } else if (event_id == IP_EVENT_GOT_IP6) { + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), + IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { + xEventGroupSetBits(s_event_group, GOT_IPV6); + } +#endif + } else if (event_id == IP_EVENT_PPP_LOST_IP) { + ESP_LOGI(TAG, "Disconnect from PPP Server"); + s_retry_num++; + if (s_retry_num > CONFIG_EXAMPLE_PPP_CONN_MAX_RETRY) { + ESP_LOGE(TAG, "PPP Connection failed %d times, stop reconnecting.", s_retry_num); + xEventGroupSetBits(s_event_group, CONNECTION_FAILED); + } else { + ESP_LOGI(TAG, "PPP Connection failed %d times, try to reconnect.", s_retry_num); + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + } + + } +} + +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB +static void cdc_rx_callback(int itf, cdcacm_event_t *event) +{ + size_t rx_size = 0; + if (itf != s_itf) { + // Not our channel + return; + } + esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); + if (ret == ESP_OK) { + ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_VERBOSE); + // pass the received data to the network interface + esp_netif_receive(s_netif, buf, rx_size, NULL); + } else { + ESP_LOGE(TAG, "Read error"); + } +} + +static void line_state_changed(int itf, cdcacm_event_t *event) +{ + s_itf = itf; // use this channel for the netif communication + ESP_LOGI(TAG, "Line state changed on channel %d", itf); +} +#else // DEVICE is UART + +static void ppp_task(void *args) +{ + uart_config_t uart_config = {}; + uart_config.baud_rate = CONFIG_EXAMPLE_CONNECT_UART_BAUDRATE; + uart_config.data_bits = UART_DATA_8_BITS; + uart_config.parity = UART_PARITY_DISABLE; + uart_config.stop_bits = UART_STOP_BITS_1; + uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; + uart_config.source_clk = UART_SCLK_DEFAULT; + + QueueHandle_t event_queue; + ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, BUF_SIZE, 0, 16, &event_queue, 0)); + ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, CONFIG_EXAMPLE_CONNECT_UART_TX_PIN, CONFIG_EXAMPLE_CONNECT_UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + ESP_ERROR_CHECK(uart_set_rx_timeout(UART_NUM_1, 1)); + + char *buffer = (char*)malloc(BUF_SIZE); + uart_event_t event; + esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_GOT_IP, esp_netif_action_connected, s_netif); + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + while (!s_stop_task) { + xQueueReceive(event_queue, &event, pdMS_TO_TICKS(1000)); + if (event.type == UART_DATA) { + size_t len; + uart_get_buffered_data_len(UART_NUM_1, &len); + if (len) { + len = uart_read_bytes(UART_NUM_1, buffer, BUF_SIZE, 0); + ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); + esp_netif_receive(s_netif, buffer, len, NULL); + } + } else { + ESP_LOGW(TAG, "Received UART event: %d", event.type); + } + } + free(buffer); + vTaskDelete(NULL); +} + +#endif // CONNECT_PPP_DEVICE + +esp_err_t example_ppp_connect(void) +{ + ESP_LOGI(TAG, "Start example_connect."); + +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + ESP_LOGI(TAG, "USB initialization"); + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .external_phy = false, + .configuration_descriptor = NULL, + }; + + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + tinyusb_config_cdcacm_t acm_cfg = { + .usb_dev = TINYUSB_USBDEV_0, + .cdc_port = TINYUSB_CDC_ACM_0, + .callback_rx = &cdc_rx_callback, + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = NULL, + .callback_line_coding_changed = NULL + }; + + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); + /* the second way to register a callback */ + ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( + TINYUSB_CDC_ACM_0, + CDC_EVENT_LINE_STATE_CHANGED, + &line_state_changed)); +#endif // CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + + s_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL)); + + esp_netif_inherent_config_t base_netif_cfg = ESP_NETIF_INHERENT_DEFAULT_PPP(); + base_netif_cfg.if_desc = EXAMPLE_NETIF_DESC_PPP; + esp_netif_config_t netif_ppp_config = { .base = &base_netif_cfg, + .driver = ppp_driver_cfg, + .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP + }; + + s_netif = esp_netif_new(&netif_ppp_config); + assert(s_netif); +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); +#else // DEVICE is UART + s_stop_task = false; + if (xTaskCreate(ppp_task, "ppp connect", 4096, NULL, 5, NULL) != pdTRUE) { + ESP_LOGE(TAG, "Failed to create a ppp connection task"); + return ESP_FAIL; + } +#endif // CONNECT_PPP_DEVICE + + ESP_LOGI(TAG, "Waiting for IP address"); + EventBits_t bits = xEventGroupWaitBits(s_event_group, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY); + if (bits & CONNECTION_FAILED) { + ESP_LOGE(TAG, "Connection failed!"); + return ESP_FAIL; + } + ESP_LOGI(TAG, "Connected!"); + + return ESP_OK; +} + +void example_ppp_shutdown(void) +{ + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event)); +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_UART + s_stop_task = true; + vTaskDelay(pdMS_TO_TICKS(1000)); // wait for the ppp task to stop +#endif + + esp_netif_action_disconnected(s_netif, 0, 0, 0); + + vEventGroupDelete(s_event_group); + esp_netif_action_stop(s_netif, 0, 0, 0); + esp_netif_destroy(s_netif); + s_netif = NULL; + s_event_group = NULL; +} + diff --git a/tests/c_headers/protocol_examples_common/protocol_examples_utils.c b/tests/c_headers/protocol_examples_common/protocol_examples_utils.c new file mode 100644 index 00000000..e6e3de5f --- /dev/null +++ b/tests/c_headers/protocol_examples_common/protocol_examples_utils.c @@ -0,0 +1,388 @@ +/* + * Utility functions for protocol examples + * + * SPDX-FileCopyrightText: 2002-2021 Igor Sysoev + * 2011-2022 Nginx, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + * + * SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD + */ +/* + * Copyright (C) 2002-2021 Igor Sysoev + * Copyright (C) 2011-2022 Nginx, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "protocol_examples_utils.h" + +/* Type of Escape algorithms to be used */ +#define NGX_ESCAPE_URI (0) +#define NGX_ESCAPE_ARGS (1) +#define NGX_ESCAPE_URI_COMPONENT (2) +#define NGX_ESCAPE_HTML (3) +#define NGX_ESCAPE_REFRESH (4) +#define NGX_ESCAPE_MEMCACHED (5) +#define NGX_ESCAPE_MAIL_AUTH (6) + +/* Type of Unescape algorithms to be used */ +#define NGX_UNESCAPE_URI (1) +#define NGX_UNESCAPE_REDIRECT (2) + + +uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size, unsigned int type) +{ + unsigned int n; + uint32_t *escape; + static u_char hex[] = "0123456789ABCDEF"; + + /* + * Per RFC 3986 only the following chars are allowed in URIs unescaped: + * + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + * + * And "%" can appear as a part of escaping itself. The following + * characters are not allowed and need to be escaped: %00-%1F, %7F-%FF, + * " ", """, "<", ">", "\", "^", "`", "{", "|", "}". + */ + + /* " ", "#", "%", "?", not allowed */ + + static uint32_t uri[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0xd000002d, /* 1101 0000 0000 0000 0000 0000 0010 1101 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */ + + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + }; + + /* " ", "#", "%", "&", "+", ";", "?", not allowed */ + + static uint32_t args[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0xd800086d, /* 1101 1000 0000 0000 0000 1000 0110 1101 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */ + + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + }; + + /* not ALPHA, DIGIT, "-", ".", "_", "~" */ + + static uint32_t uri_component[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0xfc009fff, /* 1111 1100 0000 0000 1001 1111 1111 1111 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x78000001, /* 0111 1000 0000 0000 0000 0000 0000 0001 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */ + + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + }; + + /* " ", "#", """, "%", "'", not allowed */ + + static uint32_t html[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0x500000ad, /* 0101 0000 0000 0000 0000 0000 1010 1101 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */ + + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + }; + + /* " ", """, "'", not allowed */ + + static uint32_t refresh[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0x50000085, /* 0101 0000 0000 0000 0000 0000 1000 0101 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x50000000, /* 0101 0000 0000 0000 0000 0000 0000 0000 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0xd8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */ + + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + }; + + /* " ", "%", %00-%1F */ + + static uint32_t memcached[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0x00000021, /* 0000 0000 0000 0000 0000 0000 0010 0001 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ + }; + + /* mail_auth is the same as memcached */ + + static uint32_t *map[] = + { uri, args, uri_component, html, refresh, memcached, memcached }; + + + escape = map[type]; + + if (dst == NULL) { + + /* find the number of the characters to be escaped */ + + n = 0; + + while (size) { + if (escape[*src >> 5] & (1U << (*src & 0x1f))) { + n++; + } + src++; + size--; + } + + return (uintptr_t) n; + } + + while (size) { + if (escape[*src >> 5] & (1U << (*src & 0x1f))) { + *dst++ = '%'; + *dst++ = hex[*src >> 4]; + *dst++ = hex[*src & 0xf]; + src++; + + } else { + *dst++ = *src++; + } + size--; + } + + return (uintptr_t) dst; +} + + +void ngx_unescape_uri(u_char **dst, u_char **src, size_t size, unsigned int type) +{ + u_char *d, *s, ch, c, decoded; + enum { + sw_usual = 0, + sw_quoted, + sw_quoted_second + } state; + + d = *dst; + s = *src; + + state = 0; + decoded = 0; + + while (size--) { + + ch = *s++; + + switch (state) { + case sw_usual: + if (ch == '?' + && (type & (NGX_UNESCAPE_URI | NGX_UNESCAPE_REDIRECT))) { + *d++ = ch; + goto done; + } + + if (ch == '%') { + state = sw_quoted; + break; + } + + *d++ = ch; + break; + + case sw_quoted: + + if (ch >= '0' && ch <= '9') { + decoded = (u_char) (ch - '0'); + state = sw_quoted_second; + break; + } + + c = (u_char) (ch | 0x20); + if (c >= 'a' && c <= 'f') { + decoded = (u_char) (c - 'a' + 10); + state = sw_quoted_second; + break; + } + + /* the invalid quoted character */ + + state = sw_usual; + + *d++ = ch; + + break; + + case sw_quoted_second: + + state = sw_usual; + + if (ch >= '0' && ch <= '9') { + ch = (u_char) ((decoded << 4) + (ch - '0')); + + if (type & NGX_UNESCAPE_REDIRECT) { + if (ch > '%' && ch < 0x7f) { + *d++ = ch; + break; + } + + *d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1); + + break; + } + + *d++ = ch; + + break; + } + + c = (u_char) (ch | 0x20); + if (c >= 'a' && c <= 'f') { + ch = (u_char) ((decoded << 4) + (c - 'a') + 10); + + if (type & NGX_UNESCAPE_URI) { + if (ch == '?') { + *d++ = ch; + goto done; + } + + *d++ = ch; + break; + } + + if (type & NGX_UNESCAPE_REDIRECT) { + if (ch == '?') { + *d++ = ch; + goto done; + } + + if (ch > '%' && ch < 0x7f) { + *d++ = ch; + break; + } + + *d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1); + break; + } + + *d++ = ch; + + break; + } + + /* the invalid quoted character */ + + break; + } + } + +done: + + *dst = d; + *src = s; +} + + +uint32_t example_uri_encode(char *dest, const char *src, size_t len) +{ + if (!src || !dest) { + return 0; + } + + uintptr_t ret = ngx_escape_uri((unsigned char *)dest, (unsigned char *)src, len, NGX_ESCAPE_URI_COMPONENT); + return (uint32_t)(ret - (uintptr_t)dest); +} + + +void example_uri_decode(char *dest, const char *src, size_t len) +{ + if (!src || !dest) { + return; + } + + unsigned char *src_ptr = (unsigned char *)src; + unsigned char *dst_ptr = (unsigned char *)dest; + ngx_unescape_uri(&dst_ptr, &src_ptr, len, NGX_UNESCAPE_URI); +} diff --git a/tests/c_headers/protocol_examples_common/stdin_out.c b/tests/c_headers/protocol_examples_common/stdin_out.c new file mode 100644 index 00000000..57c61fb8 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/stdin_out.c @@ -0,0 +1,32 @@ +/* Common functions for protocol examples, to configure stdin and stdout. + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + */ + +#include "protocol_examples_common.h" +#include "esp_err.h" +#include "driver/uart_vfs.h" +#include "driver/uart.h" +#include "sdkconfig.h" + +esp_err_t example_configure_stdin_stdout(void) +{ + if (uart_is_driver_installed((uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM)) { + return ESP_OK; + } + // Initialize VFS & UART so we can use std::cout/cin + setvbuf(stdin, NULL, _IONBF, 0); + /* Install UART driver for interrupt-driven reads and writes */ + ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_ESP_CONSOLE_UART_NUM, + 256, 0, 0, NULL, 0) ); + /* Tell VFS to use UART driver */ + uart_vfs_dev_use_driver(CONFIG_ESP_CONSOLE_UART_NUM); + uart_vfs_dev_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR); + /* Move the caret to the beginning of the next line on '\n' */ + uart_vfs_dev_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF); + return ESP_OK; +} diff --git a/tests/c_headers/protocol_examples_common/thread_connect.c b/tests/c_headers/protocol_examples_common/thread_connect.c new file mode 100644 index 00000000..f4dae26e --- /dev/null +++ b/tests/c_headers/protocol_examples_common/thread_connect.c @@ -0,0 +1,130 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include "esp_err.h" +#include "esp_event.h" +#include "esp_event_base.h" +#include "esp_vfs_eventfd.h" +#include "example_common_private.h" +#include "protocol_examples_common.h" +#include "protocol_examples_thread_config.h" +#include "esp_log.h" +#include + +#include +#include +#include +#include +#include +#include +#include + +static TaskHandle_t s_ot_task_handle = NULL; +static esp_netif_t *s_openthread_netif = NULL; +static SemaphoreHandle_t s_semph_thread_attached = NULL; +static SemaphoreHandle_t s_semph_thread_set_dns_server = NULL; +static const char *TAG = "example_connect"; + +static void thread_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, + void* event_data) +{ + if (event_base == OPENTHREAD_EVENT) { + if (event_id == OPENTHREAD_EVENT_ATTACHED) { + xSemaphoreGive(s_semph_thread_attached); + } else if (event_id == OPENTHREAD_EVENT_SET_DNS_SERVER) { + xSemaphoreGive(s_semph_thread_set_dns_server); + } + } +} + +static void ot_task_worker(void *aContext) +{ + esp_openthread_platform_config_t config = { + .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(), + .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), + .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), + }; + + esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_OPENTHREAD(); + esp_netif_config.if_desc = EXAMPLE_NETIF_DESC_THREAD; + esp_netif_config_t cfg = { + .base = &esp_netif_config, + .stack = &g_esp_netif_netstack_default_openthread, + }; + s_openthread_netif = esp_netif_new(&cfg); + assert(s_openthread_netif != NULL); + + // Initialize the OpenThread stack + ESP_ERROR_CHECK(esp_openthread_init(&config)); + ESP_ERROR_CHECK(esp_netif_attach(s_openthread_netif, esp_openthread_netif_glue_init(&config))); + esp_openthread_lock_acquire(portMAX_DELAY); + (void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL); + esp_openthread_cli_init(); + esp_openthread_cli_create_task(); + otOperationalDatasetTlvs dataset; + otError error = otDatasetGetActiveTlvs(esp_openthread_get_instance(), &dataset); + if (error != OT_ERROR_NONE) { + ESP_ERROR_CHECK(esp_openthread_auto_start(NULL)); + } else { + ESP_ERROR_CHECK(esp_openthread_auto_start(&dataset)); + } + esp_openthread_lock_release(); + + // Run the main loop + esp_openthread_launch_mainloop(); + + // Clean up + esp_openthread_netif_glue_deinit(); + esp_netif_destroy(s_openthread_netif); + esp_vfs_eventfd_unregister(); + vTaskDelete(NULL); +} + +/* tear down connection, release resources */ +void example_thread_shutdown(void) +{ + vTaskDelete(s_ot_task_handle); + esp_openthread_netif_glue_deinit(); + esp_netif_destroy(s_openthread_netif); + esp_vfs_eventfd_unregister(); + vSemaphoreDelete(s_semph_thread_set_dns_server); + vSemaphoreDelete(s_semph_thread_attached); +} + +esp_err_t example_thread_connect(void) +{ + s_semph_thread_attached = xSemaphoreCreateBinary(); + if (s_semph_thread_attached == NULL) { + return ESP_ERR_NO_MEM; + } + s_semph_thread_set_dns_server = xSemaphoreCreateBinary(); + if (s_semph_thread_set_dns_server == NULL) { + vSemaphoreDelete(s_semph_thread_attached); + return ESP_ERR_NO_MEM; + } + // 4 eventfds might be used for Thread + // * netif + // * ot task queue + // * radio driver + // * border router + esp_vfs_eventfd_config_t eventfd_config = { + .max_fds = 4, + }; + esp_vfs_eventfd_register(&eventfd_config); + ESP_ERROR_CHECK(esp_event_handler_register(OPENTHREAD_EVENT, ESP_EVENT_ANY_ID, thread_event_handler, NULL)); + if (xTaskCreate(ot_task_worker, "ot_br_main", CONFIG_EXAMPLE_THREAD_TASK_STACK_SIZE, NULL, 5, &s_ot_task_handle) != pdPASS) { + vSemaphoreDelete(s_semph_thread_attached); + vSemaphoreDelete(s_semph_thread_set_dns_server); + ESP_LOGE(TAG, "Failed to create openthread task"); + return ESP_FAIL; + } + xSemaphoreTake(s_semph_thread_attached, portMAX_DELAY); + // Wait 1s for the Thread device to set its DNS server with the NAT64 prefix. + if (xSemaphoreTake(s_semph_thread_set_dns_server, 1000 / portTICK_PERIOD_MS) != pdPASS) { + ESP_LOGW(TAG, "DNS server is not set for the Thread device, might be unable to access the Internet"); + } + return ESP_OK; +} diff --git a/tests/c_headers/protocol_examples_common/wifi_connect.c b/tests/c_headers/protocol_examples_common/wifi_connect.c new file mode 100644 index 00000000..a2b88200 --- /dev/null +++ b/tests/c_headers/protocol_examples_common/wifi_connect.c @@ -0,0 +1,247 @@ +/* + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection. + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + */ + +#include +#include "protocol_examples_common.h" +#include "example_common_private.h" +#include "esp_log.h" + +#if CONFIG_EXAMPLE_CONNECT_WIFI + +static const char *TAG = "example_connect"; +static esp_netif_t *s_example_sta_netif = NULL; +static SemaphoreHandle_t s_semph_get_ip_addrs = NULL; +#if CONFIG_EXAMPLE_CONNECT_IPV6 +static SemaphoreHandle_t s_semph_get_ip6_addrs = NULL; +#endif + +static int s_retry_num = 0; + +static void example_handler_on_wifi_disconnect(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + s_retry_num++; + if (s_retry_num > CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY) { + ESP_LOGI(TAG, "WiFi Connect failed %d times, stop reconnect.", s_retry_num); + /* let example_wifi_sta_do_connect() return */ + if (s_semph_get_ip_addrs) { + xSemaphoreGive(s_semph_get_ip_addrs); + } +#if CONFIG_EXAMPLE_CONNECT_IPV6 + if (s_semph_get_ip6_addrs) { + xSemaphoreGive(s_semph_get_ip6_addrs); + } +#endif + example_wifi_sta_do_disconnect(); + return; + } + wifi_event_sta_disconnected_t *disconn = event_data; + if (disconn->reason == WIFI_REASON_ROAMING) { + ESP_LOGD(TAG, "station roaming, do nothing"); + return; + } + ESP_LOGI(TAG, "Wi-Fi disconnected %d, trying to reconnect...", disconn->reason); + esp_err_t err = esp_wifi_connect(); + if (err == ESP_ERR_WIFI_NOT_STARTED) { + return; + } + ESP_ERROR_CHECK(err); +} + +static void example_handler_on_wifi_connect(void *esp_netif, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ +#if CONFIG_EXAMPLE_CONNECT_IPV6 + esp_netif_create_ip6_linklocal(esp_netif); +#endif // CONFIG_EXAMPLE_CONNECT_IPV6 +} + +static void example_handler_on_sta_got_ip(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + s_retry_num = 0; + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_STA, event->esp_netif)) { + return; + } + ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); + if (s_semph_get_ip_addrs) { + xSemaphoreGive(s_semph_get_ip_addrs); + } else { + ESP_LOGI(TAG, "- IPv4 address: " IPSTR ",", IP2STR(&event->ip_info.ip)); + } +} + +#if CONFIG_EXAMPLE_CONNECT_IPV6 +static void example_handler_on_sta_got_ipv6(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_STA, event->esp_netif)) { + return; + } + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), + IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + + if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { + if (s_semph_get_ip6_addrs) { + xSemaphoreGive(s_semph_get_ip6_addrs); + } else { + ESP_LOGI(TAG, "- IPv6 address: " IPV6STR ", type: %s", IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + } + } +} +#endif // CONFIG_EXAMPLE_CONNECT_IPV6 + + +void example_wifi_start(void) +{ + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA(); + // Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask) + esp_netif_config.if_desc = EXAMPLE_NETIF_DESC_STA; + esp_netif_config.route_prio = 128; + s_example_sta_netif = esp_netif_create_wifi(WIFI_IF_STA, &esp_netif_config); + esp_wifi_set_default_wifi_sta_handlers(); + + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + + +void example_wifi_stop(void) +{ + esp_err_t err = esp_wifi_stop(); + if (err == ESP_ERR_WIFI_NOT_INIT) { + return; + } + ESP_ERROR_CHECK(err); + ESP_ERROR_CHECK(esp_wifi_deinit()); + ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(s_example_sta_netif)); + esp_netif_destroy(s_example_sta_netif); + s_example_sta_netif = NULL; +} + + +esp_err_t example_wifi_sta_do_connect(wifi_config_t wifi_config, bool wait) +{ + if (wait) { + s_semph_get_ip_addrs = xSemaphoreCreateBinary(); + if (s_semph_get_ip_addrs == NULL) { + return ESP_ERR_NO_MEM; + } +#if CONFIG_EXAMPLE_CONNECT_IPV6 + s_semph_get_ip6_addrs = xSemaphoreCreateBinary(); + if (s_semph_get_ip6_addrs == NULL) { + vSemaphoreDelete(s_semph_get_ip_addrs); + return ESP_ERR_NO_MEM; + } +#endif + } + s_retry_num = 0; + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &example_handler_on_wifi_disconnect, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &example_handler_on_sta_got_ip, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &example_handler_on_wifi_connect, s_example_sta_netif)); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &example_handler_on_sta_got_ipv6, NULL)); +#endif + + ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + esp_err_t ret = esp_wifi_connect(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "WiFi connect failed! ret:%x", ret); + return ret; + } + if (wait) { + ESP_LOGI(TAG, "Waiting for IP(s)"); +#if CONFIG_EXAMPLE_CONNECT_IPV4 + xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY); + vSemaphoreDelete(s_semph_get_ip_addrs); + s_semph_get_ip_addrs = NULL; +#endif +#if CONFIG_EXAMPLE_CONNECT_IPV6 + xSemaphoreTake(s_semph_get_ip6_addrs, portMAX_DELAY); + vSemaphoreDelete(s_semph_get_ip6_addrs); + s_semph_get_ip6_addrs = NULL; +#endif + if (s_retry_num > CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY) { + return ESP_FAIL; + } + } + return ESP_OK; +} + +esp_err_t example_wifi_sta_do_disconnect(void) +{ + ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &example_handler_on_wifi_disconnect)); + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &example_handler_on_sta_got_ip)); + ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &example_handler_on_wifi_connect)); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &example_handler_on_sta_got_ipv6)); +#endif + return esp_wifi_disconnect(); +} + +void example_wifi_shutdown(void) +{ + example_wifi_sta_do_disconnect(); + example_wifi_stop(); +} + +esp_err_t example_wifi_connect(void) +{ + ESP_LOGI(TAG, "Start example_connect."); + example_wifi_start(); + wifi_config_t wifi_config = { + .sta = { +#if !CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN + .ssid = CONFIG_EXAMPLE_WIFI_SSID, + .password = CONFIG_EXAMPLE_WIFI_PASSWORD, +#endif + .scan_method = EXAMPLE_WIFI_SCAN_METHOD, + .sort_method = EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD, + .threshold.rssi = CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD, + .threshold.authmode = EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD, + }, + }; +#if CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN + example_configure_stdin_stdout(); + char buf[sizeof(wifi_config.sta.ssid)+sizeof(wifi_config.sta.password)+2] = {0}; + ESP_LOGI(TAG, "Please input ssid password:"); + fgets(buf, sizeof(buf), stdin); + int len = strlen(buf); + buf[len-1] = '\0'; /* removes '\n' */ + memset(wifi_config.sta.ssid, 0, sizeof(wifi_config.sta.ssid)); + + char *rest = NULL; + char *temp = strtok_r(buf, " ", &rest); + strncpy((char*)wifi_config.sta.ssid, temp, sizeof(wifi_config.sta.ssid)); + memset(wifi_config.sta.password, 0, sizeof(wifi_config.sta.password)); + temp = strtok_r(NULL, " ", &rest); + if (temp) { + strncpy((char*)wifi_config.sta.password, temp, sizeof(wifi_config.sta.password)); + } else { + wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN; + } +#endif + return example_wifi_sta_do_connect(wifi_config, true); +} + + +#endif /* CONFIG_EXAMPLE_CONNECT_WIFI */ From b8278ba6155b32dcd9494933c9b17666b6a2e8b9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 22:39:15 -0600 Subject: [PATCH 013/142] usb --- esp-idf-examples/net_pppos_usb/.gitignore | 15 ++ esp-idf-examples/net_pppos_usb/AGENTS.md | 41 ++++ esp-idf-examples/net_pppos_usb/CMakeLists.txt | 6 + esp-idf-examples/net_pppos_usb/config.nims | 5 + .../net_pppos_usb/esp32_ppp_example.nimble | 2 + .../net_pppos_usb/main/CMakeLists.txt | 16 ++ .../net_pppos_usb/main/config.nims | 13 ++ esp-idf-examples/net_pppos_usb/main/main.nim | 47 +++++ .../usb/tusb_composite_msc_serialdevice.nim | 189 ++++++++++++++++++ .../main/usb/tusb_serial_device.nim | 108 ++++++++++ esp-idf-examples/net_pppos_usb/partitions.csv | 6 + .../net_pppos_usb/sdkconfig.defaults | 14 ++ 12 files changed, 462 insertions(+) create mode 100644 esp-idf-examples/net_pppos_usb/.gitignore create mode 100644 esp-idf-examples/net_pppos_usb/AGENTS.md create mode 100644 esp-idf-examples/net_pppos_usb/CMakeLists.txt create mode 100644 esp-idf-examples/net_pppos_usb/config.nims create mode 100644 esp-idf-examples/net_pppos_usb/esp32_ppp_example.nimble create mode 100644 esp-idf-examples/net_pppos_usb/main/CMakeLists.txt create mode 100644 esp-idf-examples/net_pppos_usb/main/config.nims create mode 100644 esp-idf-examples/net_pppos_usb/main/main.nim create mode 100644 esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim create mode 100644 esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim create mode 100644 esp-idf-examples/net_pppos_usb/partitions.csv create mode 100644 esp-idf-examples/net_pppos_usb/sdkconfig.defaults diff --git a/esp-idf-examples/net_pppos_usb/.gitignore b/esp-idf-examples/net_pppos_usb/.gitignore new file mode 100644 index 00000000..dfee40a0 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/.gitignore @@ -0,0 +1,15 @@ +nim.cfg +main/nimcache +*.out +.DS_Store + +.tool-versions +*.dSYM/ +/*.png +nimble.develop +nimble.paths +deps +sdkconfig +build/ +sdkconfig.old +.cache/ diff --git a/esp-idf-examples/net_pppos_usb/AGENTS.md b/esp-idf-examples/net_pppos_usb/AGENTS.md new file mode 100644 index 00000000..fc9c3f9f --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/AGENTS.md @@ -0,0 +1,41 @@ +# Repository Guidelines + +## Project Structure & Module Organization +- main/: Nim sources and component config. Entrypoint: main/main.nim. Generated C lives in main/nimcache/. +- deps/: Vendored Nim dependencies (nesper, unittest2, etc.). Managed by Nimble/Atlas. +- build/: ESP‑IDF CMake/Ninja outputs and flash args. Not for commits. +- CMakeLists.txt: Top‑level ESP‑IDF project file. +- config.nims, nim.cfg: Nim/nesper build configuration and include paths. +- sdkconfig, sdkconfig.defaults, partitions.csv: ESP‑IDF configuration and partition table. + +## Build, Test, and Development Commands +- nim espBuild: Compile Nim and build the ESP‑IDF project (preferred dev loop). +- nim espCompile: Compile Nim to C into main/nimcache/ (no ESP‑IDF build). +- idf.py set-target esp32s3: Ensure target matches config.nims. +- idf.py -p /dev/ttyUSB0 flash monitor: Flash and open serial monitor (adjust port). +- idf.py build: Rebuild from generated C when Nim hasn’t changed. +- Clean: idf.py fullclean && rm -rf main/nimcache + +Environment: export IDF_PATH and source "$IDF_PATH/export.sh" before building. + +## Coding Style & Naming Conventions +- Indentation: 2 spaces; keep lines concise. +- Nim style: camelCase procs, PascalCase types, UPPER_SNAKE constants. Exported symbols end with *. +- Modules: lower_snake filenames (e.g., ppp_client.nim). +- Formatting: nimpretty --indent:2 main/*.nim +- Use nesper APIs where possible; isolate raw ESP‑IDF calls behind small Nim wrappers. + +## Testing Guidelines +- Current repo has no tests. Add Nim tests under tests/ using unittest2 (deps/unittest2). +- Naming: tests/test_*.nim (e.g., tests/test_ppp.nim). +- Run: nim c -r tests/test_ppp.nim. Consider a nimble test task for CI later. + +## Commit & Pull Request Guidelines +- Commits: short, imperative summaries (e.g., "ppp: add link setup"). +- PRs: include purpose, build/flash steps, linked issues, and serial logs/screenshots for hardware changes. +- Scope: keep changes focused; avoid committing build/ outputs or local sdkconfig changes unless intentional. + +## Security & Configuration Tips +- Do not commit credentials or secrets in sdkconfig or sources. +- Match target to hardware (esp32s3 by default in config.nims); update if using another SoC. +- Document required pins/peripherals in PRs when relevant. diff --git a/esp-idf-examples/net_pppos_usb/CMakeLists.txt b/esp-idf-examples/net_pppos_usb/CMakeLists.txt new file mode 100644 index 00000000..1c86d853 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(esp32_ppp_example) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims new file mode 100644 index 00000000..43733b68 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -0,0 +1,5 @@ + +switch("define", "ESP_IDF_VERSION=5.5") +switch("define", "esp32s3") # or other variants + +include nesper/build_utils/builds diff --git a/esp-idf-examples/net_pppos_usb/esp32_ppp_example.nimble b/esp-idf-examples/net_pppos_usb/esp32_ppp_example.nimble new file mode 100644 index 00000000..2ab7d97c --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/esp32_ppp_example.nimble @@ -0,0 +1,2 @@ +requires "nesper" + diff --git a/esp-idf-examples/net_pppos_usb/main/CMakeLists.txt b/esp-idf-examples/net_pppos_usb/main/CMakeLists.txt new file mode 100644 index 00000000..65748e6e --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/CMakeLists.txt @@ -0,0 +1,16 @@ +idf_component_register(SRC_DIRS "./nimcache" + INCLUDE_DIRS "" + ) + +idf_build_set_property(C_COMPILE_OPTIONS -Wno-unused-label APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-discarded-qualifiers APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-ignored-qualifiers APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-error=unused-label APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-error=parentheses APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-error=implicit-function-declaration APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-error=maybe-uninitialized APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-error=nonnull APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-error=address APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-unused-but-set-variable APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-maybe-uninitialized APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-incompatible-pointer-types APPEND) diff --git a/esp-idf-examples/net_pppos_usb/main/config.nims b/esp-idf-examples/net_pppos_usb/main/config.nims new file mode 100644 index 00000000..80a21ac4 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/config.nims @@ -0,0 +1,13 @@ +--nomain +--compileOnly +--define:NimAppMain +--nimcache:nimcache + +--gc:arc +--os:freertos +--cpu:arm +--define:useMalloc +--define:noSignalHandler +--debugger:native +--threads:on +--tls_emulation:off diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim new file mode 100644 index 00000000..2a571aad --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -0,0 +1,47 @@ +import std/strutils +import nesper +import nesper/[consts, general, timers] +import nesper/esp/esp_system +import nesper/esp/net/esp_netif +import nesper/esp/net/esp_netif_ppp + +const + TAG*: cstring = "main" + +proc setupPPP(): bool = + # Network interface configuration + var cfg: esp_netif_config_t = ESP_NETIF_DEFAULT_PPP() + let esp_netif: ptr esp_netif_t = esp_netif_new(addr cfg) + + # PPP-specific configuration + var ppp_config: esp_netif_ppp_config_t + ppp_config.ppp_phase_event_enabled = true + ppp_config.ppp_error_event_enabled = true + check: esp_netif_ppp_set_params(esp_netif, addr ppp_config) + return true + +app_main: + logi(TAG, "esp starting ... ") + + # Print chip information + var chipInfo: esp_chip_info_t + esp_chip_info(addr chipInfo) + var features = "" + try: + features &= "This is a " & $chipInfo.model + features &= " chip with " & $chipInfo.cores & " CPU core(s)" + if (chipInfo.features and CHIP_FEATURE_WIFI_BGN) != 0: + features &= "WiFi/" + if (chipInfo.features and CHIP_FEATURE_BT) != 0: + features &= "BT" + if (chipInfo.features and CHIP_FEATURE_BLE) != 0: + features &= "BLE" + if (chipInfo.features and CHIP_FEATURE_IEEE802154) != 0: + features &= "802.15.4 (Zigbee/Thread)" + logi(TAG, "chip features: %s", features.cstring) + except Defect, CatchableError: + logi(TAG, "Error getting chip info") + + while true: + logi(TAG, "Hello, World!") + delay(1_000.Millis) \ No newline at end of file diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim new file mode 100644 index 00000000..e58e426c --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim @@ -0,0 +1,189 @@ +import nesper +import nesper/[general] +import nesper/esp/queue +import nesper/esp/esp_vfs_fat # for wl_handle_t and WL_INVALID_HANDLE + +const + TAG* = "usb_composite" + RXBufSz = 64 + BasePath = "/usb" + +{.emit: """ +#include +#include +#include +#include +#include +#include "esp_partition.h" +#include "wear_levelling/wear_levelling.h" +#include "tinyusb.h" +#include "tusb_cdc_acm.h" +#include "tusb_msc_storage.h" + +// Install TinyUSB with default descriptors from Kconfig +esp_err_t nesper_tinyusb_install_default(void) { + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .string_descriptor_count = 0, + .external_phy = false, +#if (TUD_OPT_HIGH_SPEED) + .fs_configuration_descriptor = NULL, + .hs_configuration_descriptor = NULL, + .qualifier_descriptor = NULL, +#else + .configuration_descriptor = NULL, +#endif + }; + return tinyusb_driver_install(&tusb_cfg); +} + +// Init CDC-ACM with provided callbacks +esp_err_t nesper_tinyusb_cdc_acm_init_default(tinyusb_usbdev_t usb_dev, + tinyusb_cdcacm_itf_t cdc_port, + size_t rx_unread_buf_sz, + cdcacm_event_callback_t cb_rx, + cdcacm_event_callback_t cb_line_state) { + tinyusb_config_cdcacm_t acm_cfg = { + .usb_dev = usb_dev, + .cdc_port = cdc_port, + .rx_unread_buf_sz = rx_unread_buf_sz, + .callback_rx = cb_rx, + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = cb_line_state, + .callback_line_coding_changed = NULL, + }; + return tusb_cdc_acm_init(&acm_cfg); +} + +// Init MSC storage on SPI flash and mount to base path +esp_err_t nesper_msc_init_and_mount_spiflash(wl_handle_t wl_handle, const char *base_path) { + const tinyusb_msc_spiflash_config_t config_spi = { .wl_handle = wl_handle }; + esp_err_t err = tinyusb_msc_storage_init_spiflash(&config_spi); + if (err != ESP_OK) return err; + return tinyusb_msc_storage_mount(base_path); +} +""".} + +proc nesper_tinyusb_install_default(): esp_err_t {.cdecl, importc.} +proc nesper_tinyusb_cdc_acm_init_default(usb_dev: cint; cdc_port: cint; rx_unread_buf_sz: csize_t; + cb_rx, cb_line_state: proc (itf: cint; event: pointer) {.cdecl.}): esp_err_t {.cdecl, importc.} +proc nesper_msc_init_and_mount_spiflash(wl: wl_handle_t; basePath: cstring): esp_err_t {.cdecl, importc.} + +proc esp_partition_find_first(ptype: uint8; psubtype: uint8; label: cstring): pointer {.cdecl, importc: "esp_partition_find_first", header: "esp_partition.h".} +proc wl_mount(partition: pointer; outHandle: ptr wl_handle_t): esp_err_t {.cdecl, importc: "wl_mount", header: "wear_levelling/wear_levelling.h".} + +proc tinyusb_cdcacm_read(itf: cint; buf: ptr uint8; bufsize: csize_t; rx_size: ptr csize_t): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_read", header: "tusb_cdc_acm.h".} +proc tinyusb_cdcacm_write_queue(itf: cint; buf: ptr uint8; size: csize_t): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_write_queue", header: "tusb_cdc_acm.h".} +proc tinyusb_cdcacm_write_flush(itf: cint; timeout_ms: cint): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_write_flush", header: "tusb_cdc_acm.h".} + +# C stdlib helpers used by the example file operations +type Stat* {.importc: "struct stat", header: "sys/stat.h", bycopy.} = object +proc stat*(path: cstring; st: ptr Stat): cint {.cdecl, importc: "stat", header: "sys/stat.h".} +proc mkdir*(path: cstring; mode: cint): cint {.cdecl, importc: "mkdir", header: "sys/stat.h".} +proc strerror*(errnum: cint): cstring {.cdecl, importc: "strerror", header: "string.h".} +proc fopen*(path, mode: cstring): pointer {.cdecl, importc: "fopen", header: "stdio.h".} +proc fprintf*(f: pointer; fmt: cstring): cint {.varargs, cdecl, importc: "fprintf", header: "stdio.h".} +proc fclose*(f: pointer): cint {.cdecl, importc: "fclose", header: "stdio.h".} +proc fgets*(s: cstring; n: cint; f: pointer): cstring {.cdecl, importc: "fgets", header: "stdio.h".} +proc strchr*(s: cstring; c: cint): cstring {.cdecl, importc: "strchr", header: "string.h".} +var errno* {.importc: "errno", header: "errno.h".}: cint + +const + ESP_PARTITION_TYPE_DATA* = 0x01'u8 + ESP_PARTITION_SUBTYPE_DATA_FAT* = 0x81'u8 + +type + AppMessage = object + buf: array[RXBufSz + 1, uint8] + bufLen: csize_t + itf: uint8 + +var + appQueue: QueueHandle_t + rxBuf {.volatile.}: array[RXBufSz + 1, uint8] + +proc onCdcRx(itf: cint; event: pointer) {.cdecl.} = + var rxSize: csize_t = 0 + let ret = tinyusb_cdcacm_read(itf, addr rxBuf[0], RXBufSz.csize_t, addr rxSize) + if ret == ESP_OK: + var msg: AppMessage + msg.bufLen = rxSize + msg.itf = uint8(itf) + if rxSize > 0 and rxSize <= RXBufSz.csize_t: + copyMem(addr msg.buf[0], unsafeAddr rxBuf[0], rxSize) + discard xQueueSendToBack(appQueue, addr msg, 0) + else: + loge(TAG, "Read Error") + +proc onCdcLineState(itf: cint; event: pointer) {.cdecl.} = + logi(TAG, "Line state changed on channel %d", itf) + +proc fileExists(path: cstring): bool = + var s: Stat + result = stat(path, addr s) == 0 + +proc fileOperations() = + let directory = "/usb/esp" + let filePath = "/usb/esp/test.txt" + + var s: Stat + let directoryExists = (stat(directory, addr s) == 0) + if not directoryExists: + if mkdir(directory, 0o775) != 0: + loge(TAG, "mkdir failed: %s", strerror(errno)) + + if not fileExists(filePath): + logi(TAG, "Creating file") + let f = fopen(filePath, "w") + if f == nil: + loge(TAG, "Failed to open file for writing") + return + discard fprintf(f, "Hello World!\n") + discard fclose(f) + + logi(TAG, "Reading file") + let f = fopen(filePath, "r") + if f == nil: + loge(TAG, "Failed to open file for reading") + return + var line: array[64, char] + discard fgets(cast[cstring](addr line[0]), line.len.cint, f) + discard fclose(f) + var p = strchr(cast[cstring](addr line[0]), '\n'.int) + if p != nil: + p[] = '\0' + logi(TAG, "Read from file: '%s'", cast[cstring](addr line[0])) + +proc storageInitSpiFlash(wlOut: var wl_handle_t): esp_err_t = + logi(TAG, "Initializing wear levelling") + let part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, nil) + if part == nil: + loge(TAG, "Failed to find FATFS partition. Check the partition table.") + return ESP_ERR_NOT_FOUND + result = wl_mount(part, addr wlOut) + +proc runUsbCompositeMscSerial*() = + appQueue = xQueueCreate(UBaseType_t(5), UBaseType_t(sizeof(AppMessage))) + assert appQueue != nil + + logi(TAG, "Initializing storage...") + var wl: wl_handle_t = WL_INVALID_HANDLE + check: storageInitSpiFlash(wl) + check: nesper_msc_init_and_mount_spiflash(wl, BasePath) + fileOperations() + + logi(TAG, "USB Composite initialization") + check: nesper_tinyusb_install_default() + check: nesper_tinyusb_cdc_acm_init_default(0, 0, RXBufSz, onCdcRx, onCdcLineState) + logi(TAG, "USB Composite initialization DONE") + + var msg: AppMessage + while true: + if xQueueReceive(appQueue, addr msg, portMAX_DELAY) == 1: + if msg.bufLen > 0: + logi(TAG, "Data from channel %d", msg.itf.int) + discard tinyusb_cdcacm_write_queue(msg.itf.int, addr msg.buf[0], msg.bufLen) + let err = tinyusb_cdcacm_write_flush(msg.itf.int, 0) + if err != ESP_OK: + loge(TAG, "CDC ACM write flush error: %s", esp_err_to_name(err)) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim new file mode 100644 index 00000000..16f1bba7 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim @@ -0,0 +1,108 @@ +import nesper +import nesper/[general] +import nesper/esp/queue + +const + TAG* = "usb_serial" + RXBufSz = 64 # Match example default; align with Kconfig if changed + +# C includes and tinyusb helper wrappers +{.emit: """ +#include +#include "tinyusb.h" +#include "tusb_cdc_acm.h" + +// Install TinyUSB with default descriptors from Kconfig +esp_err_t nesper_tinyusb_install_default(void) { + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .string_descriptor_count = 0, + .external_phy = false, +#if (TUD_OPT_HIGH_SPEED) + .fs_configuration_descriptor = NULL, + .hs_configuration_descriptor = NULL, + .qualifier_descriptor = NULL, +#else + .configuration_descriptor = NULL, +#endif + }; + return tinyusb_driver_install(&tusb_cfg); +} + +// Init CDC-ACM port with provided callbacks +esp_err_t nesper_tinyusb_cdc_acm_init_default(tinyusb_usbdev_t usb_dev, + tinyusb_cdcacm_itf_t cdc_port, + size_t rx_unread_buf_sz, + cdcacm_event_callback_t cb_rx, + cdcacm_event_callback_t cb_line_state) { + tinyusb_config_cdcacm_t acm_cfg = { + .usb_dev = usb_dev, + .cdc_port = cdc_port, + .rx_unread_buf_sz = rx_unread_buf_sz, + .callback_rx = cb_rx, + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = cb_line_state, + .callback_line_coding_changed = NULL, + }; + return tusb_cdc_acm_init(&acm_cfg); +} +""".} + +proc nesper_tinyusb_install_default(): esp_err_t {.cdecl, importc.} +proc nesper_tinyusb_cdc_acm_init_default(usb_dev: cint; cdc_port: cint; rx_unread_buf_sz: csize_t; + cb_rx, cb_line_state: proc (itf: cint; event: pointer) {.cdecl.}): esp_err_t {.cdecl, importc.} + +proc tinyusb_cdcacm_read(itf: cint; buf: ptr uint8; bufsize: csize_t; rx_size: ptr csize_t): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_read", header: "tusb_cdc_acm.h".} +proc tinyusb_cdcacm_write_queue(itf: cint; buf: ptr uint8; size: csize_t): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_write_queue", header: "tusb_cdc_acm.h".} +proc tinyusb_cdcacm_write_flush(itf: cint; timeout_ms: cint): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_write_flush", header: "tusb_cdc_acm.h".} + +type + AppMessage = object + buf: array[RXBufSz + 1, uint8] + bufLen: csize_t + itf: uint8 + +var + appQueue: QueueHandle_t + rxBuf {.volatile.}: array[RXBufSz + 1, uint8] + +# RX callback: read bytes and forward to application queue +proc onCdcRx(itf: cint; event: pointer) {.cdecl.} = + var rxSize: csize_t = 0 + let ret = tinyusb_cdcacm_read(itf, addr rxBuf[0], RXBufSz.csize_t, addr rxSize) + if ret == ESP_OK: + var msg: AppMessage + msg.bufLen = rxSize + msg.itf = uint8(itf) + if rxSize > 0 and rxSize <= RXBufSz.csize_t: + copyMem(addr msg.buf[0], unsafeAddr rxBuf[0], rxSize) + discard xQueueSendToBack(appQueue, addr msg, 0) + else: + loge(TAG, "Read Error") + +# Line state change callback (log only) +proc onCdcLineState(itf: cint; event: pointer) {.cdecl.} = + logi(TAG, "Line state changed on channel %d", itf) + +proc runUsbSerialDevice*() = + # Create queue for app messages + appQueue = xQueueCreate(UBaseType_t(5), UBaseType_t(sizeof(AppMessage))) + assert appQueue != nil + + logi(TAG, "USB initialization") + check: nesper_tinyusb_install_default() + check: nesper_tinyusb_cdc_acm_init_default(0, 0, RXBufSz, onCdcRx, onCdcLineState) + + logi(TAG, "USB initialization DONE") + + var msg: AppMessage + while true: + if xQueueReceive(appQueue, addr msg, portMAX_DELAY) == 1: # pdTRUE + if msg.bufLen > 0: + logi(TAG, "Data from channel %d", msg.itf.int) + discard tinyusb_cdcacm_write_queue(msg.itf.int, addr msg.buf[0], msg.bufLen) + let err = tinyusb_cdcacm_write_flush(msg.itf.int, 0) + if err != ESP_OK: + loge(TAG, "CDC ACM write flush error: %s", esp_err_to_name(err)) + diff --git a/esp-idf-examples/net_pppos_usb/partitions.csv b/esp-idf-examples/net_pppos_usb/partitions.csv new file mode 100644 index 00000000..a1521751 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/partitions.csv @@ -0,0 +1,6 @@ +# ESP-IDF Partition Table for XIAO ESP32S3 (8MB flash) +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000 +otadata, data, ota, 0xE000, 0x2000 +ota_0, app, ota_0, 0x10000, 0x3F0000 +ota_1, app, ota_1, 0x410000, 0x3F0000 \ No newline at end of file diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults new file mode 100644 index 00000000..4b78d39a --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults @@ -0,0 +1,14 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.5.0 Project Minimal Configuration +# +CONFIG_IDF_TARGET="esp32s3" +CONFIG_APP_NO_BLOBS=y +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_ESP_CONSOLE_USB_CDC=y +CONFIG_LWIP_PPP_SUPPORT=y +CONFIG_LWIP_PPP_PAP_SUPPORT=y +CONFIG_LWIP_PPP_CHAP_SUPPORT=y +CONFIG_LWIP_ENABLE_LCP_ECHO=y +CONFIG_LWIP_PPP_DEBUG_ON=y From e8250d04471e2569e06afdf32b700c0d0213ac7d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 22:40:11 -0600 Subject: [PATCH 014/142] usb --- esp-idf-examples/net_pppos_usb/CMakeLists.txt | 2 +- .../{esp32_ppp_example.nimble => net_pppos_usb.nimble} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename esp-idf-examples/net_pppos_usb/{esp32_ppp_example.nimble => net_pppos_usb.nimble} (100%) diff --git a/esp-idf-examples/net_pppos_usb/CMakeLists.txt b/esp-idf-examples/net_pppos_usb/CMakeLists.txt index 1c86d853..345c4f5b 100644 --- a/esp-idf-examples/net_pppos_usb/CMakeLists.txt +++ b/esp-idf-examples/net_pppos_usb/CMakeLists.txt @@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(esp32_ppp_example) +project(net_pppos_usb) diff --git a/esp-idf-examples/net_pppos_usb/esp32_ppp_example.nimble b/esp-idf-examples/net_pppos_usb/net_pppos_usb.nimble similarity index 100% rename from esp-idf-examples/net_pppos_usb/esp32_ppp_example.nimble rename to esp-idf-examples/net_pppos_usb/net_pppos_usb.nimble From 1d1b9293eee89f06f9ace0fe89b4c84a60df4ce9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 22:56:54 -0600 Subject: [PATCH 015/142] usb --- esp-idf-examples/net_pppos_usb/.gitignore | 1 + .../net_pppos_usb/dependencies.lock | 42 +++++ .../net_pppos_usb/main/idf_component.yml | 17 ++ .../net_pppos_usb/main/usb/tusb_ncm.nim | 150 ++++++++++++++++++ 4 files changed, 210 insertions(+) create mode 100644 esp-idf-examples/net_pppos_usb/dependencies.lock create mode 100644 esp-idf-examples/net_pppos_usb/main/idf_component.yml create mode 100644 esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim diff --git a/esp-idf-examples/net_pppos_usb/.gitignore b/esp-idf-examples/net_pppos_usb/.gitignore index dfee40a0..9f8a8368 100644 --- a/esp-idf-examples/net_pppos_usb/.gitignore +++ b/esp-idf-examples/net_pppos_usb/.gitignore @@ -13,3 +13,4 @@ sdkconfig build/ sdkconfig.old .cache/ +managed_components/ diff --git a/esp-idf-examples/net_pppos_usb/dependencies.lock b/esp-idf-examples/net_pppos_usb/dependencies.lock new file mode 100644 index 00000000..5b6ba143 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/dependencies.lock @@ -0,0 +1,42 @@ +dependencies: + espressif/esp_tinyusb: + component_hash: 5e37c53a10518f40b288a48afec4ab549784be9e6eb74add699a30395543418a + dependencies: + - name: idf + require: private + version: '>=5.0' + - name: espressif/tinyusb + registry_url: https://components.espressif.com + require: public + version: 0.* + source: + registry_url: https://components.espressif.com/ + type: service + targets: + - esp32s2 + - esp32s3 + version: 1.0.3 + espressif/tinyusb: + component_hash: aa65639878f27a44d349044afd9c3fc134a92bd560874fdac1d836019b5c07ca + dependencies: + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + targets: + - esp32s2 + - esp32s3 + - esp32p4 + version: 0.18.0~4 + idf: + source: + type: idf + version: 5.5.0 +direct_dependencies: +- espressif/esp_tinyusb +- idf +manifest_hash: 0fb80733b490b7c3191c616db6fa2692104ac8ff61cac960aa2413cb8efc9e8b +target: esp32s3 +version: 2.0.0 diff --git a/esp-idf-examples/net_pppos_usb/main/idf_component.yml b/esp-idf-examples/net_pppos_usb/main/idf_component.yml new file mode 100644 index 00000000..f82f7865 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/idf_component.yml @@ -0,0 +1,17 @@ +## IDF Component Manager Manifest File +dependencies: + ## Required IDF version + idf: + version: '>=4.1.0' + # # Put list of dependencies here + # # For components maintained by Espressif: + # component: "~1.0.0" + # # For 3rd party components: + # username/component: ">=1.0.0,<2.0.0" + # username2/component2: + # version: "~1.0.0" + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't have an effect dependencies of the `main` component. + # # All dependencies of `main` are public by default. + # public: true + espressif/esp_tinyusb: ~1.0.0 diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim new file mode 100644 index 00000000..bcc11258 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim @@ -0,0 +1,150 @@ +import nesper +import nesper/[general, events, wifi] +import nesper/esp/esp_system +import nesper/esp/nvs_flash +import nesper/net_utils + +const + TAG* = "USB_NCM" + WIFI_SSID {.strdefine.}: string = "NOSSID" + WIFI_PASS {.strdefine.}: string = "" + +# C includes and helper wrappers for TinyUSB NET and internal WiFi APIs +{.emit: """ +#include +#include "tinyusb.h" +#include "tinyusb_net.h" +#include "esp_private/wifi.h" + +typedef esp_err_t (*nesper_ncm_recv_cb_t)(void *buffer, uint16_t len, void *ctx); +typedef void (*nesper_ncm_free_cb_t)(void *eb, void *ctx); + +// Install TinyUSB with default descriptors from Kconfig +esp_err_t nesper_tinyusb_install_default(void) { + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .string_descriptor_count = 0, + .external_phy = false, +#if (TUD_OPT_HIGH_SPEED) + .fs_configuration_descriptor = NULL, + .hs_configuration_descriptor = NULL, + .qualifier_descriptor = NULL, +#else + .configuration_descriptor = NULL, +#endif + }; + return tinyusb_driver_install(&tusb_cfg); +} + +// Initialize NCM with provided callbacks and MAC address +esp_err_t nesper_tinyusb_net_init_bridge(tinyusb_usbdev_t dev, + uint8_t mac_addr[6], + nesper_ncm_recv_cb_t on_recv, + nesper_ncm_free_cb_t free_tx_buf, + void *user_ctx) { + tinyusb_net_config_t cfg = { + .on_recv_callback = on_recv, + .free_tx_buffer = free_tx_buf, + .user_context = user_ctx, + }; + memcpy(cfg.mac_addr, mac_addr, 6); + return tinyusb_net_init(dev, &cfg); +} + +// Thin wrapper to expose send_sync +static inline esp_err_t nesper_tinyusb_net_send_sync(void *buffer, uint16_t len, void *eb, uint32_t timeout_ticks) { + return tinyusb_net_send_sync(buffer, len, eb, timeout_ticks); +} + +// WiFi internal helpers (signatures only, implemented by IDF) +esp_err_t esp_wifi_internal_tx(wifi_interface_t ifx, void *buffer, uint16_t len); +esp_err_t esp_wifi_internal_reg_rxcb(wifi_interface_t ifx, esp_wifi_rxcb_t rx_cb); +void esp_wifi_internal_free_rx_buffer(void *eb); +""".} + +proc nesper_tinyusb_install_default(): esp_err_t {.cdecl, importc.} +proc nesper_tinyusb_net_init_bridge(dev: cint; + mac: ptr uint8; + on_recv: proc (buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.}; + free_tx: proc (eb: pointer; ctx: pointer) {.cdecl.}; + user_ctx: pointer): esp_err_t {.cdecl, importc.} +proc nesper_tinyusb_net_send_sync(buffer: pointer; len: uint16; eb: pointer; timeoutTicks: uint32): esp_err_t {.cdecl, importc.} + +proc esp_wifi_internal_tx(ifx: wifi_interface_t; buffer: pointer; len: uint16): esp_err_t {.cdecl, importc.} +proc esp_wifi_internal_reg_rxcb(ifx: wifi_interface_t; + rx_cb: proc (buffer: pointer; len: uint16; eb: pointer): esp_err_t {.cdecl.}): esp_err_t {.cdecl, importc.} +proc esp_wifi_internal_free_rx_buffer(eb: pointer) {.cdecl, importc.} + +var sIsWifiConnected {.volatile.}: bool = false + +# USB -> WiFi callback: forward received USB frame to WiFi TX when connected +proc usbRecvCallback(buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.} = + let isConnected = cast[ptr bool](ctx) + if isConnected[]: + discard esp_wifi_internal_tx(WIFI_IF_STA, buffer, len) + return ESP_OK + +# Free WiFi RX buffer after USB send completes or on failure +proc wifiPktFree(eb: pointer; ctx: pointer) {.cdecl.} = + esp_wifi_internal_free_rx_buffer(eb) + +# WiFi -> USB path: send WiFi RX packet out over USB NCM +proc pktWifi2Usb(buffer: pointer; len: uint16; eb: pointer): esp_err_t {.cdecl.} = + if nesper_tinyusb_net_send_sync(buffer, len, eb, portMAX_DELAY.uint32) != ESP_OK: + esp_wifi_internal_free_rx_buffer(eb) + return ESP_OK + +# WiFi event handler to manage link and RX callback registration +proc wifiEventHandler(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = + let isConnected = cast[ptr bool](arg) + if event_base == WIFI_EVENT: + if event_id == WIFI_EVENT_STA_DISCONNECTED.int32: + logi(TAG, "WiFi STA disconnected") + isConnected[] = false + discard esp_wifi_internal_reg_rxcb(WIFI_IF_STA, nil) + discard esp_wifi_connect() + elif event_id == WIFI_EVENT_STA_CONNECTED.int32: + logi(TAG, "WiFi STA connected") + discard esp_wifi_internal_reg_rxcb(WIFI_IF_STA, pktWifi2Usb) + isConnected[] = true + +proc startWifi(isConnected: ptr bool): esp_err_t = + check: esp_event_loop_create_default() + + var wcfg = wifi_init_config_default() + check: esp_wifi_init(addr wcfg) + check: esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifiEventHandler, cast[pointer](isConnected)) + check: esp_wifi_set_mode(WIFI_MODE_STA) + check: esp_wifi_start() + + var wifiConfig: wifi_config_t + wifiConfig.sta.ssid.setFromString(WIFI_SSID) + wifiConfig.sta.password.setFromString(WIFI_PASS) + check: esp_wifi_set_config(ESP_IF_WIFI_STA, addr wifiConfig) + return esp_wifi_connect() + +proc runUsbNcmBridge*() = + # Initialize NVS (PHY calibration data) + var ret = nvs_flash_init() + if ret == ESP_ERR_NVS_NO_FREE_PAGES or ret == ESP_ERR_NVS_NEW_VERSION_FOUND: + check: nvs_flash_erase() + ret = nvs_flash_init() + check: ret + + logi(TAG, "USB NCM device initialization") + check: nesper_tinyusb_install_default() + + var mac: array[6, uint8] + check: esp_read_mac(addr mac[0], ESP_MAC_WIFI_STA) + logi(TAG, "Network interface HW address: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0].int, mac[1].int, mac[2].int, mac[3].int, mac[4].int, mac[5].int) + + # Initialize TinyUSB NET class with callbacks and MAC + check: nesper_tinyusb_net_init_bridge(0, addr mac[0], usbRecvCallback, wifiPktFree, addr sIsWifiConnected) + + logi(TAG, "WiFi initialization") + check: startWifi(addr sIsWifiConnected) + + logi(TAG, "USB NCM and WiFi initialized and started") + From e20e12763f1baf5c51427a532e4480344794c3b8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 23:01:57 -0600 Subject: [PATCH 016/142] usb --- src/nesper/components/esp_tinyusb/tinyusb.nim | 53 +++++ .../components/esp_tinyusb/tinyusb_types.nim | 16 ++ .../components/esp_tinyusb/tusb_cdc_acm.nim | 211 ++++++++++++++++++ .../components/esp_tinyusb/tusb_config.nim | 81 +++++++ .../components/esp_tinyusb/tusb_tasks.nim | 31 +++ .../components/esp_tinyusb/vfs_tinyusb.nim | 29 +++ 6 files changed, 421 insertions(+) create mode 100644 src/nesper/components/esp_tinyusb/tinyusb.nim create mode 100644 src/nesper/components/esp_tinyusb/tinyusb_types.nim create mode 100644 src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim create mode 100644 src/nesper/components/esp_tinyusb/tusb_config.nim create mode 100644 src/nesper/components/esp_tinyusb/tusb_tasks.nim create mode 100644 src/nesper/components/esp_tinyusb/vfs_tinyusb.nim diff --git a/src/nesper/components/esp_tinyusb/tinyusb.nim b/src/nesper/components/esp_tinyusb/tinyusb.nim new file mode 100644 index 00000000..518b21bc --- /dev/null +++ b/src/nesper/components/esp_tinyusb/tinyusb.nim @@ -0,0 +1,53 @@ +## +## SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD +## +## SPDX-License-Identifier: Apache-2.0 +## + +type + + tinyusb_config_t* {.importc: "tinyusb_config_t", header: "tinyusb.h", bycopy.} = object ## + ## + ## @brief Configuration structure of the TinyUSB core + ## + ## USB specification mandates self-powered devices to monitor USB VBUS to detect connection/disconnection events. + ## If you want to use this feature, connected VBUS to any free GPIO through a voltage divider or voltage comparator. + ## The voltage divider output should be (0.75 * Vdd) if VBUS is 4.4V (lowest valid voltage at device port). + ## The comparator thresholds should be set with hysteresis: 4.35V (falling edge) and 4.75V (raising edge). + ## + device_descriptor* {.importc: "device_descriptor".}: ptr tusb_desc_device_t ## + ## !< Pointer to a device descriptor. If set to NULL, the TinyUSB device will use a default device descriptor whose values are set in Kconfig + string_descriptor* {.importc: "string_descriptor".}: cstringArray ## + ## !< Pointer to an array of string descriptors + external_phy* {.importc: "external_phy".}: bool ## + ## !< Should USB use an external PHY + configuration_descriptor* {.importc: "configuration_descriptor".}: ptr uint8 ## + ## !< Pointer to a configuration descriptor. If set to NULL, TinyUSB device will use a default configuration descriptor whose values are set in Kconfig + self_powered* {.importc: "self_powered".}: bool ## + ## !< This is a self-powered USB device. USB VBUS must be monitored. + vbus_monitor_io* {.importc: "vbus_monitor_io".}: cint + ## !< GPIO for VBUS monitoring. Ignored if not self_powered. + + + +proc tinyusb_driver_install*(config: ptr tinyusb_config_t): esp_err_t {.cdecl, + importc: "tinyusb_driver_install", header: "tinyusb.h".} + ## + ## + ## @brief This is an all-in-one helper function, including: + ## 1. USB device driver initialization + ## 2. Descriptors preparation + ## 3. TinyUSB stack initialization + ## 4. Creates and start a task to handle usb events + ## + ## @note Don't change Custom descriptor, but if it has to be done, + ## Suggest to define as follows in order to match the Interface Association Descriptor (IAD): + ## bDeviceClass = TUSB_CLASS_MISC, + ## bDeviceSubClass = MISC_SUBCLASS_COMMON, + ## + ## @param config tinyusb stack specific configuration + ## @retval ESP_ERR_INVALID_ARG Install driver and tinyusb stack failed because of invalid argument + ## @retval ESP_FAIL Install driver and tinyusb stack failed because of internal error + ## @retval ESP_OK Install driver and tinyusb stack successfully + ## +## TODO esp_err_t tinyusb_driver_uninstall(void); (IDF-1474) diff --git a/src/nesper/components/esp_tinyusb/tinyusb_types.nim b/src/nesper/components/esp_tinyusb/tinyusb_types.nim new file mode 100644 index 00000000..bb6c956a --- /dev/null +++ b/src/nesper/components/esp_tinyusb/tinyusb_types.nim @@ -0,0 +1,16 @@ + +const + USB_ESPRESSIF_VID* = 0x303A ## + ## SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + ## + ## SPDX-License-Identifier: Apache-2.0 + ## + USB_STRING_DESCRIPTOR_ARRAY_SIZE* = 8 + +type + + tinyusb_usbdev_t* {.size: sizeof(cint).} = enum + TINYUSB_USBDEV_0 + + tusb_desc_strarray_device_t* = array[USB_STRING_DESCRIPTOR_ARRAY_SIZE, cstring] + diff --git a/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim b/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim new file mode 100644 index 00000000..d7ca02ef --- /dev/null +++ b/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim @@ -0,0 +1,211 @@ +## +## SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD +## +## SPDX-License-Identifier: Apache-2.0 +## + +type + + tinyusb_cdcacm_itf_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief CDC ports available to setup + ## + TINYUSB_CDC_ACM_0 = 0x0, TINYUSB_CDC_ACM_1, TINYUSB_CDC_ACM_MAX + + +type + + cdcacm_event_rx_wanted_char_data_t* {.importc: "cdcacm_event_rx_wanted_char_data_t", + header: "tusb_cdc_acm.h", bycopy.} = object ## + ## Callbacks and events + ## ******************************************************************** + ## + ## @brief Data provided to the input of the `callback_rx_wanted_char` callback + ## + wanted_char* {.importc: "wanted_char".}: char + ## !< Wanted character + + + cdcacm_event_line_state_changed_data_t* {. + importc: "cdcacm_event_line_state_changed_data_t", + header: "tusb_cdc_acm.h", bycopy.} = object ## + ## + ## @brief Data provided to the input of the `callback_line_state_changed` callback + ## + dtr* {.importc: "dtr".}: bool ## !< Data Terminal Ready (DTR) line state + rts* {.importc: "rts".}: bool + ## !< Request To Send (RTS) line state + + + cdcacm_event_line_coding_changed_data_t* {. + importc: "cdcacm_event_line_coding_changed_data_t", + header: "tusb_cdc_acm.h", bycopy.} = object ## + ## + ## @brief Data provided to the input of the `line_coding_changed` callback + ## + p_line_coding* {.importc: "p_line_coding".}: ptr cdc_line_coding_t + ## !< New line coding value + + + cdcacm_event_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Types of CDC ACM events + ## + CDC_EVENT_RX, CDC_EVENT_RX_WANTED_CHAR, CDC_EVENT_LINE_STATE_CHANGED, + CDC_EVENT_LINE_CODING_CHANGED + + +type + + cdcacm_event_t* {.importc: "cdcacm_event_t", header: "tusb_cdc_acm.h", bycopy.} = object ## + ## + ## @brief Describes an event passing to the input of a callbacks + ## + `type`* {.importc: "type".}: cdcacm_event_type_t ## + ## !< Event type + rx_wanted_char_data* {.importc: "rx_wanted_char_data".}: cdcacm_event_rx_wanted_char_data_t ## + ## !< Data input of the `callback_rx_wanted_char` callback + line_state_changed_data* {.importc: "line_state_changed_data".}: cdcacm_event_line_state_changed_data_t ## + ## !< Data input of the `callback_line_state_changed` callback + line_coding_changed_data* {.importc: "line_coding_changed_data".}: cdcacm_event_line_coding_changed_data_t + ## !< Data input of the `line_coding_changed` callback + + + tusb_cdcacm_callback_t* = proc (itf: cint; event: ptr cdcacm_event_t) {.cdecl.} ## + ## + ## @brief CDC-ACM callback type + ## + + tinyusb_config_cdcacm_t* {.importc: "tinyusb_config_cdcacm_t", + header: "tusb_cdc_acm.h", bycopy.} = object ## + ## ********************************************************************* Callbacks and events + ## Other structs + ## ******************************************************************** + ## + ## @brief Configuration structure for CDC-ACM + ## + usb_dev* {.importc: "usb_dev".}: tinyusb_usbdev_t ## + ## !< Usb device to set up + cdc_port* {.importc: "cdc_port".}: tinyusb_cdcacm_itf_t ## + ## !< CDC port + rx_unread_buf_sz* {.importc: "rx_unread_buf_sz".}: csize_t ## + ## !< Amount of data that can be passed to the ACM at once + callback_rx* {.importc: "callback_rx".}: tusb_cdcacm_callback_t ## + ## !< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback + callback_rx_wanted_char* {.importc: "callback_rx_wanted_char".}: tusb_cdcacm_callback_t ## + ## !< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback + callback_line_state_changed* {.importc: "callback_line_state_changed".}: tusb_cdcacm_callback_t ## + ## !< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback + callback_line_coding_changed* {.importc: "callback_line_coding_changed".}: tusb_cdcacm_callback_t + ## !< Pointer to the function with the `tusb_cdcacm_callback_t` type that will be handled as a callback + + + +proc tusb_cdc_acm_init*(cfg: ptr tinyusb_config_cdcacm_t): esp_err_t {.cdecl, + importc: "tusb_cdc_acm_init", header: "tusb_cdc_acm.h".} + ## + ## ********************************************************************* Other structs + ## Public functions + ## ******************************************************************** + ## + ## @brief Initialize CDC ACM. Initialization will be finished with + ## the `tud_cdc_line_state_cb` callback + ## + ## @param cfg - init configuration structure + ## @return esp_err_t + ## + +proc tinyusb_cdcacm_register_callback*(itf: tinyusb_cdcacm_itf_t; + event_type: cdcacm_event_type_t; + callback: tusb_cdcacm_callback_t): esp_err_t {. + cdecl, importc: "tinyusb_cdcacm_register_callback", header: "tusb_cdc_acm.h".} + ## + ## + ## @brief Register a callback invoking on CDC event. If the callback had been + ## already registered, it will be overwritten + ## + ## @param itf - number of a CDC object + ## @param event_type - type of registered event for a callback + ## @param callback - callback function + ## @return esp_err_t - ESP_OK or ESP_ERR_INVALID_ARG + ## + +proc tinyusb_cdcacm_unregister_callback*(itf: tinyusb_cdcacm_itf_t; + event_type: cdcacm_event_type_t): esp_err_t {.cdecl, + importc: "tinyusb_cdcacm_unregister_callback", header: "tusb_cdc_acm.h".} + ## + ## + ## @brief Unregister a callback invoking on CDC event. + ## + ## @param itf - number of a CDC object + ## @param event_type - type of registered event for a callback + ## @return esp_err_t - ESP_OK or ESP_ERR_INVALID_ARG + ## + +proc tinyusb_cdcacm_write_queue_char*(itf: tinyusb_cdcacm_itf_t; ch: char): csize_t {. + cdecl, importc: "tinyusb_cdcacm_write_queue_char", header: "tusb_cdc_acm.h".} + ## + ## + ## @brief Sent one character to a write buffer + ## + ## @param itf - number of a CDC object + ## @param ch - character to send + ## @return size_t - amount of queued bytes + ## + +proc tinyusb_cdcacm_write_queue*(itf: tinyusb_cdcacm_itf_t; in_buf: ptr uint8; + in_size: csize_t): csize_t {.cdecl, + importc: "tinyusb_cdcacm_write_queue", header: "tusb_cdc_acm.h".} + ## + ## + ## @brief Write data to write buffer from a byte array + ## + ## @param itf - number of a CDC object + ## @param in_buf - a source array + ## @param in_size - size to write from arr_src + ## @return size_t - amount of queued bytes + ## + +proc tinyusb_cdcacm_write_flush*(itf: tinyusb_cdcacm_itf_t; + timeout_ticks: uint32): esp_err_t {.cdecl, + importc: "tinyusb_cdcacm_write_flush", header: "tusb_cdc_acm.h".} + ## + ## + ## @brief Send all data from a write buffer. Use `tinyusb_cdcacm_write_queue` to add data to the buffer. + ## + ## WARNING! TinyUSB can block output Endpoint for several RX callbacks, after will do additional flush + ## after the each trasfer. That can leads to the situation when you requested a flush, but it will fail until + ## ont of the next callbacks ends. + ## SO USING OF THE FLUSH WITH TIMEOUTS IN CALLBACKS IS NOT RECOMENDED - YOU CAN GET A LOCK FOR THE TIMEOUT + ## + ## @param itf - number of a CDC object + ## @param timeout_ticks - waiting until flush will be considered as failed + ## @return esp_err_t - ESP_OK if (timeout_ticks > 0) and and flush was successful, + ## ESP_ERR_TIMEOUT if timeout occurred3 or flush was successful with (timeout_ticks == 0) + ## ESP_FAIL if flush was unsuccessful + ## + +proc tinyusb_cdcacm_read*(itf: tinyusb_cdcacm_itf_t; out_buf: ptr uint8; + out_buf_sz: csize_t; rx_data_size: ptr csize_t): esp_err_t {. + cdecl, importc: "tinyusb_cdcacm_read", header: "tusb_cdc_acm.h".} + ## + ## + ## @brief Read a content to the array, and defines it's size to the sz_store + ## + ## @param itf - number of a CDC object + ## @param out_buf - to this array will be stored the object from a CDC buffer + ## @param out_buf_sz - size of buffer for results + ## @param rx_data_size - to this address will be stored the object's size + ## @return esp_err_t ESP_OK, ESP_FAIL or ESP_ERR_INVALID_STATE + ## + +proc tusb_cdc_acm_initialized*(itf: tinyusb_cdcacm_itf_t): bool {.cdecl, + importc: "tusb_cdc_acm_initialized", header: "tusb_cdc_acm.h".} + ## + ## + ## @brief Check if the ACM initialized + ## + ## @param itf - number of a CDC object + ## @return true or false + ## +## ********************************************************************* Public functions diff --git a/src/nesper/components/esp_tinyusb/tusb_config.nim b/src/nesper/components/esp_tinyusb/tusb_config.nim new file mode 100644 index 00000000..d3d1ca32 --- /dev/null +++ b/src/nesper/components/esp_tinyusb/tusb_config.nim @@ -0,0 +1,81 @@ +## +## The MIT License (MIT) +## +## Copyright (c) 2019 Ha Thach (tinyusb.org), +## Additions Copyright (c) 2020, Espressif Systems (Shanghai) PTE LTD +## +## 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. +## +## + +when not defined(CONFIG_TINYUSB_CDC_ENABLED): + const + CONFIG_TINYUSB_CDC_ENABLED* = 0 +when not defined(CONFIG_TINYUSB_CDC_COUNT): + const + CONFIG_TINYUSB_CDC_COUNT* = 0 +when not defined(CONFIG_TINYUSB_MSC_ENABLED): + const + CONFIG_TINYUSB_MSC_ENABLED* = 0 +when not defined(CONFIG_TINYUSB_HID_COUNT): + const + CONFIG_TINYUSB_HID_COUNT* = 0 +when not defined(CONFIG_TINYUSB_MIDI_COUNT): + const + CONFIG_TINYUSB_MIDI_COUNT* = 0 +when not defined(CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED): + const + CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED* = 0 +when not defined(CONFIG_TINYUSB_DEBUG_LEVEL): + const + CONFIG_TINYUSB_DEBUG_LEVEL* = 0 +const + CFG_TUSB_RHPORT0_MODE* = OPT_MODE_DEVICE or OPT_MODE_FULL_SPEED + CFG_TUSB_OS* = OPT_OS_FREERTOS + +## USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. +## Tinyusb use follows macros to declare transferring memory so that they can be put +## into those specific section. +## e.g +## - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) +## - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) +## + +when not defined(CFG_TUSB_MEM_ALIGN): + const + CFG_TUSB_MEM_ALIGN* = TU_ATTR_ALIGNED(4) +when not defined(CFG_TUD_ENDPOINT0_SIZE): + const + CFG_TUD_ENDPOINT0_SIZE* = 64 +const + CFG_TUSB_DEBUG* = CONFIG_TINYUSB_DEBUG_LEVEL ## Debug Level + CFG_TUD_CDC_RX_BUFSIZE* = CONFIG_TINYUSB_CDC_RX_BUFSIZE ## + ## CDC FIFO size of TX and RX + CFG_TUD_CDC_TX_BUFSIZE* = CONFIG_TINYUSB_CDC_TX_BUFSIZE + CFG_TUD_MSC_BUFSIZE* = CONFIG_TINYUSB_MSC_BUFSIZE ## + ## MSC Buffer size of Device Mass storage + CFG_TUD_MIDI_EP_BUFSIZE* = 64 + CFG_TUD_MIDI_EPSIZE* = CFG_TUD_MIDI_EP_BUFSIZE + CFG_TUD_MIDI_RX_BUFSIZE* = 64 + CFG_TUD_MIDI_TX_BUFSIZE* = 64 + CFG_TUD_CDC* = CONFIG_TINYUSB_CDC_COUNT ## Enabled device class driver + CFG_TUD_MSC* = CONFIG_TINYUSB_MSC_ENABLED + CFG_TUD_HID* = CONFIG_TINYUSB_HID_COUNT + CFG_TUD_MIDI* = CONFIG_TINYUSB_MIDI_COUNT + CFG_TUD_CUSTOM_CLASS* = CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED diff --git a/src/nesper/components/esp_tinyusb/tusb_tasks.nim b/src/nesper/components/esp_tinyusb/tusb_tasks.nim new file mode 100644 index 00000000..5511d164 --- /dev/null +++ b/src/nesper/components/esp_tinyusb/tusb_tasks.nim @@ -0,0 +1,31 @@ +## +## SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD +## +## SPDX-License-Identifier: Apache-2.0 +## + + +proc tusb_run_task*(): esp_err_t {.cdecl, importc: "tusb_run_task", + header: "tusb_tasks.h".} + ## + ## + ## @brief This helper function creates and starts a task which wraps `tud_task()`. + ## + ## The wrapper function basically wraps tud_task and some log. + ## Default parameters: stack size and priority as configured, argument = NULL, not pinned to any core. + ## If you have more requirements for this task, you can create your own task which calls tud_task as the last step. + ## + ## @retval ESP_OK run tinyusb main task successfully + ## @retval ESP_FAIL run tinyusb main task failed of internal error + ## @retval ESP_ERR_INVALID_STATE tinyusb main task has been created before + ## + +proc tusb_stop_task*(): esp_err_t {.cdecl, importc: "tusb_stop_task", + header: "tusb_tasks.h".} + ## + ## + ## @brief This helper function stops and destroys the task created by `tusb_run_task()` + ## + ## @retval ESP_OK stop and destory tinyusb main task successfully + ## @retval ESP_ERR_INVALID_STATE tinyusb main task hasn't been created yet + ## \ No newline at end of file diff --git a/src/nesper/components/esp_tinyusb/vfs_tinyusb.nim b/src/nesper/components/esp_tinyusb/vfs_tinyusb.nim new file mode 100644 index 00000000..46e7822f --- /dev/null +++ b/src/nesper/components/esp_tinyusb/vfs_tinyusb.nim @@ -0,0 +1,29 @@ +const + VFS_TUSB_MAX_PATH* = 16 ## + ## SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + ## + ## SPDX-License-Identifier: Apache-2.0 + ## + VFS_TUSB_PATH_DEFAULT* = "/dev/tusb_cdc" + + +proc esp_vfs_tusb_cdc_register*(cdc_intf: cint; path: cstring): esp_err_t {. + cdecl, importc: "esp_vfs_tusb_cdc_register", header: "vfs_tinyusb.h".} + ## + ## + ## @brief Register TinyUSB CDC at VFS with path + ## @param cdc_intf - interface number of TinyUSB's CDC + ## @param path - path where the CDC will be registered, `/dev/tusb_cdc` will be used if left NULL. + ## + ## @return esp_err_t ESP_OK or ESP_FAIL + ## + +proc esp_vfs_tusb_cdc_unregister*(path: cstring): esp_err_t {.cdecl, + importc: "esp_vfs_tusb_cdc_unregister", header: "vfs_tinyusb.h".} + ## + ## + ## @brief Unregister TinyUSB CDC from VFS + ## @param path - path where the CDC will be unregistered if NULL will be used `/dev/tusb_cdc` + ## + ## @return esp_err_t ESP_OK or ESP_FAIL + ## \ No newline at end of file From 57aca900166742ca4e7b211ce6d473b3be5ec3f3 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 23:13:04 -0600 Subject: [PATCH 017/142] usb --- .../components/esp_tinyusb/tinyusb_types.nim | 13 +++++ .../components/esp_tinyusb/tusb_cdc_acm.nim | 3 ++ .../components/esp_tinyusb/tusb_config.nim | 51 ++++++++++--------- .../components/esp_tinyusb/tusb_tasks.nim | 1 + .../components/esp_tinyusb/vfs_tinyusb.nim | 2 + 5 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/nesper/components/esp_tinyusb/tinyusb_types.nim b/src/nesper/components/esp_tinyusb/tinyusb_types.nim index bb6c956a..56bce5b1 100644 --- a/src/nesper/components/esp_tinyusb/tinyusb_types.nim +++ b/src/nesper/components/esp_tinyusb/tinyusb_types.nim @@ -1,4 +1,6 @@ +const hdr_acm = "tusb_cdc_acm.h" + const USB_ESPRESSIF_VID* = 0x303A ## ## SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD @@ -14,3 +16,14 @@ type tusb_desc_strarray_device_t* = array[USB_STRING_DESCRIPTOR_ARRAY_SIZE, cstring] + +type + cdc_line_coding_t* {.importc: "cdc_line_coding_t", header: hdr_acm, bycopy.} = object + bit_rate*: uint32 + stop_bits*: uint8 + parity*: uint8 + data_bits*: uint8 + + cdc_line_control_state_t* {.importc: "cdc_line_control_state_t", header: hdr_acm, bycopy.} = object + dtr*: bool + rts*: bool diff --git a/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim b/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim index d7ca02ef..96eea182 100644 --- a/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim +++ b/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim @@ -4,6 +4,9 @@ ## SPDX-License-Identifier: Apache-2.0 ## +import ../../consts +import ./tinyusb_types + type tinyusb_cdcacm_itf_t* {.size: sizeof(cint).} = enum ## diff --git a/src/nesper/components/esp_tinyusb/tusb_config.nim b/src/nesper/components/esp_tinyusb/tusb_config.nim index d3d1ca32..47093014 100644 --- a/src/nesper/components/esp_tinyusb/tusb_config.nim +++ b/src/nesper/components/esp_tinyusb/tusb_config.nim @@ -24,30 +24,33 @@ ## ## -when not defined(CONFIG_TINYUSB_CDC_ENABLED): - const - CONFIG_TINYUSB_CDC_ENABLED* = 0 -when not defined(CONFIG_TINYUSB_CDC_COUNT): - const - CONFIG_TINYUSB_CDC_COUNT* = 0 -when not defined(CONFIG_TINYUSB_MSC_ENABLED): - const - CONFIG_TINYUSB_MSC_ENABLED* = 0 -when not defined(CONFIG_TINYUSB_HID_COUNT): - const - CONFIG_TINYUSB_HID_COUNT* = 0 -when not defined(CONFIG_TINYUSB_MIDI_COUNT): - const - CONFIG_TINYUSB_MIDI_COUNT* = 0 -when not defined(CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED): - const - CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED* = 0 -when not defined(CONFIG_TINYUSB_DEBUG_LEVEL): - const - CONFIG_TINYUSB_DEBUG_LEVEL* = 0 -const - CFG_TUSB_RHPORT0_MODE* = OPT_MODE_DEVICE or OPT_MODE_FULL_SPEED - CFG_TUSB_OS* = OPT_OS_FREERTOS +import ../../consts + +# when not defined(CONFIG_TINYUSB_CDC_ENABLED): +# const +# CONFIG_TINYUSB_CDC_ENABLED* = 0 +# when not defined(CONFIG_TINYUSB_CDC_COUNT): +# const +# CONFIG_TINYUSB_CDC_COUNT* = 0 +# when not defined(CONFIG_TINYUSB_MSC_ENABLED): +# const +# CONFIG_TINYUSB_MSC_ENABLED* = 0 +# when not defined(CONFIG_TINYUSB_HID_COUNT): +# const +# CONFIG_TINYUSB_HID_COUNT* = 0 +# when not defined(CONFIG_TINYUSB_MIDI_COUNT): +# const +# CONFIG_TINYUSB_MIDI_COUNT* = 0 +# when not defined(CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED): +# const +# CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED* = 0 +# when not defined(CONFIG_TINYUSB_DEBUG_LEVEL): +# const +# CONFIG_TINYUSB_DEBUG_LEVEL* = 0 + +# const +# CFG_TUSB_RHPORT0_MODE* = OPT_MODE_DEVICE or OPT_MODE_FULL_SPEED +# CFG_TUSB_OS* = OPT_OS_FREERTOS ## USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. ## Tinyusb use follows macros to declare transferring memory so that they can be put diff --git a/src/nesper/components/esp_tinyusb/tusb_tasks.nim b/src/nesper/components/esp_tinyusb/tusb_tasks.nim index 5511d164..62e48f3c 100644 --- a/src/nesper/components/esp_tinyusb/tusb_tasks.nim +++ b/src/nesper/components/esp_tinyusb/tusb_tasks.nim @@ -4,6 +4,7 @@ ## SPDX-License-Identifier: Apache-2.0 ## +import ../../consts proc tusb_run_task*(): esp_err_t {.cdecl, importc: "tusb_run_task", header: "tusb_tasks.h".} diff --git a/src/nesper/components/esp_tinyusb/vfs_tinyusb.nim b/src/nesper/components/esp_tinyusb/vfs_tinyusb.nim index 46e7822f..06f204ea 100644 --- a/src/nesper/components/esp_tinyusb/vfs_tinyusb.nim +++ b/src/nesper/components/esp_tinyusb/vfs_tinyusb.nim @@ -1,3 +1,5 @@ +import ../../consts + const VFS_TUSB_MAX_PATH* = 16 ## ## SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD From b2266cf8762d8b29229e5e22cda8a145f6875aa6 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 23:19:16 -0600 Subject: [PATCH 018/142] usb --- .../components/esp_tinyusb/tinyusb_types.nim | 13 - .../components/esp_tinyusb/tusb_cdc_acm.nim | 1 + .../components/esp_tinyusb/tusb_types.nim | 537 ++++++++++++++++++ 3 files changed, 538 insertions(+), 13 deletions(-) create mode 100644 src/nesper/components/esp_tinyusb/tusb_types.nim diff --git a/src/nesper/components/esp_tinyusb/tinyusb_types.nim b/src/nesper/components/esp_tinyusb/tinyusb_types.nim index 56bce5b1..bb6c956a 100644 --- a/src/nesper/components/esp_tinyusb/tinyusb_types.nim +++ b/src/nesper/components/esp_tinyusb/tinyusb_types.nim @@ -1,6 +1,4 @@ -const hdr_acm = "tusb_cdc_acm.h" - const USB_ESPRESSIF_VID* = 0x303A ## ## SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD @@ -16,14 +14,3 @@ type tusb_desc_strarray_device_t* = array[USB_STRING_DESCRIPTOR_ARRAY_SIZE, cstring] - -type - cdc_line_coding_t* {.importc: "cdc_line_coding_t", header: hdr_acm, bycopy.} = object - bit_rate*: uint32 - stop_bits*: uint8 - parity*: uint8 - data_bits*: uint8 - - cdc_line_control_state_t* {.importc: "cdc_line_control_state_t", header: hdr_acm, bycopy.} = object - dtr*: bool - rts*: bool diff --git a/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim b/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim index 96eea182..9f48173a 100644 --- a/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim +++ b/src/nesper/components/esp_tinyusb/tusb_cdc_acm.nim @@ -6,6 +6,7 @@ import ../../consts import ./tinyusb_types +import ./tusb_types type diff --git a/src/nesper/components/esp_tinyusb/tusb_types.nim b/src/nesper/components/esp_tinyusb/tusb_types.nim new file mode 100644 index 00000000..70d579ca --- /dev/null +++ b/src/nesper/components/esp_tinyusb/tusb_types.nim @@ -0,0 +1,537 @@ +## +## The MIT License (MIT) +## +## Copyright (c) 2019 Ha Thach (tinyusb.org) +## +## 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. +## +## This file is part of the TinyUSB stack. +## + +## ------------- Device DCache declaration -------------// + +## Declare an endpoint buffer with uint8_t[size] + +## Declare an endpoint buffer with a type + +## ------------- Host DCache declaration -------------// + +## Declare an endpoint buffer with uint8_t[size] + +## Declare an endpoint buffer with a type + +const hdr_acm = "tusb_cdc_acm.h" + +type + cdc_line_coding_t* {.importc: "cdc_line_coding_t", header: hdr_acm, bycopy.} = object + bit_rate*: uint32 + stop_bits*: uint8 + parity*: uint8 + data_bits*: uint8 + + cdc_line_control_state_t* {.importc: "cdc_line_control_state_t", header: hdr_acm, bycopy.} = object + dtr*: bool + rts*: bool + + +type + + tusb_role_t* {.size: sizeof(cint).} = enum ## ------------------------------------------------------------------ + ## CONSTANTS + ## ------------------------------------------------------------------ + TUSB_ROLE_INVALID = 0, TUSB_ROLE_DEVICE = 0x1, TUSB_ROLE_HOST = 0x2 + + +type + + tusb_speed_t* {.size: sizeof(cint).} = enum ## defined base on EHCI specs value for Endpoint Speed + TUSB_SPEED_FULL = 0, TUSB_SPEED_LOW = 1, TUSB_SPEED_HIGH = 2, + TUSB_SPEED_AUTO = 0xaa, TUSB_SPEED_INVALID = 0xff + + +type + + tusb_xfer_type_t* {.size: sizeof(cint).} = enum ## + ## defined base on USB Specs Endpoint's bmAttributes + TUSB_XFER_CONTROL = 0, TUSB_XFER_ISOCHRONOUS = 1, TUSB_XFER_BULK = 2, + TUSB_XFER_INTERRUPT = 3 + + tusb_dir_t* {.size: sizeof(cint).} = enum + TUSB_DIR_OUT = 0, TUSB_DIR_IN = 1, TUSB_DIR_IN_MASK = 0x80 + +const + TUSB_EPSIZE_BULK_FS* = 64 + TUSB_EPSIZE_BULK_HS* = 512 + TUSB_EPSIZE_ISO_FS_MAX* = 1023 + TUSB_EPSIZE_ISO_HS_MAX* = 1024 + +type + + tusb_iso_ep_attribute_t* {.size: sizeof(cint).} = enum ## + ## Isochronous Endpoint Attributes + TUSB_ISO_EP_ATT_NO_SYNC = 0x00, TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04, + TUSB_ISO_EP_ATT_ADAPTIVE = 0x08, TUSB_ISO_EP_ATT_SYNCHRONOUS = 0x0C, TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ## + ## < Feedback End Point + TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20 ## < Data endpoint that also serves as an implicit feedback + +const + TUSB_ISO_EP_ATT_DATA = TUSB_ISO_EP_ATT_NO_SYNC + +type + + tusb_desc_type_t* {.size: sizeof(cint).} = enum ## + ## USB Descriptor Types + TUSB_DESC_DEVICE = 0x01, TUSB_DESC_CONFIGURATION = 0x02, + TUSB_DESC_STRING = 0x03, TUSB_DESC_INTERFACE = 0x04, + TUSB_DESC_ENDPOINT = 0x05, TUSB_DESC_DEVICE_QUALIFIER = 0x06, + TUSB_DESC_OTHER_SPEED_CONFIG = 0x07, TUSB_DESC_INTERFACE_POWER = 0x08, + TUSB_DESC_OTG = 0x09, TUSB_DESC_DEBUG = 0x0A, + TUSB_DESC_INTERFACE_ASSOCIATION = 0x0B, TUSB_DESC_BOS = 0x0F, + TUSB_DESC_DEVICE_CAPABILITY = 0x10, TUSB_DESC_FUNCTIONAL = 0x21, ## + ## Class Specific Descriptor + TUSB_DESC_CS_CONFIGURATION = 0x22, TUSB_DESC_CS_STRING = 0x23, + TUSB_DESC_CS_INTERFACE = 0x24, TUSB_DESC_CS_ENDPOINT = 0x25, + TUSB_DESC_SUPERSPEED_ENDPOINT_COMPANION = 0x30, + TUSB_DESC_SUPERSPEED_ISO_ENDPOINT_COMPANION = 0x31 + + tusb_request_code_t* {.size: sizeof(cint).} = enum + TUSB_REQ_GET_STATUS = 0, TUSB_REQ_CLEAR_FEATURE = 1, TUSB_REQ_RESERVED = 2, + TUSB_REQ_SET_FEATURE = 3, TUSB_REQ_RESERVED2 = 4, TUSB_REQ_SET_ADDRESS = 5, + TUSB_REQ_GET_DESCRIPTOR = 6, TUSB_REQ_SET_DESCRIPTOR = 7, + TUSB_REQ_GET_CONFIGURATION = 8, TUSB_REQ_SET_CONFIGURATION = 9, + TUSB_REQ_GET_INTERFACE = 10, TUSB_REQ_SET_INTERFACE = 11, + TUSB_REQ_SYNCH_FRAME = 12 + + tusb_request_feature_selector_t* {.size: sizeof(cint).} = enum + TUSB_REQ_FEATURE_EDPT_HALT = 0, TUSB_REQ_FEATURE_REMOTE_WAKEUP = 1, + TUSB_REQ_FEATURE_TEST_MODE = 2 + + tusb_request_type_t* {.size: sizeof(cint).} = enum + TUSB_REQ_TYPE_STANDARD = 0, TUSB_REQ_TYPE_CLASS, TUSB_REQ_TYPE_VENDOR, + TUSB_REQ_TYPE_INVALID + + tusb_request_recipient_t* {.size: sizeof(cint).} = enum + TUSB_REQ_RCPT_DEVICE = 0, TUSB_REQ_RCPT_INTERFACE, TUSB_REQ_RCPT_ENDPOINT, + TUSB_REQ_RCPT_OTHER + +const + TUSB_DESC_CS_DEVICE = TUSB_DESC_FUNCTIONAL + +type + + tusb_class_code_t* {.size: sizeof(cint).} = enum ## + ## https://www.usb.org/defined-class-codes + TUSB_CLASS_UNSPECIFIED = 0, TUSB_CLASS_AUDIO = 1, TUSB_CLASS_CDC = 2, + TUSB_CLASS_HID = 3, TUSB_CLASS_RESERVED_4 = 4, TUSB_CLASS_PHYSICAL = 5, + TUSB_CLASS_IMAGE = 6, TUSB_CLASS_PRINTER = 7, TUSB_CLASS_MSC = 8, + TUSB_CLASS_HUB = 9, TUSB_CLASS_CDC_DATA = 10, TUSB_CLASS_SMART_CARD = 11, + TUSB_CLASS_RESERVED_12 = 12, TUSB_CLASS_CONTENT_SECURITY = 13, + TUSB_CLASS_VIDEO = 14, TUSB_CLASS_PERSONAL_HEALTHCARE = 15, + TUSB_CLASS_AUDIO_VIDEO = 16, TUSB_CLASS_DIAGNOSTIC = 0xDC, + TUSB_CLASS_WIRELESS_CONTROLLER = 0xE0, TUSB_CLASS_MISC = 0xEF, + TUSB_CLASS_APPLICATION_SPECIFIC = 0xFE, TUSB_CLASS_VENDOR_SPECIFIC = 0xFF + + misc_subclass_type_t* {.size: sizeof(cint).} = enum + MISC_SUBCLASS_COMMON = 2 + + misc_protocol_type_t* {.size: sizeof(cint).} = enum + MISC_PROTOCOL_IAD = 1 + + app_subclass_type_t* {.size: sizeof(cint).} = enum + APP_SUBCLASS_DFU_RUNTIME = 0x01, APP_SUBCLASS_USBTMC = 0x03 + + device_capability_type_t* {.size: sizeof(cint).} = enum + DEVICE_CAPABILITY_WIRELESS_USB = 0x01, + DEVICE_CAPABILITY_USB20_EXTENSION = 0x02, + DEVICE_CAPABILITY_SUPERSPEED_USB = 0x03, + DEVICE_CAPABILITY_CONTAINER_id = 0x04, DEVICE_CAPABILITY_PLATFORM = 0x05, + DEVICE_CAPABILITY_POWER_DELIVERY = 0x06, + DEVICE_CAPABILITY_BATTERY_INFO = 0x07, + DEVICE_CAPABILITY_PD_CONSUMER_PORT = 0x08, + DEVICE_CAPABILITY_PD_PROVIDER_PORT = 0x09, + DEVICE_CAPABILITY_SUPERSPEED_PLUS = 0x0A, + DEVICE_CAPABILITY_PRECESION_TIME_MEASUREMENT = 0x0B, + DEVICE_CAPABILITY_WIRELESS_USB_EXT = 0x0C, + DEVICE_CAPABILITY_BILLBOARD = 0x0D, DEVICE_CAPABILITY_AUTHENTICATION = 0x0E, + DEVICE_CAPABILITY_BILLBOARD_EX = 0x0F, + DEVICE_CAPABILITY_CONFIGURATION_SUMMARY = 0x10 + +const + TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP* = 1'u shl 5 + TUSB_DESC_CONFIG_ATT_SELF_POWERED* = 1'u shl 6 + +type + + tusb_feature_test_mode_t* {.size: sizeof(cint).} = enum ## + ## USB 2.0 Spec Table 9-7: Test Mode Selectors + TUSB_FEATURE_TEST_J = 1, TUSB_FEATURE_TEST_K = 2, + TUSB_FEATURE_TEST_SE0_NAK = 3, TUSB_FEATURE_TEST_PACKET = 4, + TUSB_FEATURE_TEST_FORCE_ENABLE = 5 + + +type + + xfer_result_t* {.size: sizeof(cint).} = enum ## --------------------------------------------------------------------+ + ## + ## --------------------------------------------------------------------+ + XFER_RESULT_SUCCESS = 0, XFER_RESULT_FAILED, XFER_RESULT_STALLED, + XFER_RESULT_TIMEOUT, XFER_RESULT_INVALID + +const + DESC_OFFSET_LEN* = 0 ## TODO remove + DESC_OFFSET_TYPE* = 1 + DESC_OFFSET_SUBTYPE* = 2 + INTERFACE_INVALID_NUMBER* = 0xff + +type + + microsoft_os_20_type_t* {.size: sizeof(cint).} = enum + MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00, + MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x01, + MS_OS_20_SUBSET_HEADER_FUNCTION = 0x02, + MS_OS_20_FEATURE_COMPATBLE_ID = 0x03, MS_OS_20_FEATURE_REG_PROPERTY = 0x04, + MS_OS_20_FEATURE_MIN_RESUME_TIME = 0x05, MS_OS_20_FEATURE_MODEL_ID = 0x06, + MS_OS_20_FEATURE_CCGP_DEVICE = 0x07, MS_OS_20_FEATURE_VENDOR_REVISION = 0x08 + +const + CONTROL_STAGE_IDLE* = 0 + CONTROL_STAGE_SETUP* = 1 ## 1 + CONTROL_STAGE_DATA* = 2 ## 2 + CONTROL_STAGE_ACK* = 3 ## 3 + TUSB_INDEX_INVALID_8* = 0xFF + +type + + tusb_rhport_init_t* {.importc: "tusb_rhport_init_t", header: "tusb_types.h", + bycopy.} = object ## --------------------------------------------------------------------+ + ## + ## --------------------------------------------------------------------+ + role* {.importc: "role".}: tusb_role_t + speed* {.importc: "speed".}: tusb_speed_t + + + tusb_desc_device_t* {.importc: "tusb_desc_device_t", header: "tusb_types.h", + bycopy.} = object ## --------------------------------------------------------------------+ + ## USB Descriptors + ## --------------------------------------------------------------------+ + ## Start of all packed definitions for compiler without per-type packed + ## USB Device Descriptor + bLength* {.importc: "bLength".}: uint8 ## < Size of this descriptor in bytes. + bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## + ## < DEVICE Descriptor Type. + bcdUSB* {.importc: "bcdUSB".}: uint16 ## < BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). + bDeviceClass* {.importc: "bDeviceClass".}: uint8 ## + ## < Class code (assigned by the USB-IF). + bDeviceSubClass* {.importc: "bDeviceSubClass".}: uint8 ## + ## < Subclass code (assigned by the USB-IF). + bDeviceProtocol* {.importc: "bDeviceProtocol".}: uint8 ## + ## < Protocol code (assigned by the USB-IF). + bMaxPacketSize0* {.importc: "bMaxPacketSize0".}: uint8 ## + ## < Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64. + idVendor* {.importc: "idVendor".}: uint16 ## < Vendor ID (assigned by the USB-IF). + idProduct* {.importc: "idProduct".}: uint16 ## < Product ID (assigned by the manufacturer). + bcdDevice* {.importc: "bcdDevice".}: uint16 ## < Device release number in binary-coded decimal. + iManufacturer* {.importc: "iManufacturer".}: uint8 ## + ## < Index of string descriptor describing manufacturer. + iProduct* {.importc: "iProduct".}: uint8 ## < Index of string descriptor describing product. + iSerialNumber* {.importc: "iSerialNumber".}: uint8 ## + ## < Index of string descriptor describing the device's serial number. + bNumConfigurations* {.importc: "bNumConfigurations".}: uint8 + ## < Number of possible configurations. + + +type + + tusb_desc_bos_t* {.importc: "tusb_desc_bos_t", header: "tusb_types.h", bycopy.} = object ## + ## USB Binary Device Object Store (BOS) Descriptor + bLength* {.importc: "bLength".}: uint8 ## < Size of this descriptor in bytes + bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## + ## < CONFIGURATION Descriptor Type + wTotalLength* {.importc: "wTotalLength".}: uint16 ## + ## < Total length of data returned for this descriptor + bNumDeviceCaps* {.importc: "bNumDeviceCaps".}: uint8 + ## < Number of device capability descriptors in the BOS + + +type + + tusb_desc_configuration_t* {.importc: "tusb_desc_configuration_t", + header: "tusb_types.h", bycopy.} = object ## + ## USB Configuration Descriptor + bLength* {.importc: "bLength".}: uint8 ## < Size of this descriptor in bytes + bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## + ## < CONFIGURATION Descriptor Type + wTotalLength* {.importc: "wTotalLength".}: uint16 ## + ## < Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration. + bNumInterfaces* {.importc: "bNumInterfaces".}: uint8 ## + ## < Number of interfaces supported by this configuration + bConfigurationValue* {.importc: "bConfigurationValue".}: uint8 ## + ## < Value to use as an argument to the SetConfiguration() request to select this configuration. + iConfiguration* {.importc: "iConfiguration".}: uint8 ## + ## < Index of string descriptor describing this configuration + bmAttributes* {.importc: "bmAttributes".}: uint8 ## + ## < Configuration characteristics \n D7: Reserved (set to one)\n D6: Self-powered \n D5: Remote Wakeup \n D4...0: Reserved (reset to zero) \n D7 is reserved and must be set to one for historical reasons. \n A device configuration that uses power from the bus and a local source reports a non-zero value in bMaxPower to indicate the amount of bus power required and sets D6. The actual power source at runtime may be determined using the GetStatus(DEVICE) request (see USB 2.0 spec Section 9.4.5). \n If a device configuration supports remote wakeup, D5 is set to one. + bMaxPower* {.importc: "bMaxPower".}: uint8 + ## < Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational. Expressed in 2 mA units (i.e., 50 = 100 mA). + + +type + + tusb_desc_interface_t* {.importc: "tusb_desc_interface_t", + header: "tusb_types.h", bycopy.} = object ## + ## USB Interface Descriptor + bLength* {.importc: "bLength".}: uint8 ## < Size of this descriptor in bytes + bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## + ## < INTERFACE Descriptor Type + bInterfaceNumber* {.importc: "bInterfaceNumber".}: uint8 ## + ## < Number of this interface. Zero-based value identifying the index in the array of concurrent interfaces supported by this configuration. + bAlternateSetting* {.importc: "bAlternateSetting".}: uint8 ## + ## < Value used to select this alternate setting for the interface identified in the prior field + bNumEndpoints* {.importc: "bNumEndpoints".}: uint8 ## + ## < Number of endpoints used by this interface (excluding endpoint zero). If this value is zero, this interface only uses the Default Control Pipe. + bInterfaceClass* {.importc: "bInterfaceClass".}: uint8 ## + ## < Class code (assigned by the USB-IF). \li A value of zero is reserved for future standardization. \li If this field is set to FFH, the interface class is vendor-specific. \li All other values are reserved for assignment by the USB-IF. + bInterfaceSubClass* {.importc: "bInterfaceSubClass".}: uint8 ## + ## < Subclass code (assigned by the USB-IF). \n These codes are qualified by the value of the bInterfaceClass field. \li If the bInterfaceClass field is reset to zero, this field must also be reset to zero. \li If the bInterfaceClass field is not set to FFH, all values are reserved for assignment by the USB-IF. + bInterfaceProtocol* {.importc: "bInterfaceProtocol".}: uint8 ## + ## < Protocol code (assigned by the USB). \n These codes are qualified by the value of the bInterfaceClass and the bInterfaceSubClass fields. If an interface supports class-specific requests, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use a class-specific protocol on this interface. \li If this field is set to FFH, the device uses a vendor-specific protocol for this interface. + iInterface* {.importc: "iInterface".}: uint8 + ## < Index of string descriptor describing this interface + + +type + + TU_ATTR_PACKED_tusb_types_1* {.importc: "tusb_desc_endpoint_t::no_name", + header: "tusb_types.h", bycopy.} = object ## + ## USB Endpoint Descriptor + xfer* {.importc: "xfer", bitsize: 2.}: uint8 ## Control, ISO, Bulk, Interrupt + sync* {.importc: "sync", bitsize: 2.}: uint8 ## None, Asynchronous, Adaptive, Synchronous + usage* {.importc: "usage", bitsize: 2.}: uint8 + ## Data, Feedback, Implicit feedback + + + tusb_desc_endpoint_t* {.importc: "tusb_desc_endpoint_t", + header: "tusb_types.h", bycopy.} = object + bLength* {.importc: "bLength".}: uint8 ## Size of this descriptor in bytes + bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## + ## ENDPOINT Descriptor Type + bEndpointAddress* {.importc: "bEndpointAddress".}: uint8 ## + ## The address of the endpoint + bmAttributes* {.importc: "bmAttributes".}: TU_ATTR_PACKED_tusb_types_1 + wMaxPacketSize* {.importc: "wMaxPacketSize".}: uint16 ## + ## Bit 10..0 : max packet size, bit 12..11 additional transaction per highspeed micro-frame + bInterval* {.importc: "bInterval".}: uint8 + ## Polling interval, in frames or microframes depending on the operating speed + + +type + + tusb_desc_other_speed_t* {.importc: "tusb_desc_other_speed_t", + header: "tusb_types.h", bycopy.} = object ## + ## USB Other Speed Configuration Descriptor + bLength* {.importc: "bLength".}: uint8 ## < Size of descriptor + bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## + ## < Other_speed_Configuration Type + wTotalLength* {.importc: "wTotalLength".}: uint16 ## + ## < Total length of data returned + bNumInterfaces* {.importc: "bNumInterfaces".}: uint8 ## + ## < Number of interfaces supported by this speed configuration + bConfigurationValue* {.importc: "bConfigurationValue".}: uint8 ## + ## < Value to use to select configuration + iConfiguration* {.importc: "iConfiguration".}: uint8 ## + ## < Index of string descriptor + bmAttributes* {.importc: "bmAttributes".}: uint8 ## + ## < Same as Configuration descriptor + bMaxPower* {.importc: "bMaxPower".}: uint8 + ## < Same as Configuration descriptor + + + tusb_desc_device_qualifier_t* {.importc: "tusb_desc_device_qualifier_t", + header: "tusb_types.h", bycopy.} = object ## + ## USB Device Qualifier Descriptor + bLength* {.importc: "bLength".}: uint8 ## < Size of descriptor + bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## + ## < Device Qualifier Type + bcdUSB* {.importc: "bcdUSB".}: uint16 ## < USB specification version number (e.g., 0200H for V2.00) + bDeviceClass* {.importc: "bDeviceClass".}: uint8 ## + ## < Class Code + bDeviceSubClass* {.importc: "bDeviceSubClass".}: uint8 ## + ## < SubClass Code + bDeviceProtocol* {.importc: "bDeviceProtocol".}: uint8 ## + ## < Protocol Code + bMaxPacketSize0* {.importc: "bMaxPacketSize0".}: uint8 ## + ## < Maximum packet size for other speed + bNumConfigurations* {.importc: "bNumConfigurations".}: uint8 ## + ## < Number of Other-speed Configurations + bReserved* {.importc: "bReserved".}: uint8 + ## < Reserved for future use, must be zero + + + +type + + tusb_desc_interface_assoc_t* {.importc: "tusb_desc_interface_assoc_t", + header: "tusb_types.h", bycopy.} = object ## + ## USB Interface Association Descriptor (IAD ECN) + bLength* {.importc: "bLength".}: uint8 ## < Size of descriptor + bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## + ## < Other_speed_Configuration Type + bFirstInterface* {.importc: "bFirstInterface".}: uint8 ## + ## < Index of the first associated interface. + bInterfaceCount* {.importc: "bInterfaceCount".}: uint8 ## + ## < Total number of associated interfaces. + bFunctionClass* {.importc: "bFunctionClass".}: uint8 ## + ## < Interface class ID. + bFunctionSubClass* {.importc: "bFunctionSubClass".}: uint8 ## + ## < Interface subclass ID. + bFunctionProtocol* {.importc: "bFunctionProtocol".}: uint8 ## + ## < Interface protocol ID. + iFunction* {.importc: "iFunction".}: uint8 + ## < Index of the string descriptor describing the interface association. + + +type + + tusb_desc_string_t* {.importc: "tusb_desc_string_t", header: "tusb_types.h", + bycopy.} = object ## USB String Descriptor + bLength* {.importc: "bLength".}: uint8 ## < Size of this descriptor in bytes + bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## + ## < Descriptor Type + utf16le* {.importc: "utf16le".}: UncheckedArray[uint16] + + + tusb_desc_bos_platform_t* {.importc: "tusb_desc_bos_platform_t", + header: "tusb_types.h", bycopy.} = object ## + ## USB Binary Device Object Store (BOS) + bLength* {.importc: "bLength".}: uint8 + bDescriptorType* {.importc: "bDescriptorType".}: uint8 + bDevCapabilityType* {.importc: "bDevCapabilityType".}: uint8 + bReserved* {.importc: "bReserved".}: uint8 + PlatformCapabilityUUID* {.importc: "PlatformCapabilityUUID".}: array[16, + uint8] + CapabilityData* {.importc: "CapabilityData".}: UncheckedArray[uint8] + + + tusb_desc_webusb_url_t* {.importc: "tusb_desc_webusb_url_t", + header: "tusb_types.h", bycopy.} = object ## + ## USB WebUSB URL Descriptor + bLength* {.importc: "bLength".}: uint8 + bDescriptorType* {.importc: "bDescriptorType".}: uint8 + bScheme* {.importc: "bScheme".}: uint8 + url* {.importc: "url".}: UncheckedArray[char] + + + TU_ATTR_PACKED_tusb_types_5* {.importc: "tusb_desc_dfu_functional_t::no_name", + header: "tusb_types.h", bycopy.} = object ## + ## DFU Functional Descriptor + bitCanDnload* {.importc: "bitCanDnload", bitsize: 1.}: uint8 + bitCanUpload* {.importc: "bitCanUpload", bitsize: 1.}: uint8 + bitManifestationTolerant* {.importc: "bitManifestationTolerant", bitsize: 1.}: uint8 + bitWillDetach* {.importc: "bitWillDetach", bitsize: 1.}: uint8 + reserved* {.importc: "reserved", bitsize: 4.}: uint8 + + + tusb_desc_dfu_functional_t* {.importc: "tusb_desc_dfu_functional_t", + header: "tusb_types.h", bycopy.} = object + bLength* {.importc: "bLength".}: uint8 + bDescriptorType* {.importc: "bDescriptorType".}: uint8 + bmAttributes* {.importc: "bmAttributes".}: TU_ATTR_PACKED_tusb_types_5 + bAttributes* {.importc: "bAttributes".}: uint8 + wDetachTimeOut* {.importc: "wDetachTimeOut".}: uint16 + wTransferSize* {.importc: "wTransferSize".}: uint16 + bcdDFUVersion* {.importc: "bcdDFUVersion".}: uint16 + + + TU_ATTR_PACKED_tusb_types_9* {.importc: "tusb_control_request_t::no_name", + header: "tusb_types.h", bycopy.} = object ## + ## --------------------------------------------------------------------+ + ## + ## --------------------------------------------------------------------+ + recipient* {.importc: "recipient", bitsize: 5.}: uint8 ## + ## < Recipient type tusb_request_recipient_t. + `type`* {.importc: "type", bitsize: 2.}: uint8 ## + ## < Request type tusb_request_type_t. + direction* {.importc: "direction", bitsize: 1.}: uint8 + ## < Direction type. tusb_dir_t + + + tusb_control_request_t* {.importc: "tusb_control_request_t", + header: "tusb_types.h", bycopy.} = object + bmRequestType_bit* {.importc: "bmRequestType_bit".}: TU_ATTR_PACKED_tusb_types_9 + bmRequestType* {.importc: "bmRequestType".}: uint8 + bRequest* {.importc: "bRequest".}: uint8 + wValue* {.importc: "wValue".}: uint16 + wIndex* {.importc: "wIndex".}: uint16 + wLength* {.importc: "wLength".}: uint16 + + + +proc tu_edpt_dir*(`addr`: uint8): tusb_dir_t {.inline, cdecl, + importc: "tu_edpt_dir".} + ## --------------------------------------------------------------------+ + ## Endpoint helper + ## --------------------------------------------------------------------+ + ## Get direction from Endpoint address + +proc tu_edpt_number*(`addr`: uint8): uint8 {.inline, cdecl, + importc: "tu_edpt_number".} + ## Get Endpoint number from address + +proc tu_edpt_addr*(num: uint8; dir: uint8): uint8 {.inline, cdecl, + importc: "tu_edpt_addr".} + +proc tu_edpt_packet_size*(desc_ep: ptr tusb_desc_endpoint_t): uint16 {.inline, + cdecl, importc: "tu_edpt_packet_size".} + +proc tu_edpt_type_str*(t: tusb_xfer_type_t): cstring {.inline, cdecl, + importc: "tu_edpt_type_str".} + +proc tu_desc_next*(desc: pointer): ptr uint8 {.inline, cdecl, importc: "tu_desc_next".} + ## --------------------------------------------------------------------+ + ## Descriptor helper + ## --------------------------------------------------------------------+ + ## return next descriptor + +proc tu_desc_len*(desc: pointer): uint8 {.inline, cdecl, importc: "tu_desc_len".} + ## + ## get descriptor length + +proc tu_desc_type*(desc: pointer): uint8 {.inline, cdecl, + importc: "tu_desc_type".} + ## get descriptor type + +proc tu_desc_subtype*(desc: pointer): uint8 {.inline, cdecl, + importc: "tu_desc_subtype".} + ## get descriptor subtype + +proc tu_desc_find*(desc: ptr uint8; `end`: ptr uint8; byte1: uint8): ptr uint8 {. + cdecl, importc: "tu_desc_find", header: "tusb_types.h".} + ## + ## find descriptor that match byte1 (type) + +proc tu_desc_find2*(desc: ptr uint8; `end`: ptr uint8; byte1: uint8; + byte2: uint8): ptr uint8 {.cdecl, importc: "tu_desc_find2", + header: "tusb_types.h".} + ## find descriptor that match byte1 (type) and byte2 + +proc tu_desc_find3*(desc: ptr uint8; `end`: ptr uint8; byte1: uint8; + byte2: uint8; byte3: uint8): ptr uint8 {.cdecl, + importc: "tu_desc_find3", header: "tusb_types.h".} + ## + ## find descriptor that match byte1 (type) and byte2 \ No newline at end of file From d76837aaa144a09195a5e3516c08951049fd2139 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 23:26:21 -0600 Subject: [PATCH 019/142] usb --- src/nesper/components/esp_tinyusb/tinyusb.nim | 8 ++++++++ src/nesper/components/esp_tinyusb/tusb_config.nim | 13 +++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/nesper/components/esp_tinyusb/tinyusb.nim b/src/nesper/components/esp_tinyusb/tinyusb.nim index 518b21bc..05ff8b92 100644 --- a/src/nesper/components/esp_tinyusb/tinyusb.nim +++ b/src/nesper/components/esp_tinyusb/tinyusb.nim @@ -3,6 +3,14 @@ ## ## SPDX-License-Identifier: Apache-2.0 ## +import ../../consts +import ./tusb_types +import ./tusb_cdc_acm +import ./tusb_tasks + +import ./tinyusb_types + +export tusb_types, tusb_cdc_acm, tinyusb_types, tusb_tasks type diff --git a/src/nesper/components/esp_tinyusb/tusb_config.nim b/src/nesper/components/esp_tinyusb/tusb_config.nim index 47093014..35a672cb 100644 --- a/src/nesper/components/esp_tinyusb/tusb_config.nim +++ b/src/nesper/components/esp_tinyusb/tusb_config.nim @@ -60,12 +60,13 @@ import ../../consts ## - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) ## -when not defined(CFG_TUSB_MEM_ALIGN): - const - CFG_TUSB_MEM_ALIGN* = TU_ATTR_ALIGNED(4) -when not defined(CFG_TUD_ENDPOINT0_SIZE): - const - CFG_TUD_ENDPOINT0_SIZE* = 64 +# when not defined(CFG_TUSB_MEM_ALIGN): +# const +# CFG_TUSB_MEM_ALIGN* = TU_ATTR_ALIGNED(4) +# when not defined(CFG_TUD_ENDPOINT0_SIZE): +# const +# CFG_TUD_ENDPOINT0_SIZE* = 64 + const CFG_TUSB_DEBUG* = CONFIG_TINYUSB_DEBUG_LEVEL ## Debug Level CFG_TUD_CDC_RX_BUFSIZE* = CONFIG_TINYUSB_CDC_RX_BUFSIZE ## From d9a86cbc75aeb0d95194196547d7f031b5f5465f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 23:28:26 -0600 Subject: [PATCH 020/142] usb --- .../net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim | 1 + esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim | 1 + esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim | 1 + 3 files changed, 3 insertions(+) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim index e58e426c..07617a2a 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim @@ -2,6 +2,7 @@ import nesper import nesper/[general] import nesper/esp/queue import nesper/esp/esp_vfs_fat # for wl_handle_t and WL_INVALID_HANDLE +import nesper/components/esp_tinyusb/tinyusb const TAG* = "usb_composite" diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim index bcc11258..41df0e7d 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim @@ -3,6 +3,7 @@ import nesper/[general, events, wifi] import nesper/esp/esp_system import nesper/esp/nvs_flash import nesper/net_utils +import nesper/components/esp_tinyusb/tinyusb const TAG* = "USB_NCM" diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim index 16f1bba7..5f860099 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim @@ -1,6 +1,7 @@ import nesper import nesper/[general] import nesper/esp/queue +import nesper/components/esp_tinyusb/tinyusb const TAG* = "usb_serial" From ae6789865986af424d26a7adc70f2ff7df1afbc8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Sun, 31 Aug 2025 23:33:35 -0600 Subject: [PATCH 021/142] usb --- .../usb/tusb_composite_msc_serialdevice.nim | 108 ++++++------------ .../net_pppos_usb/main/usb/tusb_ncm.nim | 96 +++++----------- .../main/usb/tusb_serial_device.nim | 78 ++++--------- 3 files changed, 83 insertions(+), 199 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim index 07617a2a..e808a1b8 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_composite_msc_serialdevice.nim @@ -3,80 +3,30 @@ import nesper/[general] import nesper/esp/queue import nesper/esp/esp_vfs_fat # for wl_handle_t and WL_INVALID_HANDLE import nesper/components/esp_tinyusb/tinyusb +import nesper/components/esp_tinyusb/tinyusb const TAG* = "usb_composite" RXBufSz = 64 BasePath = "/usb" -{.emit: """ -#include -#include -#include -#include -#include -#include "esp_partition.h" -#include "wear_levelling/wear_levelling.h" -#include "tinyusb.h" -#include "tusb_cdc_acm.h" -#include "tusb_msc_storage.h" - -// Install TinyUSB with default descriptors from Kconfig -esp_err_t nesper_tinyusb_install_default(void) { - const tinyusb_config_t tusb_cfg = { - .device_descriptor = NULL, - .string_descriptor = NULL, - .string_descriptor_count = 0, - .external_phy = false, -#if (TUD_OPT_HIGH_SPEED) - .fs_configuration_descriptor = NULL, - .hs_configuration_descriptor = NULL, - .qualifier_descriptor = NULL, -#else - .configuration_descriptor = NULL, -#endif - }; - return tinyusb_driver_install(&tusb_cfg); -} - -// Init CDC-ACM with provided callbacks -esp_err_t nesper_tinyusb_cdc_acm_init_default(tinyusb_usbdev_t usb_dev, - tinyusb_cdcacm_itf_t cdc_port, - size_t rx_unread_buf_sz, - cdcacm_event_callback_t cb_rx, - cdcacm_event_callback_t cb_line_state) { - tinyusb_config_cdcacm_t acm_cfg = { - .usb_dev = usb_dev, - .cdc_port = cdc_port, - .rx_unread_buf_sz = rx_unread_buf_sz, - .callback_rx = cb_rx, - .callback_rx_wanted_char = NULL, - .callback_line_state_changed = cb_line_state, - .callback_line_coding_changed = NULL, - }; - return tusb_cdc_acm_init(&acm_cfg); -} - -// Init MSC storage on SPI flash and mount to base path -esp_err_t nesper_msc_init_and_mount_spiflash(wl_handle_t wl_handle, const char *base_path) { - const tinyusb_msc_spiflash_config_t config_spi = { .wl_handle = wl_handle }; - esp_err_t err = tinyusb_msc_storage_init_spiflash(&config_spi); - if (err != ESP_OK) return err; - return tinyusb_msc_storage_mount(base_path); -} -""".} - -proc nesper_tinyusb_install_default(): esp_err_t {.cdecl, importc.} -proc nesper_tinyusb_cdc_acm_init_default(usb_dev: cint; cdc_port: cint; rx_unread_buf_sz: csize_t; - cb_rx, cb_line_state: proc (itf: cint; event: pointer) {.cdecl.}): esp_err_t {.cdecl, importc.} -proc nesper_msc_init_and_mount_spiflash(wl: wl_handle_t; basePath: cstring): esp_err_t {.cdecl, importc.} +## C stdlib and ESP-IDF imports needed by the example proc esp_partition_find_first(ptype: uint8; psubtype: uint8; label: cstring): pointer {.cdecl, importc: "esp_partition_find_first", header: "esp_partition.h".} proc wl_mount(partition: pointer; outHandle: ptr wl_handle_t): esp_err_t {.cdecl, importc: "wl_mount", header: "wear_levelling/wear_levelling.h".} -proc tinyusb_cdcacm_read(itf: cint; buf: ptr uint8; bufsize: csize_t; rx_size: ptr csize_t): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_read", header: "tusb_cdc_acm.h".} -proc tinyusb_cdcacm_write_queue(itf: cint; buf: ptr uint8; size: csize_t): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_write_queue", header: "tusb_cdc_acm.h".} -proc tinyusb_cdcacm_write_flush(itf: cint; timeout_ms: cint): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_write_flush", header: "tusb_cdc_acm.h".} +## TinyUSB CDC ACM from wrappers +proc tinyusb_cdcacm_read(itf: tinyusb_cdcacm_itf_t; buf: ptr uint8; bufsize: csize_t; rx_size: ptr csize_t): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_read", header: "tusb_cdc_acm.h".} +proc tinyusb_cdcacm_write_queue(itf: tinyusb_cdcacm_itf_t; buf: ptr uint8; size: csize_t): csize_t {.cdecl, importc: "tinyusb_cdcacm_write_queue", header: "tusb_cdc_acm.h".} +proc tinyusb_cdcacm_write_flush(itf: tinyusb_cdcacm_itf_t; timeout_ticks: uint32): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_write_flush", header: "tusb_cdc_acm.h".} + +## TinyUSB MSC storage minimal imports (no emit) +type + tinyusb_msc_spiflash_config_t* {.importc: "tinyusb_msc_spiflash_config_t", header: "tusb_msc_storage.h", bycopy.} = object + wl_handle* {.importc: "wl_handle".}: wl_handle_t + +proc tinyusb_msc_storage_init_spiflash*(cfg: ptr tinyusb_msc_spiflash_config_t): esp_err_t {.cdecl, importc: "tinyusb_msc_storage_init_spiflash", header: "tusb_msc_storage.h".} +proc tinyusb_msc_storage_mount*(base_path: cstring): esp_err_t {.cdecl, importc: "tinyusb_msc_storage_mount", header: "tusb_msc_storage.h".} # C stdlib helpers used by the example file operations type Stat* {.importc: "struct stat", header: "sys/stat.h", bycopy.} = object @@ -104,9 +54,9 @@ var appQueue: QueueHandle_t rxBuf {.volatile.}: array[RXBufSz + 1, uint8] -proc onCdcRx(itf: cint; event: pointer) {.cdecl.} = +proc onCdcRx(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = var rxSize: csize_t = 0 - let ret = tinyusb_cdcacm_read(itf, addr rxBuf[0], RXBufSz.csize_t, addr rxSize) + let ret = tinyusb_cdcacm_read(tinyusb_cdcacm_itf_t(itf), addr rxBuf[0], RXBufSz.csize_t, addr rxSize) if ret == ESP_OK: var msg: AppMessage msg.bufLen = rxSize @@ -117,7 +67,7 @@ proc onCdcRx(itf: cint; event: pointer) {.cdecl.} = else: loge(TAG, "Read Error") -proc onCdcLineState(itf: cint; event: pointer) {.cdecl.} = +proc onCdcLineState(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = logi(TAG, "Line state changed on channel %d", itf) proc fileExists(path: cstring): bool = @@ -171,12 +121,26 @@ proc runUsbCompositeMscSerial*() = logi(TAG, "Initializing storage...") var wl: wl_handle_t = WL_INVALID_HANDLE check: storageInitSpiFlash(wl) - check: nesper_msc_init_and_mount_spiflash(wl, BasePath) + var mscCfg: tinyusb_msc_spiflash_config_t + mscCfg.wl_handle = wl + check: tinyusb_msc_storage_init_spiflash(addr mscCfg) + check: tinyusb_msc_storage_mount(BasePath) fileOperations() logi(TAG, "USB Composite initialization") - check: nesper_tinyusb_install_default() - check: nesper_tinyusb_cdc_acm_init_default(0, 0, RXBufSz, onCdcRx, onCdcLineState) + var tusbCfg: tinyusb_config_t + tusbCfg.external_phy = false + check: tinyusb_driver_install(addr tusbCfg) + + var acmCfg: tinyusb_config_cdcacm_t + acmCfg.usb_dev = TINYUSB_USBDEV_0 + acmCfg.cdc_port = TINYUSB_CDC_ACM_0 + acmCfg.rx_unread_buf_sz = RXBufSz + acmCfg.callback_rx = onCdcRx + acmCfg.callback_rx_wanted_char = nil + acmCfg.callback_line_state_changed = onCdcLineState + acmCfg.callback_line_coding_changed = nil + check: tusb_cdc_acm_init(addr acmCfg) logi(TAG, "USB Composite initialization DONE") var msg: AppMessage @@ -184,7 +148,7 @@ proc runUsbCompositeMscSerial*() = if xQueueReceive(appQueue, addr msg, portMAX_DELAY) == 1: if msg.bufLen > 0: logi(TAG, "Data from channel %d", msg.itf.int) - discard tinyusb_cdcacm_write_queue(msg.itf.int, addr msg.buf[0], msg.bufLen) - let err = tinyusb_cdcacm_write_flush(msg.itf.int, 0) + discard tinyusb_cdcacm_write_queue(tinyusb_cdcacm_itf_t(msg.itf.int), addr msg.buf[0], msg.bufLen) + let err = tinyusb_cdcacm_write_flush(tinyusb_cdcacm_itf_t(msg.itf.int), 0) if err != ESP_OK: loge(TAG, "CDC ACM write flush error: %s", esp_err_to_name(err)) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim index 41df0e7d..d822c2c8 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim @@ -4,78 +4,30 @@ import nesper/esp/esp_system import nesper/esp/nvs_flash import nesper/net_utils import nesper/components/esp_tinyusb/tinyusb +import nesper/consts +import nesper/components/esp_tinyusb/tinyusb const TAG* = "USB_NCM" WIFI_SSID {.strdefine.}: string = "NOSSID" WIFI_PASS {.strdefine.}: string = "" -# C includes and helper wrappers for TinyUSB NET and internal WiFi APIs -{.emit: """ -#include -#include "tinyusb.h" -#include "tinyusb_net.h" -#include "esp_private/wifi.h" - -typedef esp_err_t (*nesper_ncm_recv_cb_t)(void *buffer, uint16_t len, void *ctx); -typedef void (*nesper_ncm_free_cb_t)(void *eb, void *ctx); - -// Install TinyUSB with default descriptors from Kconfig -esp_err_t nesper_tinyusb_install_default(void) { - const tinyusb_config_t tusb_cfg = { - .device_descriptor = NULL, - .string_descriptor = NULL, - .string_descriptor_count = 0, - .external_phy = false, -#if (TUD_OPT_HIGH_SPEED) - .fs_configuration_descriptor = NULL, - .hs_configuration_descriptor = NULL, - .qualifier_descriptor = NULL, -#else - .configuration_descriptor = NULL, -#endif - }; - return tinyusb_driver_install(&tusb_cfg); -} - -// Initialize NCM with provided callbacks and MAC address -esp_err_t nesper_tinyusb_net_init_bridge(tinyusb_usbdev_t dev, - uint8_t mac_addr[6], - nesper_ncm_recv_cb_t on_recv, - nesper_ncm_free_cb_t free_tx_buf, - void *user_ctx) { - tinyusb_net_config_t cfg = { - .on_recv_callback = on_recv, - .free_tx_buffer = free_tx_buf, - .user_context = user_ctx, - }; - memcpy(cfg.mac_addr, mac_addr, 6); - return tinyusb_net_init(dev, &cfg); -} - -// Thin wrapper to expose send_sync -static inline esp_err_t nesper_tinyusb_net_send_sync(void *buffer, uint16_t len, void *eb, uint32_t timeout_ticks) { - return tinyusb_net_send_sync(buffer, len, eb, timeout_ticks); -} - -// WiFi internal helpers (signatures only, implemented by IDF) -esp_err_t esp_wifi_internal_tx(wifi_interface_t ifx, void *buffer, uint16_t len); -esp_err_t esp_wifi_internal_reg_rxcb(wifi_interface_t ifx, esp_wifi_rxcb_t rx_cb); -void esp_wifi_internal_free_rx_buffer(void *eb); -""".} - -proc nesper_tinyusb_install_default(): esp_err_t {.cdecl, importc.} -proc nesper_tinyusb_net_init_bridge(dev: cint; - mac: ptr uint8; - on_recv: proc (buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.}; - free_tx: proc (eb: pointer; ctx: pointer) {.cdecl.}; - user_ctx: pointer): esp_err_t {.cdecl, importc.} -proc nesper_tinyusb_net_send_sync(buffer: pointer; len: uint16; eb: pointer; timeoutTicks: uint32): esp_err_t {.cdecl, importc.} - -proc esp_wifi_internal_tx(ifx: wifi_interface_t; buffer: pointer; len: uint16): esp_err_t {.cdecl, importc.} +# TinyUSB NET type/procs (no emit) +type + tinyusb_net_config_t* {.importc: "tinyusb_net_config_t", header: "tinyusb_net.h", bycopy.} = object + on_recv_callback* {.importc: "on_recv_callback".}: proc (buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.} + free_tx_buffer* {.importc: "free_tx_buffer".}: proc (eb: pointer; ctx: pointer) {.cdecl.} + user_context* {.importc: "user_context".}: pointer + mac_addr* {.importc: "mac_addr".}: array[6, uint8] + +proc tinyusb_net_init*(dev: tinyusb_usbdev_t; cfg: ptr tinyusb_net_config_t): esp_err_t {.cdecl, importc: "tinyusb_net_init", header: "tinyusb_net.h".} +proc tinyusb_net_send_sync*(buffer: pointer; len: uint16; eb: pointer; timeout_ticks: uint32): esp_err_t {.cdecl, importc: "tinyusb_net_send_sync", header: "tinyusb_net.h".} + +# WiFi internal helpers (signatures only) +proc esp_wifi_internal_tx(ifx: wifi_interface_t; buffer: pointer; len: uint16): esp_err_t {.cdecl, importc: "esp_wifi_internal_tx", header: "esp_private/wifi.h".} proc esp_wifi_internal_reg_rxcb(ifx: wifi_interface_t; - rx_cb: proc (buffer: pointer; len: uint16; eb: pointer): esp_err_t {.cdecl.}): esp_err_t {.cdecl, importc.} -proc esp_wifi_internal_free_rx_buffer(eb: pointer) {.cdecl, importc.} + rx_cb: proc (buffer: pointer; len: uint16; eb: pointer): esp_err_t {.cdecl.}): esp_err_t {.cdecl, importc: "esp_wifi_internal_reg_rxcb", header: "esp_private/wifi.h".} +proc esp_wifi_internal_free_rx_buffer(eb: pointer) {.cdecl, importc: "esp_wifi_internal_free_rx_buffer", header: "esp_private/wifi.h".} var sIsWifiConnected {.volatile.}: bool = false @@ -92,7 +44,7 @@ proc wifiPktFree(eb: pointer; ctx: pointer) {.cdecl.} = # WiFi -> USB path: send WiFi RX packet out over USB NCM proc pktWifi2Usb(buffer: pointer; len: uint16; eb: pointer): esp_err_t {.cdecl.} = - if nesper_tinyusb_net_send_sync(buffer, len, eb, portMAX_DELAY.uint32) != ESP_OK: + if tinyusb_net_send_sync(buffer, len, eb, portMAX_DELAY.uint32) != ESP_OK: esp_wifi_internal_free_rx_buffer(eb) return ESP_OK @@ -134,7 +86,9 @@ proc runUsbNcmBridge*() = check: ret logi(TAG, "USB NCM device initialization") - check: nesper_tinyusb_install_default() + var tusbCfg: tinyusb_config_t + tusbCfg.external_phy = false + check: tinyusb_driver_install(addr tusbCfg) var mac: array[6, uint8] check: esp_read_mac(addr mac[0], ESP_MAC_WIFI_STA) @@ -142,10 +96,14 @@ proc runUsbNcmBridge*() = mac[0].int, mac[1].int, mac[2].int, mac[3].int, mac[4].int, mac[5].int) # Initialize TinyUSB NET class with callbacks and MAC - check: nesper_tinyusb_net_init_bridge(0, addr mac[0], usbRecvCallback, wifiPktFree, addr sIsWifiConnected) + var ncfg: tinyusb_net_config_t + ncfg.on_recv_callback = usbRecvCallback + ncfg.free_tx_buffer = wifiPktFree + ncfg.user_context = addr sIsWifiConnected + for i in 0..5: ncfg.mac_addr[i] = mac[i] + check: tinyusb_net_init(TINYUSB_USBDEV_0, addr ncfg) logi(TAG, "WiFi initialization") check: startWifi(addr sIsWifiConnected) logi(TAG, "USB NCM and WiFi initialized and started") - diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim index 5f860099..17a89c1b 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_serial_device.nim @@ -2,61 +2,13 @@ import nesper import nesper/[general] import nesper/esp/queue import nesper/components/esp_tinyusb/tinyusb +import nesper/components/esp_tinyusb/tinyusb const TAG* = "usb_serial" RXBufSz = 64 # Match example default; align with Kconfig if changed -# C includes and tinyusb helper wrappers -{.emit: """ -#include -#include "tinyusb.h" -#include "tusb_cdc_acm.h" - -// Install TinyUSB with default descriptors from Kconfig -esp_err_t nesper_tinyusb_install_default(void) { - const tinyusb_config_t tusb_cfg = { - .device_descriptor = NULL, - .string_descriptor = NULL, - .string_descriptor_count = 0, - .external_phy = false, -#if (TUD_OPT_HIGH_SPEED) - .fs_configuration_descriptor = NULL, - .hs_configuration_descriptor = NULL, - .qualifier_descriptor = NULL, -#else - .configuration_descriptor = NULL, -#endif - }; - return tinyusb_driver_install(&tusb_cfg); -} - -// Init CDC-ACM port with provided callbacks -esp_err_t nesper_tinyusb_cdc_acm_init_default(tinyusb_usbdev_t usb_dev, - tinyusb_cdcacm_itf_t cdc_port, - size_t rx_unread_buf_sz, - cdcacm_event_callback_t cb_rx, - cdcacm_event_callback_t cb_line_state) { - tinyusb_config_cdcacm_t acm_cfg = { - .usb_dev = usb_dev, - .cdc_port = cdc_port, - .rx_unread_buf_sz = rx_unread_buf_sz, - .callback_rx = cb_rx, - .callback_rx_wanted_char = NULL, - .callback_line_state_changed = cb_line_state, - .callback_line_coding_changed = NULL, - }; - return tusb_cdc_acm_init(&acm_cfg); -} -""".} - -proc nesper_tinyusb_install_default(): esp_err_t {.cdecl, importc.} -proc nesper_tinyusb_cdc_acm_init_default(usb_dev: cint; cdc_port: cint; rx_unread_buf_sz: csize_t; - cb_rx, cb_line_state: proc (itf: cint; event: pointer) {.cdecl.}): esp_err_t {.cdecl, importc.} - -proc tinyusb_cdcacm_read(itf: cint; buf: ptr uint8; bufsize: csize_t; rx_size: ptr csize_t): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_read", header: "tusb_cdc_acm.h".} -proc tinyusb_cdcacm_write_queue(itf: cint; buf: ptr uint8; size: csize_t): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_write_queue", header: "tusb_cdc_acm.h".} -proc tinyusb_cdcacm_write_flush(itf: cint; timeout_ms: cint): esp_err_t {.cdecl, importc: "tinyusb_cdcacm_write_flush", header: "tusb_cdc_acm.h".} +# Use tinyusb wrappers from nesper/components/esp_tinyusb type AppMessage = object @@ -69,9 +21,9 @@ var rxBuf {.volatile.}: array[RXBufSz + 1, uint8] # RX callback: read bytes and forward to application queue -proc onCdcRx(itf: cint; event: pointer) {.cdecl.} = +proc onCdcRx(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = var rxSize: csize_t = 0 - let ret = tinyusb_cdcacm_read(itf, addr rxBuf[0], RXBufSz.csize_t, addr rxSize) + let ret = tinyusb_cdcacm_read(tinyusb_cdcacm_itf_t(itf), addr rxBuf[0], RXBufSz.csize_t, addr rxSize) if ret == ESP_OK: var msg: AppMessage msg.bufLen = rxSize @@ -83,7 +35,7 @@ proc onCdcRx(itf: cint; event: pointer) {.cdecl.} = loge(TAG, "Read Error") # Line state change callback (log only) -proc onCdcLineState(itf: cint; event: pointer) {.cdecl.} = +proc onCdcLineState(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = logi(TAG, "Line state changed on channel %d", itf) proc runUsbSerialDevice*() = @@ -92,8 +44,19 @@ proc runUsbSerialDevice*() = assert appQueue != nil logi(TAG, "USB initialization") - check: nesper_tinyusb_install_default() - check: nesper_tinyusb_cdc_acm_init_default(0, 0, RXBufSz, onCdcRx, onCdcLineState) + var tusbCfg: tinyusb_config_t + tusbCfg.external_phy = false + check: tinyusb_driver_install(addr tusbCfg) + + var acmCfg: tinyusb_config_cdcacm_t + acmCfg.usb_dev = TINYUSB_USBDEV_0 + acmCfg.cdc_port = TINYUSB_CDC_ACM_0 + acmCfg.rx_unread_buf_sz = RXBufSz + acmCfg.callback_rx = onCdcRx + acmCfg.callback_rx_wanted_char = nil + acmCfg.callback_line_state_changed = onCdcLineState + acmCfg.callback_line_coding_changed = nil + check: tusb_cdc_acm_init(addr acmCfg) logi(TAG, "USB initialization DONE") @@ -102,8 +65,7 @@ proc runUsbSerialDevice*() = if xQueueReceive(appQueue, addr msg, portMAX_DELAY) == 1: # pdTRUE if msg.bufLen > 0: logi(TAG, "Data from channel %d", msg.itf.int) - discard tinyusb_cdcacm_write_queue(msg.itf.int, addr msg.buf[0], msg.bufLen) - let err = tinyusb_cdcacm_write_flush(msg.itf.int, 0) + discard tinyusb_cdcacm_write_queue(tinyusb_cdcacm_itf_t(msg.itf.int), addr msg.buf[0], msg.bufLen) + let err = tinyusb_cdcacm_write_flush(tinyusb_cdcacm_itf_t(msg.itf.int), 0) if err != ESP_OK: loge(TAG, "CDC ACM write flush error: %s", esp_err_to_name(err)) - From bcf58e84f33a30570daac338b8278b80dc8cc168 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 00:15:03 -0600 Subject: [PATCH 022/142] usb --- .../main/usb/README-pppos-dualcdc.md | 32 +++ .../main/usb}/ppp_connect_uart.c | 0 .../net_pppos_usb/main/usb}/ppp_connect_usb.c | 0 .../main/usb/ppp_connect_usb_dualcdc.c | 194 ++++++++++++++++++ .../main/usb/ppp_connect_usb_dualcdc.nim | 140 +++++++++++++ src/nesper/components/esp_tinyusb/tinyusb.nim | 3 +- .../components/esp_tinyusb/tusb_config.nim | 34 +-- 7 files changed, 386 insertions(+), 17 deletions(-) create mode 100644 esp-idf-examples/net_pppos_usb/main/usb/README-pppos-dualcdc.md rename {tests/c_headers => esp-idf-examples/net_pppos_usb/main/usb}/ppp_connect_uart.c (100%) rename {tests/c_headers => esp-idf-examples/net_pppos_usb/main/usb}/ppp_connect_usb.c (100%) create mode 100644 esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.c create mode 100644 esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim diff --git a/esp-idf-examples/net_pppos_usb/main/usb/README-pppos-dualcdc.md b/esp-idf-examples/net_pppos_usb/main/usb/README-pppos-dualcdc.md new file mode 100644 index 00000000..2fc38567 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/usb/README-pppos-dualcdc.md @@ -0,0 +1,32 @@ +PPPoS over USB CDC (dual CDC) + +Overview +- CDC ACM 0: PPP data channel feeding `esp_netif` (PPPoS) +- CDC ACM 1: TinyUSB console for ESP logs and stdio + +Files +- `ppp_connect_usb_dualcdc.c`: C example setting up two CDC interfaces, PPP + console. +- `ppp_connect_usb_dualcdc.nim`: Nim example with equivalent behavior. + +Key Config (menuconfig) +- Component config → TinyUSB → Device + - Enable TinyUSB device stack + - Enable CDC and set `CDC count` to `2` or more + - Adjust CDC RX/TX buffer sizes as needed +- Component config → LWIP + - Enable PPP support (esp-netif PPP) + +Usage Notes +- PPP frames are read from CDC0 and passed to `esp_netif_receive`; TCP/IP replies transmit via CDC0. +- Console/log output is redirected to CDC1 using `esp_tusb_init_console(TINYUSB_CDC_ACM_1)`. +- On the host, two serial devices will appear; attach your PPP dialer to the first, and a terminal to the second for logs. + +API Entrypoints +- C: `example_ppp_connect_dualcdc()` / `example_ppp_shutdown_dualcdc()` +- Nim: `examplePppConnectDualCdc()` / `examplePppShutdownDualCdc()` + +References +- `ppp_connect_usb.c`: single-CDC PPPoS reference (upstream ESP-IDF example) +- `tests/c_headers/idf-usb/device/tusb_console/main/tusb_console_main.c`: TinyUSB console redirection +- `tusb_composite_msc_serialdevice.nim`: example TinyUSB CDC usage from Nim + diff --git a/tests/c_headers/ppp_connect_uart.c b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_uart.c similarity index 100% rename from tests/c_headers/ppp_connect_uart.c rename to esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_uart.c diff --git a/tests/c_headers/ppp_connect_usb.c b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb.c similarity index 100% rename from tests/c_headers/ppp_connect_usb.c rename to esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb.c diff --git a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.c b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.c new file mode 100644 index 00000000..fdafdac1 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.c @@ -0,0 +1,194 @@ +/* + * Dual-CDC PPPoS over USB example + * - CDC ACM 0: PPP data channel (PPPoS) + * - CDC ACM 1: Console/log output via TinyUSB console + */ + +#include +#include +#include "sdkconfig.h" +#include "protocol_examples_common.h" +#include "example_common_private.h" + +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_netif_ppp.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "tinyusb.h" +#include "tusb_cdc_acm.h" +#include "tusb_console.h" + +static const char *TAG = "pppos_dualcdc"; + +/* PPP state */ +static esp_netif_t *s_netif; +static EventGroupHandle_t s_event_group; +static const int GOT_IPV4 = BIT0; +static const int CONNECTION_FAILED = BIT1; +static const int GOT_IPV6 = BIT2; +#define CONNECT_BITS (GOT_IPV4|GOT_IPV6|CONNECTION_FAILED) + +/* USB-CDC state */ +static int s_ppp_itf = TINYUSB_CDC_ACM_0; /* PPP on CDC0 */ +static int s_log_itf = TINYUSB_CDC_ACM_1; /* Console on CDC1 */ +static uint8_t s_rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE]; + +/* PPP transmit: push bytes onto PPP CDC interface */ +static esp_err_t transmit(void *h, void *buffer, size_t len) +{ + (void)h; + ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); + tinyusb_cdcacm_write_queue(s_ppp_itf, buffer, len); + tinyusb_cdcacm_write_flush(s_ppp_itf, 0); + return ESP_OK; +} + +static esp_netif_driver_ifconfig_t s_driver_cfg = { + .handle = (void *)1, /* singleton driver, just != NULL */ + .transmit = transmit, +}; + +/* IP events */ +static void on_ip_event(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + if (event_id == IP_EVENT_PPP_GOT_IP) { + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_netif_t *netif = event->esp_netif; + esp_netif_dns_info_t dns_info; + ESP_LOGI(TAG, "Got IPv4: %s " IPSTR, esp_netif_get_desc(netif), IP2STR(&event->ip_info.ip)); + esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info); + ESP_LOGI(TAG, "DNS: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); + xEventGroupSetBits(s_event_group, GOT_IPV4); + } else if (event_id == IP_EVENT_GOT_IP6) { + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + ESP_LOGI(TAG, "Got IPv6: %s " IPV6STR ", type: %d", esp_netif_get_desc(event->esp_netif), + IPV62STR(event->ip6_info.ip), ipv6_type); + xEventGroupSetBits(s_event_group, GOT_IPV6); + } else if (event_id == IP_EVENT_PPP_LOST_IP) { + ESP_LOGI(TAG, "PPP disconnected"); + xEventGroupSetBits(s_event_group, CONNECTION_FAILED); + } +} + +/* CDC RX for PPP interface: push to esp_netif */ +static void cdc_rx_callback(int itf, cdcacm_event_t *event) +{ + size_t rx_size = 0; + if (itf != s_ppp_itf) { + return; /* not our PPP channel */ + } + if (tinyusb_cdcacm_read(itf, s_rx_buf, sizeof(s_rx_buf), &rx_size) == ESP_OK) { + if (rx_size) { + ESP_LOG_BUFFER_HEXDUMP(TAG, s_rx_buf, rx_size, ESP_LOG_VERBOSE); + esp_netif_receive(s_netif, s_rx_buf, rx_size, NULL); + } + } else { + ESP_LOGE(TAG, "CDC read error"); + } +} + +/* Optionally track line state for PPP interface */ +static void line_state_changed(int itf, cdcacm_event_t *event) +{ + ESP_LOGI(TAG, "Line state changed on itf %d", itf); +} + +/* Public helpers to start/stop PPP over CDC0 and console on CDC1 */ +esp_err_t example_ppp_connect_dualcdc(void) +{ + ESP_LOGI(TAG, "Starting dual-CDC PPPoS (PPP on CDC0, console on CDC1)"); + + /* Install TinyUSB */ + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .external_phy = false, +#if (TUD_OPT_HIGH_SPEED) + .fs_configuration_descriptor = NULL, + .hs_configuration_descriptor = NULL, + .qualifier_descriptor = NULL, +#else + .configuration_descriptor = NULL, +#endif + }; + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + /* Init CDC0 for PPP */ + tinyusb_config_cdcacm_t acm_ppp = { + .usb_dev = TINYUSB_USBDEV_0, + .cdc_port = TINYUSB_CDC_ACM_0, + .callback_rx = &cdc_rx_callback, + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = &line_state_changed, + .callback_line_coding_changed = NULL, + }; + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_ppp)); + + /* Init CDC1 for console/logs */ + tinyusb_config_cdcacm_t acm_log = { + .usb_dev = TINYUSB_USBDEV_0, + .cdc_port = TINYUSB_CDC_ACM_1, + }; + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_log)); + + /* Route console/log output to CDC1 */ + ESP_ERROR_CHECK(esp_tusb_init_console(TINYUSB_CDC_ACM_1)); + + /* Events and PPP netif */ + s_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL)); + + esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_PPP(); + base_cfg.if_desc = EXAMPLE_NETIF_DESC_PPP; + esp_netif_config_t netif_cfg = { + .base = &base_cfg, + .driver = &s_driver_cfg, + .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP, + }; + + s_netif = esp_netif_new(&netif_cfg); + assert(s_netif); + + /* Bring interface up and signal connected */ + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + + ESP_LOGI(TAG, "Waiting for IP..."); + EventBits_t bits = xEventGroupWaitBits(s_event_group, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY); + if (bits & CONNECTION_FAILED) { + ESP_LOGE(TAG, "PPP connection failed"); + return ESP_FAIL; + } + ESP_LOGI(TAG, "PPP connected"); + return ESP_OK; +} + +void example_ppp_shutdown_dualcdc(void) +{ + ESP_LOGI(TAG, "Shutting down PPP and console"); + + esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event); + if (s_netif) { + esp_netif_action_disconnected(s_netif, 0, 0, 0); + esp_netif_action_stop(s_netif, 0, 0, 0); + esp_netif_destroy(s_netif); + s_netif = NULL; + } + if (s_event_group) { + vEventGroupDelete(s_event_group); + s_event_group = NULL; + } + /* Restore console to UART if desired */ + esp_tusb_deinit_console(TINYUSB_CDC_ACM_1); +} + diff --git a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim new file mode 100644 index 00000000..c4679cf1 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim @@ -0,0 +1,140 @@ +import nesper +import nesper/[general] +import nesper/esp/esp_log +import nesper/esp/esp_event +import nesper/events +import nesper/esp/event_groups +import nesper/esp/net/esp_netif +import nesper/esp/net/esp_netif_ppp +import nesper/esp/net/esp_netif_types +import nesper/components/esp_tinyusb/tinyusb +import nesper/components/esp_tinyusb/tusb_cdc_acm + +const + TAG* = "pppos_dualcdc" + +# tinyusb console helpers (no wrapper module yet) +proc esp_tusb_init_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_init_console", header: "tusb_console.h".} +proc esp_tusb_deinit_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_deinit_console", header: "tusb_console.h".} + +# Optional IP_EVENT base import (for filtering). tcpip_adapter.h provides symbol across IDF versions. +var IP_EVENT* {.importc: "IP_EVENT", header: "tcpip_adapter.h".}: esp_event_base_t + +# State +var + sNetif: ptr esp_netif_t + sEventGroup: EventGroupHandle_t + sPppItf: tinyusb_cdcacm_itf_t = TINYUSB_CDC_ACM_0 + sLogItf: tinyusb_cdcacm_itf_t = TINYUSB_CDC_ACM_1 + rxBuf = newSeq[uint8](CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1) + +const + GOT_IPV4 = 1 shl 0 + CONN_FAILED = 1 shl 1 + GOT_IPV6 = 1 shl 2 + CONNECT_BITS = GOT_IPV4 or GOT_IPV6 or CONN_FAILED + +# PPP transmit: push bytes to CDC PPP interface +proc pppTransmit(h: pointer; buffer: pointer; len: csize_t): esp_err_t {.cdecl.} = + discard tinyusb_cdcacm_write_queue(sPppItf, cast[ptr uint8](buffer), len) + result = tinyusb_cdcacm_write_flush(sPppItf, 0'u32) + +var driverCfg: esp_netif_driver_ifconfig_t + +# CDC RX: feed data to esp_netif +proc onCdcRx(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = + if tinyusb_cdcacm_itf_t(itf) != sPppItf: + return + var rxSize: csize_t = 0 + let ret = tinyusb_cdcacm_read(tinyusb_cdcacm_itf_t(itf), addr rxBuf[0], CONFIG_TINYUSB_CDC_RX_BUFSIZE.csize_t, addr rxSize) + if ret == ESP_OK and rxSize > 0: + discard esp_netif_receive(sNetif, addr rxBuf[0], rxSize, nil) + +proc onLineState(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = + logi(TAG, "Line state changed on itf %d", itf) + +# IP events handler: filter for our PPP netif and set bits +proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = + if event_base != IP_EVENT: return + case ip_event_t(event_id) + of IP_EVENT_PPP_GOT_IP: + let ev = cast[ptr ip_event_got_ip_t](event_data) + if ev.esp_netif == sNetif: + logi(TAG, "PPP IPv4: %s %s", esp_netif_get_desc(ev.esp_netif), $ev.ip_info.ip) + discard xEventGroupSetBits(sEventGroup, EventBits_t(GOT_IPV4)) + of IP_EVENT_GOT_IP6: + let ev6 = cast[ptr ip_event_got_ip6_t](event_data) + if ev6.esp_netif == sNetif: + logi(TAG, "PPP IPv6 acquired") + discard xEventGroupSetBits(sEventGroup, EventBits_t(GOT_IPV6)) + of IP_EVENT_PPP_LOST_IP: + discard xEventGroupSetBits(sEventGroup, EventBits_t(CONN_FAILED)) + else: + discard + +proc examplePppConnectDualCdc*(): esp_err_t = + logi(TAG, "Starting dual-CDC PPPoS (PPP=CDC0, console=CDC1)") + + var tusbCfg: tinyusb_config_t + tusbCfg.external_phy = false + check: tinyusb_driver_install(addr tusbCfg) + + # CDC0 for PPP + var acmPpp: tinyusb_config_cdcacm_t + acmPpp.usb_dev = TINYUSB_USBDEV_0 + acmPpp.cdc_port = TINYUSB_CDC_ACM_0 + acmPpp.callback_rx = onCdcRx + acmPpp.callback_rx_wanted_char = nil + acmPpp.callback_line_state_changed = onLineState + acmPpp.callback_line_coding_changed = nil + check: tusb_cdc_acm_init(addr acmPpp) + + # CDC1 for logs/console + var acmLog: tinyusb_config_cdcacm_t + acmLog.usb_dev = TINYUSB_USBDEV_0 + acmLog.cdc_port = TINYUSB_CDC_ACM_1 + check: tusb_cdc_acm_init(addr acmLog) + check: esp_tusb_init_console(TINYUSB_CDC_ACM_1) + + # Event group and handler + sEventGroup = xEventGroupCreate() + if sEventGroup.isNil: return ESP_ERR_NO_MEM + check: esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID.cint, onIpEvent, nil) + + # Create PPP netif using inherent defaults and custom driver + var baseCfg = ESP_NETIF_INHERENT_DEFAULT_PPP() + baseCfg.if_desc = "example_netif_ppp" + + driverCfg.handle = cast[pointer](1) + driverCfg.transmit = pppTransmit + + var netifCfg: esp_netif_config_t + netifCfg.base = addr baseCfg + netifCfg.driver = addr driverCfg + netifCfg.stack = ESP_NETIF_NETSTACK_DEFAULT_PPP + + sNetif = esp_netif_new(addr netifCfg) + doAssert sNetif != nil + esp_netif_action_start(sNetif, nil, 0, nil) + esp_netif_action_connected(sNetif, nil, 0, nil) + + logi(TAG, "Waiting for IP...") + let bits = xEventGroupWaitBits(sEventGroup, EventBits_t(CONNECT_BITS), pdFALSE, pdFALSE, portMAX_DELAY) + if (bits and EventBits_t(CONN_FAILED)) != 0: + loge(TAG, "PPP connect failed") + return ESP_FAIL + logi(TAG, "PPP connected") + return ESP_OK + +proc examplePppShutdownDualCdc*() = + discard esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID.cint, onIpEvent) + if sNetif != nil: + esp_netif_action_disconnected(sNetif, nil, 0, nil) + esp_netif_action_stop(sNetif, nil, 0, nil) + esp_netif_destroy(sNetif) + sNetif = nil + if sEventGroup != nil: + vEventGroupDelete(sEventGroup) + sEventGroup = nil + discard esp_tusb_deinit_console(TINYUSB_CDC_ACM_1) + diff --git a/src/nesper/components/esp_tinyusb/tinyusb.nim b/src/nesper/components/esp_tinyusb/tinyusb.nim index 05ff8b92..f6818ac8 100644 --- a/src/nesper/components/esp_tinyusb/tinyusb.nim +++ b/src/nesper/components/esp_tinyusb/tinyusb.nim @@ -7,10 +7,11 @@ import ../../consts import ./tusb_types import ./tusb_cdc_acm import ./tusb_tasks +import ./tusb_config import ./tinyusb_types -export tusb_types, tusb_cdc_acm, tinyusb_types, tusb_tasks +export tusb_types, tusb_cdc_acm, tinyusb_types, tusb_tasks, tusb_config type diff --git a/src/nesper/components/esp_tinyusb/tusb_config.nim b/src/nesper/components/esp_tinyusb/tusb_config.nim index 35a672cb..4d796440 100644 --- a/src/nesper/components/esp_tinyusb/tusb_config.nim +++ b/src/nesper/components/esp_tinyusb/tusb_config.nim @@ -67,19 +67,21 @@ import ../../consts # const # CFG_TUD_ENDPOINT0_SIZE* = 64 -const - CFG_TUSB_DEBUG* = CONFIG_TINYUSB_DEBUG_LEVEL ## Debug Level - CFG_TUD_CDC_RX_BUFSIZE* = CONFIG_TINYUSB_CDC_RX_BUFSIZE ## - ## CDC FIFO size of TX and RX - CFG_TUD_CDC_TX_BUFSIZE* = CONFIG_TINYUSB_CDC_TX_BUFSIZE - CFG_TUD_MSC_BUFSIZE* = CONFIG_TINYUSB_MSC_BUFSIZE ## - ## MSC Buffer size of Device Mass storage - CFG_TUD_MIDI_EP_BUFSIZE* = 64 - CFG_TUD_MIDI_EPSIZE* = CFG_TUD_MIDI_EP_BUFSIZE - CFG_TUD_MIDI_RX_BUFSIZE* = 64 - CFG_TUD_MIDI_TX_BUFSIZE* = 64 - CFG_TUD_CDC* = CONFIG_TINYUSB_CDC_COUNT ## Enabled device class driver - CFG_TUD_MSC* = CONFIG_TINYUSB_MSC_ENABLED - CFG_TUD_HID* = CONFIG_TINYUSB_HID_COUNT - CFG_TUD_MIDI* = CONFIG_TINYUSB_MIDI_COUNT - CFG_TUD_CUSTOM_CLASS* = CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED +let CONFIG_TINYUSB_CDC_RX_BUFSIZE* {.importc: "$1", header: "tinyusb.h".}: cint + +# const +# CFG_TUSB_DEBUG* = CONFIG_TINYUSB_DEBUG_LEVEL ## Debug Level +# CFG_TUD_CDC_RX_BUFSIZE* = CONFIG_TINYUSB_CDC_RX_BUFSIZE ## +# ## CDC FIFO size of TX and RX +# CFG_TUD_CDC_TX_BUFSIZE* = CONFIG_TINYUSB_CDC_TX_BUFSIZE +# CFG_TUD_MSC_BUFSIZE* = CONFIG_TINYUSB_MSC_BUFSIZE ## +# ## MSC Buffer size of Device Mass storage +# CFG_TUD_MIDI_EP_BUFSIZE* = 64 +# CFG_TUD_MIDI_EPSIZE* = CFG_TUD_MIDI_EP_BUFSIZE +# CFG_TUD_MIDI_RX_BUFSIZE* = 64 +# CFG_TUD_MIDI_TX_BUFSIZE* = 64 +# CFG_TUD_CDC* = CONFIG_TINYUSB_CDC_COUNT ## Enabled device class driver +# CFG_TUD_MSC* = CONFIG_TINYUSB_MSC_ENABLED +# CFG_TUD_HID* = CONFIG_TINYUSB_HID_COUNT +# CFG_TUD_MIDI* = CONFIG_TINYUSB_MIDI_COUNT +# CFG_TUD_CUSTOM_CLASS* = CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED From a64b3d7f7e485f474773d7da3ac49865330c63b2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 01:40:08 -0600 Subject: [PATCH 023/142] usb --- esp-idf-examples/net_pppos_usb/main/main.nim | 32 ++++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 2a571aad..1bbb359b 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -2,23 +2,20 @@ import std/strutils import nesper import nesper/[consts, general, timers] import nesper/esp/esp_system +import nesper/esp/nvs_flash +import nesper/esp/esp_event import nesper/esp/net/esp_netif import nesper/esp/net/esp_netif_ppp +import usb/ppp_connect_usb_dualcdc const TAG*: cstring = "main" -proc setupPPP(): bool = - # Network interface configuration - var cfg: esp_netif_config_t = ESP_NETIF_DEFAULT_PPP() - let esp_netif: ptr esp_netif_t = esp_netif_new(addr cfg) - - # PPP-specific configuration - var ppp_config: esp_netif_ppp_config_t - ppp_config.ppp_phase_event_enabled = true - ppp_config.ppp_error_event_enabled = true - check: esp_netif_ppp_set_params(esp_netif, addr ppp_config) - return true +proc setupSystem(): esp_err_t = + # Initialize esp-netif and default event loop + check: esp_netif_init() + check: esp_event_loop_create_default() + return ESP_OK app_main: logi(TAG, "esp starting ... ") @@ -42,6 +39,15 @@ app_main: except Defect, CatchableError: logi(TAG, "Error getting chip info") + # Basic system setup: NVS, esp-netif, default event loop + discard setupSystem() + + # Start PPPoS over USB with dual CDC (CDC0=PPP, CDC1=console) + if examplePppConnectDualCdc() == ESP_OK: + logi(TAG, "PPPoS connected. Idle loop ...") + else: + loge(TAG, "PPPoS connect failed") + + # Keep app alive; clean shutdown not triggered in this minimal example while true: - logi(TAG, "Hello, World!") - delay(1_000.Millis) \ No newline at end of file + delay(2_000.Millis) From 7909623721ec8104a1073f1f4ed17dc8458d7f23 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 02:34:24 -0600 Subject: [PATCH 024/142] usb --- esp-idf-examples/net_pppos_usb/dependencies.lock | 11 ++++------- esp-idf-examples/net_pppos_usb/main/idf_component.yml | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/dependencies.lock b/esp-idf-examples/net_pppos_usb/dependencies.lock index 5b6ba143..b160018b 100644 --- a/esp-idf-examples/net_pppos_usb/dependencies.lock +++ b/esp-idf-examples/net_pppos_usb/dependencies.lock @@ -1,6 +1,6 @@ dependencies: espressif/esp_tinyusb: - component_hash: 5e37c53a10518f40b288a48afec4ab549784be9e6eb74add699a30395543418a + component_hash: 96d232ced7afe1976119b62f7fbf1944a2a78b36228ff6f7b9318394ac1153cc dependencies: - name: idf require: private @@ -8,14 +8,11 @@ dependencies: - name: espressif/tinyusb registry_url: https://components.espressif.com require: public - version: 0.* + version: '>=0.14.2' source: registry_url: https://components.espressif.com/ type: service - targets: - - esp32s2 - - esp32s3 - version: 1.0.3 + version: 1.7.6~1 espressif/tinyusb: component_hash: aa65639878f27a44d349044afd9c3fc134a92bd560874fdac1d836019b5c07ca dependencies: @@ -37,6 +34,6 @@ dependencies: direct_dependencies: - espressif/esp_tinyusb - idf -manifest_hash: 0fb80733b490b7c3191c616db6fa2692104ac8ff61cac960aa2413cb8efc9e8b +manifest_hash: 48b4bc7b2d1d1a86ac200b84fcb27696d651413d6f3c9dda6ae42be38b4b1ee3 target: esp32s3 version: 2.0.0 diff --git a/esp-idf-examples/net_pppos_usb/main/idf_component.yml b/esp-idf-examples/net_pppos_usb/main/idf_component.yml index f82f7865..2f216ec5 100644 --- a/esp-idf-examples/net_pppos_usb/main/idf_component.yml +++ b/esp-idf-examples/net_pppos_usb/main/idf_component.yml @@ -14,4 +14,4 @@ dependencies: # # `public` flag doesn't have an effect dependencies of the `main` component. # # All dependencies of `main` are public by default. # public: true - espressif/esp_tinyusb: ~1.0.0 + espressif/esp_tinyusb: ^1.7.6~1 From ddc88964d95c4b2f1d6c4fb4fc1d570dbbada170 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 02:36:28 -0600 Subject: [PATCH 025/142] usb --- esp-idf-examples/net_pppos_usb/sdkconfig.defaults | 3 +++ 1 file changed, 3 insertions(+) diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults index 4b78d39a..2ba10c22 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults @@ -12,3 +12,6 @@ CONFIG_LWIP_PPP_PAP_SUPPORT=y CONFIG_LWIP_PPP_CHAP_SUPPORT=y CONFIG_LWIP_ENABLE_LCP_ECHO=y CONFIG_LWIP_PPP_DEBUG_ON=y +CONFIG_TINYUSB_DEBUG_LEVEL=02 +CONFIG_TINYUSB_CDC_ENABLED=y +CONFIG_TINYUSB_CDC_COUNT=2 From b7cd1ad29c83d1221f05d8b4ecd9cc7eb520d971 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 02:50:22 -0600 Subject: [PATCH 026/142] usb --- esp-idf-examples/net_pppos_usb/config.nims | 1 - src/nesper/esp/net/esp_netif_types.nim | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index 43733b68..34429827 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -1,4 +1,3 @@ - switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants diff --git a/src/nesper/esp/net/esp_netif_types.nim b/src/nesper/esp/net/esp_netif_types.nim index 9f2211c4..e8be5a18 100644 --- a/src/nesper/esp/net/esp_netif_types.nim +++ b/src/nesper/esp/net/esp_netif_types.nim @@ -105,7 +105,7 @@ type ## @brief IP event base declaration -# ESP_EVENT_DECLARE_BASE(IP_EVENT) +let IP_EVENT* {.importc: "IP_EVENT", header: "esp_netif_types.h".}: esp_event_base_t type From dd53790ffc5f6a1c6d376b02105c027a1736aa0b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 02:59:44 -0600 Subject: [PATCH 027/142] usb --- .../main/usb/ppp_connect_usb_dualcdc.nim | 2 - .../components/esp_tinyusb/tusb_types.nim | 45 ++++++++++--------- src/nesper/esp/net/esp_netif_types.nim | 9 +--- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim index c4679cf1..0455780f 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim @@ -17,8 +17,6 @@ const proc esp_tusb_init_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_init_console", header: "tusb_console.h".} proc esp_tusb_deinit_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_deinit_console", header: "tusb_console.h".} -# Optional IP_EVENT base import (for filtering). tcpip_adapter.h provides symbol across IDF versions. -var IP_EVENT* {.importc: "IP_EVENT", header: "tcpip_adapter.h".}: esp_event_base_t # State var diff --git a/src/nesper/components/esp_tinyusb/tusb_types.nim b/src/nesper/components/esp_tinyusb/tusb_types.nim index 70d579ca..30c3a0ad 100644 --- a/src/nesper/components/esp_tinyusb/tusb_types.nim +++ b/src/nesper/components/esp_tinyusb/tusb_types.nim @@ -36,7 +36,10 @@ ## Declare an endpoint buffer with a type -const hdr_acm = "tusb_cdc_acm.h" +# const hdr_acm = "tusb_cdc_acm.h" +# const hdr = "tusb_types.h" +const hdr_acm = "tusb.h" +const hdr = "tusb.h" type cdc_line_coding_t* {.importc: "cdc_line_coding_t", header: hdr_acm, bycopy.} = object @@ -218,7 +221,7 @@ const type - tusb_rhport_init_t* {.importc: "tusb_rhport_init_t", header: "tusb_types.h", + tusb_rhport_init_t* {.importc: "tusb_rhport_init_t", header: hdr, bycopy.} = object ## --------------------------------------------------------------------+ ## ## --------------------------------------------------------------------+ @@ -226,7 +229,7 @@ type speed* {.importc: "speed".}: tusb_speed_t - tusb_desc_device_t* {.importc: "tusb_desc_device_t", header: "tusb_types.h", + tusb_desc_device_t* {.importc: "tusb_desc_device_t", header: hdr, bycopy.} = object ## --------------------------------------------------------------------+ ## USB Descriptors ## --------------------------------------------------------------------+ @@ -258,7 +261,7 @@ type type - tusb_desc_bos_t* {.importc: "tusb_desc_bos_t", header: "tusb_types.h", bycopy.} = object ## + tusb_desc_bos_t* {.importc: "tusb_desc_bos_t", header: hdr, bycopy.} = object ## ## USB Binary Device Object Store (BOS) Descriptor bLength* {.importc: "bLength".}: uint8 ## < Size of this descriptor in bytes bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## @@ -272,7 +275,7 @@ type type tusb_desc_configuration_t* {.importc: "tusb_desc_configuration_t", - header: "tusb_types.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## USB Configuration Descriptor bLength* {.importc: "bLength".}: uint8 ## < Size of this descriptor in bytes bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## @@ -294,7 +297,7 @@ type type tusb_desc_interface_t* {.importc: "tusb_desc_interface_t", - header: "tusb_types.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## USB Interface Descriptor bLength* {.importc: "bLength".}: uint8 ## < Size of this descriptor in bytes bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## @@ -318,7 +321,7 @@ type type TU_ATTR_PACKED_tusb_types_1* {.importc: "tusb_desc_endpoint_t::no_name", - header: "tusb_types.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## USB Endpoint Descriptor xfer* {.importc: "xfer", bitsize: 2.}: uint8 ## Control, ISO, Bulk, Interrupt sync* {.importc: "sync", bitsize: 2.}: uint8 ## None, Asynchronous, Adaptive, Synchronous @@ -327,7 +330,7 @@ type tusb_desc_endpoint_t* {.importc: "tusb_desc_endpoint_t", - header: "tusb_types.h", bycopy.} = object + header: hdr, bycopy.} = object bLength* {.importc: "bLength".}: uint8 ## Size of this descriptor in bytes bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## ## ENDPOINT Descriptor Type @@ -343,7 +346,7 @@ type type tusb_desc_other_speed_t* {.importc: "tusb_desc_other_speed_t", - header: "tusb_types.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## USB Other Speed Configuration Descriptor bLength* {.importc: "bLength".}: uint8 ## < Size of descriptor bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## @@ -363,7 +366,7 @@ type tusb_desc_device_qualifier_t* {.importc: "tusb_desc_device_qualifier_t", - header: "tusb_types.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## USB Device Qualifier Descriptor bLength* {.importc: "bLength".}: uint8 ## < Size of descriptor bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## @@ -387,7 +390,7 @@ type type tusb_desc_interface_assoc_t* {.importc: "tusb_desc_interface_assoc_t", - header: "tusb_types.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## USB Interface Association Descriptor (IAD ECN) bLength* {.importc: "bLength".}: uint8 ## < Size of descriptor bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## @@ -408,7 +411,7 @@ type type - tusb_desc_string_t* {.importc: "tusb_desc_string_t", header: "tusb_types.h", + tusb_desc_string_t* {.importc: "tusb_desc_string_t", header: hdr, bycopy.} = object ## USB String Descriptor bLength* {.importc: "bLength".}: uint8 ## < Size of this descriptor in bytes bDescriptorType* {.importc: "bDescriptorType".}: uint8 ## @@ -417,7 +420,7 @@ type tusb_desc_bos_platform_t* {.importc: "tusb_desc_bos_platform_t", - header: "tusb_types.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## USB Binary Device Object Store (BOS) bLength* {.importc: "bLength".}: uint8 bDescriptorType* {.importc: "bDescriptorType".}: uint8 @@ -429,7 +432,7 @@ type tusb_desc_webusb_url_t* {.importc: "tusb_desc_webusb_url_t", - header: "tusb_types.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## USB WebUSB URL Descriptor bLength* {.importc: "bLength".}: uint8 bDescriptorType* {.importc: "bDescriptorType".}: uint8 @@ -438,7 +441,7 @@ type TU_ATTR_PACKED_tusb_types_5* {.importc: "tusb_desc_dfu_functional_t::no_name", - header: "tusb_types.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## DFU Functional Descriptor bitCanDnload* {.importc: "bitCanDnload", bitsize: 1.}: uint8 bitCanUpload* {.importc: "bitCanUpload", bitsize: 1.}: uint8 @@ -448,7 +451,7 @@ type tusb_desc_dfu_functional_t* {.importc: "tusb_desc_dfu_functional_t", - header: "tusb_types.h", bycopy.} = object + header: hdr, bycopy.} = object bLength* {.importc: "bLength".}: uint8 bDescriptorType* {.importc: "bDescriptorType".}: uint8 bmAttributes* {.importc: "bmAttributes".}: TU_ATTR_PACKED_tusb_types_5 @@ -459,7 +462,7 @@ type TU_ATTR_PACKED_tusb_types_9* {.importc: "tusb_control_request_t::no_name", - header: "tusb_types.h", bycopy.} = object ## + header: hdr, bycopy.} = object ## ## --------------------------------------------------------------------+ ## ## --------------------------------------------------------------------+ @@ -472,7 +475,7 @@ type tusb_control_request_t* {.importc: "tusb_control_request_t", - header: "tusb_types.h", bycopy.} = object + header: hdr, bycopy.} = object bmRequestType_bit* {.importc: "bmRequestType_bit".}: TU_ATTR_PACKED_tusb_types_9 bmRequestType* {.importc: "bmRequestType".}: uint8 bRequest* {.importc: "bRequest".}: uint8 @@ -521,17 +524,17 @@ proc tu_desc_subtype*(desc: pointer): uint8 {.inline, cdecl, ## get descriptor subtype proc tu_desc_find*(desc: ptr uint8; `end`: ptr uint8; byte1: uint8): ptr uint8 {. - cdecl, importc: "tu_desc_find", header: "tusb_types.h".} + cdecl, importc: "tu_desc_find", header: hdr.} ## ## find descriptor that match byte1 (type) proc tu_desc_find2*(desc: ptr uint8; `end`: ptr uint8; byte1: uint8; byte2: uint8): ptr uint8 {.cdecl, importc: "tu_desc_find2", - header: "tusb_types.h".} + header: hdr.} ## find descriptor that match byte1 (type) and byte2 proc tu_desc_find3*(desc: ptr uint8; `end`: ptr uint8; byte1: uint8; byte2: uint8; byte3: uint8): ptr uint8 {.cdecl, - importc: "tu_desc_find3", header: "tusb_types.h".} + importc: "tu_desc_find3", header: hdr.} ## ## find descriptor that match byte1 (type) and byte2 \ No newline at end of file diff --git a/src/nesper/esp/net/esp_netif_types.nim b/src/nesper/esp/net/esp_netif_types.nim index e8be5a18..9892103a 100644 --- a/src/nesper/esp/net/esp_netif_types.nim +++ b/src/nesper/esp/net/esp_netif_types.nim @@ -304,8 +304,6 @@ type ## !< LwIP bridge configuration - esp_netif_config_t* = esp_netif_config - esp_netif_iodriver_handle* = pointer ## ## @brief IO driver handle type ## @@ -323,7 +321,7 @@ type ## !< netif handle - esp_netif_driver_ifconfig* {.importc: "esp_netif_driver_ifconfig", + esp_netif_driver_ifconfig_t* {.importc: "esp_netif_driver_ifconfig_t", header: hdr, bycopy.} = object ## ## ## @brief Specific IO driver configuration @@ -342,15 +340,12 @@ type cdecl.} ## !< set mac filter function pointer - - esp_netif_driver_ifconfig_t* = esp_netif_driver_ifconfig - esp_netif_netstack_config_t* = esp_netif_netstack_config ## ## ## @brief Specific L3 network stack configuration ## - esp_netif_config* {.importc: "esp_netif_config", header: hdr, + esp_netif_config_t* {.importc: "esp_netif_config_t", header: hdr, bycopy.} = object ## ## @brief Generic esp_netif configuration ## From ffce0fbace76963647e35b62d0294267989eb5f8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 03:16:28 -0600 Subject: [PATCH 028/142] usb --- src/nesper/esp/net/esp_netif_defaults.nim | 7 ++++++- src/nesper/esp/net/esp_netif_types.nim | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/nesper/esp/net/esp_netif_defaults.nim b/src/nesper/esp/net/esp_netif_defaults.nim index 4845888e..5dd60bd3 100644 --- a/src/nesper/esp/net/esp_netif_defaults.nim +++ b/src/nesper/esp/net/esp_netif_defaults.nim @@ -27,7 +27,12 @@ proc ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN*(): esp_netif_inherent_config_t {.impor proc ESP_NETIF_INHERENT_DEFAULT_ETH*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_ETH", header: hdr.} -proc ESP_NETIF_INHERENT_DEFAULT_PPP*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_PPP", header: hdr.} +proc ESP_NETIF_INHERENT_DEFAULT_PPP*(): esp_netif_inherent_config_t = + {.emit: """ + esp_netif_inherent_config_t cfg = ESP_NETIF_INHERENT_DEFAULT_PPP(); + `result` = cfg; + """.} + proc ESP_NETIF_INHERENT_DEFAULT_BR*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_BR", header: hdr.} diff --git a/src/nesper/esp/net/esp_netif_types.nim b/src/nesper/esp/net/esp_netif_types.nim index 9892103a..c052c207 100644 --- a/src/nesper/esp/net/esp_netif_types.nim +++ b/src/nesper/esp/net/esp_netif_types.nim @@ -210,9 +210,9 @@ else: type err_t* = distinct int8 - net_if* {.importc: "netif", header: hdr, bycopy.} = object + netif* {.importc: "netif", header: hdr, bycopy.} = object - init_fn_t* = proc (a1: ptr netif): err_t {.cdecl.} + init_fn_t* = proc (a1: pointer): err_t {.cdecl.} input_fn_t* = proc (netif: pointer; buffer: pointer; len: csize_t; eb: pointer): esp_netif_recv_ret_t {. cdecl.} From 6d264df73cfd088970de3d8ef9044d568d4617f2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 03:17:26 -0600 Subject: [PATCH 029/142] usb --- src/nesper/esp/net/esp_netif_defaults.nim | 66 +++++++++++++++++++---- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/src/nesper/esp/net/esp_netif_defaults.nim b/src/nesper/esp/net/esp_netif_defaults.nim index 5dd60bd3..ca3cb9f9 100644 --- a/src/nesper/esp/net/esp_netif_defaults.nim +++ b/src/nesper/esp/net/esp_netif_defaults.nim @@ -19,13 +19,29 @@ let ## @brief Default configuration reference of ethernet interface ## -proc ESP_NETIF_INHERENT_DEFAULT_WIFI_STA*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_STA", header: hdr.} +proc ESP_NETIF_INHERENT_DEFAULT_WIFI_STA*(): esp_netif_inherent_config_t = + {.emit: """ + esp_netif_inherent_config_t cfg = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA(); + `result` = cfg; + """.} -proc ESP_NETIF_INHERENT_DEFAULT_WIFI_AP*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_AP", header: hdr.} +proc ESP_NETIF_INHERENT_DEFAULT_WIFI_AP*(): esp_netif_inherent_config_t = + {.emit: """ + esp_netif_inherent_config_t cfg = ESP_NETIF_INHERENT_DEFAULT_WIFI_AP(); + `result` = cfg; + """.} -proc ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN", header: hdr.} +proc ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN*(): esp_netif_inherent_config_t = + {.emit: """ + esp_netif_inherent_config_t cfg = ESP_NETIF_INHERENT_DEFAULT_WIFI_NAN(); + `result` = cfg; + """.} -proc ESP_NETIF_INHERENT_DEFAULT_ETH*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_ETH", header: hdr.} +proc ESP_NETIF_INHERENT_DEFAULT_ETH*(): esp_netif_inherent_config_t = + {.emit: """ + esp_netif_inherent_config_t cfg = ESP_NETIF_INHERENT_DEFAULT_ETH(); + `result` = cfg; + """.} proc ESP_NETIF_INHERENT_DEFAULT_PPP*(): esp_netif_inherent_config_t = {.emit: """ @@ -34,19 +50,47 @@ proc ESP_NETIF_INHERENT_DEFAULT_PPP*(): esp_netif_inherent_config_t = """.} -proc ESP_NETIF_INHERENT_DEFAULT_BR*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_BR", header: hdr.} +proc ESP_NETIF_INHERENT_DEFAULT_BR*(): esp_netif_inherent_config_t = + {.emit: """ + esp_netif_inherent_config_t cfg = ESP_NETIF_INHERENT_DEFAULT_BR(); + `result` = cfg; + """.} -proc ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS*(): esp_netif_inherent_config_t {.importc: "ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS", header: hdr.} +proc ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS*(): esp_netif_inherent_config_t = + {.emit: """ + esp_netif_inherent_config_t cfg = ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS(); + `result` = cfg; + """.} -proc ESP_NETIF_DEFAULT_ETH*(): esp_netif_config_t {.importc: "ESP_NETIF_DEFAULT_ETH", header: hdr.} +proc ESP_NETIF_DEFAULT_ETH*(): esp_netif_config_t = + {.emit: """ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH(); + `result` = cfg; + """.} -proc ESP_NETIF_DEFAULT_WIFI_AP*(): esp_netif_config_t {.importc: "ESP_NETIF_DEFAULT_WIFI_AP", header: hdr.} +proc ESP_NETIF_DEFAULT_WIFI_AP*(): esp_netif_config_t = + {.emit: """ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_AP(); + `result` = cfg; + """.} -proc ESP_NETIF_DEFAULT_WIFI_NAN*(): esp_netif_config_t {.importc: "ESP_NETIF_DEFAULT_WIFI_NAN", header: hdr.} +proc ESP_NETIF_DEFAULT_WIFI_NAN*(): esp_netif_config_t = + {.emit: """ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_NAN(); + `result` = cfg; + """.} -proc ESP_NETIF_DEFAULT_WIFI_STA*(): esp_netif_config_t {.importc: "ESP_NETIF_DEFAULT_WIFI_STA", header: hdr.} +proc ESP_NETIF_DEFAULT_WIFI_STA*(): esp_netif_config_t = + {.emit: """ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_STA(); + `result` = cfg; + """.} -proc ESP_NETIF_DEFAULT_PPP*(): esp_netif_config_t {.importc: "ESP_NETIF_DEFAULT_PPP", header: hdr.} +proc ESP_NETIF_DEFAULT_PPP*(): esp_netif_config_t = + {.emit: """ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_PPP(); + `result` = cfg; + """.} let From 036be98c5cd47f2904396d87087e4d688be61fcd Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 03:17:43 -0600 Subject: [PATCH 030/142] usb --- nesper.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesper.nimble b/nesper.nimble index e96be411..28b8c9dd 100644 --- a/nesper.nimble +++ b/nesper.nimble @@ -1,6 +1,6 @@ # Package -version = "0.8.1" +version = "0.8.3" author = "Jaremy Creechley" description = "Nim wrappers for ESP-IDF (ESP32)" license = "Apache-2.0" From bf8548cd9f988070200fd7f79d6bfc72f6c83215 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 03:18:02 -0600 Subject: [PATCH 031/142] usb --- nesper.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesper.nimble b/nesper.nimble index 28b8c9dd..e3067769 100644 --- a/nesper.nimble +++ b/nesper.nimble @@ -1,6 +1,6 @@ # Package -version = "0.8.3" +version = "0.8.2" author = "Jaremy Creechley" description = "Nim wrappers for ESP-IDF (ESP32)" license = "Apache-2.0" From 3861b4422e2d35f55a7630f51ade935ea2b24573 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 14:19:01 -0600 Subject: [PATCH 032/142] usb --- esp-idf-examples/net_pppos_usb/main/main.nim | 3 ++- .../main/usb/ppp_connect_usb_dualcdc.nim | 11 +++-------- esp-idf-examples/net_pppos_usb/sdkconfig.defaults | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 1bbb359b..df190bcf 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -50,4 +50,5 @@ app_main: # Keep app alive; clean shutdown not triggered in this minimal example while true: - delay(2_000.Millis) + logi(TAG, "PPPoS connected. Idle loop ...") + delay(1_000.Millis) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim index 0455780f..7a4c174f 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim @@ -1,14 +1,9 @@ import nesper import nesper/[general] -import nesper/esp/esp_log -import nesper/esp/esp_event +import nesper/esp/[esp_log, esp_event, event_groups] import nesper/events -import nesper/esp/event_groups -import nesper/esp/net/esp_netif -import nesper/esp/net/esp_netif_ppp -import nesper/esp/net/esp_netif_types -import nesper/components/esp_tinyusb/tinyusb -import nesper/components/esp_tinyusb/tusb_cdc_acm +import nesper/esp/net/[esp_netif, esp_netif_ppp, esp_netif_types] +import nesper/components/esp_tinyusb/[tinyusb, tusb_cdc_acm] const TAG* = "pppos_dualcdc" diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults index 2ba10c22..f858415b 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults @@ -6,7 +6,7 @@ CONFIG_APP_NO_BLOBS=y CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_ESP_CONSOLE_USB_CDC=y +#CONFIG_ESP_CONSOLE_USB_CDC=y CONFIG_LWIP_PPP_SUPPORT=y CONFIG_LWIP_PPP_PAP_SUPPORT=y CONFIG_LWIP_PPP_CHAP_SUPPORT=y From 4719dce11d860410f420661279f90b2ec4feebdd Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 14:19:56 -0600 Subject: [PATCH 033/142] usb --- esp-idf-examples/net_pppos_usb/sdkconfig.defaults | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults index f858415b..6828fc09 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults @@ -6,7 +6,8 @@ CONFIG_APP_NO_BLOBS=y CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y CONFIG_PARTITION_TABLE_CUSTOM=y -#CONFIG_ESP_CONSOLE_USB_CDC=y +CONFIG_USJ_ENABLE_USB_SERIAL_JTAG=n +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y CONFIG_LWIP_PPP_SUPPORT=y CONFIG_LWIP_PPP_PAP_SUPPORT=y CONFIG_LWIP_PPP_CHAP_SUPPORT=y From 696f09bbb8d3fa4e13f034dd4306a09bf54d3d80 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:09:35 -0600 Subject: [PATCH 034/142] usb --- .../main/usb/ppp_connect_usb_dualcdc.c | 194 ------------------ .../net_pppos_usb/main/usb/tusb_ncm.nim | 4 +- .../net_pppos_usb/main/usb/tusb_ncm_eth.nim | 103 ++++++++++ 3 files changed, 105 insertions(+), 196 deletions(-) delete mode 100644 esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.c create mode 100644 esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim diff --git a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.c b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.c deleted file mode 100644 index fdafdac1..00000000 --- a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Dual-CDC PPPoS over USB example - * - CDC ACM 0: PPP data channel (PPPoS) - * - CDC ACM 1: Console/log output via TinyUSB console - */ - -#include -#include -#include "sdkconfig.h" -#include "protocol_examples_common.h" -#include "example_common_private.h" - -#include "esp_log.h" -#include "esp_netif.h" -#include "esp_netif_ppp.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - -#include "tinyusb.h" -#include "tusb_cdc_acm.h" -#include "tusb_console.h" - -static const char *TAG = "pppos_dualcdc"; - -/* PPP state */ -static esp_netif_t *s_netif; -static EventGroupHandle_t s_event_group; -static const int GOT_IPV4 = BIT0; -static const int CONNECTION_FAILED = BIT1; -static const int GOT_IPV6 = BIT2; -#define CONNECT_BITS (GOT_IPV4|GOT_IPV6|CONNECTION_FAILED) - -/* USB-CDC state */ -static int s_ppp_itf = TINYUSB_CDC_ACM_0; /* PPP on CDC0 */ -static int s_log_itf = TINYUSB_CDC_ACM_1; /* Console on CDC1 */ -static uint8_t s_rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE]; - -/* PPP transmit: push bytes onto PPP CDC interface */ -static esp_err_t transmit(void *h, void *buffer, size_t len) -{ - (void)h; - ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); - tinyusb_cdcacm_write_queue(s_ppp_itf, buffer, len); - tinyusb_cdcacm_write_flush(s_ppp_itf, 0); - return ESP_OK; -} - -static esp_netif_driver_ifconfig_t s_driver_cfg = { - .handle = (void *)1, /* singleton driver, just != NULL */ - .transmit = transmit, -}; - -/* IP events */ -static void on_ip_event(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - if (event_id == IP_EVENT_PPP_GOT_IP) { - ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; - if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { - return; - } - esp_netif_t *netif = event->esp_netif; - esp_netif_dns_info_t dns_info; - ESP_LOGI(TAG, "Got IPv4: %s " IPSTR, esp_netif_get_desc(netif), IP2STR(&event->ip_info.ip)); - esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info); - ESP_LOGI(TAG, "DNS: " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); - xEventGroupSetBits(s_event_group, GOT_IPV4); - } else if (event_id == IP_EVENT_GOT_IP6) { - ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; - if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { - return; - } - esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); - ESP_LOGI(TAG, "Got IPv6: %s " IPV6STR ", type: %d", esp_netif_get_desc(event->esp_netif), - IPV62STR(event->ip6_info.ip), ipv6_type); - xEventGroupSetBits(s_event_group, GOT_IPV6); - } else if (event_id == IP_EVENT_PPP_LOST_IP) { - ESP_LOGI(TAG, "PPP disconnected"); - xEventGroupSetBits(s_event_group, CONNECTION_FAILED); - } -} - -/* CDC RX for PPP interface: push to esp_netif */ -static void cdc_rx_callback(int itf, cdcacm_event_t *event) -{ - size_t rx_size = 0; - if (itf != s_ppp_itf) { - return; /* not our PPP channel */ - } - if (tinyusb_cdcacm_read(itf, s_rx_buf, sizeof(s_rx_buf), &rx_size) == ESP_OK) { - if (rx_size) { - ESP_LOG_BUFFER_HEXDUMP(TAG, s_rx_buf, rx_size, ESP_LOG_VERBOSE); - esp_netif_receive(s_netif, s_rx_buf, rx_size, NULL); - } - } else { - ESP_LOGE(TAG, "CDC read error"); - } -} - -/* Optionally track line state for PPP interface */ -static void line_state_changed(int itf, cdcacm_event_t *event) -{ - ESP_LOGI(TAG, "Line state changed on itf %d", itf); -} - -/* Public helpers to start/stop PPP over CDC0 and console on CDC1 */ -esp_err_t example_ppp_connect_dualcdc(void) -{ - ESP_LOGI(TAG, "Starting dual-CDC PPPoS (PPP on CDC0, console on CDC1)"); - - /* Install TinyUSB */ - const tinyusb_config_t tusb_cfg = { - .device_descriptor = NULL, - .string_descriptor = NULL, - .external_phy = false, -#if (TUD_OPT_HIGH_SPEED) - .fs_configuration_descriptor = NULL, - .hs_configuration_descriptor = NULL, - .qualifier_descriptor = NULL, -#else - .configuration_descriptor = NULL, -#endif - }; - ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); - - /* Init CDC0 for PPP */ - tinyusb_config_cdcacm_t acm_ppp = { - .usb_dev = TINYUSB_USBDEV_0, - .cdc_port = TINYUSB_CDC_ACM_0, - .callback_rx = &cdc_rx_callback, - .callback_rx_wanted_char = NULL, - .callback_line_state_changed = &line_state_changed, - .callback_line_coding_changed = NULL, - }; - ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_ppp)); - - /* Init CDC1 for console/logs */ - tinyusb_config_cdcacm_t acm_log = { - .usb_dev = TINYUSB_USBDEV_0, - .cdc_port = TINYUSB_CDC_ACM_1, - }; - ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_log)); - - /* Route console/log output to CDC1 */ - ESP_ERROR_CHECK(esp_tusb_init_console(TINYUSB_CDC_ACM_1)); - - /* Events and PPP netif */ - s_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL)); - - esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_PPP(); - base_cfg.if_desc = EXAMPLE_NETIF_DESC_PPP; - esp_netif_config_t netif_cfg = { - .base = &base_cfg, - .driver = &s_driver_cfg, - .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP, - }; - - s_netif = esp_netif_new(&netif_cfg); - assert(s_netif); - - /* Bring interface up and signal connected */ - esp_netif_action_start(s_netif, 0, 0, 0); - esp_netif_action_connected(s_netif, 0, 0, 0); - - ESP_LOGI(TAG, "Waiting for IP..."); - EventBits_t bits = xEventGroupWaitBits(s_event_group, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY); - if (bits & CONNECTION_FAILED) { - ESP_LOGE(TAG, "PPP connection failed"); - return ESP_FAIL; - } - ESP_LOGI(TAG, "PPP connected"); - return ESP_OK; -} - -void example_ppp_shutdown_dualcdc(void) -{ - ESP_LOGI(TAG, "Shutting down PPP and console"); - - esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event); - if (s_netif) { - esp_netif_action_disconnected(s_netif, 0, 0, 0); - esp_netif_action_stop(s_netif, 0, 0, 0); - esp_netif_destroy(s_netif); - s_netif = NULL; - } - if (s_event_group) { - vEventGroupDelete(s_event_group); - s_event_group = NULL; - } - /* Restore console to UART if desired */ - esp_tusb_deinit_console(TINYUSB_CDC_ACM_1); -} - diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim index d822c2c8..3ac10b7b 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim @@ -5,7 +5,6 @@ import nesper/esp/nvs_flash import nesper/net_utils import nesper/components/esp_tinyusb/tinyusb import nesper/consts -import nesper/components/esp_tinyusb/tinyusb const TAG* = "USB_NCM" @@ -15,10 +14,11 @@ const # TinyUSB NET type/procs (no emit) type tinyusb_net_config_t* {.importc: "tinyusb_net_config_t", header: "tinyusb_net.h", bycopy.} = object + mac_addr* {.importc: "mac_addr".}: array[6, uint8] on_recv_callback* {.importc: "on_recv_callback".}: proc (buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.} free_tx_buffer* {.importc: "free_tx_buffer".}: proc (eb: pointer; ctx: pointer) {.cdecl.} + on_init_callback* {.importc: "on_init_callback".}: proc (ctx: pointer) {.cdecl.} user_context* {.importc: "user_context".}: pointer - mac_addr* {.importc: "mac_addr".}: array[6, uint8] proc tinyusb_net_init*(dev: tinyusb_usbdev_t; cfg: ptr tinyusb_net_config_t): esp_err_t {.cdecl, importc: "tinyusb_net_init", header: "tinyusb_net.h".} proc tinyusb_net_send_sync*(buffer: pointer; len: uint16; eb: pointer; timeout_ticks: uint32): esp_err_t {.cdecl, importc: "tinyusb_net_send_sync", header: "tinyusb_net.h".} diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim new file mode 100644 index 00000000..9f6cfc5f --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim @@ -0,0 +1,103 @@ +import nesper +import nesper/[general, events] +import nesper/esp/esp_system +import nesper/esp/nvs_flash +import nesper/esp/net/esp_netif +import nesper/esp/net/esp_netif_types +import nesper/esp/net/esp_netif_defaults +import nesper/components/esp_tinyusb/tinyusb + +# TinyUSB NET imports +type + tinyusb_net_config_t* {.importc: "tinyusb_net_config_t", header: "tinyusb_net.h", bycopy.} = object + mac_addr* {.importc: "mac_addr".}: array[6, uint8] + on_recv_callback* {.importc: "on_recv_callback".}: proc (buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.} + free_tx_buffer* {.importc: "free_tx_buffer".}: proc (eb: pointer; ctx: pointer) {.cdecl.} + on_init_callback* {.importc: "on_init_callback".}: proc (ctx: pointer) {.cdecl.} + user_context* {.importc: "user_context".}: pointer + +proc tinyusb_net_init*(dev: tinyusb_usbdev_t; cfg: ptr tinyusb_net_config_t): esp_err_t {.cdecl, importc: "tinyusb_net_init", header: "tinyusb_net.h".} +proc tinyusb_net_send_sync*(buffer: pointer; len: uint16; eb: pointer; timeout_ticks: uint32): esp_err_t {.cdecl, importc: "tinyusb_net_send_sync", header: "tinyusb_net.h".} + +const TAG* = "USB_NCM_ETH" + +var + sNetif: ptr esp_netif_t + +# RX from USB NCM into esp-netif (L3 stack) +proc ncmRecvToNetif(buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.} = + if sNetif != nil and len.uint32 > 0'u32: + discard esp_netif_receive(sNetif, buffer, len.csize_t, nil) + return ESP_OK + +# esp-netif transmit to USB NCM +proc ncmTransmit(h: pointer; buffer: pointer; len: csize_t): esp_err_t {.cdecl.} = + let res = tinyusb_net_send_sync(buffer, uint16(len), nil, portMAX_DELAY.uint32) + return res + +# IP event logging +proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = + if event_base == IP_EVENT and event_id == IP_EVENT_GOT_IP6.int32: + let ev6 = cast[ptr ip_event_got_ip6_t](event_data) + if ev6.esp_netif == sNetif: + logi(TAG, "Got IPv6: %s", $ev6.ip6_info.ip) + elif event_base == IP_EVENT and event_id == IP_EVENT_ETH_GOT_IP.int32: + let ev = cast[ptr ip_event_got_ip_t](event_data) + if ev.esp_netif == sNetif: + logi(TAG, "Got IPv4: %s", $ev.ip_info.ip) + +proc runUsbNcmAsEth*() = + # NVS init (common) + var ret = nvs_flash_init() + if ret == ESP_ERR_NVS_NO_FREE_PAGES or ret == ESP_ERR_NVS_NEW_VERSION_FOUND: + check: nvs_flash_erase() + ret = nvs_flash_init() + check: ret + + # Netif + event loop + check: esp_netif_init() + check: esp_event_loop_create_default() + + # TinyUSB init + var tusbCfg: tinyusb_config_t + tusbCfg.external_phy = false + check: tinyusb_driver_install(addr tusbCfg) + + # MAC address + var mac: array[6, uint8] + check: esp_read_mac(addr mac[0], ESP_MAC_WIFI_STA) + logi(TAG, "Using MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0].int, mac[1].int, mac[2].int, mac[3].int, mac[4].int, mac[5].int) + + # TinyUSB NET config + var ncfg: tinyusb_net_config_t + for i in 0..5: ncfg.mac_addr[i] = mac[i] + ncfg.on_recv_callback = ncmRecvToNetif + ncfg.free_tx_buffer = nil + ncfg.on_init_callback = nil + ncfg.user_context = nil + check: tinyusb_net_init(TINYUSB_USBDEV_0, addr ncfg) + + # Create an Ethernet-like esp-netif bound to NCM + var baseCfg = ESP_NETIF_INHERENT_DEFAULT_ETH() + baseCfg.if_desc = "usb_ncm_eth" + var driverCfg: esp_netif_driver_ifconfig_t + driverCfg.handle = cast[pointer](1) + driverCfg.transmit = ncmTransmit + var netifCfg: esp_netif_config_t + netifCfg.base = addr baseCfg + netifCfg.driver = addr driverCfg + netifCfg.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH + + sNetif = esp_netif_new(addr netifCfg) + doAssert sNetif != nil + discard esp_netif_set_mac(sNetif, addr mac[0]) + + # Listen for IP events + check: esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, onIpEvent, nil) + + # Bring up interface; DHCP client should run per default ETH config + esp_netif_action_start(sNetif, nil, 0, nil) + esp_netif_action_connected(sNetif, nil, 0, nil) + + logi(TAG, "USB NCM Ethernet-like interface started") + From a999d85f6c76dafd563bcc0b8cb7d492e82ff92a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:09:55 -0600 Subject: [PATCH 035/142] usb --- esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim | 7 ------- 1 file changed, 7 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim index 9f6cfc5f..215b34cd 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim @@ -47,13 +47,6 @@ proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; even logi(TAG, "Got IPv4: %s", $ev.ip_info.ip) proc runUsbNcmAsEth*() = - # NVS init (common) - var ret = nvs_flash_init() - if ret == ESP_ERR_NVS_NO_FREE_PAGES or ret == ESP_ERR_NVS_NEW_VERSION_FOUND: - check: nvs_flash_erase() - ret = nvs_flash_init() - check: ret - # Netif + event loop check: esp_netif_init() check: esp_event_loop_create_default() From a1f3b701aad027271c71e99d48944b5e80c7ddb8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:11:49 -0600 Subject: [PATCH 036/142] usb --- .../net_pppos_usb/main/usb/ppp_connect_uart.c | 179 ----------------- .../net_pppos_usb/main/usb/ppp_connect_usb.c | 186 ------------------ .../main/usb/tusb_ncm_eth_dualcdc.nim | 123 ++++++++++++ 3 files changed, 123 insertions(+), 365 deletions(-) delete mode 100644 esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_uart.c delete mode 100644 esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb.c create mode 100644 esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim diff --git a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_uart.c b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_uart.c deleted file mode 100644 index 98db74d6..00000000 --- a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_uart.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include -#include -#include "sdkconfig.h" -#include "protocol_examples_common.h" -#include "example_common_private.h" - -#include "esp_log.h" -#include "esp_netif.h" -#include "esp_netif_ppp.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - -#include "driver/uart.h" -#define BUF_SIZE (1024) -static bool s_stop_task = false; - - -static const char *TAG = "example_connect_ppp"; -static int s_retry_num = 0; -static EventGroupHandle_t s_event_group = NULL; -static esp_netif_t *s_netif; -static const int GOT_IPV4 = BIT0; -static const int CONNECTION_FAILED = BIT1; -#if CONFIG_EXAMPLE_CONNECT_IPV6 -static const int GOT_IPV6 = BIT2; -#define CONNECT_BITS (GOT_IPV4|GOT_IPV6|CONNECTION_FAILED) -#else -#define CONNECT_BITS (GOT_IPV4|CONNECTION_FAILED) -#endif - -static esp_err_t transmit(void *h, void *buffer, size_t len) -{ - ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); - uart_write_bytes(UART_NUM_1, buffer, len); - return ESP_OK; -} - -static esp_netif_driver_ifconfig_t driver_cfg = { - .handle = (void *)1, // singleton driver, just to != NULL - .transmit = transmit, -}; -const esp_netif_driver_ifconfig_t *ppp_driver_cfg = &driver_cfg; - -static void on_ip_event(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - - if (event_id == IP_EVENT_PPP_GOT_IP) { - ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; - if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { - return; - } - esp_netif_t *netif = event->esp_netif; - esp_netif_dns_info_t dns_info; - ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); - esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info); - ESP_LOGI(TAG, "Main DNS server : " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); - xEventGroupSetBits(s_event_group, GOT_IPV4); - } else if (event_id == IP_EVENT_GOT_IP6) { - ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; - if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { - return; - } - esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); - ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), - IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); - if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { - xEventGroupSetBits(s_event_group, GOT_IPV6); - } - } else if (event_id == IP_EVENT_PPP_LOST_IP) { - ESP_LOGI(TAG, "Disconnect from PPP Server"); - s_retry_num++; - if (s_retry_num > CONFIG_EXAMPLE_PPP_CONN_MAX_RETRY) { - ESP_LOGE(TAG, "PPP Connection failed %d times, stop reconnecting.", s_retry_num); - xEventGroupSetBits(s_event_group, CONNECTION_FAILED); - } else { - ESP_LOGI(TAG, "PPP Connection failed %d times, try to reconnect.", s_retry_num); - esp_netif_action_start(s_netif, 0, 0, 0); - esp_netif_action_connected(s_netif, 0, 0, 0); - } - - } -} - - -static void ppp_task(void *args) -{ - uart_config_t uart_config = {}; - uart_config.baud_rate = CONFIG_EXAMPLE_CONNECT_UART_BAUDRATE; - uart_config.data_bits = UART_DATA_8_BITS; - uart_config.parity = UART_PARITY_DISABLE; - uart_config.stop_bits = UART_STOP_BITS_1; - uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; - uart_config.source_clk = UART_SCLK_DEFAULT; - - QueueHandle_t event_queue; - ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, BUF_SIZE, 0, 16, &event_queue, 0)); - ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config)); - ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, CONFIG_EXAMPLE_CONNECT_UART_TX_PIN, CONFIG_EXAMPLE_CONNECT_UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); - ESP_ERROR_CHECK(uart_set_rx_timeout(UART_NUM_1, 1)); - - char *buffer = (char*)malloc(BUF_SIZE); - uart_event_t event; - esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_GOT_IP, esp_netif_action_connected, s_netif); - esp_netif_action_start(s_netif, 0, 0, 0); - esp_netif_action_connected(s_netif, 0, 0, 0); - while (!s_stop_task) { - xQueueReceive(event_queue, &event, pdMS_TO_TICKS(1000)); - if (event.type == UART_DATA) { - size_t len; - uart_get_buffered_data_len(UART_NUM_1, &len); - if (len) { - len = uart_read_bytes(UART_NUM_1, buffer, BUF_SIZE, 0); - ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); - esp_netif_receive(s_netif, buffer, len, NULL); - } - } else { - ESP_LOGW(TAG, "Received UART event: %d", event.type); - } - } - free(buffer); - vTaskDelete(NULL); -} - - -esp_err_t example_ppp_connect(void) -{ - ESP_LOGI(TAG, "Start example_connect."); - - s_event_group = xEventGroupCreate(); - - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL)); - - esp_netif_inherent_config_t base_netif_cfg = ESP_NETIF_INHERENT_DEFAULT_PPP(); - base_netif_cfg.if_desc = EXAMPLE_NETIF_DESC_PPP; - esp_netif_config_t netif_ppp_config = { .base = &base_netif_cfg, - .driver = ppp_driver_cfg, - .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP - }; - - s_netif = esp_netif_new(&netif_ppp_config); - assert(s_netif); - s_stop_task = false; - if (xTaskCreate(ppp_task, "ppp connect", 4096, NULL, 5, NULL) != pdTRUE) { - ESP_LOGE(TAG, "Failed to create a ppp connection task"); - return ESP_FAIL; - } - - ESP_LOGI(TAG, "Waiting for IP address"); - EventBits_t bits = xEventGroupWaitBits(s_event_group, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY); - if (bits & CONNECTION_FAILED) { - ESP_LOGE(TAG, "Connection failed!"); - return ESP_FAIL; - } - ESP_LOGI(TAG, "Connected!"); - - return ESP_OK; -} - -void example_ppp_shutdown(void) -{ - ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event)); - s_stop_task = true; - vTaskDelay(pdMS_TO_TICKS(1000)); // wait for the ppp task to stop - - esp_netif_action_disconnected(s_netif, 0, 0, 0); - - vEventGroupDelete(s_event_group); - esp_netif_action_stop(s_netif, 0, 0, 0); - esp_netif_destroy(s_netif); - s_netif = NULL; - s_event_group = NULL; -} diff --git a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb.c b/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb.c deleted file mode 100644 index 97c0902d..00000000 --- a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include -#include -#include "sdkconfig.h" -#include "protocol_examples_common.h" -#include "example_common_private.h" - -#include "esp_log.h" -#include "esp_netif.h" -#include "esp_netif_ppp.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - -#define CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB 1 - -#include "tinyusb.h" -#include "tusb_cdc_acm.h" - -static int s_itf; -static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE]; - - -static const char *TAG = "example_connect_ppp"; -static int s_retry_num = 0; -static EventGroupHandle_t s_event_group = NULL; -static esp_netif_t *s_netif; -static const int GOT_IPV4 = BIT0; -static const int CONNECTION_FAILED = BIT1; -static const int GOT_IPV6 = BIT2; -#define CONNECT_BITS (GOT_IPV4|GOT_IPV6|CONNECTION_FAILED) - -static esp_err_t transmit(void *h, void *buffer, size_t len) -{ - ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); - - tinyusb_cdcacm_write_queue(s_itf, buffer, len); - tinyusb_cdcacm_write_flush(s_itf, 0); - - return ESP_OK; -} - -static esp_netif_driver_ifconfig_t driver_cfg = { - .handle = (void *)1, // singleton driver, just to != NULL - .transmit = transmit, -}; -const esp_netif_driver_ifconfig_t *ppp_driver_cfg = &driver_cfg; - -static void on_ip_event(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - - if (event_id == IP_EVENT_PPP_GOT_IP) { - ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; - if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { - return; - } - esp_netif_t *netif = event->esp_netif; - esp_netif_dns_info_t dns_info; - ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); - esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info); - ESP_LOGI(TAG, "Main DNS server : " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); - xEventGroupSetBits(s_event_group, GOT_IPV4); - } else if (event_id == IP_EVENT_GOT_IP6) { - ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; - if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { - return; - } - esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); - ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), - IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); - if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { - xEventGroupSetBits(s_event_group, GOT_IPV6); - } - } else if (event_id == IP_EVENT_PPP_LOST_IP) { - ESP_LOGI(TAG, "Disconnect from PPP Server"); - s_retry_num++; - if (s_retry_num > CONFIG_EXAMPLE_PPP_CONN_MAX_RETRY) { - ESP_LOGE(TAG, "PPP Connection failed %d times, stop reconnecting.", s_retry_num); - xEventGroupSetBits(s_event_group, CONNECTION_FAILED); - } else { - ESP_LOGI(TAG, "PPP Connection failed %d times, try to reconnect.", s_retry_num); - esp_netif_action_start(s_netif, 0, 0, 0); - esp_netif_action_connected(s_netif, 0, 0, 0); - } - - } -} - -static void cdc_rx_callback(int itf, cdcacm_event_t *event) -{ - size_t rx_size = 0; - if (itf != s_itf) { - // Not our channel - return; - } - esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); - if (ret == ESP_OK) { - ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_VERBOSE); - // pass the received data to the network interface - esp_netif_receive(s_netif, buf, rx_size, NULL); - } else { - ESP_LOGE(TAG, "Read error"); - } -} - -static void line_state_changed(int itf, cdcacm_event_t *event) -{ - s_itf = itf; // use this channel for the netif communication - ESP_LOGI(TAG, "Line state changed on channel %d", itf); -} - -esp_err_t example_ppp_connect(void) -{ - ESP_LOGI(TAG, "Start example_connect."); - - ESP_LOGI(TAG, "USB initialization"); - const tinyusb_config_t tusb_cfg = { - .device_descriptor = NULL, - .string_descriptor = NULL, - .external_phy = false, - .configuration_descriptor = NULL, - }; - - ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); - - tinyusb_config_cdcacm_t acm_cfg = { - .usb_dev = TINYUSB_USBDEV_0, - .cdc_port = TINYUSB_CDC_ACM_0, - .callback_rx = &cdc_rx_callback, - .callback_rx_wanted_char = NULL, - .callback_line_state_changed = NULL, - .callback_line_coding_changed = NULL - }; - - ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); - /* the second way to register a callback */ - ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( - TINYUSB_CDC_ACM_0, - CDC_EVENT_LINE_STATE_CHANGED, - &line_state_changed)); - - s_event_group = xEventGroupCreate(); - - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL)); - - esp_netif_inherent_config_t base_netif_cfg = ESP_NETIF_INHERENT_DEFAULT_PPP(); - base_netif_cfg.if_desc = EXAMPLE_NETIF_DESC_PPP; - esp_netif_config_t netif_ppp_config = { .base = &base_netif_cfg, - .driver = ppp_driver_cfg, - .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP - }; - - s_netif = esp_netif_new(&netif_ppp_config); - assert(s_netif); - esp_netif_action_start(s_netif, 0, 0, 0); - esp_netif_action_connected(s_netif, 0, 0, 0); - - ESP_LOGI(TAG, "Waiting for IP address"); - EventBits_t bits = xEventGroupWaitBits(s_event_group, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY); - if (bits & CONNECTION_FAILED) { - ESP_LOGE(TAG, "Connection failed!"); - return ESP_FAIL; - } - ESP_LOGI(TAG, "Connected!"); - - return ESP_OK; -} - -void example_ppp_shutdown(void) -{ - ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event)); - - esp_netif_action_disconnected(s_netif, 0, 0, 0); - - vEventGroupDelete(s_event_group); - esp_netif_action_stop(s_netif, 0, 0, 0); - esp_netif_destroy(s_netif); - s_netif = NULL; - s_event_group = NULL; -} - diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim new file mode 100644 index 00000000..74f1d9ca --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim @@ -0,0 +1,123 @@ +import nesper +import nesper/[general, events] +import nesper/esp/esp_log +import nesper/esp/esp_system +import nesper/esp/nvs_flash +import nesper/esp/net/esp_netif +import nesper/esp/net/esp_netif_types +import nesper/esp/net/esp_netif_defaults +import nesper/components/esp_tinyusb/tinyusb +import nesper/components/esp_tinyusb/tusb_cdc_acm + +# TinyUSB NET (NCM) imports +type + tinyusb_net_config_t* {.importc: "tinyusb_net_config_t", header: "tinyusb_net.h", bycopy.} = object + mac_addr* {.importc: "mac_addr".}: array[6, uint8] + on_recv_callback* {.importc: "on_recv_callback".}: proc (buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.} + free_tx_buffer* {.importc: "free_tx_buffer".}: proc (eb: pointer; ctx: pointer) {.cdecl.} + on_init_callback* {.importc: "on_init_callback".}: proc (ctx: pointer) {.cdecl.} + user_context* {.importc: "user_context".}: pointer + +proc tinyusb_net_init*(dev: tinyusb_usbdev_t; cfg: ptr tinyusb_net_config_t): esp_err_t {.cdecl, importc: "tinyusb_net_init", header: "tinyusb_net.h".} +proc tinyusb_net_send_sync*(buffer: pointer; len: uint16; eb: pointer; timeout_ticks: uint32): esp_err_t {.cdecl, importc: "tinyusb_net_send_sync", header: "tinyusb_net.h".} + +# tinyusb console helpers (not wrapped): +proc esp_tusb_init_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_init_console", header: "tusb_console.h".} +proc esp_tusb_deinit_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_deinit_console", header: "tusb_console.h".} + +const TAG* = "ncm_eth_dualcdc" + +var + sNetif: ptr esp_netif_t + +# NCM RX -> L3 stack +proc ncmRecvToNetif(buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.} = + if sNetif != nil and len.uint32 > 0'u32: + discard esp_netif_receive(sNetif, buffer, len.csize_t, nil) + return ESP_OK + +# L3 TX -> NCM +proc ncmTransmit(h: pointer; buffer: pointer; len: csize_t): esp_err_t {.cdecl.} = + result = tinyusb_net_send_sync(buffer, uint16(len), nil, portMAX_DELAY.uint32) + +# IP event logging +proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = + if event_base == IP_EVENT and event_id == IP_EVENT_ETH_GOT_IP.int32: + let ev = cast[ptr ip_event_got_ip_t](event_data) + if ev.esp_netif == sNetif: + logi(TAG, "Got IPv4: %s", $ev.ip_info.ip) + elif event_base == IP_EVENT and event_id == IP_EVENT_GOT_IP6.int32: + let ev6 = cast[ptr ip_event_got_ip6_t](event_data) + if ev6.esp_netif == sNetif: + logi(TAG, "Got IPv6: %s", $ev6.ip6_info.ip) + +proc runUsbNcmEthWithConsole*() = + # NVS init + var ret = nvs_flash_init() + if ret == ESP_ERR_NVS_NO_FREE_PAGES or ret == ESP_ERR_NVS_NEW_VERSION_FOUND: + check: nvs_flash_erase() + ret = nvs_flash_init() + check: ret + + # Netif + event loop + check: esp_netif_init() + check: esp_event_loop_create_default() + + # TinyUSB device stack + var tusbCfg: tinyusb_config_t + tusbCfg.external_phy = false + check: tinyusb_driver_install(addr tusbCfg) + + # CDC ACM for console on CDC1 (leave CDC0 free if desired) + var acmLog: tinyusb_config_cdcacm_t + acmLog.usb_dev = TINYUSB_USBDEV_0 + acmLog.cdc_port = TINYUSB_CDC_ACM_1 + check: tusb_cdc_acm_init(addr acmLog) + check: esp_tusb_init_console(TINYUSB_CDC_ACM_1) + + # MAC address + var mac: array[6, uint8] + check: esp_read_mac(addr mac[0], ESP_MAC_WIFI_STA) + logi(TAG, "Using MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0].int, mac[1].int, mac[2].int, mac[3].int, mac[4].int, mac[5].int) + + # Initialize TinyUSB NET (NCM) + var ncfg: tinyusb_net_config_t + for i in 0..5: ncfg.mac_addr[i] = mac[i] + ncfg.on_recv_callback = ncmRecvToNetif + ncfg.free_tx_buffer = nil + ncfg.on_init_callback = nil + ncfg.user_context = nil + check: tinyusb_net_init(TINYUSB_USBDEV_0, addr ncfg) + + # Create Ethernet-like netif backed by NCM + var baseCfg = ESP_NETIF_INHERENT_DEFAULT_ETH() + baseCfg.if_desc = "usb_ncm_eth" + var driverCfg: esp_netif_driver_ifconfig_t + driverCfg.handle = cast[pointer](1) + driverCfg.transmit = ncmTransmit + var netifCfg: esp_netif_config_t + netifCfg.base = addr baseCfg + netifCfg.driver = addr driverCfg + netifCfg.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH + + sNetif = esp_netif_new(addr netifCfg) + doAssert sNetif != nil + discard esp_netif_set_mac(sNetif, addr mac[0]) + + # Listen for IP events + check: esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, onIpEvent, nil) + + # Bring up netif; DHCP client will run per default ETH config + esp_netif_action_start(sNetif, nil, 0, nil) + esp_netif_action_connected(sNetif, nil, 0, nil) + + logi(TAG, "USB NCM Ethernet + CDC console started") + +proc stopUsbNcmEthWithConsole*() = + if sNetif != nil: + esp_netif_action_disconnected(sNetif, nil, 0, nil) + esp_netif_action_stop(sNetif, nil, 0, nil) + esp_netif_destroy(sNetif) + sNetif = nil + discard esp_tusb_deinit_console(TINYUSB_CDC_ACM_1) + From 4e858484d0f3d35a3bb1c9cf6406d3446143185d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:12:11 -0600 Subject: [PATCH 037/142] usb --- .../net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim | 7 ------- 1 file changed, 7 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim index 74f1d9ca..b4c90616 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim @@ -52,13 +52,6 @@ proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; even logi(TAG, "Got IPv6: %s", $ev6.ip6_info.ip) proc runUsbNcmEthWithConsole*() = - # NVS init - var ret = nvs_flash_init() - if ret == ESP_ERR_NVS_NO_FREE_PAGES or ret == ESP_ERR_NVS_NEW_VERSION_FOUND: - check: nvs_flash_erase() - ret = nvs_flash_init() - check: ret - # Netif + event loop check: esp_netif_init() check: esp_event_loop_create_default() From 40d4231137db09a0b98cec2bb22b23f5844d6faf Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:13:41 -0600 Subject: [PATCH 038/142] usb --- esp-idf-examples/net_pppos_usb/main/main.nim | 22 +++++---- .../net_pppos_usb/main/usb/README.md | 45 +++++++++++++++++++ 2 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 esp-idf-examples/net_pppos_usb/main/usb/README.md diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index df190bcf..81373263 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -6,7 +6,10 @@ import nesper/esp/nvs_flash import nesper/esp/esp_event import nesper/esp/net/esp_netif import nesper/esp/net/esp_netif_ppp -import usb/ppp_connect_usb_dualcdc +when defined(RUN_NCM): + import usb/tusb_ncm_eth_dualcdc as ncm_eth +else: + import usb/ppp_connect_usb_dualcdc const TAG*: cstring = "main" @@ -39,14 +42,17 @@ app_main: except Defect, CatchableError: logi(TAG, "Error getting chip info") - # Basic system setup: NVS, esp-netif, default event loop - discard setupSystem() - - # Start PPPoS over USB with dual CDC (CDC0=PPP, CDC1=console) - if examplePppConnectDualCdc() == ESP_OK: - logi(TAG, "PPPoS connected. Idle loop ...") + when defined(RUN_NCM): + # Start USB NCM-as-Ethernet with separate CDC console + ncm_eth.runUsbNcmEthWithConsole() else: - loge(TAG, "PPPoS connect failed") + # Basic system setup: NVS, esp-netif, default event loop + discard setupSystem() + # Start PPPoS over USB with dual CDC (CDC0=PPP, CDC1=console) + if examplePppConnectDualCdc() == ESP_OK: + logi(TAG, "PPPoS connected. Idle loop ...") + else: + loge(TAG, "PPPoS connect failed") # Keep app alive; clean shutdown not triggered in this minimal example while true: diff --git a/esp-idf-examples/net_pppos_usb/main/usb/README.md b/esp-idf-examples/net_pppos_usb/main/usb/README.md new file mode 100644 index 00000000..5756e524 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/usb/README.md @@ -0,0 +1,45 @@ +USB Networking Modes (PPP and NCM) + +Overview +- PPPoS dual-CDC (default): + - CDC0 = PPP data channel for `esp_netif`. + - CDC1 = USB console/log output via TinyUSB console. + - Files: `ppp_connect_usb_dualcdc.nim`, `ppp_connect_usb_dualcdc.c`. + +- NCM-as-Ethernet dual-CDC: + - Networking over TinyUSB NCM bound to an Ethernet-like `esp_netif`. + - CDC1 = USB console/log output via TinyUSB console. + - File: `tusb_ncm_eth_dualcdc.nim`. + +Alternate (bridge) example +- `tusb_ncm.nim`: Bridges USB NCM <-> WiFi STA (packets forward both ways). Not used by `main.nim` by default. + +Selecting Mode +- Default (PPPoS + CDC console): build as-is. +- NCM-as-Ethernet + CDC console: pass `-d:RUN_NCM` to Nim build (e.g., in your Atlas task or Nim command). + - `main.nim` imports and runs `usb/tusb_ncm_eth_dualcdc.runUsbNcmEthWithConsole()` when `RUN_NCM` is defined. + +Kconfig Requirements +- Common: + - Enable TinyUSB device stack. + - Enable CDC class; set CDC count accordingly (2 for dual console + data). +- PPP mode: + - LWIP → Enable PPP support. +- NCM-as-Ethernet mode: + - TinyUSB → Enable NET (NCM) device class. + - DHCP client runs on the device (default ETH netif config). Ensure host provides DHCP or set static IP as needed. + +Host Expectations +- PPPoS: + - Host sees two serial ports. Attach PPP dialer to CDC0; logs on CDC1. +- NCM-as-Ethernet: + - Host enumerates a USB network interface. Device requests IP via DHCP; logs on CDC1. + +Useful Tweaks +- CDC RX/TX buffer size: TinyUSB → CDC → adjust `CONFIG_TINYUSB_CDC_RX_BUFSIZE`/`TX_BUFSIZE`. +- Console over USB: handled via `esp_tusb_init_console(TINYUSB_CDC_ACM_1)` in the dual-CDC samples. + +Entrypoints +- PPP: `examplePppConnectDualCdc()` / `examplePppShutdownDualCdc()`. +- NCM ETH: `runUsbNcmEthWithConsole()` / `stopUsbNcmEthWithConsole()`. + From 6cd737d1886105c24a39ca06ef0ea175d5e82c95 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:14:39 -0600 Subject: [PATCH 039/142] usb --- esp-idf-examples/net_pppos_usb/config.nims | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index 34429827..9a895ba3 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -1,4 +1,6 @@ switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants +switch("define", "RUN_NCM") + include nesper/build_utils/builds From f0a9c7412b8e9fc36b95eb07af53268d169ab6a2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:17:41 -0600 Subject: [PATCH 040/142] usb --- esp-idf-examples/net_pppos_usb/sdkconfig.defaults | 1 + 1 file changed, 1 insertion(+) diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults index 6828fc09..1f23dfb2 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults @@ -16,3 +16,4 @@ CONFIG_LWIP_PPP_DEBUG_ON=y CONFIG_TINYUSB_DEBUG_LEVEL=02 CONFIG_TINYUSB_CDC_ENABLED=y CONFIG_TINYUSB_CDC_COUNT=2 +CONFIG_TINYUSB_NET_MODE_NCM=y From 23990832f1fb66f67dc630297776c8d62afb9f30 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:28:41 -0600 Subject: [PATCH 041/142] usb --- .../net_pppos_usb/main/usb/README.md | 8 +++++++ .../net_pppos_usb/sdkconfig.defaults | 2 +- .../net_pppos_usb/sdkconfig.defaults.ncm | 18 +++++++++++++++ .../net_pppos_usb/sdkconfig.defaults.ppp | 23 +++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ncm create mode 100644 esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp diff --git a/esp-idf-examples/net_pppos_usb/main/usb/README.md b/esp-idf-examples/net_pppos_usb/main/usb/README.md index 5756e524..30217b38 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/README.md +++ b/esp-idf-examples/net_pppos_usb/main/usb/README.md @@ -29,6 +29,11 @@ Kconfig Requirements - TinyUSB → Enable NET (NCM) device class. - DHCP client runs on the device (default ETH netif config). Ensure host provides DHCP or set static IP as needed. +Endpoint-safe defaults +- PPP mode (default): `sdkconfig.defaults` (or `sdkconfig.defaults.ppp`) sets CDC count = 2 and disables NCM. +- NCM mode: use `sdkconfig.defaults.ncm` to enable NCM and set CDC count = 1 (console only). + - Having both NCM and two CDCs may exceed endpoint limits on some targets. + Host Expectations - PPPoS: - Host sees two serial ports. Attach PPP dialer to CDC0; logs on CDC1. @@ -43,3 +48,6 @@ Entrypoints - PPP: `examplePppConnectDualCdc()` / `examplePppShutdownDualCdc()`. - NCM ETH: `runUsbNcmEthWithConsole()` / `stopUsbNcmEthWithConsole()`. +Switching modes +- PPP (default): build normally. +- NCM: either pass `-d:RUN_NCM` at build time or temporarily copy `sdkconfig.defaults.ncm` to `sdkconfig.defaults` and reconfigure. diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults index 1f23dfb2..867efcea 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults @@ -15,5 +15,5 @@ CONFIG_LWIP_ENABLE_LCP_ECHO=y CONFIG_LWIP_PPP_DEBUG_ON=y CONFIG_TINYUSB_DEBUG_LEVEL=02 CONFIG_TINYUSB_CDC_ENABLED=y -CONFIG_TINYUSB_CDC_COUNT=2 +CONFIG_TINYUSB_CDC_COUNT=1 CONFIG_TINYUSB_NET_MODE_NCM=y diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ncm b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ncm new file mode 100644 index 00000000..5b71077d --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ncm @@ -0,0 +1,18 @@ +# NCM-as-Ethernet + one CDC for console +CONFIG_IDF_TARGET="esp32s3" +CONFIG_APP_NO_BLOBS=y +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_USJ_ENABLE_USB_SERIAL_JTAG=n +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y + +# Disable PPP +# CONFIG_LWIP_PPP_SUPPORT is not set + +# TinyUSB +CONFIG_TINYUSB_DEBUG_LEVEL=02 +CONFIG_TINYUSB_CDC_ENABLED=y +CONFIG_TINYUSB_CDC_COUNT=1 +CONFIG_TINYUSB_NET_MODE_NCM=y + diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp new file mode 100644 index 00000000..82f46eaf --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp @@ -0,0 +1,23 @@ +# PPPoS dual-CDC (CDC0=PPP, CDC1=console) +CONFIG_IDF_TARGET="esp32s3" +CONFIG_APP_NO_BLOBS=y +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_USJ_ENABLE_USB_SERIAL_JTAG=n +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y + +# LWIP PPP +CONFIG_LWIP_PPP_SUPPORT=y +CONFIG_LWIP_PPP_PAP_SUPPORT=y +CONFIG_LWIP_PPP_CHAP_SUPPORT=y +CONFIG_LWIP_ENABLE_LCP_ECHO=y +# CONFIG_LWIP_DEBUG=y +CONFIG_LWIP_PPP_DEBUG_ON=y + +# TinyUSB +CONFIG_TINYUSB_DEBUG_LEVEL=02 +CONFIG_TINYUSB_CDC_ENABLED=y +CONFIG_TINYUSB_CDC_COUNT=2 +CONFIG_TINYUSB_NET_MODE_NONE=y + From c7aa196677e28d2ea5861c836338c74bb2485d2a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:42:00 -0600 Subject: [PATCH 042/142] fixups --- .../net_pppos_usb/main/usb/tusb_ncm.nim | 11 ++++---- .../net_pppos_usb/main/usb/tusb_ncm_eth.nim | 11 ++++---- .../main/usb/tusb_ncm_eth_dualcdc.nim | 27 +++++++++---------- .../net_pppos_usb/sdkconfig.defaults | 4 +-- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim index 3ac10b7b..1fd9d510 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm.nim @@ -85,16 +85,17 @@ proc runUsbNcmBridge*() = ret = nvs_flash_init() check: ret - logi(TAG, "USB NCM device initialization") - var tusbCfg: tinyusb_config_t - tusbCfg.external_phy = false - check: tinyusb_driver_install(addr tusbCfg) - + # Read MAC before enabling USB, to set MAC string immediately after install var mac: array[6, uint8] check: esp_read_mac(addr mac[0], ESP_MAC_WIFI_STA) logi(TAG, "Network interface HW address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0].int, mac[1].int, mac[2].int, mac[3].int, mac[4].int, mac[5].int) + logi(TAG, "USB NCM device initialization") + var tusbCfg: tinyusb_config_t + tusbCfg.external_phy = false + check: tinyusb_driver_install(addr tusbCfg) + # Initialize TinyUSB NET class with callbacks and MAC var ncfg: tinyusb_net_config_t ncfg.on_recv_callback = usbRecvCallback diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim index 215b34cd..e6caae28 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth.nim @@ -51,16 +51,16 @@ proc runUsbNcmAsEth*() = check: esp_netif_init() check: esp_event_loop_create_default() - # TinyUSB init - var tusbCfg: tinyusb_config_t - tusbCfg.external_phy = false - check: tinyusb_driver_install(addr tusbCfg) - # MAC address var mac: array[6, uint8] check: esp_read_mac(addr mac[0], ESP_MAC_WIFI_STA) logi(TAG, "Using MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0].int, mac[1].int, mac[2].int, mac[3].int, mac[4].int, mac[5].int) + # TinyUSB init + var tusbCfg: tinyusb_config_t + tusbCfg.external_phy = false + check: tinyusb_driver_install(addr tusbCfg) + # TinyUSB NET config var ncfg: tinyusb_net_config_t for i in 0..5: ncfg.mac_addr[i] = mac[i] @@ -93,4 +93,3 @@ proc runUsbNcmAsEth*() = esp_netif_action_connected(sNetif, nil, 0, nil) logi(TAG, "USB NCM Ethernet-like interface started") - diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim index b4c90616..30d93971 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim @@ -56,24 +56,17 @@ proc runUsbNcmEthWithConsole*() = check: esp_netif_init() check: esp_event_loop_create_default() + # Read MAC before enabling USB so we can set it immediately + var mac: array[6, uint8] + check: esp_read_mac(addr mac[0], ESP_MAC_WIFI_STA) + logi(TAG, "Using MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0].int, mac[1].int, mac[2].int, mac[3].int, mac[4].int, mac[5].int) + # TinyUSB device stack var tusbCfg: tinyusb_config_t tusbCfg.external_phy = false check: tinyusb_driver_install(addr tusbCfg) - # CDC ACM for console on CDC1 (leave CDC0 free if desired) - var acmLog: tinyusb_config_cdcacm_t - acmLog.usb_dev = TINYUSB_USBDEV_0 - acmLog.cdc_port = TINYUSB_CDC_ACM_1 - check: tusb_cdc_acm_init(addr acmLog) - check: esp_tusb_init_console(TINYUSB_CDC_ACM_1) - - # MAC address - var mac: array[6, uint8] - check: esp_read_mac(addr mac[0], ESP_MAC_WIFI_STA) - logi(TAG, "Using MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0].int, mac[1].int, mac[2].int, mac[3].int, mac[4].int, mac[5].int) - - # Initialize TinyUSB NET (NCM) + # Initialize TinyUSB NET (NCM) as early as possible so host can read MAC string var ncfg: tinyusb_net_config_t for i in 0..5: ncfg.mac_addr[i] = mac[i] ncfg.on_recv_callback = ncmRecvToNetif @@ -82,6 +75,13 @@ proc runUsbNcmEthWithConsole*() = ncfg.user_context = nil check: tinyusb_net_init(TINYUSB_USBDEV_0, addr ncfg) + # CDC ACM for console on CDC1 (leave CDC0 free if desired) + var acmLog: tinyusb_config_cdcacm_t + acmLog.usb_dev = TINYUSB_USBDEV_0 + acmLog.cdc_port = TINYUSB_CDC_ACM_1 + check: tusb_cdc_acm_init(addr acmLog) + check: esp_tusb_init_console(TINYUSB_CDC_ACM_1) + # Create Ethernet-like netif backed by NCM var baseCfg = ESP_NETIF_INHERENT_DEFAULT_ETH() baseCfg.if_desc = "usb_ncm_eth" @@ -113,4 +113,3 @@ proc stopUsbNcmEthWithConsole*() = esp_netif_destroy(sNetif) sNetif = nil discard esp_tusb_deinit_console(TINYUSB_CDC_ACM_1) - diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults index 867efcea..36a591b8 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults @@ -15,5 +15,5 @@ CONFIG_LWIP_ENABLE_LCP_ECHO=y CONFIG_LWIP_PPP_DEBUG_ON=y CONFIG_TINYUSB_DEBUG_LEVEL=02 CONFIG_TINYUSB_CDC_ENABLED=y -CONFIG_TINYUSB_CDC_COUNT=1 -CONFIG_TINYUSB_NET_MODE_NCM=y +CONFIG_TINYUSB_CDC_COUNT=2 +CONFIG_TINYUSB_NET_MODE_NCM=n From 382d2e81e18453010c41b9174e00e1c02235c058 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:46:48 -0600 Subject: [PATCH 043/142] fixups --- esp-idf-examples/net_pppos_usb/config.nims | 2 +- esp-idf-examples/net_pppos_usb/sdkconfig.defaults | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index 9a895ba3..498b2aa3 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -1,6 +1,6 @@ switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants -switch("define", "RUN_NCM") +# switch("define", "RUN_NCM") include nesper/build_utils/builds diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults index 36a591b8..6828fc09 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults @@ -16,4 +16,3 @@ CONFIG_LWIP_PPP_DEBUG_ON=y CONFIG_TINYUSB_DEBUG_LEVEL=02 CONFIG_TINYUSB_CDC_ENABLED=y CONFIG_TINYUSB_CDC_COUNT=2 -CONFIG_TINYUSB_NET_MODE_NCM=n From 84c335e6685e9876e990506d5bafde135296d18c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:47:04 -0600 Subject: [PATCH 044/142] fixups --- esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp | 1 - 1 file changed, 1 deletion(-) diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp index 82f46eaf..180a9b21 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp @@ -19,5 +19,4 @@ CONFIG_LWIP_PPP_DEBUG_ON=y CONFIG_TINYUSB_DEBUG_LEVEL=02 CONFIG_TINYUSB_CDC_ENABLED=y CONFIG_TINYUSB_CDC_COUNT=2 -CONFIG_TINYUSB_NET_MODE_NONE=y From 14fe6e5b65c132633446898a825b0748989b9c82 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:48:59 -0600 Subject: [PATCH 045/142] fixups --- .../net_pppos_usb/sdkconfig.defaults | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 esp-idf-examples/net_pppos_usb/sdkconfig.defaults diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults deleted file mode 100644 index 6828fc09..00000000 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults +++ /dev/null @@ -1,18 +0,0 @@ -# This file was generated using idf.py save-defconfig. It can be edited manually. -# Espressif IoT Development Framework (ESP-IDF) 5.5.0 Project Minimal Configuration -# -CONFIG_IDF_TARGET="esp32s3" -CONFIG_APP_NO_BLOBS=y -CONFIG_ESPTOOLPY_FLASHMODE_QIO=y -CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y -CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_USJ_ENABLE_USB_SERIAL_JTAG=n -CONFIG_ESP_CONSOLE_SECONDARY_NONE=y -CONFIG_LWIP_PPP_SUPPORT=y -CONFIG_LWIP_PPP_PAP_SUPPORT=y -CONFIG_LWIP_PPP_CHAP_SUPPORT=y -CONFIG_LWIP_ENABLE_LCP_ECHO=y -CONFIG_LWIP_PPP_DEBUG_ON=y -CONFIG_TINYUSB_DEBUG_LEVEL=02 -CONFIG_TINYUSB_CDC_ENABLED=y -CONFIG_TINYUSB_CDC_COUNT=2 From 07ab54901e30742234dc86e67b1392f8759ef94a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:49:42 -0600 Subject: [PATCH 046/142] fixups --- esp-idf-examples/net_pppos_usb/sdkconfig.defaults | 1 + 1 file changed, 1 insertion(+) create mode 120000 esp-idf-examples/net_pppos_usb/sdkconfig.defaults diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults new file mode 120000 index 00000000..4c6fb694 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults @@ -0,0 +1 @@ +sdkconfig.defaults.ncm \ No newline at end of file From 7222828a5be2593ddd95c128937258f16d1417af Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:57:11 -0600 Subject: [PATCH 047/142] fixups --- esp-idf-examples/net_pppos_usb/sdkconfig.defaults | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults index 4c6fb694..16ada53c 120000 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults @@ -1 +1 @@ -sdkconfig.defaults.ncm \ No newline at end of file +sdkconfig.defaults.ppp \ No newline at end of file From 7d68fd999f5d003ad2f71abe33f811dc97834f9f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:57:27 -0600 Subject: [PATCH 048/142] fixups --- .../net_pppos_usb/{main/usb => }/README-pppos-dualcdc.md | 0 esp-idf-examples/net_pppos_usb/{main/usb => }/README.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename esp-idf-examples/net_pppos_usb/{main/usb => }/README-pppos-dualcdc.md (100%) rename esp-idf-examples/net_pppos_usb/{main/usb => }/README.md (100%) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/README-pppos-dualcdc.md b/esp-idf-examples/net_pppos_usb/README-pppos-dualcdc.md similarity index 100% rename from esp-idf-examples/net_pppos_usb/main/usb/README-pppos-dualcdc.md rename to esp-idf-examples/net_pppos_usb/README-pppos-dualcdc.md diff --git a/esp-idf-examples/net_pppos_usb/main/usb/README.md b/esp-idf-examples/net_pppos_usb/README.md similarity index 100% rename from esp-idf-examples/net_pppos_usb/main/usb/README.md rename to esp-idf-examples/net_pppos_usb/README.md From 0ff5d187429f88cb4494412a1e856f1584bf052f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 18:59:14 -0600 Subject: [PATCH 049/142] add disclean --- src/nesper/build_utils/builds.nim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nesper/build_utils/builds.nim b/src/nesper/build_utils/builds.nim index 8a700e82..629f940a 100644 --- a/src/nesper/build_utils/builds.nim +++ b/src/nesper/build_utils/builds.nim @@ -37,6 +37,11 @@ task espClean, "clean the Nim code": rmDir(cacheDir) mkDir(cacheDir) +task espDistClean, "clean the Nim code": + espCleanTask() + rmDir("build") + rmFile("sdkconfig") # this will trigger going back to sdkconfig.defaults + task espSetup, "setup the esp-idf project": let idfPath = getEnv("IDF_PATH") if idfPath == "": From 01814c4c38a1f6fec73b07f4670cb7c8b33cb8c2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 19:04:41 -0600 Subject: [PATCH 050/142] fixups --- esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp index 180a9b21..22f3f87e 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp @@ -1,4 +1,6 @@ -# PPPoS dual-CDC (CDC0=PPP, CDC1=console) +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.5.0 Project Minimal Configuration +# CONFIG_IDF_TARGET="esp32s3" CONFIG_APP_NO_BLOBS=y CONFIG_ESPTOOLPY_FLASHMODE_QIO=y @@ -12,11 +14,9 @@ CONFIG_LWIP_PPP_SUPPORT=y CONFIG_LWIP_PPP_PAP_SUPPORT=y CONFIG_LWIP_PPP_CHAP_SUPPORT=y CONFIG_LWIP_ENABLE_LCP_ECHO=y -# CONFIG_LWIP_DEBUG=y CONFIG_LWIP_PPP_DEBUG_ON=y - -# TinyUSB +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y CONFIG_TINYUSB_DEBUG_LEVEL=02 CONFIG_TINYUSB_CDC_ENABLED=y CONFIG_TINYUSB_CDC_COUNT=2 - From 7f0a4d37e5a762351bcc0184c3404754038bea72 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 19:07:11 -0600 Subject: [PATCH 051/142] fixups --- esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ncm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ncm b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ncm index 5b71077d..fbe774f8 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ncm +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ncm @@ -9,6 +9,8 @@ CONFIG_ESP_CONSOLE_SECONDARY_NONE=y # Disable PPP # CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_MULTICAST_PING=y +CONFIG_LWIP_BROADCAST_PING=y # TinyUSB CONFIG_TINYUSB_DEBUG_LEVEL=02 From c810eae3af9e3620597609230cfc5fa360fee389 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 19:08:46 -0600 Subject: [PATCH 052/142] fixups --- .../usb/{tusb_ncm_eth_dualcdc.nim => usb_ncm_eth_dualcdc.nim} | 0 .../{ppp_connect_usb_dualcdc.nim => usb_ppp_connect_dualcdc.nim} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename esp-idf-examples/net_pppos_usb/main/usb/{tusb_ncm_eth_dualcdc.nim => usb_ncm_eth_dualcdc.nim} (100%) rename esp-idf-examples/net_pppos_usb/main/usb/{ppp_connect_usb_dualcdc.nim => usb_ppp_connect_dualcdc.nim} (100%) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/usb_ncm_eth_dualcdc.nim similarity index 100% rename from esp-idf-examples/net_pppos_usb/main/usb/tusb_ncm_eth_dualcdc.nim rename to esp-idf-examples/net_pppos_usb/main/usb/usb_ncm_eth_dualcdc.nim diff --git a/esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim similarity index 100% rename from esp-idf-examples/net_pppos_usb/main/usb/ppp_connect_usb_dualcdc.nim rename to esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim From 75737acfd063bca2f13917da8d543f991adafd4c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 19:09:16 -0600 Subject: [PATCH 053/142] fixups --- esp-idf-examples/net_pppos_usb/main/main.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 81373263..352aef0a 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -7,9 +7,9 @@ import nesper/esp/esp_event import nesper/esp/net/esp_netif import nesper/esp/net/esp_netif_ppp when defined(RUN_NCM): - import usb/tusb_ncm_eth_dualcdc as ncm_eth + import usb/usb_ncm_eth_dualcdc as ncm_eth else: - import usb/ppp_connect_usb_dualcdc + import usb/usb_ppp_connect_dualcdc const TAG*: cstring = "main" From c6360b361605949c77e4d31a27a60175f1582c4f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 19:16:22 -0600 Subject: [PATCH 054/142] fixups --- .../net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim index 7a4c174f..18ec6ada 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim @@ -45,6 +45,13 @@ proc onCdcRx(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = proc onLineState(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = logi(TAG, "Line state changed on itf %d", itf) + # Allow host tools (esptool) to reset via DTR/RTS on the console CDC + if tinyusb_cdcacm_itf_t(itf) == sLogItf: + let ls = event.line_state_changed_data + # Common esptool pattern: RTS asserted and DTR deasserted -> reset to enter flashing + if ls.rts and not ls.dtr: + logi(TAG, "DTR/RTS trigger: restarting for flashing") + esp_restart() # IP events handler: filter for our PPP netif and set bits proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = @@ -86,6 +93,7 @@ proc examplePppConnectDualCdc*(): esp_err_t = var acmLog: tinyusb_config_cdcacm_t acmLog.usb_dev = TINYUSB_USBDEV_0 acmLog.cdc_port = TINYUSB_CDC_ACM_1 + acmLog.callback_line_state_changed = onLineState check: tusb_cdc_acm_init(addr acmLog) check: esp_tusb_init_console(TINYUSB_CDC_ACM_1) @@ -130,4 +138,3 @@ proc examplePppShutdownDualCdc*() = vEventGroupDelete(sEventGroup) sEventGroup = nil discard esp_tusb_deinit_console(TINYUSB_CDC_ACM_1) - From 025bf1936269b0931adafb71ba1c23e111c96292 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 1 Sep 2025 19:21:41 -0600 Subject: [PATCH 055/142] fixups --- .../net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim index 18ec6ada..c03cb2e8 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim @@ -47,6 +47,7 @@ proc onLineState(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = logi(TAG, "Line state changed on itf %d", itf) # Allow host tools (esptool) to reset via DTR/RTS on the console CDC if tinyusb_cdcacm_itf_t(itf) == sLogItf: + logi(TAG, "DTR/RTS triggered on console: restarting for flashing") let ls = event.line_state_changed_data # Common esptool pattern: RTS asserted and DTR deasserted -> reset to enter flashing if ls.rts and not ls.dtr: From 268aae335b75f013007d86efdbaddc967a9a37ca Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 2 Sep 2025 00:25:39 -0600 Subject: [PATCH 056/142] fixups --- .../net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim index c03cb2e8..8a870f0b 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim @@ -1,5 +1,5 @@ import nesper -import nesper/[general] +import nesper/[general, gpios, timers] import nesper/esp/[esp_log, esp_event, event_groups] import nesper/events import nesper/esp/net/[esp_netif, esp_netif_ppp, esp_netif_types] @@ -47,11 +47,12 @@ proc onLineState(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = logi(TAG, "Line state changed on itf %d", itf) # Allow host tools (esptool) to reset via DTR/RTS on the console CDC if tinyusb_cdcacm_itf_t(itf) == sLogItf: - logi(TAG, "DTR/RTS triggered on console: restarting for flashing") let ls = event.line_state_changed_data + logi(TAG, "DTR/RTS triggered on console rts: %s, dtr: %s", $ls.rts, $ls.dtr) # Common esptool pattern: RTS asserted and DTR deasserted -> reset to enter flashing if ls.rts and not ls.dtr: - logi(TAG, "DTR/RTS trigger: restarting for flashing") + logi(TAG, "DTR/RTS trigger: restarting...") + delay(10.Millis) esp_restart() # IP events handler: filter for our PPP netif and set bits From a40b553c6f972a8d653b563d5b287a146ac21b4d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 2 Sep 2025 00:53:13 -0600 Subject: [PATCH 057/142] fixups --- esp-idf-examples/net_pppos_usb/main/main.nim | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 352aef0a..f9cfeb6f 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -6,6 +6,9 @@ import nesper/esp/nvs_flash import nesper/esp/esp_event import nesper/esp/net/esp_netif import nesper/esp/net/esp_netif_ppp + +import nesper/servers/rpc/rpcsocket_json + when defined(RUN_NCM): import usb/usb_ncm_eth_dualcdc as ncm_eth else: @@ -14,6 +17,15 @@ else: const TAG*: cstring = "main" +proc setupRpc(rt: var RpcRouter) = + rt.rpc("hello") do(input: string) -> string: + # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' + result = "Hello " & input + + rt.rpc("add") do(a: int, b: int) -> int: + # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' + result = a + b + proc setupSystem(): esp_err_t = # Initialize esp-netif and default event loop check: esp_netif_init() @@ -54,6 +66,11 @@ app_main: else: loge(TAG, "PPPoS connect failed") + var rt: RpcRouter = createRpcRouter(4096) + rt.setupRpc() + + startRpcSocketServer(port=Port(5555), address="::", router=rt) + # Keep app alive; clean shutdown not triggered in this minimal example while true: logi(TAG, "PPPoS connected. Idle loop ...") From 8de2d574b7a627fcd26a67088b84291f40a0597f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 2 Sep 2025 01:32:13 -0600 Subject: [PATCH 058/142] fixups --- .../net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim | 3 ++- src/nesper/esp/esp_system.nim | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim index 8a870f0b..e990e69e 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim @@ -1,6 +1,7 @@ import nesper import nesper/[general, gpios, timers] import nesper/esp/[esp_log, esp_event, event_groups] +import nesper/esp/esp_system import nesper/events import nesper/esp/net/[esp_netif, esp_netif_ppp, esp_netif_types] import nesper/components/esp_tinyusb/[tinyusb, tusb_cdc_acm] @@ -53,7 +54,7 @@ proc onLineState(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = if ls.rts and not ls.dtr: logi(TAG, "DTR/RTS trigger: restarting...") delay(10.Millis) - esp_restart() + espReboot() # IP events handler: filter for our PPP netif and set bits proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = diff --git a/src/nesper/esp/esp_system.nim b/src/nesper/esp/esp_system.nim index 51539a62..97c87bde 100644 --- a/src/nesper/esp/esp_system.nim +++ b/src/nesper/esp/esp_system.nim @@ -91,7 +91,8 @@ proc esp_unregister_shutdown_handler*(handle: shutdown_handler_t): esp_err_t {. ## This function does not return. ## -proc esp_restart*() {.importc: "esp_restart", header: "esp_system.h".} +# defined in general.nim +# proc esp_restart*() {.importc: "esp_restart", header: "esp_system.h".} ## * From b4cc155a48c2868c9eee70caa20f555472a71575 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 2 Sep 2025 01:45:02 -0600 Subject: [PATCH 059/142] cleanups --- esp-idf-examples/net_pppos_usb/main/main.nim | 12 +- .../main/usb/usb_ncm_eth_dualcdc.nim | 15 -- .../components/esp_tinyusb/tinyusb_net.nim | 20 +++ src/nesper/esp/esp_system.nim | 4 +- src/nesper/networking/usb_ppp_dualcdc.nim | 148 ++++++++++++++++++ 5 files changed, 173 insertions(+), 26 deletions(-) create mode 100644 src/nesper/components/esp_tinyusb/tinyusb_net.nim create mode 100644 src/nesper/networking/usb_ppp_dualcdc.nim diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index f9cfeb6f..bb537884 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -12,7 +12,7 @@ import nesper/servers/rpc/rpcsocket_json when defined(RUN_NCM): import usb/usb_ncm_eth_dualcdc as ncm_eth else: - import usb/usb_ppp_connect_dualcdc + import nesper/networking/usb_ppp_dualcdc const TAG*: cstring = "main" @@ -26,12 +26,6 @@ proc setupRpc(rt: var RpcRouter) = # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' result = a + b -proc setupSystem(): esp_err_t = - # Initialize esp-netif and default event loop - check: esp_netif_init() - check: esp_event_loop_create_default() - return ESP_OK - app_main: logi(TAG, "esp starting ... ") @@ -59,9 +53,9 @@ app_main: ncm_eth.runUsbNcmEthWithConsole() else: # Basic system setup: NVS, esp-netif, default event loop - discard setupSystem() + setupNetworking() # Start PPPoS over USB with dual CDC (CDC0=PPP, CDC1=console) - if examplePppConnectDualCdc() == ESP_OK: + if initPppConnectDualCdc() == ESP_OK: logi(TAG, "PPPoS connected. Idle loop ...") else: loge(TAG, "PPPoS connect failed") diff --git a/esp-idf-examples/net_pppos_usb/main/usb/usb_ncm_eth_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/usb_ncm_eth_dualcdc.nim index 30d93971..74fe68b4 100644 --- a/esp-idf-examples/net_pppos_usb/main/usb/usb_ncm_eth_dualcdc.nim +++ b/esp-idf-examples/net_pppos_usb/main/usb/usb_ncm_eth_dualcdc.nim @@ -9,21 +9,6 @@ import nesper/esp/net/esp_netif_defaults import nesper/components/esp_tinyusb/tinyusb import nesper/components/esp_tinyusb/tusb_cdc_acm -# TinyUSB NET (NCM) imports -type - tinyusb_net_config_t* {.importc: "tinyusb_net_config_t", header: "tinyusb_net.h", bycopy.} = object - mac_addr* {.importc: "mac_addr".}: array[6, uint8] - on_recv_callback* {.importc: "on_recv_callback".}: proc (buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.} - free_tx_buffer* {.importc: "free_tx_buffer".}: proc (eb: pointer; ctx: pointer) {.cdecl.} - on_init_callback* {.importc: "on_init_callback".}: proc (ctx: pointer) {.cdecl.} - user_context* {.importc: "user_context".}: pointer - -proc tinyusb_net_init*(dev: tinyusb_usbdev_t; cfg: ptr tinyusb_net_config_t): esp_err_t {.cdecl, importc: "tinyusb_net_init", header: "tinyusb_net.h".} -proc tinyusb_net_send_sync*(buffer: pointer; len: uint16; eb: pointer; timeout_ticks: uint32): esp_err_t {.cdecl, importc: "tinyusb_net_send_sync", header: "tinyusb_net.h".} - -# tinyusb console helpers (not wrapped): -proc esp_tusb_init_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_init_console", header: "tusb_console.h".} -proc esp_tusb_deinit_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_deinit_console", header: "tusb_console.h".} const TAG* = "ncm_eth_dualcdc" diff --git a/src/nesper/components/esp_tinyusb/tinyusb_net.nim b/src/nesper/components/esp_tinyusb/tinyusb_net.nim new file mode 100644 index 00000000..70816e16 --- /dev/null +++ b/src/nesper/components/esp_tinyusb/tinyusb_net.nim @@ -0,0 +1,20 @@ +import ../../consts + +import ./tinyusb_types +import ./tusb_cdc_acm + +# TinyUSB NET (NCM) imports +type + tinyusb_net_config_t* {.importc: "tinyusb_net_config_t", header: "tinyusb_net.h", bycopy.} = object + mac_addr* {.importc: "mac_addr".}: array[6, uint8] + on_recv_callback* {.importc: "on_recv_callback".}: proc (buffer: pointer; len: uint16; ctx: pointer): esp_err_t {.cdecl.} + free_tx_buffer* {.importc: "free_tx_buffer".}: proc (eb: pointer; ctx: pointer) {.cdecl.} + on_init_callback* {.importc: "on_init_callback".}: proc (ctx: pointer) {.cdecl.} + user_context* {.importc: "user_context".}: pointer + +proc tinyusb_net_init*(dev: tinyusb_usbdev_t; cfg: ptr tinyusb_net_config_t): esp_err_t {.cdecl, importc: "tinyusb_net_init", header: "tinyusb_net.h".} +proc tinyusb_net_send_sync*(buffer: pointer; len: uint16; eb: pointer; timeout_ticks: uint32): esp_err_t {.cdecl, importc: "tinyusb_net_send_sync", header: "tinyusb_net.h".} + +# tinyusb console helpers (not wrapped): +proc esp_tusb_init_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_init_console", header: "tusb_console.h".} +proc esp_tusb_deinit_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_deinit_console", header: "tusb_console.h".} \ No newline at end of file diff --git a/src/nesper/esp/esp_system.nim b/src/nesper/esp/esp_system.nim index 97c87bde..e20b5a37 100644 --- a/src/nesper/esp/esp_system.nim +++ b/src/nesper/esp/esp_system.nim @@ -91,8 +91,8 @@ proc esp_unregister_shutdown_handler*(handle: shutdown_handler_t): esp_err_t {. ## This function does not return. ## -# defined in general.nim -# proc esp_restart*() {.importc: "esp_restart", header: "esp_system.h".} +## defined in general.nim +## proc esp_restart*() {.importc: "esp_restart", header: "esp_system.h".} ## * diff --git a/src/nesper/networking/usb_ppp_dualcdc.nim b/src/nesper/networking/usb_ppp_dualcdc.nim new file mode 100644 index 00000000..9b233480 --- /dev/null +++ b/src/nesper/networking/usb_ppp_dualcdc.nim @@ -0,0 +1,148 @@ +import nesper +import nesper/[general, gpios, timers] +import nesper/esp/[esp_log, esp_event, event_groups] +import nesper/esp/esp_system +import nesper/events +import nesper/esp/net/[esp_netif, esp_netif_ppp, esp_netif_types] +import nesper/components/esp_tinyusb/[tinyusb, tinyusb_net, tusb_cdc_acm] + +const + TAG* = "pppos_dualcdc" + +# State +var + sNetif: ptr esp_netif_t + sEventGroup: EventGroupHandle_t + sPppItf: tinyusb_cdcacm_itf_t = TINYUSB_CDC_ACM_0 + sLogItf: tinyusb_cdcacm_itf_t = TINYUSB_CDC_ACM_1 + rxBuf = newSeq[uint8](CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1) + +const + GOT_IPV4 = 1 shl 0 + CONN_FAILED = 1 shl 1 + GOT_IPV6 = 1 shl 2 + CONNECT_BITS = GOT_IPV4 or GOT_IPV6 or CONN_FAILED + +# PPP transmit: push bytes to CDC PPP interface +proc pppTransmit(h: pointer; buffer: pointer; len: csize_t): esp_err_t {.cdecl.} = + discard tinyusb_cdcacm_write_queue(sPppItf, cast[ptr uint8](buffer), len) + result = tinyusb_cdcacm_write_flush(sPppItf, 0'u32) + +var driverCfg: esp_netif_driver_ifconfig_t + +# CDC RX: feed data to esp_netif +proc onCdcRx(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = + if tinyusb_cdcacm_itf_t(itf) != sPppItf: + return + var rxSize: csize_t = 0 + let ret = tinyusb_cdcacm_read(tinyusb_cdcacm_itf_t(itf), addr rxBuf[0], CONFIG_TINYUSB_CDC_RX_BUFSIZE.csize_t, addr rxSize) + if ret == ESP_OK and rxSize > 0: + discard esp_netif_receive(sNetif, addr rxBuf[0], rxSize, nil) + +proc onLineState(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = + logi(TAG, "Line state changed on itf %d", itf) + # Allow host tools (esptool) to reset via DTR/RTS on the console CDC + if tinyusb_cdcacm_itf_t(itf) == sLogItf: + let ls = event.line_state_changed_data + logi(TAG, "DTR/RTS triggered on console rts: %s, dtr: %s", $ls.rts, $ls.dtr) + # Common esptool pattern: RTS asserted and DTR deasserted -> reset to enter flashing + if ls.rts and not ls.dtr: + logi(TAG, "DTR/RTS trigger: restarting...") + delay(10.Millis) + esp_restart() + +# IP events handler: filter for our PPP netif and set bits +proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = + if event_base != IP_EVENT: return + case ip_event_t(event_id) + of IP_EVENT_PPP_GOT_IP: + let ev = cast[ptr ip_event_got_ip_t](event_data) + if ev.esp_netif == sNetif: + logi(TAG, "PPP IPv4: %s %s", esp_netif_get_desc(ev.esp_netif), $ev.ip_info.ip) + discard xEventGroupSetBits(sEventGroup, EventBits_t(GOT_IPV4)) + of IP_EVENT_GOT_IP6: + let ev6 = cast[ptr ip_event_got_ip6_t](event_data) + if ev6.esp_netif == sNetif: + logi(TAG, "PPP IPv6 acquired") + discard xEventGroupSetBits(sEventGroup, EventBits_t(GOT_IPV6)) + of IP_EVENT_PPP_LOST_IP: + discard xEventGroupSetBits(sEventGroup, EventBits_t(CONN_FAILED)) + else: + discard + +proc setupNetworking*() = + # Initialize esp-netif and default event loop + check: esp_netif_init() + check: esp_event_loop_create_default() + +proc initPppConnectDualCdc*(): esp_err_t = + ## Initializes USB CDC for PPPoS and a serial console + ## requires TinyUSB and incompatible with USB JTAG or OTG Modes + ## CDC0 is used for PPP data, CDC1 is used for console + ## + logi(TAG, "Starting dual-CDC PPPoS (PPP=CDC0, console=CDC1)") + + var tusbCfg: tinyusb_config_t + tusbCfg.external_phy = false + check: tinyusb_driver_install(addr tusbCfg) + + # CDC0 for PPP + var acmPpp: tinyusb_config_cdcacm_t + acmPpp.usb_dev = TINYUSB_USBDEV_0 + acmPpp.cdc_port = TINYUSB_CDC_ACM_0 + acmPpp.callback_rx = onCdcRx + acmPpp.callback_rx_wanted_char = nil + acmPpp.callback_line_state_changed = onLineState + acmPpp.callback_line_coding_changed = nil + check: tusb_cdc_acm_init(addr acmPpp) + + # CDC1 for logs/console + var acmLog: tinyusb_config_cdcacm_t + acmLog.usb_dev = TINYUSB_USBDEV_0 + acmLog.cdc_port = TINYUSB_CDC_ACM_1 + acmLog.callback_line_state_changed = onLineState + check: tusb_cdc_acm_init(addr acmLog) + check: esp_tusb_init_console(TINYUSB_CDC_ACM_1) + + # Event group and handler + sEventGroup = xEventGroupCreate() + if sEventGroup.isNil: return ESP_ERR_NO_MEM + check: esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID.cint, onIpEvent, nil) + + # Create PPP netif using inherent defaults and custom driver + logi(TAG, "Creating PPP netif...") + var baseCfg = ESP_NETIF_INHERENT_DEFAULT_PPP() + baseCfg.if_desc = "example_netif_ppp" + + driverCfg.handle = cast[pointer](1) + driverCfg.transmit = pppTransmit + + var netifCfg: esp_netif_config_t + netifCfg.base = addr baseCfg + netifCfg.driver = addr driverCfg + netifCfg.stack = ESP_NETIF_NETSTACK_DEFAULT_PPP + + sNetif = esp_netif_new(addr netifCfg) + doAssert sNetif != nil + esp_netif_action_start(sNetif, nil, 0, nil) + esp_netif_action_connected(sNetif, nil, 0, nil) + + logi(TAG, "Waiting for IP...") + let bits = xEventGroupWaitBits(sEventGroup, EventBits_t(CONNECT_BITS), pdFALSE, pdFALSE, portMAX_DELAY) + if (bits and EventBits_t(CONN_FAILED)) != 0: + loge(TAG, "PPP connect failed") + return ESP_FAIL + logi(TAG, "PPP connected") + return ESP_OK + +proc shutdownPppConnectDualCdc*() = + discard esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID.cint, onIpEvent) + if sNetif != nil: + esp_netif_action_disconnected(sNetif, nil, 0, nil) + esp_netif_action_stop(sNetif, nil, 0, nil) + esp_netif_destroy(sNetif) + sNetif = nil + if sEventGroup != nil: + vEventGroupDelete(sEventGroup) + sEventGroup = nil + discard esp_tusb_deinit_console(TINYUSB_CDC_ACM_1) From c7a80dfc2f2d089c15d72c589b6f4003cd3663df Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 2 Sep 2025 01:45:37 -0600 Subject: [PATCH 060/142] cleanups --- .../main/usb/usb_ppp_connect_dualcdc.nim | 143 ------------------ .../components/esp_tinyusb/tinyusb_net.nim | 2 +- 2 files changed, 1 insertion(+), 144 deletions(-) delete mode 100644 esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim diff --git a/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim b/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim deleted file mode 100644 index e990e69e..00000000 --- a/esp-idf-examples/net_pppos_usb/main/usb/usb_ppp_connect_dualcdc.nim +++ /dev/null @@ -1,143 +0,0 @@ -import nesper -import nesper/[general, gpios, timers] -import nesper/esp/[esp_log, esp_event, event_groups] -import nesper/esp/esp_system -import nesper/events -import nesper/esp/net/[esp_netif, esp_netif_ppp, esp_netif_types] -import nesper/components/esp_tinyusb/[tinyusb, tusb_cdc_acm] - -const - TAG* = "pppos_dualcdc" - -# tinyusb console helpers (no wrapper module yet) -proc esp_tusb_init_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_init_console", header: "tusb_console.h".} -proc esp_tusb_deinit_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_deinit_console", header: "tusb_console.h".} - - -# State -var - sNetif: ptr esp_netif_t - sEventGroup: EventGroupHandle_t - sPppItf: tinyusb_cdcacm_itf_t = TINYUSB_CDC_ACM_0 - sLogItf: tinyusb_cdcacm_itf_t = TINYUSB_CDC_ACM_1 - rxBuf = newSeq[uint8](CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1) - -const - GOT_IPV4 = 1 shl 0 - CONN_FAILED = 1 shl 1 - GOT_IPV6 = 1 shl 2 - CONNECT_BITS = GOT_IPV4 or GOT_IPV6 or CONN_FAILED - -# PPP transmit: push bytes to CDC PPP interface -proc pppTransmit(h: pointer; buffer: pointer; len: csize_t): esp_err_t {.cdecl.} = - discard tinyusb_cdcacm_write_queue(sPppItf, cast[ptr uint8](buffer), len) - result = tinyusb_cdcacm_write_flush(sPppItf, 0'u32) - -var driverCfg: esp_netif_driver_ifconfig_t - -# CDC RX: feed data to esp_netif -proc onCdcRx(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = - if tinyusb_cdcacm_itf_t(itf) != sPppItf: - return - var rxSize: csize_t = 0 - let ret = tinyusb_cdcacm_read(tinyusb_cdcacm_itf_t(itf), addr rxBuf[0], CONFIG_TINYUSB_CDC_RX_BUFSIZE.csize_t, addr rxSize) - if ret == ESP_OK and rxSize > 0: - discard esp_netif_receive(sNetif, addr rxBuf[0], rxSize, nil) - -proc onLineState(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = - logi(TAG, "Line state changed on itf %d", itf) - # Allow host tools (esptool) to reset via DTR/RTS on the console CDC - if tinyusb_cdcacm_itf_t(itf) == sLogItf: - let ls = event.line_state_changed_data - logi(TAG, "DTR/RTS triggered on console rts: %s, dtr: %s", $ls.rts, $ls.dtr) - # Common esptool pattern: RTS asserted and DTR deasserted -> reset to enter flashing - if ls.rts and not ls.dtr: - logi(TAG, "DTR/RTS trigger: restarting...") - delay(10.Millis) - espReboot() - -# IP events handler: filter for our PPP netif and set bits -proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = - if event_base != IP_EVENT: return - case ip_event_t(event_id) - of IP_EVENT_PPP_GOT_IP: - let ev = cast[ptr ip_event_got_ip_t](event_data) - if ev.esp_netif == sNetif: - logi(TAG, "PPP IPv4: %s %s", esp_netif_get_desc(ev.esp_netif), $ev.ip_info.ip) - discard xEventGroupSetBits(sEventGroup, EventBits_t(GOT_IPV4)) - of IP_EVENT_GOT_IP6: - let ev6 = cast[ptr ip_event_got_ip6_t](event_data) - if ev6.esp_netif == sNetif: - logi(TAG, "PPP IPv6 acquired") - discard xEventGroupSetBits(sEventGroup, EventBits_t(GOT_IPV6)) - of IP_EVENT_PPP_LOST_IP: - discard xEventGroupSetBits(sEventGroup, EventBits_t(CONN_FAILED)) - else: - discard - -proc examplePppConnectDualCdc*(): esp_err_t = - logi(TAG, "Starting dual-CDC PPPoS (PPP=CDC0, console=CDC1)") - - var tusbCfg: tinyusb_config_t - tusbCfg.external_phy = false - check: tinyusb_driver_install(addr tusbCfg) - - # CDC0 for PPP - var acmPpp: tinyusb_config_cdcacm_t - acmPpp.usb_dev = TINYUSB_USBDEV_0 - acmPpp.cdc_port = TINYUSB_CDC_ACM_0 - acmPpp.callback_rx = onCdcRx - acmPpp.callback_rx_wanted_char = nil - acmPpp.callback_line_state_changed = onLineState - acmPpp.callback_line_coding_changed = nil - check: tusb_cdc_acm_init(addr acmPpp) - - # CDC1 for logs/console - var acmLog: tinyusb_config_cdcacm_t - acmLog.usb_dev = TINYUSB_USBDEV_0 - acmLog.cdc_port = TINYUSB_CDC_ACM_1 - acmLog.callback_line_state_changed = onLineState - check: tusb_cdc_acm_init(addr acmLog) - check: esp_tusb_init_console(TINYUSB_CDC_ACM_1) - - # Event group and handler - sEventGroup = xEventGroupCreate() - if sEventGroup.isNil: return ESP_ERR_NO_MEM - check: esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID.cint, onIpEvent, nil) - - # Create PPP netif using inherent defaults and custom driver - var baseCfg = ESP_NETIF_INHERENT_DEFAULT_PPP() - baseCfg.if_desc = "example_netif_ppp" - - driverCfg.handle = cast[pointer](1) - driverCfg.transmit = pppTransmit - - var netifCfg: esp_netif_config_t - netifCfg.base = addr baseCfg - netifCfg.driver = addr driverCfg - netifCfg.stack = ESP_NETIF_NETSTACK_DEFAULT_PPP - - sNetif = esp_netif_new(addr netifCfg) - doAssert sNetif != nil - esp_netif_action_start(sNetif, nil, 0, nil) - esp_netif_action_connected(sNetif, nil, 0, nil) - - logi(TAG, "Waiting for IP...") - let bits = xEventGroupWaitBits(sEventGroup, EventBits_t(CONNECT_BITS), pdFALSE, pdFALSE, portMAX_DELAY) - if (bits and EventBits_t(CONN_FAILED)) != 0: - loge(TAG, "PPP connect failed") - return ESP_FAIL - logi(TAG, "PPP connected") - return ESP_OK - -proc examplePppShutdownDualCdc*() = - discard esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID.cint, onIpEvent) - if sNetif != nil: - esp_netif_action_disconnected(sNetif, nil, 0, nil) - esp_netif_action_stop(sNetif, nil, 0, nil) - esp_netif_destroy(sNetif) - sNetif = nil - if sEventGroup != nil: - vEventGroupDelete(sEventGroup) - sEventGroup = nil - discard esp_tusb_deinit_console(TINYUSB_CDC_ACM_1) diff --git a/src/nesper/components/esp_tinyusb/tinyusb_net.nim b/src/nesper/components/esp_tinyusb/tinyusb_net.nim index 70816e16..a415a769 100644 --- a/src/nesper/components/esp_tinyusb/tinyusb_net.nim +++ b/src/nesper/components/esp_tinyusb/tinyusb_net.nim @@ -17,4 +17,4 @@ proc tinyusb_net_send_sync*(buffer: pointer; len: uint16; eb: pointer; timeout_t # tinyusb console helpers (not wrapped): proc esp_tusb_init_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_init_console", header: "tusb_console.h".} -proc esp_tusb_deinit_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_deinit_console", header: "tusb_console.h".} \ No newline at end of file +proc esp_tusb_deinit_console*(itf: tinyusb_cdcacm_itf_t): esp_err_t {.cdecl, importc: "esp_tusb_deinit_console", header: "tusb_console.h".} From 8f5b99e998f92b856d28a1b8e11c8f9ae3706c4f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 2 Sep 2025 02:25:45 -0600 Subject: [PATCH 061/142] set ula address --- esp-idf-examples/net_pppos_usb/main/main.nim | 16 ++++++++++++++++ src/nesper/esp/net/esp_netif_impl.nim | 10 ++++++++++ src/nesper/net_utils.nim | 11 ++++++++++- src/nesper/networking/usb_ppp_dualcdc.nim | 4 ++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index bb537884..779832d8 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -6,6 +6,8 @@ import nesper/esp/nvs_flash import nesper/esp/esp_event import nesper/esp/net/esp_netif import nesper/esp/net/esp_netif_ppp +import nesper/esp/net/esp_netif_impl +import nesper/net_utils import nesper/servers/rpc/rpcsocket_json @@ -17,6 +19,11 @@ else: const TAG*: cstring = "main" +proc addIpv6ToNetif*(netif: ptr esp_netif_t; ip: IpAddress): esp_err_t = + ## Convert Nim IpAddress to esp_ip6_addr_t and add it to the interface + let espIp6 = toEspIp6Addr(ip) + result = esp_netif_add_ip6_address(netif, espIp6, preferred=true) + proc setupRpc(rt: var RpcRouter) = rt.rpc("hello") do(input: string) -> string: # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' @@ -57,6 +64,15 @@ app_main: # Start PPPoS over USB with dual CDC (CDC0=PPP, CDC1=console) if initPppConnectDualCdc() == ESP_OK: logi(TAG, "PPPoS connected. Idle loop ...") + + # Demo: add a static IPv6 address to the PPP netif + let netif = pppInterface() + let demoIp = parseIpAddress("fd12:4FE6:B3B5:0E74::2") + let rc = addIpv6ToNetif(netif, demoIp) + if rc == ESP_OK: + logi(TAG, "Added IPv6 %s to PPP interface", $demoIp) + else: + logw(TAG, "Failed to add IPv6 (%d)", rc) else: loge(TAG, "PPPoS connect failed") diff --git a/src/nesper/esp/net/esp_netif_impl.nim b/src/nesper/esp/net/esp_netif_impl.nim index a40df2a4..a23061ed 100644 --- a/src/nesper/esp/net/esp_netif_impl.nim +++ b/src/nesper/esp/net/esp_netif_impl.nim @@ -647,6 +647,16 @@ proc esp_netif_get_ip6_linklocal*(esp_netif: ptr esp_netif_t; proc esp_netif_get_ip6_global*(esp_netif: ptr esp_netif_t; if_ip6: ptr esp_ip6_addr_t): esp_err_t {. importc: "esp_netif_get_ip6_global", header: "esp_netif.h".} + +proc esp_netif_add_ip6_address*(esp_netif: ptr esp_netif_t; + ip6addr: esp_ip6_addr_t, + preferred: bool): esp_err_t {. + importc: "esp_netif_add_ip6_address", header: "esp_netif.h".} ##\ + ## @brief Add a static IPv6 address to the specified interface + ## + ## Adds the given IPv6 address to the interface and triggers related events. + ## + ## * ## @brief Sets IPv4 address to the specified octets ## diff --git a/src/nesper/net_utils.nim b/src/nesper/net_utils.nim index 7d38b3b0..9f986852 100644 --- a/src/nesper/net_utils.nim +++ b/src/nesper/net_utils.nim @@ -87,6 +87,16 @@ when not defined(ESP_IDF_V4_0): proc toIpAddress*(ip: esp_ip6_addr_t): IpAddress = toIpAddress(ip.address) +when not defined(ESP_IDF_V4_0): + ## Convert a Nim IPv6 IpAddress to ESP-IDF esp_ip6_addr_t + proc toEspIp6Addr*(ip: IpAddress): esp_ip6_addr_t = + ## Ensures the input is IPv6 and maps bytes directly + doAssert ip.family == IpAddressFamily.IPv6 + var res: esp_ip6_addr_t + res.zone = 0'u8 + copyMem(res.address[0].unsafeAddr, ip.address_v6[0].unsafeAddr, 16) + return res + ## * Generate host name based on sdkconfig, optionally adding a portion of MAC address to it. proc generate_hostname*(hostname: string): string = var mac: array[6, uint8] @@ -109,4 +119,3 @@ proc generate_sensor_id*(): string = sensor_id.add(mac[i].toHex(2)) return sensor_id.join(":") - diff --git a/src/nesper/networking/usb_ppp_dualcdc.nim b/src/nesper/networking/usb_ppp_dualcdc.nim index 9b233480..84cc432c 100644 --- a/src/nesper/networking/usb_ppp_dualcdc.nim +++ b/src/nesper/networking/usb_ppp_dualcdc.nim @@ -146,3 +146,7 @@ proc shutdownPppConnectDualCdc*() = vEventGroupDelete(sEventGroup) sEventGroup = nil discard esp_tusb_deinit_console(TINYUSB_CDC_ACM_1) + +proc pppInterface*(): ptr esp_netif_t = + ## Returns the PPP esp-netif created by initPppConnectDualCdc + sNetif From d67341cc07c5ed1f9e00dae771702eb542bf9f44 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 2 Sep 2025 02:29:41 -0600 Subject: [PATCH 062/142] set ula address --- src/nesper/networking/usb_ppp_dualcdc.nim | 68 +++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/nesper/networking/usb_ppp_dualcdc.nim b/src/nesper/networking/usb_ppp_dualcdc.nim index 84cc432c..ef82a298 100644 --- a/src/nesper/networking/usb_ppp_dualcdc.nim +++ b/src/nesper/networking/usb_ppp_dualcdc.nim @@ -6,6 +6,74 @@ import nesper/events import nesper/esp/net/[esp_netif, esp_netif_ppp, esp_netif_types] import nesper/components/esp_tinyusb/[tinyusb, tinyusb_net, tusb_cdc_acm] +## Code that is specific to the USB PPP over Dual CDC (CDC0=PPP, CDC1=console) +## Requires TinyUSB and incompatible with USB JTAG or OTG Modes +## CDC0 is used for PPP data, CDC1 is used for console +## +## Example /etc/ppp/ipv6-up script: +## ```sh +## #!/bin/sh +## +## INTERFACE=$1 +## DEVICE=$2 +## SPEED=$3 +## LOCAL_IP=$4 +## REMOTE_IP=$5 +## IPPARAM=$6 +## +## echo 0 > /proc/sys/net/ipv6/conf/$1/use_tempaddr +## echo 2 > /proc/sys/net/ipv6/conf/$1/accept_ra +## echo 1 > /proc/sys/net/ipv6/conf/all/forwarding +## +## ULA_PREFIX="fd12:1234:0E74" # Choose your own prefix!!! +## HOST_ULA="${ULA_PREFIX}::1/64" +## DEVICE_ULA="${ULA_PREFIX}::2/64" +## +## # Add the ULA address to the PPP interface +## ip -6 addr add $HOST_ULA dev $INTERFACE +## +## # Add a route to the device's ULA address +## ip -6 route add $DEVICE_ULA dev $INTERFACE +## +## # Optional: Add the ULA subnet to the routing table +## ip -6 route add ${ULA_PREFIX}::/64 dev $INTERFACE +## +## # Log the configuration +## logger "IPv6-up: Added ULA addresses - Host: $HOST_ULA, Device: $DEVICE_ULA on $INTERFACE" +## ``` +## +## Example of /etc/ppp/peers/esp32 config: +## +## ```sh +## # Serial device +## /dev/ttyACM0 +## # Baud rate (match your ESP32-S3 configuration) +## 115200 +## # Hardware flow control +## crtscts +## # Don't use modem control lines +## local +## # Don't require authentication from peer +## noauth +## # Set this side as client +## noipdefault +## defaultroute +## # Use peer's DNS +## usepeerdns +## # Enable debug (remove after testing) +## debug +## dump +## # Keep connection alive +## persist +## maxfail 0 +## +## # Optional: specific IP addresses if your ESP32-S3 assigns them +## # 192.168.1.100:192.168.1.101 +## +ipv6 +## ``` +## +## Then you can simply run `sudo pppd call esp32` + const TAG* = "pppos_dualcdc" From e12f29f83d6827b31b925df202be26f86f01cf94 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 2 Sep 2025 02:37:23 -0600 Subject: [PATCH 063/142] try mummy --- esp-idf-examples/net_pppos_usb/main/main.nim | 38 ++++++++++++++------ nesper.nimble | 2 ++ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 779832d8..f5274ce0 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -9,7 +9,6 @@ import nesper/esp/net/esp_netif_ppp import nesper/esp/net/esp_netif_impl import nesper/net_utils -import nesper/servers/rpc/rpcsocket_json when defined(RUN_NCM): import usb/usb_ncm_eth_dualcdc as ncm_eth @@ -24,14 +23,31 @@ proc addIpv6ToNetif*(netif: ptr esp_netif_t; ip: IpAddress): esp_err_t = let espIp6 = toEspIp6Addr(ip) result = esp_netif_add_ip6_address(netif, espIp6, preferred=true) -proc setupRpc(rt: var RpcRouter) = - rt.rpc("hello") do(input: string) -> string: - # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' - result = "Hello " & input +when defined(RPC_JSON): + import nesper/servers/rpc/rpcsocket_json + proc setupRpc(rt: var RpcRouter) = + rt.rpc("hello") do(input: string) -> string: + # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' + result = "Hello " & input - rt.rpc("add") do(a: int, b: int) -> int: - # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' - result = a + b + rt.rpc("add") do(a: int, b: int) -> int: + # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' + result = a + b + +import mummy, mummy/routers + +proc indexHandler(request: Request) = + var headers: HttpHeaders + headers["Content-Type"] = "text/plain" + request.respond(200, headers, "Hello, World!") + +proc runMummy() = + var router: Router + router.get("/", indexHandler) + + let server = newServer(router) + echo "Serving on http://localhost:8080" + server.serve(Port(8080), address="::") app_main: logi(TAG, "esp starting ... ") @@ -76,10 +92,10 @@ app_main: else: loge(TAG, "PPPoS connect failed") - var rt: RpcRouter = createRpcRouter(4096) - rt.setupRpc() + # var rt: RpcRouter = createRpcRouter(4096) + # rt.setupRpc() - startRpcSocketServer(port=Port(5555), address="::", router=rt) + # startRpcSocketServer(port=Port(5555), address="::", router=rt) # Keep app alive; clean shutdown not triggered in this minimal example while true: diff --git a/nesper.nimble b/nesper.nimble index e3067769..2bc5a8ec 100644 --- a/nesper.nimble +++ b/nesper.nimble @@ -13,3 +13,5 @@ requires "msgpack4nim >= 0.3.1" requires "stew >= 0.1.0" requires "bytesequtils" +feature "examples": + requires "mummy" \ No newline at end of file From 62cb505cbfa96d924e871f61cae20fe4c3faf4e6 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 2 Sep 2025 02:37:32 -0600 Subject: [PATCH 064/142] try mummy --- esp-idf-examples/net_pppos_usb/main/main.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index f5274ce0..279888af 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -45,7 +45,7 @@ proc runMummy() = var router: Router router.get("/", indexHandler) - let server = newServer(router) + let server = newServer(router, workerThreads=1) echo "Serving on http://localhost:8080" server.serve(Port(8080), address="::") From a7df965dd0a3125614513f3586e306a362b41ebb Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 2 Sep 2025 02:46:45 -0600 Subject: [PATCH 065/142] try mummy --- esp-idf-examples/net_pppos_usb/config.nims | 2 ++ esp-idf-examples/net_pppos_usb/main/cpuinfo.nim | 2 ++ esp-idf-examples/net_pppos_usb/main/main.nim | 9 ++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 esp-idf-examples/net_pppos_usb/main/cpuinfo.nim diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index 498b2aa3..0187383d 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -3,4 +3,6 @@ switch("define", "esp32s3") # or other variants # switch("define", "RUN_NCM") +patchFile("stdlib", "cpuinfo", "main/cpuinfo.nim") + include nesper/build_utils/builds diff --git a/esp-idf-examples/net_pppos_usb/main/cpuinfo.nim b/esp-idf-examples/net_pppos_usb/main/cpuinfo.nim new file mode 100644 index 00000000..ffe9285f --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/cpuinfo.nim @@ -0,0 +1,2 @@ + +proc countProcessors*(): int = 1 diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 279888af..4461ec23 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -45,7 +45,14 @@ proc runMummy() = var router: Router router.get("/", indexHandler) - let server = newServer(router, workerThreads=1) + let server = newServer(router, + websocketHandler=nil, + logHandler=nil, + workerThreads=1, + maxHeadersLen=8*1024, + maxBodyLen=128*1024, + maxMessageLen=16*1024 + ) echo "Serving on http://localhost:8080" server.serve(Port(8080), address="::") From c0dcf3b86b3d9d5a688f717549a4601c7b008367 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 00:09:23 -0600 Subject: [PATCH 066/142] cleanup --- esp-idf-examples/net_pppos_usb/main/main.nim | 45 +++++--------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 4461ec23..779832d8 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -9,6 +9,7 @@ import nesper/esp/net/esp_netif_ppp import nesper/esp/net/esp_netif_impl import nesper/net_utils +import nesper/servers/rpc/rpcsocket_json when defined(RUN_NCM): import usb/usb_ncm_eth_dualcdc as ncm_eth @@ -23,38 +24,14 @@ proc addIpv6ToNetif*(netif: ptr esp_netif_t; ip: IpAddress): esp_err_t = let espIp6 = toEspIp6Addr(ip) result = esp_netif_add_ip6_address(netif, espIp6, preferred=true) -when defined(RPC_JSON): - import nesper/servers/rpc/rpcsocket_json - proc setupRpc(rt: var RpcRouter) = - rt.rpc("hello") do(input: string) -> string: - # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' - result = "Hello " & input +proc setupRpc(rt: var RpcRouter) = + rt.rpc("hello") do(input: string) -> string: + # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' + result = "Hello " & input - rt.rpc("add") do(a: int, b: int) -> int: - # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' - result = a + b - -import mummy, mummy/routers - -proc indexHandler(request: Request) = - var headers: HttpHeaders - headers["Content-Type"] = "text/plain" - request.respond(200, headers, "Hello, World!") - -proc runMummy() = - var router: Router - router.get("/", indexHandler) - - let server = newServer(router, - websocketHandler=nil, - logHandler=nil, - workerThreads=1, - maxHeadersLen=8*1024, - maxBodyLen=128*1024, - maxMessageLen=16*1024 - ) - echo "Serving on http://localhost:8080" - server.serve(Port(8080), address="::") + rt.rpc("add") do(a: int, b: int) -> int: + # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' + result = a + b app_main: logi(TAG, "esp starting ... ") @@ -99,10 +76,10 @@ app_main: else: loge(TAG, "PPPoS connect failed") - # var rt: RpcRouter = createRpcRouter(4096) - # rt.setupRpc() + var rt: RpcRouter = createRpcRouter(4096) + rt.setupRpc() - # startRpcSocketServer(port=Port(5555), address="::", router=rt) + startRpcSocketServer(port=Port(5555), address="::", router=rt) # Keep app alive; clean shutdown not triggered in this minimal example while true: From c36ea89013301bf357543a85f14735626961e050 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 00:26:41 -0600 Subject: [PATCH 067/142] cleanup --- src/nesper/servers/rpc/rpc_cli_utils.nim | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/nesper/servers/rpc/rpc_cli_utils.nim b/src/nesper/servers/rpc/rpc_cli_utils.nim index d77eeef6..ae8e30a1 100644 --- a/src/nesper/servers/rpc/rpc_cli_utils.nim +++ b/src/nesper/servers/rpc/rpc_cli_utils.nim @@ -192,10 +192,9 @@ proc runRpc*(args: var RpcCli) = else: call = %* { "jsonrpc": "2.0", "id": 1 } - let m = parseJson(args.jsonArg) - - for (f,v) in m.pairs(): - call[f] = v + let m = parseJson(args.jsonArg) + for (f,v) in m.pairs(): + call[f] = v let client: Socket = newSocket(buffered=false) client.connect(args.ipAddr, args.port) From c9c7c5f1c410d70fbd89cad677e5586164b21a39 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 00:37:51 -0600 Subject: [PATCH 068/142] cleanup --- src/nesper/servers/rpc/rpc_cli_utils.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nesper/servers/rpc/rpc_cli_utils.nim b/src/nesper/servers/rpc/rpc_cli_utils.nim index ae8e30a1..7642da63 100644 --- a/src/nesper/servers/rpc/rpc_cli_utils.nim +++ b/src/nesper/servers/rpc/rpc_cli_utils.nim @@ -196,7 +196,7 @@ proc runRpc*(args: var RpcCli) = for (f,v) in m.pairs(): call[f] = v - let client: Socket = newSocket(buffered=false) + let client: Socket = newSocket(buffered=false, domain = AF_UNSPEC) client.connect(args.ipAddr, args.port) echo(yellow, "[connected to server ip addr: ", args.ipAddr,"]") echo(blue, "[call: ", $call, "]") From 9e42a50f8d3e990bf78cbb97c1871ebb75354de5 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 01:13:06 -0600 Subject: [PATCH 069/142] build on host --- src/nesper/esp/esp_log.nim | 30 ++++++++++++++------- src/nesper/servers/rpc/rpcsocket_json.nim | 8 +++--- src/nesper/servers/tcpsocket.nim | 5 ++-- src/nesper/timers.nim | 33 +++++++++++++++++++++-- tests/c_headers/mock/esp_log.h | 1 + utils/config.nims | 1 + utils/rpc_server.nim | 14 ++++++++++ 7 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 utils/config.nims create mode 100644 utils/rpc_server.nim diff --git a/src/nesper/esp/esp_log.nim b/src/nesper/esp/esp_log.nim index 968c79a5..09e41d0e 100644 --- a/src/nesper/esp/esp_log.nim +++ b/src/nesper/esp/esp_log.nim @@ -1,6 +1,9 @@ import ../consts -var LOG_LOCAL_LEVEL* {.importc: "CONFIG_LOG_DEFAULT_LEVEL", header: "esp_log.nim".}: cint +when defined(freertos): + var LOG_LOCAL_LEVEL* {.importc: "CONFIG_LOG_DEFAULT_LEVEL", header: "esp_log.nim".}: cint +else: + var LOG_LOCAL_LEVEL*: cint = 4 type esp_log_level_t* {.size: sizeof(cint).} = enum @@ -12,18 +15,25 @@ type ESP_LOG_VERBOSE ## !< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. -proc esp_log_timestamp*(): uint32 {.importc: "esp_log_timestamp", header: "esp_log.h".} +when defined(freertos): + proc esp_log_timestamp*(): uint32 {.importc: "esp_log_timestamp", header: "esp_log.h".} -proc esp_log_write*(level: esp_log_level_t, tag: cstring, format: cstring) {. - importc: "esp_log_write", varargs, header: "esp_log.h".} + proc esp_log_write*(level: esp_log_level_t, tag: cstring, format: cstring) {. + importc: "esp_log_write", varargs, header: "esp_log.h".} -proc loge*(tag: cstring, formatstr: cstring) {.importc: "ESP_LOGE", varargs, header: "esp_log.h".} -proc logw*(tag: cstring, formatstr: cstring) {.importc: "ESP_LOGW", varargs, header: "esp_log.h".} -proc logi*(tag: cstring, formatstr: cstring) {.importc: "ESP_LOGI", varargs, header: "esp_log.h".} -proc logd*(tag: cstring, formatstr: cstring) {.importc: "ESP_LOGD", varargs, header: "esp_log.h".} -proc logv*(tag: cstring, formatstr: cstring) {.importc: "ESP_LOGV", varargs, header: "esp_log.h".} + proc loge*(tag: cstring, formatstr: cstring) {.importc: "ESP_LOGE", varargs, header: "esp_log.h".} + proc logw*(tag: cstring, formatstr: cstring) {.importc: "ESP_LOGW", varargs, header: "esp_log.h".} + proc logi*(tag: cstring, formatstr: cstring) {.importc: "ESP_LOGI", varargs, header: "esp_log.h".} + proc logd*(tag: cstring, formatstr: cstring) {.importc: "ESP_LOGD", varargs, header: "esp_log.h".} + proc logv*(tag: cstring, formatstr: cstring) {.importc: "ESP_LOGV", varargs, header: "esp_log.h".} -proc log_timestamp*(): uint32 {.cdecl, importc: "esp_log_timestamp", header: "esp_log.h".} + proc log_timestamp*(): uint32 {.cdecl, importc: "esp_log_timestamp", header: "esp_log.h".} +else: + proc loge*(tag: cstring, formatstr: cstring) {.importc: "printf", varargs, header: "stdio.h".} + proc logw*(tag: cstring, formatstr: cstring) {.importc: "printf", varargs, header: "stdio.h".} + proc logi*(tag: cstring, formatstr: cstring) {.importc: "printf", varargs, header: "stdio.h".} + proc logd*(tag: cstring, formatstr: cstring) {.importc: "printf", varargs, header: "stdio.h".} + proc logv*(tag: cstring, formatstr: cstring) {.importc: "printf", varargs, header: "stdio.h".} type MallocCapacity* = enum diff --git a/src/nesper/servers/rpc/rpcsocket_json.nim b/src/nesper/servers/rpc/rpcsocket_json.nim index 823ca2bc..68018449 100644 --- a/src/nesper/servers/rpc/rpcsocket_json.nim +++ b/src/nesper/servers/rpc/rpcsocket_json.nim @@ -4,8 +4,10 @@ import selectors import tables import posix -import ../../consts -import ../../general +when defined(freertos): + import ../../consts + import ../../general + import ../tcpsocket import router import json @@ -40,7 +42,7 @@ proc rpcMsgPackReadHandler*(srv: TcpServerInfo[RpcRouter], result: ReadyKey, sou proc startRpcSocketServer*(port: Port; address="", router: var RpcRouter) = - logi(TAG, "starting json rpc server: buffer: %s", $router.buffer) + logi(TAG, "starting json rpc server: buffer: %s, port: %s", $router.buffer, $port) startSocketServer[RpcRouter]( port, diff --git a/src/nesper/servers/tcpsocket.nim b/src/nesper/servers/tcpsocket.nim index defc76a3..b9e8a9be 100644 --- a/src/nesper/servers/tcpsocket.nim +++ b/src/nesper/servers/tcpsocket.nim @@ -6,12 +6,11 @@ import posix import ../consts import ../general -import ../tasks import ../timers +export consts, general, timers export net, selectors, tables, posix -export consts, general, timers const TAG = "socketrpc" @@ -157,7 +156,7 @@ proc startSocketServer*[T](port: Port, address: string = "", readHandler: TcpSer result.processWrites(srv, data) # taskYIELD() # delayMillis(1) - vTaskDelay(1.TickType_t) + delay(1.Micros) select.close() diff --git a/src/nesper/timers.nim b/src/nesper/timers.nim index 675ddd99..81dcae4d 100644 --- a/src/nesper/timers.nim +++ b/src/nesper/timers.nim @@ -2,10 +2,39 @@ import consts import general -import esp/esp_timer +export consts +when defined(freertos): + import esp/esp_timer + export esp_timer +else: + import std/monotimes + proc esp_timer_get_time*(): uint64 = return uint64(getMonoTime().ticks * 1_000_000) + type + esp_timer_cb_t* = proc (arg: pointer) {.cdecl.} + esp_timer_dispatch_t* = enum + ESP_TIMER_DISPATCH_NOW = 0, + ESP_TIMER_DISPATCH_NEXT = 1, + ESP_TIMER_DISPATCH_LATE = 2, + ESP_TIMER_DISPATCH_UNIQUE = 3 + esp_timer_handle_t* = ptr esp_timer_t + esp_timer_t* = object + callback: esp_timer_cb_t + arg: pointer + dispatch_method: esp_timer_dispatch_t + name: cstring + esp_timer_create_args_t* = object + callback: esp_timer_cb_t + arg: pointer + dispatch_method: esp_timer_dispatch_t + name: cstring + proc esp_timer_create*(create_args: ptr esp_timer_create_args_t; out_handle: ptr esp_timer_handle_t): esp_err_t {.cdecl.} = return ESP_OK + proc esp_timer_start_once*(timer: esp_timer_handle_t; timeout_us: uint64): esp_err_t {.cdecl.} = return ESP_OK + proc esp_timer_start_periodic*(timer: esp_timer_handle_t; period: uint64): esp_err_t {.cdecl.} = return ESP_OK + proc esp_timer_stop*(timer: esp_timer_handle_t): esp_err_t {.cdecl.} = return ESP_OK + proc esp_timer_delete*(timer: esp_timer_handle_t): esp_err_t {.cdecl.} = return ESP_OK + # import esp/driver/timer -export consts, esp_timer type TimerError* = object of OSError diff --git a/tests/c_headers/mock/esp_log.h b/tests/c_headers/mock/esp_log.h index 8afe8abd..c4df3a68 100644 --- a/tests/c_headers/mock/esp_log.h +++ b/tests/c_headers/mock/esp_log.h @@ -2,5 +2,6 @@ #include #define ESP_LOGI(fmt, args...) printf(fmt, args); +#define ESP_LOGD(fmt, args...) printf(fmt, args); // #define esp_err_to_name(id) ("ERROR" ## id) diff --git a/utils/config.nims b/utils/config.nims new file mode 100644 index 00000000..a1192088 --- /dev/null +++ b/utils/config.nims @@ -0,0 +1 @@ +--path:"../src" diff --git a/utils/rpc_server.nim b/utils/rpc_server.nim new file mode 100644 index 00000000..37cfcaec --- /dev/null +++ b/utils/rpc_server.nim @@ -0,0 +1,14 @@ + +import nesper/servers/rpc/rpcsocket_json + +proc setupRpc(rt: var RpcRouter) = + rt.rpc("hello") do(input: string) -> string: + # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' + result = "Hello " & input + + rt.rpc("add") do(a: int, b: int) -> int: + # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' + result = a + b + +var rt: RpcRouter = createRpcRouter(4096) +startRpcSocketServer(port=Port(5555), address="::", router=rt) From 8813e3bc9a895426c90b154796c0a0c612acd322 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 01:20:10 -0600 Subject: [PATCH 070/142] build on host --- src/nesper/servers/rpc/rpc_cli_utils.nim | 2 +- src/nesper/servers/tcpsocket.nim | 2 +- src/nesper/timers.nim | 2 +- utils/rpc_client.nim | 12 ++++++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 utils/rpc_client.nim diff --git a/src/nesper/servers/rpc/rpc_cli_utils.nim b/src/nesper/servers/rpc/rpc_cli_utils.nim index 7642da63..464e0f3d 100644 --- a/src/nesper/servers/rpc/rpc_cli_utils.nim +++ b/src/nesper/servers/rpc/rpc_cli_utils.nim @@ -196,7 +196,7 @@ proc runRpc*(args: var RpcCli) = for (f,v) in m.pairs(): call[f] = v - let client: Socket = newSocket(buffered=false, domain = AF_UNSPEC) + let client: Socket = newSocket(buffered=false, domain = AF_INET6) client.connect(args.ipAddr, args.port) echo(yellow, "[connected to server ip addr: ", args.ipAddr,"]") echo(blue, "[call: ", $call, "]") diff --git a/src/nesper/servers/tcpsocket.nim b/src/nesper/servers/tcpsocket.nim index b9e8a9be..46188a8e 100644 --- a/src/nesper/servers/tcpsocket.nim +++ b/src/nesper/servers/tcpsocket.nim @@ -130,7 +130,7 @@ proc echoReadHandler*(srv: TcpServerInfo[string], result: ReadyKey, sourceClient client.sendWrap(data & message & "\r\L") proc startSocketServer*[T](port: Port, address: string = "", readHandler: TcpServerHandler[T], writeHandler: TcpServerHandler[T], data: var T) = - var server: Socket = newSocket() + var server: Socket = newSocket(domain=AF_INET6) var select: Selector[T] = newSelector[T]() server.setSockOpt(OptReuseAddr, true) diff --git a/src/nesper/timers.nim b/src/nesper/timers.nim index 81dcae4d..a37b59f7 100644 --- a/src/nesper/timers.nim +++ b/src/nesper/timers.nim @@ -8,7 +8,7 @@ when defined(freertos): export esp_timer else: import std/monotimes - proc esp_timer_get_time*(): uint64 = return uint64(getMonoTime().ticks * 1_000_000) + proc esp_timer_get_time*(): uint64 = return uint64(getMonoTime().ticks div 1_000) type esp_timer_cb_t* = proc (arg: pointer) {.cdecl.} esp_timer_dispatch_t* = enum diff --git a/utils/rpc_client.nim b/utils/rpc_client.nim new file mode 100644 index 00000000..505d90f2 --- /dev/null +++ b/utils/rpc_client.nim @@ -0,0 +1,12 @@ + +const RpcServerType* = "json" + +import parseopt + +include nesper/servers/rpc/rpc_cli_utils + +var p = initOptParser() + +var args = p.rpcOptions() + +args.runRpc() From d683c2a8de69abed26512343b63ca7d0140c36af Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 01:29:12 -0600 Subject: [PATCH 071/142] fix ip family affinity --- src/nesper/servers/rpc/rpc_cli_utils.nim | 22 ++++++++++++++-------- src/nesper/servers/tcpsocket.nim | 9 ++++++++- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/nesper/servers/rpc/rpc_cli_utils.nim b/src/nesper/servers/rpc/rpc_cli_utils.nim index 464e0f3d..73ab0654 100644 --- a/src/nesper/servers/rpc/rpc_cli_utils.nim +++ b/src/nesper/servers/rpc/rpc_cli_utils.nim @@ -48,7 +48,8 @@ type count: int delay: int jsonArg: string - ipAddr: string + host: string + ipaddr: IpAddress port: Port prettyPrint: bool quiet: bool @@ -65,7 +66,7 @@ proc rpcOptions*(p: var OptParser): RpcCli = result.delay = 0 result.quiet = false result.jsonArg = "" - result.ipAddr = "" + result.host = "" result.port = Port(5555) result.prettyPrint = false result.id = 1 @@ -79,7 +80,7 @@ proc rpcOptions*(p: var OptParser): RpcCli = of "count", "c": result.count = parseInt(val) of "ip", "i": - result.ipAddr = val + result.host = val of "port", "p": result.port = Port(parseInt(val)) of "stats", "s": @@ -92,7 +93,7 @@ proc rpcOptions*(p: var OptParser): RpcCli = echo "args: ", $result - if result.ipAddr == "": + if result.host == "": # no filename has been given, so we show the help raise newException(ValueError, "missing ip address") @@ -100,7 +101,7 @@ proc rpcOptions*(p: var OptParser): RpcCli = # Check IP address try: - discard parseIpAddress(result.ipAddr) + result.ipaddr = parseIpAddress(result.host) except CatchableError as err: echo "invalid IP address, check the --ip:$IP argument" raise err @@ -196,9 +197,14 @@ proc runRpc*(args: var RpcCli) = for (f,v) in m.pairs(): call[f] = v - let client: Socket = newSocket(buffered=false, domain = AF_INET6) - client.connect(args.ipAddr, args.port) - echo(yellow, "[connected to server ip addr: ", args.ipAddr,"]") + var client: Socket + if args.ipaddr.family == IpAddressFamily.IPv6: + client = newSocket(buffered=false, domain = AF_INET6) + else: + client = newSocket(buffered=false, domain = AF_INET) + + client.connect(args.host, args.port) + echo(yellow, "[connected to server ip addr: ", args.host,"]") echo(blue, "[call: ", $call, "]") for i in 1..args.count: diff --git a/src/nesper/servers/tcpsocket.nim b/src/nesper/servers/tcpsocket.nim index 46188a8e..d3c7ede9 100644 --- a/src/nesper/servers/tcpsocket.nim +++ b/src/nesper/servers/tcpsocket.nim @@ -130,7 +130,14 @@ proc echoReadHandler*(srv: TcpServerInfo[string], result: ReadyKey, sourceClient client.sendWrap(data & message & "\r\L") proc startSocketServer*[T](port: Port, address: string = "", readHandler: TcpServerHandler[T], writeHandler: TcpServerHandler[T], data: var T) = - var server: Socket = newSocket(domain=AF_INET6) + + let ip = parseIpAddress(address) + var server: Socket + if ip.family == IpAddressFamily.IPv6: + server = newSocket(domain=AF_INET6) + else: + server = newSocket(domain=AF_INET) + var select: Selector[T] = newSelector[T]() server.setSockOpt(OptReuseAddr, true) From 7afd0ef8563d4643df750abadd48799427c6c6b1 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 01:47:51 -0600 Subject: [PATCH 072/142] fix ip family affinity --- src/nesper/esp/esp_log.nim | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/nesper/esp/esp_log.nim b/src/nesper/esp/esp_log.nim index 09e41d0e..3a5ccc06 100644 --- a/src/nesper/esp/esp_log.nim +++ b/src/nesper/esp/esp_log.nim @@ -29,11 +29,12 @@ when defined(freertos): proc log_timestamp*(): uint32 {.cdecl, importc: "esp_log_timestamp", header: "esp_log.h".} else: - proc loge*(tag: cstring, formatstr: cstring) {.importc: "printf", varargs, header: "stdio.h".} - proc logw*(tag: cstring, formatstr: cstring) {.importc: "printf", varargs, header: "stdio.h".} - proc logi*(tag: cstring, formatstr: cstring) {.importc: "printf", varargs, header: "stdio.h".} - proc logd*(tag: cstring, formatstr: cstring) {.importc: "printf", varargs, header: "stdio.h".} - proc logv*(tag: cstring, formatstr: cstring) {.importc: "printf", varargs, header: "stdio.h".} + proc c_printf*(formatstr: cstring) {.importc: "printf", header: "stdio.h", varargs.} + template loge*(tag: cstring, formatstr: cstring, args: varargs[untyped]) = stdout.write "ERROR: ", tag, ": "; c_printf(formatstr, args); echo "" + template logw*(tag: cstring, formatstr: cstring, args: varargs[untyped]) = stdout.write "WARN: ", tag, ": "; c_printf(formatstr, args); echo "" + template logi*(tag: cstring, formatstr: cstring, args: varargs[untyped]) = stdout.write "INFO: ", tag, ": "; c_printf(formatstr, args); echo "" + template logd*(tag: cstring, formatstr: cstring, args: varargs[untyped]) = stdout.write "DEBUG: ", tag, ": "; c_printf(formatstr, args); echo "" + template logv*(tag: cstring, formatstr: cstring, args: varargs[untyped]) = stdout.write "VERBOSE: ", tag, ": "; c_printf(formatstr, args); echo "" type MallocCapacity* = enum From 5fa14f2236b8f50c7610714b2800910b7f7c5ac2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 01:53:30 -0600 Subject: [PATCH 073/142] fix ip family affinity --- src/nesper/servers/tcpsocket.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nesper/servers/tcpsocket.nim b/src/nesper/servers/tcpsocket.nim index d3c7ede9..c31c2e9b 100644 --- a/src/nesper/servers/tcpsocket.nim +++ b/src/nesper/servers/tcpsocket.nim @@ -145,7 +145,7 @@ proc startSocketServer*[T](port: Port, address: string = "", readHandler: TcpSer server.bindAddr(port, address=address) server.listen() - logi TAG, "Server: started. Listening to new connections on port: %s", $port + logi TAG, "Server: started. Listening to new connections on address: %s, port: %s, domain: %s", $address, $port, $server.getFd().getSockDomain() var srv = createServerInfo[T](server, select) srv.readHandler = readHandler From 2080eb426bd789ad3916c236ce4f58d1f80ce9be Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 01:58:49 -0600 Subject: [PATCH 074/142] fix ip family affinity --- esp-idf-examples/net_pppos_usb/main/main.nim | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 779832d8..584c37de 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -55,6 +55,8 @@ app_main: except Defect, CatchableError: logi(TAG, "Error getting chip info") + let ipAddr = parseIpAddress("fd12:4FE6:B3B5:0E74::2") + when defined(RUN_NCM): # Start USB NCM-as-Ethernet with separate CDC console ncm_eth.runUsbNcmEthWithConsole() @@ -67,10 +69,9 @@ app_main: # Demo: add a static IPv6 address to the PPP netif let netif = pppInterface() - let demoIp = parseIpAddress("fd12:4FE6:B3B5:0E74::2") - let rc = addIpv6ToNetif(netif, demoIp) + let rc = addIpv6ToNetif(netif, ipAddr) if rc == ESP_OK: - logi(TAG, "Added IPv6 %s to PPP interface", $demoIp) + logi(TAG, "Added IPv6 %s to PPP interface", $ipAddr) else: logw(TAG, "Failed to add IPv6 (%d)", rc) else: @@ -79,7 +80,7 @@ app_main: var rt: RpcRouter = createRpcRouter(4096) rt.setupRpc() - startRpcSocketServer(port=Port(5555), address="::", router=rt) + startRpcSocketServer(port=Port(5555), address = $ipAddr, router = rt) # Keep app alive; clean shutdown not triggered in this minimal example while true: From d4b2fe669731c3a6119ea5eec9ffe0d1912bc72b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 02:13:16 -0600 Subject: [PATCH 075/142] fix ip family affinity --- utils/rpc_server.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/rpc_server.nim b/utils/rpc_server.nim index 37cfcaec..eb28a9dc 100644 --- a/utils/rpc_server.nim +++ b/utils/rpc_server.nim @@ -11,4 +11,5 @@ proc setupRpc(rt: var RpcRouter) = result = a + b var rt: RpcRouter = createRpcRouter(4096) +rt.setupRpc() startRpcSocketServer(port=Port(5555), address="::", router=rt) From 8d83e0ef938041ed115936262dbafef83fc06298 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 02:25:16 -0600 Subject: [PATCH 076/142] fix ip family affinity --- esp-idf-examples/net_pppos_usb/main/main.nim | 6 +++++- src/nesper/servers/tcpsocket.nim | 12 ++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 584c37de..63ae0292 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -27,9 +27,12 @@ proc addIpv6ToNetif*(netif: ptr esp_netif_t; ip: IpAddress): esp_err_t = proc setupRpc(rt: var RpcRouter) = rt.rpc("hello") do(input: string) -> string: # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' + logi(TAG, "rcp hello: %s", input) result = "Hello " & input rt.rpc("add") do(a: int, b: int) -> int: + echo "ADDING!" + logi(TAG, "rcp add: %s, %s", $a, $b) # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' result = a + b @@ -80,7 +83,8 @@ app_main: var rt: RpcRouter = createRpcRouter(4096) rt.setupRpc() - startRpcSocketServer(port=Port(5555), address = $ipAddr, router = rt) + delay(4_000.Millis) + startRpcSocketServer(port=Port(5555), address = "::", router = rt) # Keep app alive; clean shutdown not triggered in this minimal example while true: diff --git a/src/nesper/servers/tcpsocket.nim b/src/nesper/servers/tcpsocket.nim index c31c2e9b..cb0c0202 100644 --- a/src/nesper/servers/tcpsocket.nim +++ b/src/nesper/servers/tcpsocket.nim @@ -36,11 +36,11 @@ template sendWrap*(socket: Socket, data: untyped) = proc sendChunks*(sourceClient: Socket, rmsg: string) = let rN = rmsg.len() - # logd(TAG,"rpc handler send client: %d bytes", rN) + logi(TAG,"rpc handler send client: %d bytes", rN) var i = 0 while i < rN: var j = min(i + MsgChunk, rN) - # logd(TAG,"rpc handler sending: i: %s j: %s ", $i, $j) + logi(TAG,"rpc handler sending: i: %s j: %s ", $i, $j) var sl = rmsg[i.. Date: Wed, 3 Sep 2025 02:35:31 -0600 Subject: [PATCH 077/142] tcp echo --- esp-idf-examples/net_pppos_usb/config.nims | 1 + esp-idf-examples/net_pppos_usb/main/main.nim | 40 +++++++++++++++++-- .../net_pppos_usb/sdkconfig.defaults.ppp | 8 ++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index 0187383d..6ed0bfa9 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -1,5 +1,6 @@ switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants +switch("define", "TcpEchoServer") # or other variants # switch("define", "RUN_NCM") diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 63ae0292..d8800ab7 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -36,6 +36,35 @@ proc setupRpc(rt: var RpcRouter) = # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' result = a + b +proc runTcpEcho*() = + # Create the server socket + let server = newSocket() + server.setSockOpt(OptReuseAddr, true) + server.bindAddr(Port(8080)) + server.listen() + + echo "Echo server listening on port 8080" + + while true: + # Accept a client connection + let client = server.accept() + echo "Client connected" + + # Echo loop for this client + while true: + try: + echo "Client waiting for data" + let data = client.recv(1024) + echo "Client waiting received data: ", data.repr() + if data.len == 0: + break # Client disconnected + client.send(data) # Echo back the data + except: + break # Error occurred + + echo "Client disconnected" + client.close() + app_main: logi(TAG, "esp starting ... ") @@ -80,11 +109,14 @@ app_main: else: loge(TAG, "PPPoS connect failed") - var rt: RpcRouter = createRpcRouter(4096) - rt.setupRpc() + when defined(RpcServer): + var rt: RpcRouter = createRpcRouter(4096) + rt.setupRpc() - delay(4_000.Millis) - startRpcSocketServer(port=Port(5555), address = "::", router = rt) + delay(4_000.Millis) + startRpcSocketServer(port=Port(5555), address = "::", router = rt) + when defined(TcpEchoServer): + runTcpEcho() # Keep app alive; clean shutdown not triggered in this minimal example while true: diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp index 22f3f87e..3f0e1fd6 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp @@ -20,3 +20,11 @@ CONFIG_LWIP_BROADCAST_PING=y CONFIG_TINYUSB_DEBUG_LEVEL=02 CONFIG_TINYUSB_CDC_ENABLED=y CONFIG_TINYUSB_CDC_COUNT=2 + +CONFIG_LWIP_USE_ONLY_LWIP_SELECT=n +CONFIG_VFS_SUPPORT_SELECT=y + +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y + From 7956141459cc362e6e330b980a0177ee267524c2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 02:36:57 -0600 Subject: [PATCH 078/142] tcp echo --- esp-idf-examples/net_pppos_usb/main/main.nim | 83 +++++++++++--------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index d8800ab7..6d5bbbab 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -9,7 +9,10 @@ import nesper/esp/net/esp_netif_ppp import nesper/esp/net/esp_netif_impl import nesper/net_utils -import nesper/servers/rpc/rpcsocket_json +when defined(RpcServer): + import nesper/servers/rpc/rpcsocket_json +when defined(TcpEchoServer): + import std/net when defined(RUN_NCM): import usb/usb_ncm_eth_dualcdc as ncm_eth @@ -24,46 +27,48 @@ proc addIpv6ToNetif*(netif: ptr esp_netif_t; ip: IpAddress): esp_err_t = let espIp6 = toEspIp6Addr(ip) result = esp_netif_add_ip6_address(netif, espIp6, preferred=true) -proc setupRpc(rt: var RpcRouter) = - rt.rpc("hello") do(input: string) -> string: - # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' - logi(TAG, "rcp hello: %s", input) - result = "Hello " & input +when defined(RpcServer): + proc setupRpc(rt: var RpcRouter) = + rt.rpc("hello") do(input: string) -> string: + # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' + logi(TAG, "rcp hello: %s", input) + result = "Hello " & input + + rt.rpc("add") do(a: int, b: int) -> int: + echo "ADDING!" + logi(TAG, "rcp add: %s, %s", $a, $b) + # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' + result = a + b + +when defined(TcpEchoServer): + proc runTcpEcho*() = + # Create the server socket + let server = newSocket() + server.setSockOpt(OptReuseAddr, true) + server.bindAddr(Port(8080)) + server.listen() + + echo "Echo server listening on port 8080" - rt.rpc("add") do(a: int, b: int) -> int: - echo "ADDING!" - logi(TAG, "rcp add: %s, %s", $a, $b) - # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' - result = a + b - -proc runTcpEcho*() = - # Create the server socket - let server = newSocket() - server.setSockOpt(OptReuseAddr, true) - server.bindAddr(Port(8080)) - server.listen() - - echo "Echo server listening on port 8080" - - while true: - # Accept a client connection - let client = server.accept() - echo "Client connected" - - # Echo loop for this client while true: - try: - echo "Client waiting for data" - let data = client.recv(1024) - echo "Client waiting received data: ", data.repr() - if data.len == 0: - break # Client disconnected - client.send(data) # Echo back the data - except: - break # Error occurred - - echo "Client disconnected" - client.close() + # Accept a client connection + let client = server.accept() + echo "Client connected" + + # Echo loop for this client + while true: + try: + echo "Client waiting for data" + let data = client.recv(1024) + echo "Client waiting received data: ", data.repr() + if data.len == 0: + break # Client disconnected + client.send(data) # Echo back the data + except: + break # Error occurred + + echo "Client disconnected" + client.close() app_main: logi(TAG, "esp starting ... ") From 684e04a8dc56eb63dcb63b922df694a76527a5a4 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 02:39:39 -0600 Subject: [PATCH 079/142] tcp echo --- esp-idf-examples/net_pppos_usb/main/main.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 6d5bbbab..df573ffe 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -52,7 +52,8 @@ when defined(TcpEchoServer): while true: # Accept a client connection - let client = server.accept() + var client: Socket = new(Socket) + server.accept(client) echo "Client connected" # Echo loop for this client @@ -121,6 +122,7 @@ app_main: delay(4_000.Millis) startRpcSocketServer(port=Port(5555), address = "::", router = rt) when defined(TcpEchoServer): + delay(4_000.Millis) runTcpEcho() # Keep app alive; clean shutdown not triggered in this minimal example From 2e5c402ee399b89b12f47881eca200fd4e4c6708 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 02:45:36 -0600 Subject: [PATCH 080/142] tcp echo --- esp-idf-examples/net_pppos_usb/main/main.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index df573ffe..99f73e3b 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -43,9 +43,9 @@ when defined(RpcServer): when defined(TcpEchoServer): proc runTcpEcho*() = # Create the server socket - let server = newSocket() + let server = newSocket(domain=AF_INET6) server.setSockOpt(OptReuseAddr, true) - server.bindAddr(Port(8080)) + server.bindAddr(Port(8080), address="::") server.listen() echo "Echo server listening on port 8080" @@ -122,7 +122,7 @@ app_main: delay(4_000.Millis) startRpcSocketServer(port=Port(5555), address = "::", router = rt) when defined(TcpEchoServer): - delay(4_000.Millis) + delay(10_000.Millis) runTcpEcho() # Keep app alive; clean shutdown not triggered in this minimal example From 2078b942f05d4fe0f62a513b4e375161c199bd02 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 03:09:45 -0600 Subject: [PATCH 081/142] tcp echo --- esp-idf-examples/net_pppos_usb/config.nims | 2 +- esp-idf-examples/net_pppos_usb/main/main.nim | 32 ++++++++++++++++++++ src/nesper/networking/usb_ppp_dualcdc.nim | 5 +++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index 6ed0bfa9..01a0bd44 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -1,6 +1,6 @@ switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants -switch("define", "TcpEchoServer") # or other variants +switch("define", "UdpEchoServer") # or other variants # switch("define", "RUN_NCM") diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 99f73e3b..c9230a6a 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -13,6 +13,8 @@ when defined(RpcServer): import nesper/servers/rpc/rpcsocket_json when defined(TcpEchoServer): import std/net +when defined(UdpEchoServer): + import std/net when defined(RUN_NCM): import usb/usb_ncm_eth_dualcdc as ncm_eth @@ -71,6 +73,33 @@ when defined(TcpEchoServer): echo "Client disconnected" client.close() +when defined(UdpEchoServer): + proc runUdpEcho*() = + + # Create UDP socket + let server = newSocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP) + server.bindAddr(Port(9090), address="::") + + echo "UDP echo server listening on port 8080" + + while true: + try: + var + data: string + address: string + port: Port + + echo "UDP echo server waiting for data" + # Receive data from any client + let res = server.recvFrom(data, 1024, address, port) + + echo "Received from ", address, ":", port, " -> ", data.repr() + + # Echo back to the sender + server.sendTo(address, port, data) + except Defect, CatchableError: + loge(TAG, "Error receiving from UDP socket: %s", getCurrentExceptionMsg()) + app_main: logi(TAG, "esp starting ... ") @@ -124,6 +153,9 @@ app_main: when defined(TcpEchoServer): delay(10_000.Millis) runTcpEcho() + when defined(UdpEchoServer): + delay(10_000.Millis) + runUdpEcho() # Keep app alive; clean shutdown not triggered in this minimal example while true: diff --git a/src/nesper/networking/usb_ppp_dualcdc.nim b/src/nesper/networking/usb_ppp_dualcdc.nim index ef82a298..a3e667c7 100644 --- a/src/nesper/networking/usb_ppp_dualcdc.nim +++ b/src/nesper/networking/usb_ppp_dualcdc.nim @@ -93,6 +93,7 @@ const # PPP transmit: push bytes to CDC PPP interface proc pppTransmit(h: pointer; buffer: pointer; len: csize_t): esp_err_t {.cdecl.} = + logi(TAG, "CDC TX: %d", len) discard tinyusb_cdcacm_write_queue(sPppItf, cast[ptr uint8](buffer), len) result = tinyusb_cdcacm_write_flush(sPppItf, 0'u32) @@ -100,10 +101,13 @@ var driverCfg: esp_netif_driver_ifconfig_t # CDC RX: feed data to esp_netif proc onCdcRx(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = + logi(TAG, "CDC RX: interface %d", itf) if tinyusb_cdcacm_itf_t(itf) != sPppItf: + logi(TAG, "CDC RX: interface %d not sPppItf", itf) return var rxSize: csize_t = 0 let ret = tinyusb_cdcacm_read(tinyusb_cdcacm_itf_t(itf), addr rxBuf[0], CONFIG_TINYUSB_CDC_RX_BUFSIZE.csize_t, addr rxSize) + logi(TAG, "CDC RX: interface %d returned %d rxBuf: %d", itf, ret, rxBuf.len()) if ret == ESP_OK and rxSize > 0: discard esp_netif_receive(sNetif, addr rxBuf[0], rxSize, nil) @@ -134,6 +138,7 @@ proc onIpEvent(arg: pointer; event_base: esp_event_base_t; event_id: int32; even logi(TAG, "PPP IPv6 acquired") discard xEventGroupSetBits(sEventGroup, EventBits_t(GOT_IPV6)) of IP_EVENT_PPP_LOST_IP: + logi(TAG, "PPP IPv6 lost") discard xEventGroupSetBits(sEventGroup, EventBits_t(CONN_FAILED)) else: discard From fccd505b6e264e2ff6491ea195140e73714dec4d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 03:19:18 -0600 Subject: [PATCH 082/142] tcp echo --- esp-idf-examples/net_pppos_usb/config.nims | 3 ++- esp-idf-examples/net_pppos_usb/main/main.nim | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index 01a0bd44..dcf74656 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -1,6 +1,7 @@ switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants -switch("define", "UdpEchoServer") # or other variants +switch("define", "TcpEchoServer") # or other variants +# switch("define", "UdpEchoServer") # or other variants # switch("define", "RUN_NCM") diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index c9230a6a..1458eb67 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -46,7 +46,7 @@ when defined(TcpEchoServer): proc runTcpEcho*() = # Create the server socket let server = newSocket(domain=AF_INET6) - server.setSockOpt(OptReuseAddr, true) + # server.setSockOpt(OptReuseAddr, true) server.bindAddr(Port(8080), address="::") server.listen() @@ -54,9 +54,13 @@ when defined(TcpEchoServer): while true: # Accept a client connection + echo "Waiting for client connection" var client: Socket = new(Socket) server.accept(client) echo "Client connected" + if client == nil: + loge(TAG, "Error accepting client connection") + continue # Echo loop for this client while true: @@ -67,8 +71,8 @@ when defined(TcpEchoServer): if data.len == 0: break # Client disconnected client.send(data) # Echo back the data - except: - break # Error occurred + except Defect, CatchableError: + loge(TAG, "Error receiving from TCP socket: %s", getCurrentExceptionMsg()) echo "Client disconnected" client.close() From 93151006b5b8b2ec49e8a127175854592be3f6a6 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 03:25:33 -0600 Subject: [PATCH 083/142] tcp echo --- esp-idf-examples/net_pppos_usb/main/main.nim | 49 +++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 1458eb67..4bd7af88 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -53,29 +53,32 @@ when defined(TcpEchoServer): echo "Echo server listening on port 8080" while true: - # Accept a client connection - echo "Waiting for client connection" - var client: Socket = new(Socket) - server.accept(client) - echo "Client connected" - if client == nil: - loge(TAG, "Error accepting client connection") - continue - - # Echo loop for this client - while true: - try: - echo "Client waiting for data" - let data = client.recv(1024) - echo "Client waiting received data: ", data.repr() - if data.len == 0: - break # Client disconnected - client.send(data) # Echo back the data - except Defect, CatchableError: - loge(TAG, "Error receiving from TCP socket: %s", getCurrentExceptionMsg()) - - echo "Client disconnected" - client.close() + try: + # Accept a client connection + echo "Waiting for client connection" + var client: Socket = new(Socket) + server.accept(client) + echo "Client connected" + if client == nil: + loge(TAG, "Error accepting client connection") + continue + + # Echo loop for this client + while true: + try: + echo "Client waiting for data" + let data = client.recv(1024) + echo "Client waiting received data: ", data.repr() + if data.len == 0: + break # Client disconnected + client.send(data) # Echo back the data + except Defect, CatchableError: + loge(TAG, "Error receiving from client: %s", getCurrentExceptionMsg()) + + echo "Client disconnected" + client.close() + except Defect, CatchableError: + loge(TAG, "Error receiving from TCP socket: %s", getCurrentExceptionMsg()) when defined(UdpEchoServer): proc runUdpEcho*() = From 0afb1fb004330cb8f75c7648a615440423958f61 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 04:37:06 -0600 Subject: [PATCH 084/142] tcp echo --- esp-idf-examples/net_pppos_usb/main/main.nim | 9 +++++---- src/nesper/esp/net/esp_netif_types.nim | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 4bd7af88..00e18f96 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -13,6 +13,7 @@ when defined(RpcServer): import nesper/servers/rpc/rpcsocket_json when defined(TcpEchoServer): import std/net + import std/nativesockets when defined(UdpEchoServer): import std/net @@ -45,9 +46,9 @@ when defined(RpcServer): when defined(TcpEchoServer): proc runTcpEcho*() = # Create the server socket - let server = newSocket(domain=AF_INET6) - # server.setSockOpt(OptReuseAddr, true) - server.bindAddr(Port(8080), address="::") + let server = newSocket(domain=AF_INET6, protocol=IPPROTO_IPV6) + server.setSockOpt(OptReuseAddr, true) + server.bindAddr(Port(5555), address="::") server.listen() echo "Echo server listening on port 8080" @@ -67,7 +68,7 @@ when defined(TcpEchoServer): while true: try: echo "Client waiting for data" - let data = client.recv(1024) + let data = client.recv(128) echo "Client waiting received data: ", data.repr() if data.len == 0: break # Client disconnected diff --git a/src/nesper/esp/net/esp_netif_types.nim b/src/nesper/esp/net/esp_netif_types.nim index c052c207..9b115c81 100644 --- a/src/nesper/esp/net/esp_netif_types.nim +++ b/src/nesper/esp/net/esp_netif_types.nim @@ -211,6 +211,7 @@ type err_t* = distinct int8 netif* {.importc: "netif", header: hdr, bycopy.} = object + mtu* {.importc: "mtu".}: uint16 init_fn_t* = proc (a1: pointer): err_t {.cdecl.} From 74324cd20234b8b896613e84e4261d4c272de28f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 04:43:29 -0600 Subject: [PATCH 085/142] tcp echo --- esp-idf-examples/net_pppos_usb/config.nims | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index dcf74656..8c1c8081 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -1,7 +1,7 @@ switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants -switch("define", "TcpEchoServer") # or other variants -# switch("define", "UdpEchoServer") # or other variants +# switch("define", "TcpEchoServer") # or other variants +switch("define", "UdpEchoServer") # or other variants # switch("define", "RUN_NCM") From 015817cbe3c9d293cc9baf360aa9360a782e4640 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 04:45:05 -0600 Subject: [PATCH 086/142] udp echo --- src/nesper/servers/rpc/rpcsocket_json.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nesper/servers/rpc/rpcsocket_json.nim b/src/nesper/servers/rpc/rpcsocket_json.nim index 68018449..8d0d0572 100644 --- a/src/nesper/servers/rpc/rpcsocket_json.nim +++ b/src/nesper/servers/rpc/rpcsocket_json.nim @@ -16,10 +16,10 @@ export tcpsocket, router const TAG = "socketrpc" -proc rpcMsgPackWriteHandler*(srv: TcpServerInfo[RpcRouter], result: ReadyKey, sourceClient: Socket, rt: RpcRouter) = +proc rpcJsonWriteHandler*(srv: TcpServerInfo[RpcRouter], result: ReadyKey, sourceClient: Socket, rt: RpcRouter) = raise newException(OSError, "the request to the OS failed") -proc rpcMsgPackReadHandler*(srv: TcpServerInfo[RpcRouter], result: ReadyKey, sourceClient: Socket, rt: RpcRouter) = +proc rpcJsonReadHandler*(srv: TcpServerInfo[RpcRouter], result: ReadyKey, sourceClient: Socket, rt: RpcRouter) = try: logd(TAG, "rpc server handler: router: %x", rt.buffer) @@ -44,11 +44,11 @@ proc rpcMsgPackReadHandler*(srv: TcpServerInfo[RpcRouter], result: ReadyKey, sou proc startRpcSocketServer*(port: Port; address="", router: var RpcRouter) = logi(TAG, "starting json rpc server: buffer: %s, port: %s", $router.buffer, $port) - startSocketServer[RpcRouter]( + startUdpSocketServer[RpcRouter]( port, address=address, - readHandler=rpcMsgPackReadHandler, - writeHandler=rpcMsgPackWriteHandler, + readHandler=rpcJsonReadHandler, + writeHandler=rpcJsonWriteHandler, data=router) From 8847b67263d57ba6837326654e70c9cc93200284 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 04:57:57 -0600 Subject: [PATCH 087/142] udp echo --- src/nesper/networking/usb_ppp_dualcdc.nim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nesper/networking/usb_ppp_dualcdc.nim b/src/nesper/networking/usb_ppp_dualcdc.nim index a3e667c7..1650c15b 100644 --- a/src/nesper/networking/usb_ppp_dualcdc.nim +++ b/src/nesper/networking/usb_ppp_dualcdc.nim @@ -93,7 +93,7 @@ const # PPP transmit: push bytes to CDC PPP interface proc pppTransmit(h: pointer; buffer: pointer; len: csize_t): esp_err_t {.cdecl.} = - logi(TAG, "CDC TX: %d", len) + # logi(TAG, "CDC TX: %d", len) discard tinyusb_cdcacm_write_queue(sPppItf, cast[ptr uint8](buffer), len) result = tinyusb_cdcacm_write_flush(sPppItf, 0'u32) @@ -101,25 +101,25 @@ var driverCfg: esp_netif_driver_ifconfig_t # CDC RX: feed data to esp_netif proc onCdcRx(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = - logi(TAG, "CDC RX: interface %d", itf) + # logi(TAG, "CDC RX: interface %d", itf) if tinyusb_cdcacm_itf_t(itf) != sPppItf: - logi(TAG, "CDC RX: interface %d not sPppItf", itf) + # logi(TAG, "CDC RX: interface %d not sPppItf", itf) return var rxSize: csize_t = 0 let ret = tinyusb_cdcacm_read(tinyusb_cdcacm_itf_t(itf), addr rxBuf[0], CONFIG_TINYUSB_CDC_RX_BUFSIZE.csize_t, addr rxSize) - logi(TAG, "CDC RX: interface %d returned %d rxBuf: %d", itf, ret, rxBuf.len()) + # logi(TAG, "CDC RX: interface %d returned %d rxBuf: %d", itf, ret, rxBuf.len()) if ret == ESP_OK and rxSize > 0: discard esp_netif_receive(sNetif, addr rxBuf[0], rxSize, nil) proc onLineState(itf: cint; event: ptr cdcacm_event_t) {.cdecl.} = - logi(TAG, "Line state changed on itf %d", itf) + # logi(TAG, "Line state changed on itf %d", itf) # Allow host tools (esptool) to reset via DTR/RTS on the console CDC if tinyusb_cdcacm_itf_t(itf) == sLogItf: let ls = event.line_state_changed_data - logi(TAG, "DTR/RTS triggered on console rts: %s, dtr: %s", $ls.rts, $ls.dtr) + # logi(TAG, "DTR/RTS triggered on console rts: %s, dtr: %s", $ls.rts, $ls.dtr) # Common esptool pattern: RTS asserted and DTR deasserted -> reset to enter flashing if ls.rts and not ls.dtr: - logi(TAG, "DTR/RTS trigger: restarting...") + # logi(TAG, "DTR/RTS trigger: restarting...") delay(10.Millis) esp_restart() From fe711ec8791a8d4251787228b410dbf079011466 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 04:58:15 -0600 Subject: [PATCH 088/142] udp echo --- esp-idf-examples/net_pppos_usb/main/main.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 00e18f96..1204b846 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -51,7 +51,7 @@ when defined(TcpEchoServer): server.bindAddr(Port(5555), address="::") server.listen() - echo "Echo server listening on port 8080" + echo "Echo server listening on port 5555" while true: try: @@ -88,7 +88,7 @@ when defined(UdpEchoServer): let server = newSocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP) server.bindAddr(Port(9090), address="::") - echo "UDP echo server listening on port 8080" + echo "UDP echo server listening on port 9090" while true: try: From e6139911ebf0fcc5901fc907da1a263952d672e6 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Wed, 3 Sep 2025 20:25:55 -0600 Subject: [PATCH 089/142] bump version --- nesper.nimble | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nesper.nimble b/nesper.nimble index 2bc5a8ec..5a5021a7 100644 --- a/nesper.nimble +++ b/nesper.nimble @@ -14,4 +14,5 @@ requires "stew >= 0.1.0" requires "bytesequtils" feature "examples": - requires "mummy" \ No newline at end of file + requires "mummy" + requires "fastrpc@#head" \ No newline at end of file From cf89a0104699cd48155ece893fa329f2a0a5ca2b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 01:52:20 -0600 Subject: [PATCH 090/142] cleanup --- nesper.nimble | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nesper.nimble b/nesper.nimble index 5a5021a7..74056c40 100644 --- a/nesper.nimble +++ b/nesper.nimble @@ -14,5 +14,4 @@ requires "stew >= 0.1.0" requires "bytesequtils" feature "examples": - requires "mummy" - requires "fastrpc@#head" \ No newline at end of file + requires "fastrpc > 0.5.1" \ No newline at end of file From 64eff9f20596c8778b44b22de1eb77e9306546f6 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 01:58:19 -0600 Subject: [PATCH 091/142] fastrpc --- esp-idf-examples/net_pppos_usb/config.nims | 3 +- esp-idf-examples/net_pppos_usb/main/main.nim | 35 ++++++++++++++------ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index 8c1c8081..56de7697 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -1,7 +1,8 @@ switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants # switch("define", "TcpEchoServer") # or other variants -switch("define", "UdpEchoServer") # or other variants +# switch("define", "UdpEchoServer") # or other variants +switch("define", "FastRpcServer") # or other variants # switch("define", "RUN_NCM") diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 1204b846..0dff478c 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -9,14 +9,6 @@ import nesper/esp/net/esp_netif_ppp import nesper/esp/net/esp_netif_impl import nesper/net_utils -when defined(RpcServer): - import nesper/servers/rpc/rpcsocket_json -when defined(TcpEchoServer): - import std/net - import std/nativesockets -when defined(UdpEchoServer): - import std/net - when defined(RUN_NCM): import usb/usb_ncm_eth_dualcdc as ncm_eth else: @@ -31,6 +23,7 @@ proc addIpv6ToNetif*(netif: ptr esp_netif_t; ip: IpAddress): esp_err_t = result = esp_netif_add_ip6_address(netif, espIp6, preferred=true) when defined(RpcServer): + import nesper/servers/rpc/rpcsocket_json proc setupRpc(rt: var RpcRouter) = rt.rpc("hello") do(input: string) -> string: # example: ./rpc_cli --ip:$IP -c:1 '{"method": "hello", "params": ["world"]}' @@ -43,7 +36,21 @@ when defined(RpcServer): # example: ./rpc_cli --ip:$IP -c:1 '{"method": "add", "params": [1, 2]}' result = a + b +when defined(FastRpcServer): + import fastrpc/server/fastrpcserver + import fastrpc/server/rpcmethods + + # Define RPC Server # + DefineRpcs(name=exampleRpcs): + + proc add(a: int, b: int): int {.rpc.} = + result = 1 + a + b + + when defined(TcpEchoServer): + import std/net + import std/nativesockets + proc runTcpEcho*() = # Create the server socket let server = newSocket(domain=AF_INET6, protocol=IPPROTO_IPV6) @@ -82,6 +89,8 @@ when defined(TcpEchoServer): loge(TAG, "Error receiving from TCP socket: %s", getCurrentExceptionMsg()) when defined(UdpEchoServer): + import std/net + proc runUdpEcho*() = # Create UDP socket @@ -155,9 +164,15 @@ app_main: when defined(RpcServer): var rt: RpcRouter = createRpcRouter(4096) rt.setupRpc() + when defined(FastRpcServer): + let inetAddrs = [ + newInetAddr("::", 5555, Protocol.IPPROTO_UDP), + ] + var rt: FastRpcRouter = createFastRpcRouter(4096) + rt.registerRpcs(exampleRpcs) + var frpcServer = newFastRpcServer(router, prefixMsgSize=true, threaded=false) + startSocketServer(inetAddrs, frpcServer) - delay(4_000.Millis) - startRpcSocketServer(port=Port(5555), address = "::", router = rt) when defined(TcpEchoServer): delay(10_000.Millis) runTcpEcho() From 2a92066b15ebbe66e8d5fa4406d4f09762be2e54 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 01:59:21 -0600 Subject: [PATCH 092/142] fastrpc --- nesper.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesper.nimble b/nesper.nimble index 74056c40..1cbec311 100644 --- a/nesper.nimble +++ b/nesper.nimble @@ -14,4 +14,4 @@ requires "stew >= 0.1.0" requires "bytesequtils" feature "examples": - requires "fastrpc > 0.5.1" \ No newline at end of file + requires "fastrpc >= 0.5.1" \ No newline at end of file From 9ef850cd1c10d8fd2bcc84b0ffe6e7e7c2c654af Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 02:03:15 -0600 Subject: [PATCH 093/142] fastrpc --- nesper.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesper.nimble b/nesper.nimble index 1cbec311..9aede13a 100644 --- a/nesper.nimble +++ b/nesper.nimble @@ -14,4 +14,4 @@ requires "stew >= 0.1.0" requires "bytesequtils" feature "examples": - requires "fastrpc >= 0.5.1" \ No newline at end of file + requires "https://github.com/elcritch/fastrpc >= 0.5.1" \ No newline at end of file From a277922a7af8c9ae9ef4f874dec2e473a0e031ed Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 02:15:37 -0600 Subject: [PATCH 094/142] nimNetSocketExtras note --- esp-idf-examples/net_pppos_usb/config.nims | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index 56de7697..7d7b18cd 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -1,8 +1,9 @@ switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants -# switch("define", "TcpEchoServer") # or other variants -# switch("define", "UdpEchoServer") # or other variants -switch("define", "FastRpcServer") # or other variants +switch("define", "nimNetSocketExtras") +# switch("define", "TcpEchoServer") +# switch("define", "UdpEchoServer") +switch("define", "FastRpcServer") # switch("define", "RUN_NCM") From befa3ff2982b82ee3f2dc414d79fe19235494f52 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 02:18:33 -0600 Subject: [PATCH 095/142] nimNetSocketExtras note --- esp-idf-examples/net_pppos_usb/main/main.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 0dff478c..d0750f13 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -168,9 +168,9 @@ app_main: let inetAddrs = [ newInetAddr("::", 5555, Protocol.IPPROTO_UDP), ] - var rt: FastRpcRouter = createFastRpcRouter(4096) + var rt: FastRpcRouter = newFastRpcRouter() rt.registerRpcs(exampleRpcs) - var frpcServer = newFastRpcServer(router, prefixMsgSize=true, threaded=false) + var frpcServer = newFastRpcServer(rt, prefixMsgSize=true, threaded=false) startSocketServer(inetAddrs, frpcServer) when defined(TcpEchoServer): From b3a0839b07f2f221a941861656acba5cb9f78a81 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 02:36:04 -0600 Subject: [PATCH 096/142] nimIoselectorEventfd --- esp-idf-examples/net_pppos_usb/config.nims | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index 7d7b18cd..cfd1a887 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -1,6 +1,7 @@ switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants switch("define", "nimNetSocketExtras") +switch("define", "nimIoselectorEventfd") # switch("define", "TcpEchoServer") # switch("define", "UdpEchoServer") switch("define", "FastRpcServer") @@ -8,5 +9,6 @@ switch("define", "FastRpcServer") # switch("define", "RUN_NCM") patchFile("stdlib", "cpuinfo", "main/cpuinfo.nim") +patchFile("stdlib", "ioselectors_select", "main/ioselectors_select.nim") include nesper/build_utils/builds From 2aaa726618b03a57806a4f1c23256b718d3494c0 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 02:36:11 -0600 Subject: [PATCH 097/142] nimIoselectorEventfd --- .../net_pppos_usb/main/ioselectors_select.nim | 479 ++++++++++++++++++ 1 file changed, 479 insertions(+) create mode 100644 esp-idf-examples/net_pppos_usb/main/ioselectors_select.nim diff --git a/esp-idf-examples/net_pppos_usb/main/ioselectors_select.nim b/esp-idf-examples/net_pppos_usb/main/ioselectors_select.nim new file mode 100644 index 00000000..b052a296 --- /dev/null +++ b/esp-idf-examples/net_pppos_usb/main/ioselectors_select.nim @@ -0,0 +1,479 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2016 Eugene Kabanov +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +# This module implements Posix and Windows select(). + +import std/[times, nativesockets] + +when defined(windows): + import std/winlean + when defined(gcc): + {.passl: "-lws2_32".} + elif defined(vcc): + {.passl: "ws2_32.lib".} + const platformHeaders = """#include + #include """ + const EAGAIN = WSAEWOULDBLOCK +else: + const platformHeaders = """#include + #include + #include + #include """ +type + FdSet {.importc: "fd_set", header: platformHeaders, pure, final.} = object +var + FD_SETSIZE {.importc: "FD_SETSIZE", header: platformHeaders.}: cint + +proc IOFD_SET(fd: SocketHandle, fdset: ptr FdSet) + {.cdecl, importc: "FD_SET", header: platformHeaders, inline.} +proc IOFD_CLR(fd: SocketHandle, fdset: ptr FdSet) + {.cdecl, importc: "FD_CLR", header: platformHeaders, inline.} +proc IOFD_ZERO(fdset: ptr FdSet) + {.cdecl, importc: "FD_ZERO", header: platformHeaders, inline.} + +when defined(windows): + proc IOFD_ISSET(fd: SocketHandle, fdset: ptr FdSet): cint + {.stdcall, importc: "FD_ISSET", header: platformHeaders, inline.} + proc ioselect(nfds: cint, readFds, writeFds, exceptFds: ptr FdSet, + timeout: ptr Timeval): cint + {.stdcall, importc: "select", header: platformHeaders.} +else: + proc IOFD_ISSET(fd: SocketHandle, fdset: ptr FdSet): cint + {.cdecl, importc: "FD_ISSET", header: platformHeaders, inline.} + proc ioselect(nfds: cint, readFds, writeFds, exceptFds: ptr FdSet, + timeout: ptr Timeval): cint + {.cdecl, importc: "select", header: platformHeaders.} + +when hasThreadSupport: + type + SelectorImpl[T] = object + rSet: FdSet + wSet: FdSet + eSet: FdSet + maxFD: int + fds: ptr SharedArray[SelectorKey[T]] + count*: int + lock: Lock + Selector*[T] = ptr SelectorImpl[T] +else: + type + SelectorImpl[T] = object + rSet: FdSet + wSet: FdSet + eSet: FdSet + maxFD: int + fds: seq[SelectorKey[T]] + count*: int + Selector*[T] = ref SelectorImpl[T] + +type + SelectEventImpl = object + rsock: SocketHandle + wsock: SocketHandle + SelectEvent* = ptr SelectEventImpl + +when hasThreadSupport: + template withSelectLock[T](s: Selector[T], body: untyped) = + acquire(s.lock) + {.locks: [s.lock].}: + try: + body + finally: + release(s.lock) +else: + template withSelectLock[T](s: Selector[T], body: untyped) = + body + +proc newSelector*[T](): Selector[T] = + when hasThreadSupport: + result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T]))) + result.fds = allocSharedArray[SelectorKey[T]](FD_SETSIZE) + initLock result.lock + else: + result = Selector[T]() + result.fds = newSeq[SelectorKey[T]](FD_SETSIZE) + + for i in 0 ..< FD_SETSIZE: + result.fds[i].ident = InvalidIdent + + IOFD_ZERO(addr result.rSet) + IOFD_ZERO(addr result.wSet) + IOFD_ZERO(addr result.eSet) + +proc close*[T](s: Selector[T]) = + when hasThreadSupport: + deallocSharedArray(s.fds) + deallocShared(cast[pointer](s)) + deinitLock(s.lock) + +when defined(windows): + proc newSelectEvent*(): SelectEvent = + var ssock = createNativeSocket() + var wsock = createNativeSocket() + var rsock: SocketHandle = INVALID_SOCKET + var saddr = Sockaddr_in() + + saddr.sin_family = winlean.AF_INET + saddr.sin_port = 0 + saddr.sin_addr.s_addr = INADDR_ANY + if bindAddr(ssock, cast[ptr SockAddr](addr(saddr)), + sizeof(saddr).SockLen) < 0'i32: + raiseIOSelectorsError(osLastError()) + + if winlean.listen(ssock, 1) != 0: + raiseIOSelectorsError(osLastError()) + + var namelen = sizeof(saddr).SockLen + if getsockname(ssock, cast[ptr SockAddr](addr(saddr)), + addr(namelen)) != 0'i32: + raiseIOSelectorsError(osLastError()) + + saddr.sin_addr.s_addr = 0x0100007F + if winlean.connect(wsock, cast[ptr SockAddr](addr(saddr)), + sizeof(saddr).SockLen) != 0: + raiseIOSelectorsError(osLastError()) + namelen = sizeof(saddr).SockLen + rsock = winlean.accept(ssock, cast[ptr SockAddr](addr(saddr)), + cast[ptr SockLen](addr(namelen))) + if rsock == SocketHandle(-1): + raiseIOSelectorsError(osLastError()) + + if winlean.closesocket(ssock) != 0: + raiseIOSelectorsError(osLastError()) + + var mode = clong(1) + if ioctlsocket(rsock, FIONBIO, addr(mode)) != 0: + raiseIOSelectorsError(osLastError()) + mode = clong(1) + if ioctlsocket(wsock, FIONBIO, addr(mode)) != 0: + raiseIOSelectorsError(osLastError()) + + result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) + result.rsock = rsock + result.wsock = wsock + + proc trigger*(ev: SelectEvent) = + var data: uint64 = 1 + if winlean.send(ev.wsock, cast[pointer](addr data), + cint(sizeof(uint64)), 0) != sizeof(uint64): + raiseIOSelectorsError(osLastError()) + + proc close*(ev: SelectEvent) = + let res1 = winlean.closesocket(ev.rsock) + let res2 = winlean.closesocket(ev.wsock) + deallocShared(cast[pointer](ev)) + if res1 != 0 or res2 != 0: + raiseIOSelectorsError(osLastError()) + +elif defined(nimIoselectorEventfd): + proc eventfd(fd: cint, flags: cint): cint {.importc: "eventfd", header: platformHeaders, inline.} + + proc newSelectEvent*(): SelectEvent = + when compiles(O_CLOEXEC): + let fdci = eventfd(0, O_CLOEXEC or O_NONBLOCK) + else: + let fdci = eventfd(0, O_NONBLOCK) + if fdci == -1: + raiseIOSelectorsError(osLastError()) + result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) + result.rsock = SocketHandle(fdci) + result.wsock = SocketHandle(-1) + + proc trigger*(ev: SelectEvent) = + var data: uint64 = 1 + if posix.write(ev.rsock.cint, addr data, sizeof(uint64)) == -1: + raiseIOSelectorsError(osLastError()) + + proc close*(ev: SelectEvent) = + let res = posix.close(ev.rsock.cint) + deallocShared(cast[pointer](ev)) + if res != 0: + raiseIOSelectorsError(osLastError()) + +else: + proc newSelectEvent*(): SelectEvent = + var fds: array[2, cint] + if posix.pipe(fds) != 0: + raiseIOSelectorsError(osLastError()) + setNonBlocking(fds[0]) + setNonBlocking(fds[1]) + result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) + result.rsock = SocketHandle(fds[0]) + result.wsock = SocketHandle(fds[1]) + + proc trigger*(ev: SelectEvent) = + var data: uint64 = 1 + if posix.write(cint(ev.wsock), addr data, sizeof(uint64)) != sizeof(uint64): + raiseIOSelectorsError(osLastError()) + + proc close*(ev: SelectEvent) = + let res1 = posix.close(cint(ev.rsock)) + let res2 = posix.close(cint(ev.wsock)) + deallocShared(cast[pointer](ev)) + if res1 != 0 or res2 != 0: + raiseIOSelectorsError(osLastError()) + +proc setSelectKey[T](s: Selector[T], fd: SocketHandle, events: set[Event], + data: T) = + var i = 0 + let fdi = int(fd) + while i < FD_SETSIZE: + if s.fds[i].ident == InvalidIdent: + var pkey = addr(s.fds[i]) + pkey.ident = fdi + pkey.events = events + pkey.data = data + break + inc(i) + if i >= FD_SETSIZE: + raiseIOSelectorsError("Maximum number of descriptors is exhausted!") + +proc getKey[T](s: Selector[T], fd: SocketHandle): ptr SelectorKey[T] = + var i = 0 + let fdi = int(fd) + while i < FD_SETSIZE: + if s.fds[i].ident == fdi: + result = addr(s.fds[i]) + break + inc(i) + doAssert(i < FD_SETSIZE, + "Descriptor [" & $int(fd) & "] is not registered in the queue!") + +proc delKey[T](s: Selector[T], fd: SocketHandle) = + var empty: T + var i = 0 + while i < FD_SETSIZE: + if s.fds[i].ident == fd.int: + s.fds[i].ident = InvalidIdent + s.fds[i].events = {} + s.fds[i].data = empty + break + inc(i) + doAssert(i < FD_SETSIZE, + "Descriptor [" & $int(fd) & "] is not registered in the queue!") + +proc registerHandle*[T](s: Selector[T], fd: int | SocketHandle, + events: set[Event], data: T) = + when not defined(windows): + let fdi = int(fd) + s.withSelectLock(): + s.setSelectKey(fd, events, data) + when not defined(windows): + if fdi > s.maxFD: s.maxFD = fdi + if Event.Read in events: + IOFD_SET(fd, addr s.rSet) + inc(s.count) + if Event.Write in events: + IOFD_SET(fd, addr s.wSet) + IOFD_SET(fd, addr s.eSet) + inc(s.count) + +proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = + when not defined(windows): + let fdi = int(ev.rsock) + s.withSelectLock(): + s.setSelectKey(ev.rsock, {Event.User}, data) + when not defined(windows): + if fdi > s.maxFD: s.maxFD = fdi + IOFD_SET(ev.rsock, addr s.rSet) + inc(s.count) + +proc updateHandle*[T](s: Selector[T], fd: int | SocketHandle, + events: set[Event]) = + let maskEvents = {Event.Timer, Event.Signal, Event.Process, Event.Vnode, + Event.User, Event.Oneshot, Event.Error} + s.withSelectLock(): + var pkey = s.getKey(fd) + doAssert(pkey.events * maskEvents == {}) + if pkey.events != events: + if (Event.Read in pkey.events) and (Event.Read notin events): + IOFD_CLR(fd, addr s.rSet) + dec(s.count) + if (Event.Write in pkey.events) and (Event.Write notin events): + IOFD_CLR(fd, addr s.wSet) + IOFD_CLR(fd, addr s.eSet) + dec(s.count) + if (Event.Read notin pkey.events) and (Event.Read in events): + IOFD_SET(fd, addr s.rSet) + inc(s.count) + if (Event.Write notin pkey.events) and (Event.Write in events): + IOFD_SET(fd, addr s.wSet) + IOFD_SET(fd, addr s.eSet) + inc(s.count) + pkey.events = events + +proc unregister*[T](s: Selector[T], fd: SocketHandle|int) = + s.withSelectLock(): + let fd = fd.SocketHandle + var pkey = s.getKey(fd) + if Event.Read in pkey.events or Event.User in pkey.events: + IOFD_CLR(fd, addr s.rSet) + dec(s.count) + if Event.Write in pkey.events: + IOFD_CLR(fd, addr s.wSet) + IOFD_CLR(fd, addr s.eSet) + dec(s.count) + s.delKey(fd) + +proc unregister*[T](s: Selector[T], ev: SelectEvent) = + let fd = ev.rsock + s.withSelectLock(): + var pkey = s.getKey(fd) + IOFD_CLR(fd, addr s.rSet) + dec(s.count) + s.delKey(fd) + +proc selectInto*[T](s: Selector[T], timeout: int, + results: var openArray[ReadyKey]): int = + var tv = Timeval() + var ptv = addr tv + var rset, wset, eset: FdSet + + verifySelectParams(timeout) + + if timeout != -1: + when defined(genode) or defined(freertos) or defined(zephyr) or defined(nuttx): + tv.tv_sec = posix.Time(timeout div 1_000) + else: + tv.tv_sec = timeout.int32 div 1_000 + tv.tv_usec = (timeout.int32 %% 1_000) * 1_000 + else: + ptv = nil + + s.withSelectLock(): + rset = s.rSet + wset = s.wSet + eset = s.eSet + + var count = ioselect(cint(s.maxFD) + 1, addr(rset), addr(wset), + addr(eset), ptv) + if count < 0: + result = 0 + when defined(windows): + raiseIOSelectorsError(osLastError()) + else: + let err = osLastError() + if cint(err) != EINTR: + raiseIOSelectorsError(err) + elif count == 0: + result = 0 + else: + var rindex = 0 + var i = 0 + var k = 0 + + while (i < FD_SETSIZE) and (k < count): + if s.fds[i].ident != InvalidIdent: + var flag = false + var pkey = addr(s.fds[i]) + var rkey = ReadyKey(fd: int(pkey.ident), events: {}) + let fd = SocketHandle(pkey.ident) + if IOFD_ISSET(fd, addr rset) != 0: + if Event.User in pkey.events: + var data: uint64 = 0 + if recv(fd, cast[pointer](addr(data)), + sizeof(uint64).cint, 0) != sizeof(uint64): + let err = osLastError() + if cint(err) != EAGAIN: + raiseIOSelectorsError(err) + else: + inc(i) + inc(k) + continue + else: + flag = true + rkey.events = {Event.User} + else: + flag = true + rkey.events = {Event.Read} + if IOFD_ISSET(fd, addr wset) != 0: + rkey.events.incl(Event.Write) + if IOFD_ISSET(fd, addr eset) != 0: + rkey.events.incl(Event.Error) + flag = true + if flag: + results[rindex] = rkey + inc(rindex) + inc(k) + inc(i) + result = rindex + +proc select*[T](s: Selector[T], timeout: int): seq[ReadyKey] = + result = newSeq[ReadyKey](FD_SETSIZE) + var count = selectInto(s, timeout, result) + result.setLen(count) + +proc flush*[T](s: Selector[T]) = discard + +template isEmpty*[T](s: Selector[T]): bool = + (s.count == 0) + +proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} = + s.withSelectLock(): + result = false + + let fdi = int(fd) + for i in 0.. Date: Thu, 4 Sep 2025 03:15:25 -0600 Subject: [PATCH 098/142] old logs --- esp-idf-examples/net_pppos_usb/main/main.nim | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index d0750f13..49571cbc 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -165,13 +165,18 @@ app_main: var rt: RpcRouter = createRpcRouter(4096) rt.setupRpc() when defined(FastRpcServer): - let inetAddrs = [ - newInetAddr("::", 5555, Protocol.IPPROTO_UDP), - ] - var rt: FastRpcRouter = newFastRpcRouter() - rt.registerRpcs(exampleRpcs) - var frpcServer = newFastRpcServer(rt, prefixMsgSize=true, threaded=false) - startSocketServer(inetAddrs, frpcServer) + try: + let inetAddrs = [ + newInetAddr("::", 5555, Protocol.IPPROTO_UDP), + ] + var rt: FastRpcRouter = newFastRpcRouter() + rt.registerRpcs(exampleRpcs) + var frpcServer = newFastRpcServer(rt, prefixMsgSize=true, threaded=false) + startSocketServer(inetAddrs, frpcServer) + except Defect, CatchableError: + loge(TAG, "Error starting FastRpcServer: %s", getCurrentExceptionMsg()) + for st in getCurrentException().getStackTrace(): + loge(TAG, "Error: %s", $st) when defined(TcpEchoServer): delay(10_000.Millis) From 39cba2169b6f63d3a695e3201e9fec2e4c961285 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 03:29:06 -0600 Subject: [PATCH 099/142] old logs --- esp-idf-examples/net_pppos_usb/config.nims | 1 + esp-idf-examples/net_pppos_usb/main/config.nims | 3 ++- esp-idf-examples/net_pppos_usb/main/main.nim | 9 +++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index cfd1a887..bfa97030 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -6,6 +6,7 @@ switch("define", "nimIoselectorEventfd") # switch("define", "UdpEchoServer") switch("define", "FastRpcServer") +switch("define", "McuUtilsLoggingLevel:lvlTrace") # switch("define", "RUN_NCM") patchFile("stdlib", "cpuinfo", "main/cpuinfo.nim") diff --git a/esp-idf-examples/net_pppos_usb/main/config.nims b/esp-idf-examples/net_pppos_usb/main/config.nims index 80a21ac4..3259fd64 100644 --- a/esp-idf-examples/net_pppos_usb/main/config.nims +++ b/esp-idf-examples/net_pppos_usb/main/config.nims @@ -1,5 +1,6 @@ --nomain --compileOnly +--define:debug --define:NimAppMain --nimcache:nimcache @@ -8,6 +9,6 @@ --cpu:arm --define:useMalloc --define:noSignalHandler ---debugger:native +# --debugger:native --threads:on --tls_emulation:off diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 49571cbc..5e4e6cf2 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -166,17 +166,22 @@ app_main: rt.setupRpc() when defined(FastRpcServer): try: + logi(TAG, "setting up fast rpc router") let inetAddrs = [ newInetAddr("::", 5555, Protocol.IPPROTO_UDP), ] var rt: FastRpcRouter = newFastRpcRouter() + logi(TAG, "registering rpcs") rt.registerRpcs(exampleRpcs) + logi(TAG, "newing fast rpc server") var frpcServer = newFastRpcServer(rt, prefixMsgSize=true, threaded=false) + logi(TAG, "starting fast rpc server") startSocketServer(inetAddrs, frpcServer) + logi(TAG, "fast rpc server done") except Defect, CatchableError: loge(TAG, "Error starting FastRpcServer: %s", getCurrentExceptionMsg()) - for st in getCurrentException().getStackTrace(): - loge(TAG, "Error: %s", $st) + for ste in getCurrentException().getStackTraceEntries(): + loge(TAG, "Error: %s", $ste) when defined(TcpEchoServer): delay(10_000.Millis) From 672ba51e90c7f516d77c6900a13018ed5239f076 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 04:04:10 -0600 Subject: [PATCH 100/142] old logs --- .../net_pppos_usb/main/ioselectors_select.nim | 5 +- esp-idf-examples/net_pppos_usb/main/main.nim | 9 ++- src/nesper/esp/esp_vfs_eventfd.nim | 61 +++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 src/nesper/esp/esp_vfs_eventfd.nim diff --git a/esp-idf-examples/net_pppos_usb/main/ioselectors_select.nim b/esp-idf-examples/net_pppos_usb/main/ioselectors_select.nim index b052a296..80f62ad7 100644 --- a/esp-idf-examples/net_pppos_usb/main/ioselectors_select.nim +++ b/esp-idf-examples/net_pppos_usb/main/ioselectors_select.nim @@ -176,9 +176,12 @@ elif defined(nimIoselectorEventfd): proc newSelectEvent*(): SelectEvent = when compiles(O_CLOEXEC): + echo "eventfd O_CLOEXEC or O_NONBLOCK" let fdci = eventfd(0, O_CLOEXEC or O_NONBLOCK) else: - let fdci = eventfd(0, O_NONBLOCK) + echo "eventfd O_NONBLOCK" + let fdci = eventfd(0, 0) + echo "eventfd O_NONBLOCK result: ", $fdci if fdci == -1: raiseIOSelectorsError(osLastError()) result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 5e4e6cf2..2582a6b6 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -166,10 +166,15 @@ app_main: rt.setupRpc() when defined(FastRpcServer): try: + logi(TAG, "setting up select event") + let ev = newSelectEvent() + logi(TAG, "ev: %s", repr(ev)) + logi(TAG, "setting up fast rpc router") let inetAddrs = [ newInetAddr("::", 5555, Protocol.IPPROTO_UDP), ] + logi(TAG, "newing fast rpc router") var rt: FastRpcRouter = newFastRpcRouter() logi(TAG, "registering rpcs") rt.registerRpcs(exampleRpcs) @@ -178,8 +183,8 @@ app_main: logi(TAG, "starting fast rpc server") startSocketServer(inetAddrs, frpcServer) logi(TAG, "fast rpc server done") - except Defect, CatchableError: - loge(TAG, "Error starting FastRpcServer: %s", getCurrentExceptionMsg()) + except CatchableError as e: + loge(TAG, "Error starting FastRpcServer: %s, %s", $e.name, $e.msg) for ste in getCurrentException().getStackTraceEntries(): loge(TAG, "Error: %s", $ste) diff --git a/src/nesper/esp/esp_vfs_eventfd.nim b/src/nesper/esp/esp_vfs_eventfd.nim new file mode 100644 index 00000000..0ee9184d --- /dev/null +++ b/src/nesper/esp/esp_vfs_eventfd.nim @@ -0,0 +1,61 @@ +import ../consts + +const + EFD_SUPPORT_ISR* = (1 shl 4) ## + ## SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + ## + ## SPDX-License-Identifier: Apache-2.0 + ## + +type + + esp_vfs_eventfd_config_t* {.importc: "esp_vfs_eventfd_config_t", + header: "esp_vfs_eventfd.h", bycopy.} = object ## + ## + ## @brief Eventfd vfs initialization settings + ## + max_fds* {.importc: "max_fds".}: csize_t + ## !< The maximum number of eventfds supported + + + +proc ESP_VFS_EVENTD_CONFIG_DEFAULT*(): esp_vfs_eventfd_config_t = + {.emit: """ + esp_vfs_eventfd_config_t cfg = ESP_VFS_EVENTD_CONFIG_DEFAULT(); + `result` = cfg; + """.} + +proc esp_vfs_eventfd_register*(config: ptr esp_vfs_eventfd_config_t): esp_err_t {. + cdecl, importc: "esp_vfs_eventfd_register", header: "esp_vfs_eventfd.h".} + ## + ## + ## @brief Registers the event vfs. + ## + ## @return ESP_OK if successful, ESP_ERR_NO_MEM if too many VFSes are + ## registered. + ## + +proc esp_vfs_eventfd_unregister*(): esp_err_t {.cdecl, + importc: "esp_vfs_eventfd_unregister", header: "esp_vfs_eventfd.h".} + ## + ## + ## @brief Unregisters the event vfs. + ## + ## @return ESP_OK if successful, ESP_ERR_INVALID_STATE if VFS for given prefix + ## hasn't been registered + ## + +proc eventfd*(initval: cuint; flags: cint): cint {.cdecl, importc: "eventfd", + header: "esp_vfs_eventfd.h".} + ## + ## @brief Creates an event file descriptor. + ## + ## The behavior of read, write and select is the same as man(2) eventfd with + ## EFD_SEMAPHORE **NOT** specified. A new flag EFD_SUPPORT_ISR has been added. + ## This flag is required to write to event fds in interrupt handlers. Accessing + ## the control blocks of event fds with EFD_SUPPORT_ISR will cause interrupts to + ## be temporarily blocked (e.g. during read, write and beginning and ending of + ## the * select). + ## + ## @return The file descriptor if successful, -1 if error happens. + ## \ No newline at end of file From 42afe458a481fd0b51965b771110fac48eaf2c0b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 04:09:35 -0600 Subject: [PATCH 101/142] old logs --- esp-idf-examples/net_pppos_usb/main/main.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 2582a6b6..9879fc62 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -7,6 +7,7 @@ import nesper/esp/esp_event import nesper/esp/net/esp_netif import nesper/esp/net/esp_netif_ppp import nesper/esp/net/esp_netif_impl +import nesper/esp/esp_vfs_eventfd import nesper/net_utils when defined(RUN_NCM): @@ -166,9 +167,9 @@ app_main: rt.setupRpc() when defined(FastRpcServer): try: - logi(TAG, "setting up select event") - let ev = newSelectEvent() - logi(TAG, "ev: %s", repr(ev)) + let cfg = ESP_VFS_EVENTD_CONFIG_DEFAULT() + logi(TAG, "cfg: %s", repr(cfg)) + check esp_vfs_eventfd_register(addr cfg) logi(TAG, "setting up fast rpc router") let inetAddrs = [ From 3a373454248c0bbf79b4e66cdc1675fab1fc919f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 04:27:13 -0600 Subject: [PATCH 102/142] old logs --- esp-idf-examples/net_pppos_usb/main/main.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 9879fc62..0c0901fe 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -45,6 +45,7 @@ when defined(FastRpcServer): DefineRpcs(name=exampleRpcs): proc add(a: int, b: int): int {.rpc.} = + echo "adding: ", a, " + ", b result = 1 + a + b From d03cb93afe5f6087b17c3e94446de9f14204c605 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 21:25:52 -0600 Subject: [PATCH 103/142] update esp_events --- esp-idf-examples/simplewifi/config.nims | 37 +- .../simplewifi/main/ioselectors_select.nim | 482 ++++++++++++++++++ src/nesper/consts.nim | 13 - src/nesper/esp/esp_event.nim | 14 + src/nesper/esp/net/esp_eth_com.nim | 1 + src/nesper/esp/net/esp_netif_impl.nim | 2 +- src/nesper/esp/net/esp_netif_types.nim | 5 +- src/nesper/esp/net/esp_wifi_types.nim | 3 +- 8 files changed, 516 insertions(+), 41 deletions(-) create mode 100644 esp-idf-examples/simplewifi/main/ioselectors_select.nim diff --git a/esp-idf-examples/simplewifi/config.nims b/esp-idf-examples/simplewifi/config.nims index b7ce864d..926fbaa5 100644 --- a/esp-idf-examples/simplewifi/config.nims +++ b/esp-idf-examples/simplewifi/config.nims @@ -1,26 +1,19 @@ -import os, strutils +switch("define", "ESP_IDF_VERSION=5.5") +switch("define", "esp32s3") # or other variants +switch("define", "nimNetSocketExtras") +switch("define", "nimIoselectorEventfd") +# switch("define", "TcpEchoServer") +# switch("define", "UdpEchoServer") +switch("define", "FastRpcServer") -task prepare, "Compile to C code": - mkDir("./main/nimcache") - let nimbasepath = selfExe().splitFile.dir.parentDir / "lib" / "nimbase.h" - let nimcachepath = "main" / "nimcache" - cpFile(nimbasepath, nimcachepath / "nimbase.h") - let params = commandLineParams() - let file = params[1] - let rest = params[2..high(params)].join(" ") - - let wifi_ssid = getEnv("WIFI_SSID") - let wifi_pass = getEnv("WIFI_PASSWORD") +switch("define", "McuUtilsLoggingLevel:lvlTrace") +# switch("define", "RUN_NCM") - let wifidefs = - if wifi_ssid != "" and wifi_pass != "": - "-d:WIFI_SSID=$1 -d:WIFI_PASSWORD=$2 " % [wifi_ssid, wifi_pass] - else: - "" +patchFile("stdlib", "cpuinfo", "main/cpuinfo.nim") +patchFile("stdlib", "ioselectors_select", "main/ioselectors_select.nim") - let - cmd = "nim c --os:freertos --cpu:esp --nomain --nimcache:$1 --compileOnly -d:NimAppMain $4 $3 $2 " % - [nimcachepath, file, rest, wifidefs] +switch("define", "WIFI_SSID", getEnv("WIFI_SSID")) +switch("define", "WIFI_PASSWORD", getEnv("WIFI_PASSWORD")) - echo("cmd: " & cmd) - exec(cmd) + +include nesper/build_utils/builds diff --git a/esp-idf-examples/simplewifi/main/ioselectors_select.nim b/esp-idf-examples/simplewifi/main/ioselectors_select.nim new file mode 100644 index 00000000..80f62ad7 --- /dev/null +++ b/esp-idf-examples/simplewifi/main/ioselectors_select.nim @@ -0,0 +1,482 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2016 Eugene Kabanov +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +# This module implements Posix and Windows select(). + +import std/[times, nativesockets] + +when defined(windows): + import std/winlean + when defined(gcc): + {.passl: "-lws2_32".} + elif defined(vcc): + {.passl: "ws2_32.lib".} + const platformHeaders = """#include + #include """ + const EAGAIN = WSAEWOULDBLOCK +else: + const platformHeaders = """#include + #include + #include + #include """ +type + FdSet {.importc: "fd_set", header: platformHeaders, pure, final.} = object +var + FD_SETSIZE {.importc: "FD_SETSIZE", header: platformHeaders.}: cint + +proc IOFD_SET(fd: SocketHandle, fdset: ptr FdSet) + {.cdecl, importc: "FD_SET", header: platformHeaders, inline.} +proc IOFD_CLR(fd: SocketHandle, fdset: ptr FdSet) + {.cdecl, importc: "FD_CLR", header: platformHeaders, inline.} +proc IOFD_ZERO(fdset: ptr FdSet) + {.cdecl, importc: "FD_ZERO", header: platformHeaders, inline.} + +when defined(windows): + proc IOFD_ISSET(fd: SocketHandle, fdset: ptr FdSet): cint + {.stdcall, importc: "FD_ISSET", header: platformHeaders, inline.} + proc ioselect(nfds: cint, readFds, writeFds, exceptFds: ptr FdSet, + timeout: ptr Timeval): cint + {.stdcall, importc: "select", header: platformHeaders.} +else: + proc IOFD_ISSET(fd: SocketHandle, fdset: ptr FdSet): cint + {.cdecl, importc: "FD_ISSET", header: platformHeaders, inline.} + proc ioselect(nfds: cint, readFds, writeFds, exceptFds: ptr FdSet, + timeout: ptr Timeval): cint + {.cdecl, importc: "select", header: platformHeaders.} + +when hasThreadSupport: + type + SelectorImpl[T] = object + rSet: FdSet + wSet: FdSet + eSet: FdSet + maxFD: int + fds: ptr SharedArray[SelectorKey[T]] + count*: int + lock: Lock + Selector*[T] = ptr SelectorImpl[T] +else: + type + SelectorImpl[T] = object + rSet: FdSet + wSet: FdSet + eSet: FdSet + maxFD: int + fds: seq[SelectorKey[T]] + count*: int + Selector*[T] = ref SelectorImpl[T] + +type + SelectEventImpl = object + rsock: SocketHandle + wsock: SocketHandle + SelectEvent* = ptr SelectEventImpl + +when hasThreadSupport: + template withSelectLock[T](s: Selector[T], body: untyped) = + acquire(s.lock) + {.locks: [s.lock].}: + try: + body + finally: + release(s.lock) +else: + template withSelectLock[T](s: Selector[T], body: untyped) = + body + +proc newSelector*[T](): Selector[T] = + when hasThreadSupport: + result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T]))) + result.fds = allocSharedArray[SelectorKey[T]](FD_SETSIZE) + initLock result.lock + else: + result = Selector[T]() + result.fds = newSeq[SelectorKey[T]](FD_SETSIZE) + + for i in 0 ..< FD_SETSIZE: + result.fds[i].ident = InvalidIdent + + IOFD_ZERO(addr result.rSet) + IOFD_ZERO(addr result.wSet) + IOFD_ZERO(addr result.eSet) + +proc close*[T](s: Selector[T]) = + when hasThreadSupport: + deallocSharedArray(s.fds) + deallocShared(cast[pointer](s)) + deinitLock(s.lock) + +when defined(windows): + proc newSelectEvent*(): SelectEvent = + var ssock = createNativeSocket() + var wsock = createNativeSocket() + var rsock: SocketHandle = INVALID_SOCKET + var saddr = Sockaddr_in() + + saddr.sin_family = winlean.AF_INET + saddr.sin_port = 0 + saddr.sin_addr.s_addr = INADDR_ANY + if bindAddr(ssock, cast[ptr SockAddr](addr(saddr)), + sizeof(saddr).SockLen) < 0'i32: + raiseIOSelectorsError(osLastError()) + + if winlean.listen(ssock, 1) != 0: + raiseIOSelectorsError(osLastError()) + + var namelen = sizeof(saddr).SockLen + if getsockname(ssock, cast[ptr SockAddr](addr(saddr)), + addr(namelen)) != 0'i32: + raiseIOSelectorsError(osLastError()) + + saddr.sin_addr.s_addr = 0x0100007F + if winlean.connect(wsock, cast[ptr SockAddr](addr(saddr)), + sizeof(saddr).SockLen) != 0: + raiseIOSelectorsError(osLastError()) + namelen = sizeof(saddr).SockLen + rsock = winlean.accept(ssock, cast[ptr SockAddr](addr(saddr)), + cast[ptr SockLen](addr(namelen))) + if rsock == SocketHandle(-1): + raiseIOSelectorsError(osLastError()) + + if winlean.closesocket(ssock) != 0: + raiseIOSelectorsError(osLastError()) + + var mode = clong(1) + if ioctlsocket(rsock, FIONBIO, addr(mode)) != 0: + raiseIOSelectorsError(osLastError()) + mode = clong(1) + if ioctlsocket(wsock, FIONBIO, addr(mode)) != 0: + raiseIOSelectorsError(osLastError()) + + result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) + result.rsock = rsock + result.wsock = wsock + + proc trigger*(ev: SelectEvent) = + var data: uint64 = 1 + if winlean.send(ev.wsock, cast[pointer](addr data), + cint(sizeof(uint64)), 0) != sizeof(uint64): + raiseIOSelectorsError(osLastError()) + + proc close*(ev: SelectEvent) = + let res1 = winlean.closesocket(ev.rsock) + let res2 = winlean.closesocket(ev.wsock) + deallocShared(cast[pointer](ev)) + if res1 != 0 or res2 != 0: + raiseIOSelectorsError(osLastError()) + +elif defined(nimIoselectorEventfd): + proc eventfd(fd: cint, flags: cint): cint {.importc: "eventfd", header: platformHeaders, inline.} + + proc newSelectEvent*(): SelectEvent = + when compiles(O_CLOEXEC): + echo "eventfd O_CLOEXEC or O_NONBLOCK" + let fdci = eventfd(0, O_CLOEXEC or O_NONBLOCK) + else: + echo "eventfd O_NONBLOCK" + let fdci = eventfd(0, 0) + echo "eventfd O_NONBLOCK result: ", $fdci + if fdci == -1: + raiseIOSelectorsError(osLastError()) + result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) + result.rsock = SocketHandle(fdci) + result.wsock = SocketHandle(-1) + + proc trigger*(ev: SelectEvent) = + var data: uint64 = 1 + if posix.write(ev.rsock.cint, addr data, sizeof(uint64)) == -1: + raiseIOSelectorsError(osLastError()) + + proc close*(ev: SelectEvent) = + let res = posix.close(ev.rsock.cint) + deallocShared(cast[pointer](ev)) + if res != 0: + raiseIOSelectorsError(osLastError()) + +else: + proc newSelectEvent*(): SelectEvent = + var fds: array[2, cint] + if posix.pipe(fds) != 0: + raiseIOSelectorsError(osLastError()) + setNonBlocking(fds[0]) + setNonBlocking(fds[1]) + result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) + result.rsock = SocketHandle(fds[0]) + result.wsock = SocketHandle(fds[1]) + + proc trigger*(ev: SelectEvent) = + var data: uint64 = 1 + if posix.write(cint(ev.wsock), addr data, sizeof(uint64)) != sizeof(uint64): + raiseIOSelectorsError(osLastError()) + + proc close*(ev: SelectEvent) = + let res1 = posix.close(cint(ev.rsock)) + let res2 = posix.close(cint(ev.wsock)) + deallocShared(cast[pointer](ev)) + if res1 != 0 or res2 != 0: + raiseIOSelectorsError(osLastError()) + +proc setSelectKey[T](s: Selector[T], fd: SocketHandle, events: set[Event], + data: T) = + var i = 0 + let fdi = int(fd) + while i < FD_SETSIZE: + if s.fds[i].ident == InvalidIdent: + var pkey = addr(s.fds[i]) + pkey.ident = fdi + pkey.events = events + pkey.data = data + break + inc(i) + if i >= FD_SETSIZE: + raiseIOSelectorsError("Maximum number of descriptors is exhausted!") + +proc getKey[T](s: Selector[T], fd: SocketHandle): ptr SelectorKey[T] = + var i = 0 + let fdi = int(fd) + while i < FD_SETSIZE: + if s.fds[i].ident == fdi: + result = addr(s.fds[i]) + break + inc(i) + doAssert(i < FD_SETSIZE, + "Descriptor [" & $int(fd) & "] is not registered in the queue!") + +proc delKey[T](s: Selector[T], fd: SocketHandle) = + var empty: T + var i = 0 + while i < FD_SETSIZE: + if s.fds[i].ident == fd.int: + s.fds[i].ident = InvalidIdent + s.fds[i].events = {} + s.fds[i].data = empty + break + inc(i) + doAssert(i < FD_SETSIZE, + "Descriptor [" & $int(fd) & "] is not registered in the queue!") + +proc registerHandle*[T](s: Selector[T], fd: int | SocketHandle, + events: set[Event], data: T) = + when not defined(windows): + let fdi = int(fd) + s.withSelectLock(): + s.setSelectKey(fd, events, data) + when not defined(windows): + if fdi > s.maxFD: s.maxFD = fdi + if Event.Read in events: + IOFD_SET(fd, addr s.rSet) + inc(s.count) + if Event.Write in events: + IOFD_SET(fd, addr s.wSet) + IOFD_SET(fd, addr s.eSet) + inc(s.count) + +proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = + when not defined(windows): + let fdi = int(ev.rsock) + s.withSelectLock(): + s.setSelectKey(ev.rsock, {Event.User}, data) + when not defined(windows): + if fdi > s.maxFD: s.maxFD = fdi + IOFD_SET(ev.rsock, addr s.rSet) + inc(s.count) + +proc updateHandle*[T](s: Selector[T], fd: int | SocketHandle, + events: set[Event]) = + let maskEvents = {Event.Timer, Event.Signal, Event.Process, Event.Vnode, + Event.User, Event.Oneshot, Event.Error} + s.withSelectLock(): + var pkey = s.getKey(fd) + doAssert(pkey.events * maskEvents == {}) + if pkey.events != events: + if (Event.Read in pkey.events) and (Event.Read notin events): + IOFD_CLR(fd, addr s.rSet) + dec(s.count) + if (Event.Write in pkey.events) and (Event.Write notin events): + IOFD_CLR(fd, addr s.wSet) + IOFD_CLR(fd, addr s.eSet) + dec(s.count) + if (Event.Read notin pkey.events) and (Event.Read in events): + IOFD_SET(fd, addr s.rSet) + inc(s.count) + if (Event.Write notin pkey.events) and (Event.Write in events): + IOFD_SET(fd, addr s.wSet) + IOFD_SET(fd, addr s.eSet) + inc(s.count) + pkey.events = events + +proc unregister*[T](s: Selector[T], fd: SocketHandle|int) = + s.withSelectLock(): + let fd = fd.SocketHandle + var pkey = s.getKey(fd) + if Event.Read in pkey.events or Event.User in pkey.events: + IOFD_CLR(fd, addr s.rSet) + dec(s.count) + if Event.Write in pkey.events: + IOFD_CLR(fd, addr s.wSet) + IOFD_CLR(fd, addr s.eSet) + dec(s.count) + s.delKey(fd) + +proc unregister*[T](s: Selector[T], ev: SelectEvent) = + let fd = ev.rsock + s.withSelectLock(): + var pkey = s.getKey(fd) + IOFD_CLR(fd, addr s.rSet) + dec(s.count) + s.delKey(fd) + +proc selectInto*[T](s: Selector[T], timeout: int, + results: var openArray[ReadyKey]): int = + var tv = Timeval() + var ptv = addr tv + var rset, wset, eset: FdSet + + verifySelectParams(timeout) + + if timeout != -1: + when defined(genode) or defined(freertos) or defined(zephyr) or defined(nuttx): + tv.tv_sec = posix.Time(timeout div 1_000) + else: + tv.tv_sec = timeout.int32 div 1_000 + tv.tv_usec = (timeout.int32 %% 1_000) * 1_000 + else: + ptv = nil + + s.withSelectLock(): + rset = s.rSet + wset = s.wSet + eset = s.eSet + + var count = ioselect(cint(s.maxFD) + 1, addr(rset), addr(wset), + addr(eset), ptv) + if count < 0: + result = 0 + when defined(windows): + raiseIOSelectorsError(osLastError()) + else: + let err = osLastError() + if cint(err) != EINTR: + raiseIOSelectorsError(err) + elif count == 0: + result = 0 + else: + var rindex = 0 + var i = 0 + var k = 0 + + while (i < FD_SETSIZE) and (k < count): + if s.fds[i].ident != InvalidIdent: + var flag = false + var pkey = addr(s.fds[i]) + var rkey = ReadyKey(fd: int(pkey.ident), events: {}) + let fd = SocketHandle(pkey.ident) + if IOFD_ISSET(fd, addr rset) != 0: + if Event.User in pkey.events: + var data: uint64 = 0 + if recv(fd, cast[pointer](addr(data)), + sizeof(uint64).cint, 0) != sizeof(uint64): + let err = osLastError() + if cint(err) != EAGAIN: + raiseIOSelectorsError(err) + else: + inc(i) + inc(k) + continue + else: + flag = true + rkey.events = {Event.User} + else: + flag = true + rkey.events = {Event.Read} + if IOFD_ISSET(fd, addr wset) != 0: + rkey.events.incl(Event.Write) + if IOFD_ISSET(fd, addr eset) != 0: + rkey.events.incl(Event.Error) + flag = true + if flag: + results[rindex] = rkey + inc(rindex) + inc(k) + inc(i) + result = rindex + +proc select*[T](s: Selector[T], timeout: int): seq[ReadyKey] = + result = newSeq[ReadyKey](FD_SETSIZE) + var count = selectInto(s, timeout, result) + result.setLen(count) + +proc flush*[T](s: Selector[T]) = discard + +template isEmpty*[T](s: Selector[T]): bool = + (s.count == 0) + +proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} = + s.withSelectLock(): + result = false + + let fdi = int(fd) + for i in 0.. Date: Thu, 4 Sep 2025 21:34:53 -0600 Subject: [PATCH 104/142] esp events --- src/nesper/esp/esp_event.nim | 807 +++++++++++++++++------------------ 1 file changed, 393 insertions(+), 414 deletions(-) diff --git a/src/nesper/esp/esp_event.nim b/src/nesper/esp/esp_event.nim index 022e1e20..68970b7c 100644 --- a/src/nesper/esp/esp_event.nim +++ b/src/nesper/esp/esp_event.nim @@ -34,6 +34,9 @@ type event_id: int32; event_data: pointer) {.cdecl.} +type + esp_event_handler_instance_t* {.importc: "esp_event_handler_instance_t", header: "esp_event.h".} = object + ## / Configuration for creating event loops type @@ -48,122 +51,123 @@ type ## ignored if task name is NULL -## * -## @brief Create a new event loop. -## -## @param[in] event_loop_args configuration structure for the event loop to create -## @param[out] event_loop handle to the created event loop -## -## @return -## - ESP_OK: Success -## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list -## - ESP_FAIL: Failed to create task loop -## - Others: Fail -## - proc esp_event_loop_create*(event_loop_args: ptr esp_event_loop_args_t; event_loop: ptr esp_event_loop_handle_t): esp_err_t {. - importc: "esp_event_loop_create", header: "esp_event.h".} -## * -## @brief Delete an existing event loop. -## -## @param[in] event_loop event loop to delete -## -## @return -## - ESP_OK: Success -## - Others: Fail -## + importc: "esp_event_loop_create", header: "esp_event.h".} ##| + ## * + ## @brief Create a new event loop. + ## + ## @param[in] event_loop_args configuration structure for the event loop to create + ## @param[out] event_loop handle to the created event loop + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list + ## - ESP_FAIL: Failed to create task loop + ## - Others: Fail + ## proc esp_event_loop_delete*(event_loop: esp_event_loop_handle_t): esp_err_t {. - importc: "esp_event_loop_delete", header: "esp_event.h".} -## * -## @brief Create default event loop -## -## @return -## - ESP_OK: Success -## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list -## - ESP_FAIL: Failed to create task loop -## - Others: Fail -## + importc: "esp_event_loop_delete", header: "esp_event.h".} ##\ + ## * + ## @brief Delete an existing event loop. + ## + ## @param[in] event_loop event loop to delete + ## + ## @return + ## - ESP_OK: Success + ## - Others: Fail + ## proc esp_event_loop_create_default*(): esp_err_t {. - importc: "esp_event_loop_create_default", header: "esp_event.h".} -## * -## @brief Delete the default event loop -## -## @return -## - ESP_OK: Success -## - Others: Fail -## + importc: "esp_event_loop_create_default", header: "esp_event.h".} ##\ + ## * + ## @brief Create default event loop + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list + ## - ESP_FAIL: Failed to create task loop + ## - Others: Fail + ## proc esp_event_loop_delete_default*(): esp_err_t {. - importc: "esp_event_loop_delete_default", header: "esp_event.h".} -## * -## @brief Dispatch events posted to an event loop. -## -## This function is used to dispatch events posted to a loop with no dedicated task, i.e task name was set to NULL -## in event_loop_args argument during loop creation. This function includes an argument to limit the amount of time -## it runs, returning control to the caller when that time expires (or some time afterwards). There is no guarantee -## that a call to this function will exit at exactly the time of expiry. There is also no guarantee that events have -## been dispatched during the call, as the function might have spent all of the alloted time waiting on the event queue. -## Once an event has been unqueued, however, it is guaranteed to be dispatched. This guarantee contributes to not being -## able to exit exactly at time of expiry as (1) blocking on internal mutexes is necessary for dispatching the unqueued -## event, and (2) during dispatch of the unqueued event there is no way to control the time occupied by handler code -## execution. The guaranteed time of exit is therefore the alloted time + amount of time required to dispatch -## the last unqueued event. -## -## In cases where waiting on the queue times out, ESP_OK is returned and not ESP_ERR_TIMEOUT, since it is -## normal behavior. -## -## @param[in] event_loop event loop to dispatch posted events from -## @param[in] ticks_to_run number of ticks to run the loop -## -## @note encountering an unknown event that has been posted to the loop will only generate a warning, not an error. -## -## @return -## - ESP_OK: Success -## - Others: Fail -## + importc: "esp_event_loop_delete_default", header: "esp_event.h".} ##\ + ## * + ## @brief Delete the default event loop + ## + ## @return + ## - ESP_OK: Success + ## - Others: Fail + ## + proc esp_event_loop_run*(event_loop: esp_event_loop_handle_t; ticks_to_run: TickType_t): esp_err_t {. - importc: "esp_event_loop_run", header: "esp_event.h".} -## * -## @brief Register an event handler to the system event loop (legacy). -## -## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_register() -## instead. -## -## This function can be used to register a handler for either: (1) specific events, -## (2) all events of a certain event base, or (3) all events known by the system event loop. -## -## - specific events: specify exact event_base and event_id -## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id -## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id -## -## Registering multiple handlers to events is possible. Registering a single handler to multiple events is -## also possible. However, registering the same handler to the same event multiple times would cause the -## previous registrations to be overwritten. -## -## @param[in] event_base the base id of the event to register the handler for -## @param[in] event_id the id of the event to register the handler for -## @param[in] event_handler the handler function which gets called when the event is dispatched -## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called -## -## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should -## ensure that event_handler_arg still points to a valid location by the time the handler gets called -## -## @return -## - ESP_OK: Success -## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id -## - Others: Fail -## + importc: "esp_event_loop_run", header: "esp_event.h".} ##\ + ## * + ## @brief Dispatch events posted to an event loop. + ## + ## This function is used to dispatch events posted to a loop with no dedicated task, i.e task name was set to NULL + ## in event_loop_args argument during loop creation. This function includes an argument to limit the amount of time + ## it runs, returning control to the caller when that time expires (or some time afterwards). There is no guarantee + ## that a call to this function will exit at exactly the time of expiry. There is also no guarantee that events have + ## been dispatched during the call, as the function might have spent all of the alloted time waiting on the event queue. + ## Once an event has been unqueued, however, it is guaranteed to be dispatched. This guarantee contributes to not being + ## able to exit exactly at time of expiry as (1) blocking on internal mutexes is necessary for dispatching the unqueued + ## event, and (2) during dispatch of the unqueued event there is no way to control the time occupied by handler code + ## execution. The guaranteed time of exit is therefore the alloted time + amount of time required to dispatch + ## the last unqueued event. + ## + ## In cases where waiting on the queue times out, ESP_OK is returned and not ESP_ERR_TIMEOUT, since it is + ## normal behavior. + ## + ## @param[in] event_loop event loop to dispatch posted events from + ## @param[in] ticks_to_run number of ticks to run the loop + ## + ## @note encountering an unknown event that has been posted to the loop will only generate a warning, not an error. + ## + ## @return + ## - ESP_OK: Success + ## - Others: Fail + ## + ## * + ## @brief Register an event handler to the system event loop (legacy). + ## + ## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_register() + ## instead. + ## + ## This function can be used to register a handler for either: (1) specific events, + ## (2) all events of a certain event base, or (3) all events known by the system event loop. + ## + ## - specific events: specify exact event_base and event_id + ## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id + ## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id + ## + ## Registering multiple handlers to events is possible. Registering a single handler to multiple events is + ## also possible. However, registering the same handler to the same event multiple times would cause the + ## previous registrations to be overwritten. + ## + ## @param[in] event_base the base id of the event to register the handler for + ## @param[in] event_id the id of the event to register the handler for + ## @param[in] event_handler the handler function which gets called when the event is dispatched + ## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called + ## + ## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should + ## ensure that event_handler_arg still points to a valid location by the time the handler gets called + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id + ## - Others: Fail + ## # proc esp_event_handler_register*(event_base: esp_event_base_t; event_id: int32; # event_handler: esp_event_handler_t; # event_handler_arg: pointer): esp_err_t {. # importc: "esp_event_handler_register", header: "esp_event.h".} + proc esp_event_handler_register*( event_base: esp_event_base_t; event_id: cint; @@ -171,30 +175,6 @@ proc esp_event_handler_register*( event_handler_arg: pointer ): esp_err_t {.importc: "esp_event_handler_register", header: "esp_event.h".} -## * -## @brief Register an event handler to a specific loop (legacy). -## -## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_register_with() -## instead. -## -## This function behaves in the same manner as esp_event_handler_register, except the additional -## specification of the event loop to register the handler to. -## -## @param[in] event_loop the event loop to register this handler function to -## @param[in] event_base the base id of the event to register the handler for -## @param[in] event_id the id of the event to register the handler for -## @param[in] event_handler the handler function which gets called when the event is dispatched -## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called -## -## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should -## ensure that event_handler_arg still points to a valid location by the time the handler gets called -## -## @return -## - ESP_OK: Success -## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id -## - Others: Fail -## proc esp_event_handler_register_with*(event_loop: esp_event_loop_handle_t; event_base: esp_event_base_t; @@ -202,343 +182,342 @@ proc esp_event_handler_register_with*(event_loop: esp_event_loop_handle_t; event_handler: esp_event_handler_t; event_handler_arg: pointer): esp_err_t {. importc: "esp_event_handler_register_with", header: "esp_event.h".} -## * -## @brief Register an instance of event handler to a specific loop. -## -## This function can be used to register a handler for either: (1) specific events, -## (2) all events of a certain event base, or (3) all events known by the system event loop. -## -## - specific events: specify exact event_base and event_id -## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id -## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id -## -## Besides the error, the function returns an instance object as output parameter to identify each registration. -## This is necessary to remove (unregister) the registration before the event loop is deleted. -## -## Registering multiple handlers to events, registering a single handler to multiple events as well as registering -## the same handler to the same event multiple times is possible. -## Each registration yields a distinct instance object which identifies it over the registration -## lifetime. -## -## @param[in] event_loop the event loop to register this handler function to -## @param[in] event_base the base id of the event to register the handler for -## @param[in] event_id the id of the event to register the handler for -## @param[in] event_handler the handler function which gets called when the event is dispatched -## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called -## @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL. -## This needs to be kept if the specific callback instance should be unregistered before deleting the whole -## event loop. Registering the same event handler multiple times is possible and yields distinct instance -## objects. The data can be the same for all registrations. -## If no unregistration is needed but the handler should be deleted when the event loop is deleted, -## instance can be NULL. -## -## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should -## ensure that event_handler_arg still points to a valid location by the time the handler gets called -## -## @return -## - ESP_OK: Success -## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id or instance is NULL -## - Others: Fail -## + ## * + ## @brief Register an event handler to a specific loop (legacy). + ## + ## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_register_with() + ## instead. + ## + ## This function behaves in the same manner as esp_event_handler_register, except the additional + ## specification of the event loop to register the handler to. + ## + ## @param[in] event_loop the event loop to register this handler function to + ## @param[in] event_base the base id of the event to register the handler for + ## @param[in] event_id the id of the event to register the handler for + ## @param[in] event_handler the handler function which gets called when the event is dispatched + ## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called + ## + ## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should + ## ensure that event_handler_arg still points to a valid location by the time the handler gets called + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id + ## - Others: Fail + ## -type - esp_event_handler_instance_t* {.importc: "esp_event_handler_instance_t", header: "esp_event.h".} = object proc esp_event_handler_instance_register_with*( event_loop: esp_event_loop_handle_t; event_base: esp_event_base_t; event_id: int32; event_handler: esp_event_handler_t; event_handler_arg: pointer; instance: ptr esp_event_handler_instance_t): esp_err_t {. - importc: "esp_event_handler_instance_register_with", header: "esp_event.h".} -## * -## @brief Register an instance of event handler to the default loop. -## -## This function does the same as esp_event_handler_instance_register_with, except that it registers the -## handler to the default event loop. -## -## @param[in] event_base the base id of the event to register the handler for -## @param[in] event_id the id of the event to register the handler for -## @param[in] event_handler the handler function which gets called when the event is dispatched -## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called -## @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL. -## This needs to be kept if the specific callback instance should be unregistered before deleting the whole -## event loop. Registering the same event handler multiple times is possible and yields distinct instance -## objects. The data can be the same for all registrations. -## If no unregistration is needed but the handler should be deleted when the event loop is deleted, -## instance can be NULL. -## -## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should -## ensure that event_handler_arg still points to a valid location by the time the handler gets called -## -## @return -## - ESP_OK: Success -## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id or instance is NULL -## - Others: Fail -## + importc: "esp_event_handler_instance_register_with", header: "esp_event.h".} ##\ + ## + ## This function can be used to register a handler for either: (1) specific events, + ## (2) all events of a certain event base, or (3) all events known by the system event loop. + ## + ## - specific events: specify exact event_base and event_id + ## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id + ## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id + ## + ## Besides the error, the function returns an instance object as output parameter to identify each registration. + ## This is necessary to remove (unregister) the registration before the event loop is deleted. + ## + ## Registering multiple handlers to events, registering a single handler to multiple events as well as registering + ## the same handler to the same event multiple times is possible. + ## Each registration yields a distinct instance object which identifies it over the registration + ## lifetime. + ## + ## @param[in] event_loop the event loop to register this handler function to + ## @param[in] event_base the base id of the event to register the handler for + ## @param[in] event_id the id of the event to register the handler for + ## @param[in] event_handler the handler function which gets called when the event is dispatched + ## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called + ## @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL. + ## This needs to be kept if the specific callback instance should be unregistered before deleting the whole + ## event loop. Registering the same event handler multiple times is possible and yields distinct instance + ## objects. The data can be the same for all registrations. + ## If no unregistration is needed but the handler should be deleted when the event loop is deleted, + ## instance can be NULL. + ## + ## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should + ## ensure that event_handler_arg still points to a valid location by the time the handler gets called + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id or instance is NULL + ## - Others: Fail + ## proc esp_event_handler_instance_register*(event_base: esp_event_base_t; event_id: int32; event_handler: esp_event_handler_t; event_handler_arg: pointer; instance: ptr esp_event_handler_instance_t): esp_err_t {. importc: "esp_event_handler_instance_register", header: "esp_event.h".} -## * -## @brief Unregister a handler with the system event loop (legacy). -## -## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_unregister() -## instead. -## -## This function can be used to unregister a handler so that it no longer gets called during dispatch. -## Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base, -## or (3) all events known by the system event loop -## -## - specific events: specify exact event_base and event_id -## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id -## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id -## -## This function ignores unregistration of handlers that has not been previously registered. -## -## @param[in] event_base the base of the event with which to unregister the handler -## @param[in] event_id the id of the event with which to unregister the handler -## @param[in] event_handler the handler to unregister -## -## @return ESP_OK success -## @return ESP_ERR_INVALID_ARG invalid combination of event base and event id -## @return others fail -## + proc esp_event_handler_unregister*( event_base: esp_event_base_t; event_id: int32; event_handler: esp_event_handler_t - ): esp_err_t {.importc: "esp_event_handler_unregister", header: "esp_event.h".} + ): esp_err_t {.importc: "esp_event_handler_unregister", header: "esp_event.h".} ##| + ## * + ## @brief Unregister a handler with the system event loop (legacy). + ## + ## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_unregister() + ## instead. + ## + ## This function can be used to unregister a handler so that it no longer gets called during dispatch. + ## Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base, + ## or (3) all events known by the system event loop + ## + ## - specific events: specify exact event_base and event_id + ## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id + ## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id + ## + ## This function ignores unregistration of handlers that has not been previously registered. + ## + ## @param[in] event_base the base of the event with which to unregister the handler + ## @param[in] event_id the id of the event with which to unregister the handler + ## @param[in] event_handler the handler to unregister + ## + ## @return ESP_OK success + ## @return ESP_ERR_INVALID_ARG invalid combination of event base and event id + ## @return others fail + ## -## * -## @brief Unregister a handler from a specific event loop (legacy). -## -## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_unregister_with() -## instead. -## -## This function behaves in the same manner as esp_event_handler_unregister, except the additional specification of -## the event loop to unregister the handler with. -## -## @param[in] event_loop the event loop with which to unregister this handler function -## @param[in] event_base the base of the event with which to unregister the handler -## @param[in] event_id the id of the event with which to unregister the handler -## @param[in] event_handler the handler to unregister -## -## @return -## - ESP_OK: Success -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id -## - Others: Fail -## proc esp_event_handler_unregister_with*(event_loop: esp_event_loop_handle_t; event_base: esp_event_base_t; event_id: int32; event_handler: esp_event_handler_t): esp_err_t {. importc: "esp_event_handler_unregister_with", header: "esp_event.h".} -## * -## @brief Unregister a handler instance from a specific event loop. -## -## This function can be used to unregister a handler so that it no longer gets called during dispatch. -## Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base, -## or (3) all events known by the system event loop -## -## - specific events: specify exact event_base and event_id -## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id -## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id -## -## This function ignores unregistration of handler instances that have not been previously registered. -## -## @param[in] event_loop the event loop with which to unregister this handler function -## @param[in] event_base the base of the event with which to unregister the handler -## @param[in] event_id the id of the event with which to unregister the handler -## @param[in] instance the instance object of the registration to be unregistered -## -## @return -## - ESP_OK: Success -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id -## - Others: Fail -## + ## * + ## @brief Unregister a handler from a specific event loop (legacy). + ## + ## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_unregister_with() + ## instead. + ## + ## This function behaves in the same manner as esp_event_handler_unregister, except the additional specification of + ## the event loop to unregister the handler with. + ## + ## @param[in] event_loop the event loop with which to unregister this handler function + ## @param[in] event_base the base of the event with which to unregister the handler + ## @param[in] event_id the id of the event with which to unregister the handler + ## @param[in] event_handler the handler to unregister + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id + ## - Others: Fail + ## + proc esp_event_handler_instance_unregister_with*( event_loop: esp_event_loop_handle_t; event_base: esp_event_base_t; event_id: int32; instance: esp_event_handler_instance_t): esp_err_t {. - importc: "esp_event_handler_instance_unregister_with", header: "esp_event.h".} -## * -## @brief Unregister a handler from the system event loop. -## -## This function does the same as esp_event_handler_instance_unregister_with, except that it unregisters the -## handler instance from the default event loop. -## -## @param[in] event_base the base of the event with which to unregister the handler -## @param[in] event_id the id of the event with which to unregister the handler -## @param[in] instance the instance object of the registration to be unregistered -## -## @return -## - ESP_OK: Success -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id -## - Others: Fail -## + importc: "esp_event_handler_instance_unregister_with", header: "esp_event.h".} ##| + ## * + ## @brief Unregister a handler instance from a specific event loop. + ## + ## This function can be used to unregister a handler so that it no longer gets called during dispatch. + ## Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base, + ## or (3) all events known by the system event loop + ## + ## - specific events: specify exact event_base and event_id + ## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id + ## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id + ## + ## This function ignores unregistration of handler instances that have not been previously registered. + ## + ## @param[in] event_loop the event loop with which to unregister this handler function + ## @param[in] event_base the base of the event with which to unregister the handler + ## @param[in] event_id the id of the event with which to unregister the handler + ## @param[in] instance the instance object of the registration to be unregistered + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id + ## - Others: Fail + ## + proc esp_event_handler_instance_unregister*(event_base: esp_event_base_t; event_id: int32; instance: esp_event_handler_instance_t): esp_err_t {. - importc: "esp_event_handler_instance_unregister", header: "esp_event.h".} + importc: "esp_event_handler_instance_unregister", header: "esp_event.h".} ##| + ## * + ## @brief Unregister a handler from the system event loop. + ## + ## This function does the same as esp_event_handler_instance_unregister_with, except that it unregisters the + ## handler instance from the default event loop. + ## + ## @param[in] event_base the base of the event with which to unregister the handler + ## @param[in] event_id the id of the event with which to unregister the handler + ## @param[in] instance the instance object of the registration to be unregistered + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id + ## - Others: Fail + ## -## * -## @brief Posts an event to the system default event loop. The event loop library keeps a copy of event_data and manages -## the copy's lifetime automatically (allocation + deletion); this ensures that the data the -## handler recieves is always valid. -## -## @param[in] event_base the event base that identifies the event -## @param[in] event_id the event id that identifies the event -## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler -## @param[in] event_data_size the size of the event data -## @param[in] ticks_to_wait number of ticks to block on a full event queue -## -## @return -## - ESP_OK: Success -## - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired, -## queue full when posting from ISR -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id -## - Others: Fail -## proc esp_event_post*(event_base: esp_event_base_t; event_id: int32; event_data: pointer; event_data_size: csize; ticks_to_wait: TickType_t): esp_err_t {. - importc: "esp_event_post", header: "esp_event.h".} + importc: "esp_event_post", header: "esp_event.h".} ##| + ## * + ## @brief Posts an event to the system default event loop. The event loop library keeps a copy of event_data and manages + ## the copy's lifetime automatically (allocation + deletion); this ensures that the data the + ## handler recieves is always valid. + ## + ## @param[in] event_base the event base that identifies the event + ## @param[in] event_id the event id that identifies the event + ## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler + ## @param[in] event_data_size the size of the event data + ## @param[in] ticks_to_wait number of ticks to block on a full event queue + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired, + ## queue full when posting from ISR + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id + ## - Others: Fail + ## -## * -## @brief Posts an event to the specified event loop. The event loop library keeps a copy of event_data and manages -## the copy's lifetime automatically (allocation + deletion); this ensures that the data the -## handler recieves is always valid. -## -## This function behaves in the same manner as esp_event_post_to, except the additional specification of the event loop -## to post the event to. -## -## @param[in] event_loop the event loop to post to -## @param[in] event_base the event base that identifies the event -## @param[in] event_id the event id that identifies the event -## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler -## @param[in] event_data_size the size of the event data -## @param[in] ticks_to_wait number of ticks to block on a full event queue -## -## @return -## - ESP_OK: Success -## - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired, -## queue full when posting from ISR -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id -## - Others: Fail -## proc esp_event_post_to*(event_loop: esp_event_loop_handle_t; event_base: esp_event_base_t; event_id: int32; event_data: pointer; event_data_size: csize_t; ticks_to_wait: TickType_t): esp_err_t {. - importc: "esp_event_post_to", header: "esp_event.h".} + importc: "esp_event_post_to", header: "esp_event.h".} ##\ + ## * + ## @brief Posts an event to the specified event loop. The event loop library keeps a copy of event_data and manages + ## the copy's lifetime automatically (allocation + deletion); this ensures that the data the + ## handler recieves is always valid. + ## + ## This function behaves in the same manner as esp_event_post_to, except the additional specification of the event loop + ## to post the event to. + ## + ## @param[in] event_loop the event loop to post to + ## @param[in] event_base the event base that identifies the event + ## @param[in] event_id the event id that identifies the event + ## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler + ## @param[in] event_data_size the size of the event data + ## @param[in] ticks_to_wait number of ticks to block on a full event queue + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired, + ## queue full when posting from ISR + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id + ## - Others: Fail + ## + -# when CONFIG_ESP_EVENT_POST_FROM_ISR: -## * -## @brief Special variant of esp_event_post for posting events from interrupt handlers. -## -## @param[in] event_base the event base that identifies the event -## @param[in] event_id the event id that identifies the event -## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler -## @param[in] event_data_size the size of the event data; max is 4 bytes -## @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with -## higher priority than currently running task has been unblocked by the posted event; -## a context switch should be requested before the interrupt is existed. -## -## @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled -## @note when this function is called from an interrupt handler placed in IRAM, this function should -## be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR -## -## @return -## - ESP_OK: Success -## - ESP_FAIL: Event queue for the default event loop full -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id, -## data size of more than 4 bytes -## - Others: Fail -## -proc esp_event_isr_post*(event_base: esp_event_base_t; event_id: int32; - event_data: pointer; event_data_size: csize; - task_unblocked: ptr BaseType_t): esp_err_t {. - importc: "esp_event_isr_post", header: "esp_event.h".} -## * -## @brief Special variant of esp_event_post_to for posting events from interrupt handlers -## -## @param[in] event_loop the event loop to post to -## @param[in] event_base the event base that identifies the event -## @param[in] event_id the event id that identifies the event -## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler -## @param[in] event_data_size the size of the event data -## @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with -## higher priority than currently running task has been unblocked by the posted event; -## a context switch should be requested before the interrupt is existed. -## -## @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled -## @note when this function is called from an interrupt handler placed in IRAM, this function should -## be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR -## -## @return -## - ESP_OK: Success -## - ESP_FAIL: Event queue for the loop full -## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id, -## data size of more than 4 bytes -## - Others: Fail -## proc esp_event_isr_post_to*(event_loop: esp_event_loop_handle_t; event_base: esp_event_base_t; event_id: int32; event_data: pointer; event_data_size: csize; task_unblocked: ptr BaseType_t): esp_err_t {. - importc: "esp_event_isr_post_to", header: "esp_event.h".} -## * -## @brief Dumps statistics of all event loops. -## -## Dumps event loop info in the format: -## -## @verbatim -## event loop -## handler -## handler -## ... -## event loop -## handler -## handler -## ... -## -## where: -## -## event loop -## format: address,name rx:total_recieved dr:total_dropped -## where: -## address - memory address of the event loop -## name - name of the event loop, 'none' if no dedicated task -## total_recieved - number of successfully posted events -## total_dropped - number of events unsuccessfully posted due to queue being full -## -## handler -## format: address ev:base,id inv:total_invoked run:total_runtime -## where: -## address - address of the handler function -## base,id - the event specified by event base and id this handler executes -## total_invoked - number of times this handler has been invoked -## total_runtime - total amount of time used for invoking this handler -## -## @endverbatim -## -## @param[in] file the file stream to output to -## -## @note this function is a noop when CONFIG_ESP_EVENT_LOOP_PROFILING is disabled -## -## @return -## - ESP_OK: Success -## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list -## - Others: Fail -## + importc: "esp_event_isr_post_to", header: "esp_event.h".} ##| + ## * + ## @brief Special variant of esp_event_post for posting events from interrupt handlers. + ## + ## @param[in] event_base the event base that identifies the event + ## @param[in] event_id the event id that identifies the event + ## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler + ## @param[in] event_data_size the size of the event data; max is 4 bytes + ## @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with + ## higher priority than currently running task has been unblocked by the posted event; + ## a context switch should be requested before the interrupt is existed. + ## + ## @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled + ## @note when this function is called from an interrupt handler placed in IRAM, this function should + ## be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR + ## + ## @return + ## - ESP_OK: Success + ## - ESP_FAIL: Event queue for the default event loop full + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id, + ## data size of more than 4 bytes + ## - Others: Fail + ## + +proc esp_event_isr_post*(event_base: esp_event_base_t; event_id: int32; + event_data: pointer; event_data_size: csize; + task_unblocked: ptr BaseType_t): esp_err_t {. + importc: "esp_event_isr_post", header: "esp_event.h".} ##| + ## * + ## @brief Special variant of esp_event_post_to for posting events from interrupt handlers + ## + ## @param[in] event_loop the event loop to post to + ## @param[in] event_base the event base that identifies the event + ## @param[in] event_id the event id that identifies the event + ## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler + ## @param[in] event_data_size the size of the event data + ## @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with + ## higher priority than currently running task has been unblocked by the posted event; + ## a context switch should be requested before the interrupt is existed. + ## + ## @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled + ## @note when this function is called from an interrupt handler placed in IRAM, this function should + ## be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR + ## + ## @return + ## - ESP_OK: Success + ## - ESP_FAIL: Event queue for the loop full + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id, + ## data size of more than 4 bytes + ## - Others: Fail + ## + proc esp_event_dump*(file: ptr FILE): esp_err_t {.importc: "esp_event_dump", - header: "esp_event.h".} \ No newline at end of file + header: "esp_event.h".} ##\ + ## * + ## @brief Dumps statistics of all event loops. + ## + ## Dumps event loop info in the format: + ## + ## @verbatim + ## event loop + ## handler + ## handler + ## ... + ## event loop + ## handler + ## handler + ## ... + ## + ## where: + ## + ## event loop + ## format: address,name rx:total_recieved dr:total_dropped + ## where: + ## address - memory address of the event loop + ## name - name of the event loop, 'none' if no dedicated task + ## total_recieved - number of successfully posted events + ## total_dropped - number of events unsuccessfully posted due to queue being full + ## + ## handler + ## format: address ev:base,id inv:total_invoked run:total_runtime + ## where: + ## address - address of the handler function + ## base,id - the event specified by event base and id this handler executes + ## total_invoked - number of times this handler has been invoked + ## total_runtime - total amount of time used for invoking this handler + ## + ## @endverbatim + ## + ## @param[in] file the file stream to output to + ## + ## @note this function is a noop when CONFIG_ESP_EVENT_LOOP_PROFILING is disabled + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list + ## - Others: Fail + ## \ No newline at end of file From 3f444bab3c5dcc22b49941565fcb80397d58db72 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 21:38:52 -0600 Subject: [PATCH 105/142] update espevents --- src/nesper/esp/esp_event.nim | 936 ++++++++++++++++++----------------- 1 file changed, 477 insertions(+), 459 deletions(-) diff --git a/src/nesper/esp/esp_event.nim b/src/nesper/esp/esp_event.nim index 68970b7c..e5bd3099 100644 --- a/src/nesper/esp/esp_event.nim +++ b/src/nesper/esp/esp_event.nim @@ -1,16 +1,8 @@ -## Copyright 2018 Espressif Systems (Shanghai) PTE LTD ## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at +## SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD ## -## http://www.apache.org/licenses/LICENSE-2.0 +## SPDX-License-Identifier: Apache-2.0 ## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. import ../consts export consts @@ -37,487 +29,513 @@ type type esp_event_handler_instance_t* {.importc: "esp_event_handler_instance_t", header: "esp_event.h".} = object -## / Configuration for creating event loops - type - esp_event_loop_args_t* {.importc: "esp_event_loop_args_t", header: "esp_event.h", - bycopy.} = object - queue_size* {.importc: "queue_size".}: int32 ## *< size of the event loop queue - task_name* {.importc: "task_name".}: cstring ## *< name of the event loop task; if NULL, - ## a dedicated task is not created for event loop - task_priority* {.importc: "task_priority".}: UBaseType_t ## *< priority of the event loop task, ignored if task name is NULL - task_stack_size* {.importc: "task_stack_size".}: uint32 ## *< stack size of the event loop task, ignored if task name is NULL - task_core_id* {.importc: "task_core_id".}: BaseType_t ## *< core to which the event loop task is pinned to, - ## ignored if task name is NULL - -proc esp_event_loop_create*(event_loop_args: ptr esp_event_loop_args_t; - event_loop: ptr esp_event_loop_handle_t): esp_err_t {. - importc: "esp_event_loop_create", header: "esp_event.h".} ##| - ## * - ## @brief Create a new event loop. - ## - ## @param[in] event_loop_args configuration structure for the event loop to create - ## @param[out] event_loop handle to the created event loop - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list - ## - ESP_FAIL: Failed to create task loop - ## - Others: Fail - ## + esp_event_loop_args_t* {.importc: "esp_event_loop_args_t", + header: "esp_event.h", bycopy.} = object ## + ## Configuration for creating event loops + queue_size* {.importc: "queue_size".}: int32 ## < size of the event loop queue + task_name* {.importc: "task_name".}: cstring ## < name of the event loop task; if NULL, + ## a dedicated task is not created for event loop + task_priority* {.importc: "task_priority".}: UBaseType_t ## + ## < priority of the event loop task, ignored if task name is NULL + task_stack_size* {.importc: "task_stack_size".}: uint32 ## + ## < stack size of the event loop task, ignored if task name is NULL + task_core_id* {.importc: "task_core_id".}: BaseType_t + ## < core to which the event loop task is pinned to, + ## ignored if task name is NULL -proc esp_event_loop_delete*(event_loop: esp_event_loop_handle_t): esp_err_t {. - importc: "esp_event_loop_delete", header: "esp_event.h".} ##\ - ## * - ## @brief Delete an existing event loop. - ## - ## @param[in] event_loop event loop to delete - ## - ## @return - ## - ESP_OK: Success - ## - Others: Fail - ## -proc esp_event_loop_create_default*(): esp_err_t {. - importc: "esp_event_loop_create_default", header: "esp_event.h".} ##\ - ## * - ## @brief Create default event loop - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list - ## - ESP_FAIL: Failed to create task loop - ## - Others: Fail - ## -proc esp_event_loop_delete_default*(): esp_err_t {. - importc: "esp_event_loop_delete_default", header: "esp_event.h".} ##\ - ## * - ## @brief Delete the default event loop - ## - ## @return - ## - ESP_OK: Success - ## - Others: Fail - ## +proc esp_event_loop_create*(event_loop_args: ptr esp_event_loop_args_t; + event_loop: ptr esp_event_loop_handle_t): esp_err_t {. + cdecl, importc: "esp_event_loop_create", header: "esp_event.h".} + ## + ## + ## @brief Create a new event loop. + ## + ## @param[in] event_loop_args configuration structure for the event loop to create + ## @param[out] event_loop handle to the created event loop + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_INVALID_ARG: event_loop_args or event_loop was NULL + ## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list + ## - ESP_FAIL: Failed to create task loop + ## - Others: Fail + ## +proc esp_event_loop_delete*(event_loop: esp_event_loop_handle_t): esp_err_t {. + cdecl, importc: "esp_event_loop_delete", header: "esp_event.h".} + ## + ## + ## @brief Delete an existing event loop. + ## + ## @param[in] event_loop event loop to delete, must not be NULL + ## + ## @return + ## - ESP_OK: Success + ## - Others: Fail + ## + +proc esp_event_loop_create_default*(): esp_err_t {.cdecl, + importc: "esp_event_loop_create_default", header: "esp_event.h".} + ## + ## + ## @brief Create default event loop + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list + ## - ESP_ERR_INVALID_STATE: Default event loop has already been created + ## - ESP_FAIL: Failed to create task loop + ## - Others: Fail + ## + +proc esp_event_loop_delete_default*(): esp_err_t {.cdecl, + importc: "esp_event_loop_delete_default", header: "esp_event.h".} + ## + ## + ## @brief Delete the default event loop + ## + ## @return + ## - ESP_OK: Success + ## - Others: Fail + ## proc esp_event_loop_run*(event_loop: esp_event_loop_handle_t; - ticks_to_run: TickType_t): esp_err_t {. - importc: "esp_event_loop_run", header: "esp_event.h".} ##\ - ## * - ## @brief Dispatch events posted to an event loop. - ## - ## This function is used to dispatch events posted to a loop with no dedicated task, i.e task name was set to NULL - ## in event_loop_args argument during loop creation. This function includes an argument to limit the amount of time - ## it runs, returning control to the caller when that time expires (or some time afterwards). There is no guarantee - ## that a call to this function will exit at exactly the time of expiry. There is also no guarantee that events have - ## been dispatched during the call, as the function might have spent all of the alloted time waiting on the event queue. - ## Once an event has been unqueued, however, it is guaranteed to be dispatched. This guarantee contributes to not being - ## able to exit exactly at time of expiry as (1) blocking on internal mutexes is necessary for dispatching the unqueued - ## event, and (2) during dispatch of the unqueued event there is no way to control the time occupied by handler code - ## execution. The guaranteed time of exit is therefore the alloted time + amount of time required to dispatch - ## the last unqueued event. - ## - ## In cases where waiting on the queue times out, ESP_OK is returned and not ESP_ERR_TIMEOUT, since it is - ## normal behavior. - ## - ## @param[in] event_loop event loop to dispatch posted events from - ## @param[in] ticks_to_run number of ticks to run the loop - ## - ## @note encountering an unknown event that has been posted to the loop will only generate a warning, not an error. - ## - ## @return - ## - ESP_OK: Success - ## - Others: Fail - ## - ## * - ## @brief Register an event handler to the system event loop (legacy). - ## - ## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_register() - ## instead. - ## - ## This function can be used to register a handler for either: (1) specific events, - ## (2) all events of a certain event base, or (3) all events known by the system event loop. - ## - ## - specific events: specify exact event_base and event_id - ## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id - ## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id - ## - ## Registering multiple handlers to events is possible. Registering a single handler to multiple events is - ## also possible. However, registering the same handler to the same event multiple times would cause the - ## previous registrations to be overwritten. - ## - ## @param[in] event_base the base id of the event to register the handler for - ## @param[in] event_id the id of the event to register the handler for - ## @param[in] event_handler the handler function which gets called when the event is dispatched - ## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called - ## - ## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should - ## ensure that event_handler_arg still points to a valid location by the time the handler gets called - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler - ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id - ## - Others: Fail - ## - -# proc esp_event_handler_register*(event_base: esp_event_base_t; event_id: int32; -# event_handler: esp_event_handler_t; -# event_handler_arg: pointer): esp_err_t {. -# importc: "esp_event_handler_register", header: "esp_event.h".} - -proc esp_event_handler_register*( - event_base: esp_event_base_t; - event_id: cint; - event_handler: esp_event_handler_t; - event_handler_arg: pointer - ): esp_err_t {.importc: "esp_event_handler_register", header: "esp_event.h".} - + ticks_to_run: TickType_t): esp_err_t {.cdecl, + importc: "esp_event_loop_run", header: "esp_event.h".} + ## + ## + ## @brief Dispatch events posted to an event loop. + ## + ## This function is used to dispatch events posted to a loop with no dedicated task, i.e. task name was set to NULL + ## in event_loop_args argument during loop creation. This function includes an argument to limit the amount of time + ## it runs, returning control to the caller when that time expires (or some time afterwards). There is no guarantee + ## that a call to this function will exit at exactly the time of expiry. There is also no guarantee that events have + ## been dispatched during the call, as the function might have spent all the allotted time waiting on the event queue. + ## Once an event has been dequeued, however, it is guaranteed to be dispatched. This guarantee contributes to not being + ## able to exit exactly at time of expiry as (1) blocking on internal mutexes is necessary for dispatching the dequeued + ## event, and (2) during dispatch of the dequeued event there is no way to control the time occupied by handler code + ## execution. The guaranteed time of exit is therefore the allotted time + amount of time required to dispatch + ## the last dequeued event. + ## + ## In cases where waiting on the queue times out, ESP_OK is returned and not ESP_ERR_TIMEOUT, since it is + ## normal behavior. + ## + ## @param[in] event_loop event loop to dispatch posted events from, must not be NULL + ## @param[in] ticks_to_run number of ticks to run the loop + ## + ## @note encountering an unknown event that has been posted to the loop will only generate a warning, not an error. + ## + ## @return + ## - ESP_OK: Success + ## - Others: Fail + ## + +proc esp_event_handler_register*(event_base: esp_event_base_t; event_id: int32; + event_handler: esp_event_handler_t; + event_handler_arg: pointer): esp_err_t {.cdecl, + importc: "esp_event_handler_register", header: "esp_event.h".} + ## + ## + ## @brief Register an event handler to the system event loop (legacy). + ## + ## This function can be used to register a handler for either: (1) specific events, + ## (2) all events of a certain event base, or (3) all events known by the system event loop. + ## + ## - specific events: specify exact event_base and event_id + ## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id + ## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id + ## + ## Registering multiple handlers to events is possible. Registering a single handler to multiple events is + ## also possible. However, registering the same handler to the same event multiple times would cause the + ## overwriting of the event_handler_arg but the handler will be kept at the same position in the list associated + ## with the event that triggers it. It means that the call order of registered handlers for that event will remain + ## the same. + ## + ## @param[in] event_base the base ID of the event to register the handler for + ## @param[in] event_id the ID of the event to register the handler for + ## @param[in] event_handler the handler function which gets called when the event is dispatched + ## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called + ## + ## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should + ## ensure that event_handler_arg still points to a valid location by the time the handler gets called + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID + ## - Others: Fail + ## proc esp_event_handler_register_with*(event_loop: esp_event_loop_handle_t; - event_base: esp_event_base_t; - event_id: int32; - event_handler: esp_event_handler_t; - event_handler_arg: pointer): esp_err_t {. - importc: "esp_event_handler_register_with", header: "esp_event.h".} - ## * - ## @brief Register an event handler to a specific loop (legacy). - ## - ## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_register_with() - ## instead. - ## - ## This function behaves in the same manner as esp_event_handler_register, except the additional - ## specification of the event loop to register the handler to. - ## - ## @param[in] event_loop the event loop to register this handler function to - ## @param[in] event_base the base id of the event to register the handler for - ## @param[in] event_id the id of the event to register the handler for - ## @param[in] event_handler the handler function which gets called when the event is dispatched - ## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called - ## - ## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should - ## ensure that event_handler_arg still points to a valid location by the time the handler gets called - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler - ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id - ## - Others: Fail - ## - + event_base: esp_event_base_t; + event_id: int32; + event_handler: esp_event_handler_t; + event_handler_arg: pointer): esp_err_t {. + cdecl, importc: "esp_event_handler_register_with", header: "esp_event.h".} + ## + ## + ## @brief Register an event handler to a specific loop (legacy). + ## + ## This function behaves in the same manner as esp_event_handler_register, except the additional + ## specification of the event loop to register the handler to. + ## + ## @param[in] event_loop the event loop to register this handler function to, must not be NULL + ## @param[in] event_base the base ID of the event to register the handler for + ## @param[in] event_id the ID of the event to register the handler for + ## @param[in] event_handler the handler function which gets called when the event is dispatched + ## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called + ## + ## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should + ## ensure that event_handler_arg still points to a valid location by the time the handler gets called + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID + ## - Others: Fail + ## proc esp_event_handler_instance_register_with*( event_loop: esp_event_loop_handle_t; event_base: esp_event_base_t; event_id: int32; event_handler: esp_event_handler_t; event_handler_arg: pointer; instance: ptr esp_event_handler_instance_t): esp_err_t {. - importc: "esp_event_handler_instance_register_with", header: "esp_event.h".} ##\ - ## - ## This function can be used to register a handler for either: (1) specific events, - ## (2) all events of a certain event base, or (3) all events known by the system event loop. - ## - ## - specific events: specify exact event_base and event_id - ## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id - ## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id - ## - ## Besides the error, the function returns an instance object as output parameter to identify each registration. - ## This is necessary to remove (unregister) the registration before the event loop is deleted. - ## - ## Registering multiple handlers to events, registering a single handler to multiple events as well as registering - ## the same handler to the same event multiple times is possible. - ## Each registration yields a distinct instance object which identifies it over the registration - ## lifetime. - ## - ## @param[in] event_loop the event loop to register this handler function to - ## @param[in] event_base the base id of the event to register the handler for - ## @param[in] event_id the id of the event to register the handler for - ## @param[in] event_handler the handler function which gets called when the event is dispatched - ## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called - ## @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL. - ## This needs to be kept if the specific callback instance should be unregistered before deleting the whole - ## event loop. Registering the same event handler multiple times is possible and yields distinct instance - ## objects. The data can be the same for all registrations. - ## If no unregistration is needed but the handler should be deleted when the event loop is deleted, - ## instance can be NULL. - ## - ## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should - ## ensure that event_handler_arg still points to a valid location by the time the handler gets called - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler - ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id or instance is NULL - ## - Others: Fail - ## + cdecl, importc: "esp_event_handler_instance_register_with", + header: "esp_event.h".} + ## + ## @brief Register an instance of event handler to a specific loop. + ## + ## This function can be used to register a handler for either: (1) specific events, + ## (2) all events of a certain event base, or (3) all events known by the system event loop. + ## + ## - specific events: specify exact event_base and event_id + ## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id + ## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id + ## + ## Besides the error, the function returns an instance object as output parameter to identify each registration. + ## This is necessary to remove (unregister) the registration before the event loop is deleted. + ## + ## Registering multiple handlers to events, registering a single handler to multiple events as well as registering + ## the same handler to the same event multiple times is possible. + ## Each registration yields a distinct instance object which identifies it over the registration + ## lifetime. + ## + ## @param[in] event_loop the event loop to register this handler function to, must not be NULL + ## @param[in] event_base the base ID of the event to register the handler for + ## @param[in] event_id the ID of the event to register the handler for + ## @param[in] event_handler the handler function which gets called when the event is dispatched + ## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called + ## @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL. + ## This needs to be kept if the specific callback instance should be unregistered before deleting the whole + ## event loop. Registering the same event handler multiple times is possible and yields distinct instance + ## objects. The data can be the same for all registrations. + ## If no unregistration is needed, but the handler should be deleted when the event loop is deleted, + ## instance can be NULL. + ## + ## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should + ## ensure that event_handler_arg still points to a valid location by the time the handler gets called + ## + ## @note Calling this function with instance set to NULL is equivalent to calling esp_event_handler_register_with. + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID or instance is NULL + ## - Others: Fail + ## proc esp_event_handler_instance_register*(event_base: esp_event_base_t; event_id: int32; event_handler: esp_event_handler_t; event_handler_arg: pointer; instance: ptr esp_event_handler_instance_t): esp_err_t {. - importc: "esp_event_handler_instance_register", header: "esp_event.h".} - - -proc esp_event_handler_unregister*( - event_base: esp_event_base_t; - event_id: int32; - event_handler: esp_event_handler_t - ): esp_err_t {.importc: "esp_event_handler_unregister", header: "esp_event.h".} ##| - ## * - ## @brief Unregister a handler with the system event loop (legacy). - ## - ## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_unregister() - ## instead. - ## - ## This function can be used to unregister a handler so that it no longer gets called during dispatch. - ## Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base, - ## or (3) all events known by the system event loop - ## - ## - specific events: specify exact event_base and event_id - ## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id - ## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id - ## - ## This function ignores unregistration of handlers that has not been previously registered. - ## - ## @param[in] event_base the base of the event with which to unregister the handler - ## @param[in] event_id the id of the event with which to unregister the handler - ## @param[in] event_handler the handler to unregister - ## - ## @return ESP_OK success - ## @return ESP_ERR_INVALID_ARG invalid combination of event base and event id - ## @return others fail - ## - + cdecl, importc: "esp_event_handler_instance_register", header: "esp_event.h".} + ## + ## + ## @brief Register an instance of event handler to the default loop. + ## + ## This function does the same as esp_event_handler_instance_register_with, except that it registers the + ## handler to the default event loop. + ## + ## @param[in] event_base the base ID of the event to register the handler for + ## @param[in] event_id the ID of the event to register the handler for + ## @param[in] event_handler the handler function which gets called when the event is dispatched + ## @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called + ## @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL. + ## This needs to be kept if the specific callback instance should be unregistered before deleting the whole + ## event loop. Registering the same event handler multiple times is possible and yields distinct instance + ## objects. The data can be the same for all registrations. + ## If no unregistration is needed, but the handler should be deleted when the event loop is deleted, + ## instance can be NULL. + ## + ## @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should + ## ensure that event_handler_arg still points to a valid location by the time the handler gets called + ## + ## @note Calling this function with instance set to NULL is equivalent to calling esp_event_handler_register. + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for the handler + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID or instance is NULL + ## - Others: Fail + ## + +proc esp_event_handler_unregister*(event_base: esp_event_base_t; + event_id: int32; + event_handler: esp_event_handler_t): esp_err_t {. + cdecl, importc: "esp_event_handler_unregister", header: "esp_event.h".} + ## + ## + ## @brief Unregister a handler with the system event loop (legacy). + ## + ## Unregisters a handler, so it will no longer be called during dispatch. + ## Handlers can be unregistered for any combination of event_base and event_id which were previously registered. + ## To unregister a handler, the event_base and event_id arguments must match exactly the arguments passed to + ## esp_event_handler_register() when that handler was registered. Passing ESP_EVENT_ANY_BASE and/or ESP_EVENT_ANY_ID + ## will only unregister handlers that were registered with the same wildcard arguments. + ## + ## @note When using ESP_EVENT_ANY_ID, handlers registered to specific event IDs using the same base will not be + ## unregistered. When using ESP_EVENT_ANY_BASE, events registered to specific bases will also not be + ## unregistered. This avoids accidental unregistration of handlers registered by other users or components. + ## + ## @param[in] event_base the base of the event with which to unregister the handler + ## @param[in] event_id the ID of the event with which to unregister the handler + ## @param[in] event_handler the handler to unregister + ## + ## @return ESP_OK success + ## @return ESP_ERR_INVALID_ARG invalid combination of event base and event ID + ## @return others fail + ## proc esp_event_handler_unregister_with*(event_loop: esp_event_loop_handle_t; - event_base: esp_event_base_t; - event_id: int32; - event_handler: esp_event_handler_t): esp_err_t {. - importc: "esp_event_handler_unregister_with", header: "esp_event.h".} - ## * - ## @brief Unregister a handler from a specific event loop (legacy). - ## - ## @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_unregister_with() - ## instead. - ## - ## This function behaves in the same manner as esp_event_handler_unregister, except the additional specification of - ## the event loop to unregister the handler with. - ## - ## @param[in] event_loop the event loop with which to unregister this handler function - ## @param[in] event_base the base of the event with which to unregister the handler - ## @param[in] event_id the id of the event with which to unregister the handler - ## @param[in] event_handler the handler to unregister - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id - ## - Others: Fail - ## - + event_base: esp_event_base_t; + event_id: int32; + event_handler: esp_event_handler_t): esp_err_t {. + cdecl, importc: "esp_event_handler_unregister_with", header: "esp_event.h".} + ## + ## + ## @brief Unregister a handler from a specific event loop (legacy). + ## + ## This function behaves in the same manner as esp_event_handler_unregister, except the additional specification of + ## the event loop to unregister the handler with. + ## + ## @param[in] event_loop the event loop with which to unregister this handler function, must not be NULL + ## @param[in] event_base the base of the event with which to unregister the handler + ## @param[in] event_id the ID of the event with which to unregister the handler + ## @param[in] event_handler the handler to unregister + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID + ## - Others: Fail + ## proc esp_event_handler_instance_unregister_with*( event_loop: esp_event_loop_handle_t; event_base: esp_event_base_t; - event_id: int32; instance: esp_event_handler_instance_t): esp_err_t {. - importc: "esp_event_handler_instance_unregister_with", header: "esp_event.h".} ##| - ## * - ## @brief Unregister a handler instance from a specific event loop. - ## - ## This function can be used to unregister a handler so that it no longer gets called during dispatch. - ## Handlers can be unregistered for either: (1) specific events, (2) all events of a certain event base, - ## or (3) all events known by the system event loop - ## - ## - specific events: specify exact event_base and event_id - ## - all events of a certain base: specify exact event_base and use ESP_EVENT_ANY_ID as the event_id - ## - all events known by the loop: use ESP_EVENT_ANY_BASE for event_base and ESP_EVENT_ANY_ID as the event_id - ## - ## This function ignores unregistration of handler instances that have not been previously registered. - ## - ## @param[in] event_loop the event loop with which to unregister this handler function - ## @param[in] event_base the base of the event with which to unregister the handler - ## @param[in] event_id the id of the event with which to unregister the handler - ## @param[in] instance the instance object of the registration to be unregistered - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id - ## - Others: Fail - ## - + event_id: int32; instance: esp_event_handler_instance_t): esp_err_t {.cdecl, + importc: "esp_event_handler_instance_unregister_with", header: "esp_event.h".} + ## + ## + ## @brief Unregister a handler instance from a specific event loop. + ## + ## Unregisters a handler instance, so it will no longer be called during dispatch. + ## Handler instances can be unregistered for any combination of event_base and event_id which were previously + ## registered. To unregister a handler instance, the event_base and event_id arguments must match exactly the + ## arguments passed to esp_event_handler_instance_register() when that handler instance was registered. + ## Passing ESP_EVENT_ANY_BASE and/or ESP_EVENT_ANY_ID will only unregister handler instances that were registered + ## with the same wildcard arguments. + ## + ## @note When using ESP_EVENT_ANY_ID, handlers registered to specific event IDs using the same base will not be + ## unregistered. When using ESP_EVENT_ANY_BASE, events registered to specific bases will also not be + ## unregistered. This avoids accidental unregistration of handlers registered by other users or components. + ## + ## @param[in] event_loop the event loop with which to unregister this handler function, must not be NULL + ## @param[in] event_base the base of the event with which to unregister the handler + ## @param[in] event_id the ID of the event with which to unregister the handler + ## @param[in] instance the instance object of the registration to be unregistered + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID + ## - Others: Fail + ## proc esp_event_handler_instance_unregister*(event_base: esp_event_base_t; - event_id: int32; instance: esp_event_handler_instance_t): esp_err_t {. - importc: "esp_event_handler_instance_unregister", header: "esp_event.h".} ##| - ## * - ## @brief Unregister a handler from the system event loop. - ## - ## This function does the same as esp_event_handler_instance_unregister_with, except that it unregisters the - ## handler instance from the default event loop. - ## - ## @param[in] event_base the base of the event with which to unregister the handler - ## @param[in] event_id the id of the event with which to unregister the handler - ## @param[in] instance the instance object of the registration to be unregistered - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id - ## - Others: Fail - ## - - + event_id: int32; instance: esp_event_handler_instance_t): esp_err_t {.cdecl, + importc: "esp_event_handler_instance_unregister", header: "esp_event.h".} + ## + ## + ## @brief Unregister a handler from the system event loop. + ## + ## This function does the same as esp_event_handler_instance_unregister_with, except that it unregisters the + ## handler instance from the default event loop. + ## + ## @param[in] event_base the base of the event with which to unregister the handler + ## @param[in] event_id the ID of the event with which to unregister the handler + ## @param[in] instance the instance object of the registration to be unregistered + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID + ## - Others: Fail + ## proc esp_event_post*(event_base: esp_event_base_t; event_id: int32; - event_data: pointer; event_data_size: csize; - ticks_to_wait: TickType_t): esp_err_t {. - importc: "esp_event_post", header: "esp_event.h".} ##| - ## * - ## @brief Posts an event to the system default event loop. The event loop library keeps a copy of event_data and manages - ## the copy's lifetime automatically (allocation + deletion); this ensures that the data the - ## handler recieves is always valid. - ## - ## @param[in] event_base the event base that identifies the event - ## @param[in] event_id the event id that identifies the event - ## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler - ## @param[in] event_data_size the size of the event data - ## @param[in] ticks_to_wait number of ticks to block on a full event queue - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired, - ## queue full when posting from ISR - ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id - ## - Others: Fail - ## - - + event_data: pointer; event_data_size: csize_t; + ticks_to_wait: TickType_t): esp_err_t {.cdecl, + importc: "esp_event_post", header: "esp_event.h".} + ## + ## + ## @brief Posts an event to the system default event loop. The event loop library keeps a copy of event_data and manages + ## the copy's lifetime automatically (allocation + deletion); this ensures that the data the + ## handler receives is always valid. + ## + ## @param[in] event_base the event base that identifies the event + ## @param[in] event_id the event ID that identifies the event + ## @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler + ## @param[in] event_data_size the size of the event data + ## @param[in] ticks_to_wait number of ticks to block on a full event queue + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired, + ## queue full when posting from ISR + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID + ## - Others: Fail + ## proc esp_event_post_to*(event_loop: esp_event_loop_handle_t; - event_base: esp_event_base_t; event_id: int32; - event_data: pointer; event_data_size: csize_t; - ticks_to_wait: TickType_t): esp_err_t {. - importc: "esp_event_post_to", header: "esp_event.h".} ##\ - ## * - ## @brief Posts an event to the specified event loop. The event loop library keeps a copy of event_data and manages - ## the copy's lifetime automatically (allocation + deletion); this ensures that the data the - ## handler recieves is always valid. - ## - ## This function behaves in the same manner as esp_event_post_to, except the additional specification of the event loop - ## to post the event to. - ## - ## @param[in] event_loop the event loop to post to - ## @param[in] event_base the event base that identifies the event - ## @param[in] event_id the event id that identifies the event - ## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler - ## @param[in] event_data_size the size of the event data - ## @param[in] ticks_to_wait number of ticks to block on a full event queue - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired, - ## queue full when posting from ISR - ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id - ## - Others: Fail - ## + event_base: esp_event_base_t; event_id: int32; + event_data: pointer; event_data_size: csize_t; + ticks_to_wait: TickType_t): esp_err_t {.cdecl, + importc: "esp_event_post_to", header: "esp_event.h".} + ## + ## + ## @brief Posts an event to the specified event loop. The event loop library keeps a copy of event_data and manages + ## the copy's lifetime automatically (allocation + deletion); this ensures that the data the + ## handler receives is always valid. + ## + ## This function behaves in the same manner as esp_event_post, except the additional specification of the event loop + ## to post the event to. + ## + ## @param[in] event_loop the event loop to post to, must not be NULL + ## @param[in] event_base the event base that identifies the event + ## @param[in] event_id the event ID that identifies the event + ## @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler + ## @param[in] event_data_size the size of the event data + ## @param[in] ticks_to_wait number of ticks to block on a full event queue + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired, + ## queue full when posting from ISR + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID + ## - Others: Fail + ## +proc esp_event_isr_post*(event_base: esp_event_base_t; event_id: int32; + event_data: pointer; event_data_size: csize_t; + task_unblocked: ptr BaseType_t): esp_err_t {.cdecl, + importc: "esp_event_isr_post", header: "esp_event.h".} + ## + ## + ## @brief Special variant of esp_event_post for posting events from interrupt handlers. + ## + ## @param[in] event_base the event base that identifies the event + ## @param[in] event_id the event ID that identifies the event + ## @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler + ## @param[in] event_data_size the size of the event data; max is 4 bytes + ## @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with + ## higher priority than currently running task has been unblocked by the posted event; + ## a context switch should be requested before the interrupt is existed. + ## + ## @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled + ## @note when this function is called from an interrupt handler placed in IRAM, this function should + ## be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR + ## + ## @return + ## - ESP_OK: Success + ## - ESP_FAIL: Event queue for the default event loop full + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID, + ## data size of more than 4 bytes + ## - Others: Fail + ## proc esp_event_isr_post_to*(event_loop: esp_event_loop_handle_t; event_base: esp_event_base_t; event_id: int32; - event_data: pointer; event_data_size: csize; + event_data: pointer; event_data_size: csize_t; task_unblocked: ptr BaseType_t): esp_err_t {. - importc: "esp_event_isr_post_to", header: "esp_event.h".} ##| - ## * - ## @brief Special variant of esp_event_post for posting events from interrupt handlers. - ## - ## @param[in] event_base the event base that identifies the event - ## @param[in] event_id the event id that identifies the event - ## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler - ## @param[in] event_data_size the size of the event data; max is 4 bytes - ## @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with - ## higher priority than currently running task has been unblocked by the posted event; - ## a context switch should be requested before the interrupt is existed. - ## - ## @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled - ## @note when this function is called from an interrupt handler placed in IRAM, this function should - ## be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR - ## - ## @return - ## - ESP_OK: Success - ## - ESP_FAIL: Event queue for the default event loop full - ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id, - ## data size of more than 4 bytes - ## - Others: Fail - ## - -proc esp_event_isr_post*(event_base: esp_event_base_t; event_id: int32; - event_data: pointer; event_data_size: csize; - task_unblocked: ptr BaseType_t): esp_err_t {. - importc: "esp_event_isr_post", header: "esp_event.h".} ##| - ## * - ## @brief Special variant of esp_event_post_to for posting events from interrupt handlers - ## - ## @param[in] event_loop the event loop to post to - ## @param[in] event_base the event base that identifies the event - ## @param[in] event_id the event id that identifies the event - ## @param[in] event_data the data, specific to the event occurence, that gets passed to the handler - ## @param[in] event_data_size the size of the event data - ## @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with - ## higher priority than currently running task has been unblocked by the posted event; - ## a context switch should be requested before the interrupt is existed. - ## - ## @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled - ## @note when this function is called from an interrupt handler placed in IRAM, this function should - ## be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR - ## - ## @return - ## - ESP_OK: Success - ## - ESP_FAIL: Event queue for the loop full - ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id, - ## data size of more than 4 bytes - ## - Others: Fail - ## - - -proc esp_event_dump*(file: ptr FILE): esp_err_t {.importc: "esp_event_dump", - header: "esp_event.h".} ##\ - ## * - ## @brief Dumps statistics of all event loops. - ## - ## Dumps event loop info in the format: - ## - ## @verbatim - ## event loop - ## handler - ## handler - ## ... - ## event loop - ## handler - ## handler - ## ... - ## - ## where: - ## - ## event loop - ## format: address,name rx:total_recieved dr:total_dropped - ## where: - ## address - memory address of the event loop - ## name - name of the event loop, 'none' if no dedicated task - ## total_recieved - number of successfully posted events - ## total_dropped - number of events unsuccessfully posted due to queue being full - ## - ## handler - ## format: address ev:base,id inv:total_invoked run:total_runtime - ## where: - ## address - address of the handler function - ## base,id - the event specified by event base and id this handler executes - ## total_invoked - number of times this handler has been invoked - ## total_runtime - total amount of time used for invoking this handler - ## - ## @endverbatim - ## - ## @param[in] file the file stream to output to - ## - ## @note this function is a noop when CONFIG_ESP_EVENT_LOOP_PROFILING is disabled - ## - ## @return - ## - ESP_OK: Success - ## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list - ## - Others: Fail - ## \ No newline at end of file + cdecl, importc: "esp_event_isr_post_to", header: "esp_event.h".} + ## + ## + ## @brief Special variant of esp_event_post_to for posting events from interrupt handlers + ## + ## @param[in] event_loop the event loop to post to, must not be NULL + ## @param[in] event_base the event base that identifies the event + ## @param[in] event_id the event ID that identifies the event + ## @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler + ## @param[in] event_data_size the size of the event data + ## @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with + ## higher priority than currently running task has been unblocked by the posted event; + ## a context switch should be requested before the interrupt is existed. + ## + ## @note this function is only available when CONFIG_ESP_EVENT_POST_FROM_ISR is enabled + ## @note when this function is called from an interrupt handler placed in IRAM, this function should + ## be placed in IRAM as well by enabling CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR + ## + ## @return + ## - ESP_OK: Success + ## - ESP_FAIL: Event queue for the loop full + ## - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID, + ## data size of more than 4 bytes + ## - Others: Fail + ## + +proc esp_event_dump*(file: ptr FILE): esp_err_t {.cdecl, + importc: "esp_event_dump", header: "esp_event.h".} + ## + ## + ## @brief Dumps statistics of all event loops. + ## + ## Dumps event loop info in the format: + ## + ## @verbatim + ## event loop + ## handler + ## handler + ## ... + ## event loop + ## handler + ## handler + ## ... + ## + ## where: + ## + ## event loop + ## format: address,name rx:total_received dr:total_dropped + ## where: + ## address - memory address of the event loop + ## name - name of the event loop, 'none' if no dedicated task + ## total_received - number of successfully posted events + ## total_dropped - number of events unsuccessfully posted due to queue being full + ## + ## handler + ## format: address ev:base,id inv:total_invoked run:total_runtime + ## where: + ## address - address of the handler function + ## base,id - the event specified by event base and ID this handler executes + ## total_invoked - number of times this handler has been invoked + ## total_runtime - total amount of time used for invoking this handler + ## + ## @endverbatim + ## + ## @param[in] file the file stream to output to + ## + ## @note this function is a noop when CONFIG_ESP_EVENT_LOOP_PROFILING is disabled + ## + ## @return + ## - ESP_OK: Success + ## - ESP_ERR_NO_MEM: Cannot allocate memory for event loops list + ## - Others: Fail + ## \ No newline at end of file From fd8bc33a1c97016254e90f1286a173683805228b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 21:38:59 -0600 Subject: [PATCH 106/142] updates --- esp-idf-examples/simplewifi/config.nims | 9 ++------- .../simplewifi/main/{wifi_example_main.nim => main.nim} | 3 ++- 2 files changed, 4 insertions(+), 8 deletions(-) rename esp-idf-examples/simplewifi/main/{wifi_example_main.nim => main.nim} (97%) diff --git a/esp-idf-examples/simplewifi/config.nims b/esp-idf-examples/simplewifi/config.nims index 926fbaa5..94d6132b 100644 --- a/esp-idf-examples/simplewifi/config.nims +++ b/esp-idf-examples/simplewifi/config.nims @@ -2,18 +2,13 @@ switch("define", "ESP_IDF_VERSION=5.5") switch("define", "esp32s3") # or other variants switch("define", "nimNetSocketExtras") switch("define", "nimIoselectorEventfd") -# switch("define", "TcpEchoServer") -# switch("define", "UdpEchoServer") -switch("define", "FastRpcServer") switch("define", "McuUtilsLoggingLevel:lvlTrace") -# switch("define", "RUN_NCM") -patchFile("stdlib", "cpuinfo", "main/cpuinfo.nim") patchFile("stdlib", "ioselectors_select", "main/ioselectors_select.nim") -switch("define", "WIFI_SSID", getEnv("WIFI_SSID")) -switch("define", "WIFI_PASSWORD", getEnv("WIFI_PASSWORD")) +switch("define", "WIFI_SSID=" & getEnv("WIFI_SSID")) +switch("define", "WIFI_PASSWORD=" & getEnv("WIFI_PASSWORD")) include nesper/build_utils/builds diff --git a/esp-idf-examples/simplewifi/main/wifi_example_main.nim b/esp-idf-examples/simplewifi/main/main.nim similarity index 97% rename from esp-idf-examples/simplewifi/main/wifi_example_main.nim rename to esp-idf-examples/simplewifi/main/main.nim index 014916b2..8e9a3c0b 100644 --- a/esp-idf-examples/simplewifi/main/wifi_example_main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -46,7 +46,8 @@ proc wifiStart*() = discard esp_wifi_init(unsafeAddr(wcfg)) - WIFI_EVENT_STA_DISCONNECTED.eventRegister(onWifiDisconnect, nil) + let disEv: esp_event_handler_t = onWifiDisconnect + WIFI_EVENT_STA_DISCONNECTED.eventRegister(disEv, nil) IP_EVENT_STA_GOT_IP.eventRegister(ipReceivedHandler, nil) check: esp_wifi_set_storage(WIFI_STORAGE_RAM) From 93f3564b87613a78368447c9dcbcf7b3604b643f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 21:52:43 -0600 Subject: [PATCH 107/142] updates --- src/nesper/events.nim | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/nesper/events.nim b/src/nesper/events.nim index d4c5cbdb..29ebc4f4 100644 --- a/src/nesper/events.nim +++ b/src/nesper/events.nim @@ -21,10 +21,18 @@ type EventError* = object of OSError code*: esp_err_t -template eventRegister*[EVT]( +type + ## *< a number that identifies an event with respect to a base + EventHandlerCb[T]* = proc (event_handler_arg: T; + event_base: esp_event_base_t; + event_id: int32; + event_data: pointer) {.cdecl.} + +template eventRegister*[EVT; T: ptr]( evt_id: EVT; - evt_handler: esp_event_handler_t; - evt_handler_arg: pointer = nil, + evt_handler: EventHandlerCb[T]; + evt_handler_arg: T = nil, + handler_instance: ptr esp_event_handler_instance_t = nil ) = ## Register event with the default event loop. Understand WIFI & IP Events @@ -39,27 +47,30 @@ template eventRegister*[EVT]( {.fatal: "Uknown event type, don't know how to unregister automatically".} let ret = - esp_event_handler_register( + esp_event_handler_instance_register( event_base = evt_base, - event_id = cint(evt_id), + event_id = int32(evt_id), event_handler = evt_handler, - event_handler_arg = evt_handler_arg) + event_handler_arg = evt_handler_arg, + handler_instance = handler_instance) if ret != ESP_OK: raise newEspError[EventError]("register: " & $esp_err_to_name(ret), ret) -template eventRegister*[EVT]( +template eventRegister*[EVT; T: ptr]( event_base: esp_event_base_t; event_id: EVT; - event_handler: esp_event_handler_t; - event_handler_arg: pointer = nil + event_handler: EventHandlerCb[T]; + event_handler_arg: T = nil, + handler_instance: ptr esp_event_handler_instance_t = nil ) = ## Register event for an event base on the default loop. - let ret = esp_event_handler_register( + let ret = esp_event_handler_instance_register( event_base, event_id.cint, event_handler, - event_handler_arg) + event_handler_arg, + handler_instance) if ret != ESP_OK: raise newEspError[EventError]("register: " & $esp_err_to_name(ret), ret) @@ -74,7 +85,7 @@ template eventRegisterWith*[EVT, TP]( ## Register event with a given event loop. let ret = esp_event_handler_register_with( event_loop, - event_base, cint(event_id), + event_base, int32(event_id), cast[esp_event_handler_t](event_handler), event_handler_arg) if ret != ESP_OK: @@ -89,7 +100,7 @@ template eventPost*[EVT]( ticks_to_wait: TickType_t = 1000 ) = ## Register event with a given event loop. - let ret = esp_event_post_to(evt_loop, evt_base, cint(evt_id), evt_data, csize_t(evt_data_size), ticks_to_wait) + let ret = esp_event_post_to(evt_loop, evt_base, int32(evt_id), evt_data, csize_t(evt_data_size), ticks_to_wait) if ret != ESP_OK: raise newEspError[EventError]("post: " & $esp_err_to_name(ret), ret) @@ -128,7 +139,7 @@ template eventUnregister*[EVT]( let ret = esp_event_handler_unregister( event_base = evt_base, - event_id = cint(evt_id), + event_id = int32(evt_id), event_handler = evt_handler) if ret != ESP_OK: @@ -144,7 +155,7 @@ template eventUnregister*( let ret = esp_event_handler_unregister( event_base = evt_base, event_base = IP_EVENT, - event_id = cint(evt_id), + event_id = int32(evt_id), event_handler = evt_handler) if ret != ESP_OK: From c2b33b7e53f356fd03fb2d7e22787b8a58d7725d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 21:53:07 -0600 Subject: [PATCH 108/142] updates --- src/nesper/events.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nesper/events.nim b/src/nesper/events.nim index 29ebc4f4..9588c719 100644 --- a/src/nesper/events.nim +++ b/src/nesper/events.nim @@ -23,7 +23,7 @@ type type ## *< a number that identifies an event with respect to a base - EventHandlerCb[T]* = proc (event_handler_arg: T; + EventHandlerCb*[T] = proc (event_handler_arg: T; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} From cd38f55ff25a66e5d840b6de7d49929e06f138a2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 22:01:18 -0600 Subject: [PATCH 109/142] updates --- esp-idf-examples/simplewifi/main/main.nim | 12 ++++++------ src/nesper/events.nim | 16 +++++++++------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/esp-idf-examples/simplewifi/main/main.nim b/esp-idf-examples/simplewifi/main/main.nim index 8e9a3c0b..eccee816 100644 --- a/esp-idf-examples/simplewifi/main/main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -23,8 +23,8 @@ var sConnectEventGroup*: EventGroupHandle_t var sIpAddr*: IpAddress var sConnectionName*: cstring -proc ipReceivedHandler*(arg: esp_event_base_t; event_base: esp_event_base_t; event_id: int32; - event_data: pointer) {.cdecl.} = +proc ipReceivedHandler*(arg: pointer; event_base: esp_event_base_t; event_id: int32; + event_data: pointer) {.cdecl.} = var event: ptr ip_event_got_ip_t = cast[ptr ip_event_got_ip_t](event_data) logi TAG, "event.ip_info.ip: %s", $(event.ip_info.ip) @@ -33,7 +33,7 @@ proc ipReceivedHandler*(arg: esp_event_base_t; event_base: esp_event_base_t; eve logw TAG, "got event ip: %s", $sIpAddr discard xEventGroupSetBits(sConnectEventGroup, GOT_IPV4_BIT) -proc onWifiDisconnect*(arg: esp_event_base_t; +proc onWifiDisconnect*(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = @@ -46,9 +46,9 @@ proc wifiStart*() = discard esp_wifi_init(unsafeAddr(wcfg)) - let disEv: esp_event_handler_t = onWifiDisconnect - WIFI_EVENT_STA_DISCONNECTED.eventRegister(disEv, nil) - IP_EVENT_STA_GOT_IP.eventRegister(ipReceivedHandler, nil) + let evDis: EventHandlerCb[pointer] = onWifiDisconnect + eventRegister(WIFI_EVENT_STA_DISCONNECTED, evDis) + eventRegister(IP_EVENT_STA_GOT_IP, ipReceivedHandler) check: esp_wifi_set_storage(WIFI_STORAGE_RAM) diff --git a/src/nesper/events.nim b/src/nesper/events.nim index 9588c719..193f6361 100644 --- a/src/nesper/events.nim +++ b/src/nesper/events.nim @@ -24,11 +24,11 @@ type type ## *< a number that identifies an event with respect to a base EventHandlerCb*[T] = proc (event_handler_arg: T; - event_base: esp_event_base_t; - event_id: int32; - event_data: pointer) {.cdecl.} + event_base: esp_event_base_t; + event_id: int32; + event_data: pointer) {.cdecl.} -template eventRegister*[EVT; T: ptr]( +template eventRegister*[EVT; T: pointer]( evt_id: EVT; evt_handler: EventHandlerCb[T]; evt_handler_arg: T = nil, @@ -46,18 +46,19 @@ template eventRegister*[EVT; T: ptr]( else: {.fatal: "Uknown event type, don't know how to unregister automatically".} + let handler: esp_event_handler_t = cast[esp_event_handler_t](evt_handler) let ret = esp_event_handler_instance_register( event_base = evt_base, event_id = int32(evt_id), - event_handler = evt_handler, + event_handler = handler, event_handler_arg = evt_handler_arg, handler_instance = handler_instance) if ret != ESP_OK: raise newEspError[EventError]("register: " & $esp_err_to_name(ret), ret) -template eventRegister*[EVT; T: ptr]( +template eventRegister*[EVT; T: pointer]( event_base: esp_event_base_t; event_id: EVT; event_handler: EventHandlerCb[T]; @@ -65,10 +66,11 @@ template eventRegister*[EVT; T: ptr]( handler_instance: ptr esp_event_handler_instance_t = nil ) = ## Register event for an event base on the default loop. + let handler: esp_event_handler_t = cast[esp_event_handler_t](event_handler) let ret = esp_event_handler_instance_register( event_base, event_id.cint, - event_handler, + handler, event_handler_arg, handler_instance) From 8035992caf7215bda7538c2f8b575c15b04947b8 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 22:23:39 -0600 Subject: [PATCH 110/142] updating wifi example --- esp-idf-examples/simplewifi/main/config.nims | 14 + esp-idf-examples/simplewifi/main/main.nim | 5 +- esp-idf-examples/simplewifi/sdkconfig | 2129 +++++++++++++++--- src/nesper/esp/esp_event.nim | 9 +- src/nesper/events.nim | 65 +- 5 files changed, 1911 insertions(+), 311 deletions(-) create mode 100644 esp-idf-examples/simplewifi/main/config.nims diff --git a/esp-idf-examples/simplewifi/main/config.nims b/esp-idf-examples/simplewifi/main/config.nims new file mode 100644 index 00000000..3259fd64 --- /dev/null +++ b/esp-idf-examples/simplewifi/main/config.nims @@ -0,0 +1,14 @@ +--nomain +--compileOnly +--define:debug +--define:NimAppMain +--nimcache:nimcache + +--gc:arc +--os:freertos +--cpu:arm +--define:useMalloc +--define:noSignalHandler +# --debugger:native +--threads:on +--tls_emulation:off diff --git a/esp-idf-examples/simplewifi/main/main.nim b/esp-idf-examples/simplewifi/main/main.nim index eccee816..4a8f8910 100644 --- a/esp-idf-examples/simplewifi/main/main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -46,9 +46,8 @@ proc wifiStart*() = discard esp_wifi_init(unsafeAddr(wcfg)) - let evDis: EventHandlerCb[pointer] = onWifiDisconnect - eventRegister(WIFI_EVENT_STA_DISCONNECTED, evDis) - eventRegister(IP_EVENT_STA_GOT_IP, ipReceivedHandler) + eventRegister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, onWifiDisconnect, nil) + eventRegister(IP_EVENT, IP_EVENT_STA_GOT_IP, ipReceivedHandler) check: esp_wifi_set_storage(WIFI_STORAGE_RAM) diff --git a/esp-idf-examples/simplewifi/sdkconfig b/esp-idf-examples/simplewifi/sdkconfig index 454ebcab..7b29707d 100644 --- a/esp-idf-examples/simplewifi/sdkconfig +++ b/esp-idf-examples/simplewifi/sdkconfig @@ -1,19 +1,310 @@ # # Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# Espressif IoT Development Framework (ESP-IDF) 5.5.0 Project Configuration # -CONFIG_IDF_TARGET_ESP32=y +CONFIG_SOC_CAPS_ECO_VER_MAX=301 +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_MCPWM_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SDMMC_HOST_SUPPORTED=y +CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_EMAC_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 +CONFIG_SOC_XTAL_SUPPORT_26M=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=16 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y +CONFIG_SOC_IDCACHE_PER_CORE=y +CONFIG_SOC_CPU_CORES_NUM=2 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_HAS_FPU=y +CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=0x40 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=40 +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=39 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y +CONFIG_SOC_I2C_STOP_INDEPENDENT=y +CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y +CONFIG_SOC_I2S_SUPPORTS_PCM2PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_SUPPORTS_PDM2PCM=y +CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 +CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y +CONFIG_SOC_I2S_SUPPORTS_ADC=y +CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 +CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=2 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_TIMER_NUM=4 +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 +CONFIG_SOC_MCPWM_GROUPS=2 +CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 +CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 +CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 +CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y +CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 +CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 +CONFIG_SOC_MMU_PERIPH_NUM=2 +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=18 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_AS_CS_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=2 +CONFIG_SOC_SPI_MAX_CS_NUM=3 +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 +CONFIG_SOC_TOUCH_SENSOR_VERSION=1 +CONFIG_SOC_TOUCH_SENSOR_NUM=10 +CONFIG_SOC_TOUCH_MIN_CHAN_ID=0 +CONFIG_SOC_TOUCH_MAX_CHAN_ID=9 +CONFIG_SOC_TOUCH_SUPPORT_SLEEP_WAKEUP=y +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_MASK_FILTER_NUM=1 +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y +CONFIG_SOC_UART_NUM=3 +CONFIG_SOC_UART_HP_NUM=3 +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE=y +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y +CONFIG_SOC_SHA_ENDIANNESS_BE=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=1 +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=1 +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_PM_SUPPORT_MODEM_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_PM_MODEM_PD_BY_SW=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_CLK_LP_FAST_SUPPORT_XTAL_D4=y +CONFIG_SOC_SDMMC_USE_IOMUX=y +CONFIG_SOC_SDMMC_NUM_SLOTS=2 +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_BLE_SUPPORTED=y +CONFIG_SOC_BLE_MESH_SUPPORTED=y +CONFIG_SOC_BT_CLASSIC_SUPPORTED=y +CONFIG_SOC_BLUFI_SUPPORTED=y +CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y +CONFIG_SOC_BLE_MULTI_CONN_OPTIMIZATION=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TOOLCHAIN_GCC=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_INIT_VERSION="5.5.0" +CONFIG_IDF_TARGET_ESP32=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 # -# SDK tool configuration +# Build type # -CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-" -CONFIG_APP_COMPILE_TIME_DATE=y -# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +# +# Application Rollback +# +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# end of Application Rollback + +# +# Recovery Bootloader and Rollback +# +# end of Recovery Bootloader and Rollback + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set + +# +# Log +# +CONFIG_BOOTLOADER_LOG_VERSION_1=y +CONFIG_BOOTLOADER_LOG_VERSION=1 # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set # CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set @@ -21,22 +312,87 @@ CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y # CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y +# end of Format + +# +# Settings +# +CONFIG_BOOTLOADER_LOG_MODE_TEXT_EN=y +CONFIG_BOOTLOADER_LOG_MODE_TEXT=y +# end of Settings +# end of Log + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y # CONFIG_BOOTLOADER_FACTORY_RESET is not set # CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V1_SUPPORTED=y # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# CONFIG_SECURE_BOOT_ENABLED is not set +# CONFIG_SECURE_BOOT is not set # CONFIG_SECURE_FLASH_ENC_ENABLED is not set -CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_CRC_BE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_JPEG_DECODE=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_OTG_NUM=-1 +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y +CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set CONFIG_ESPTOOLPY_FLASHMODE_DIO=y # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y CONFIG_ESPTOOLPY_FLASHMODE="dio" # CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set CONFIG_ESPTOOLPY_FLASHFREQ_40M=y @@ -48,208 +404,888 @@ CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set CONFIG_ESPTOOLPY_BEFORE_RESET=y # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set CONFIG_ESPTOOLPY_BEFORE="default_reset" CONFIG_ESPTOOLPY_AFTER_RESET=y # CONFIG_ESPTOOLPY_AFTER_NORESET is not set CONFIG_ESPTOOLPY_AFTER="hard_reset" -# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set -CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y -# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set -CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set # CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set # CONFIG_PARTITION_TABLE_CUSTOM is not set CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Wifi Example Configuration +# CONFIG_EXAMPLE_WIFI_SSID="myssid" CONFIG_EXAMPLE_WIFI_PASSWORD="mypassword" +# end of Wifi Example Configuration + +# +# Example Connection Configuration +# +CONFIG_ENV_GPIO_RANGE_MIN=0 +CONFIG_ENV_GPIO_RANGE_MAX=39 +CONFIG_ENV_GPIO_IN_RANGE_MAX=39 +CONFIG_ENV_GPIO_OUT_RANGE_MAX=33 CONFIG_EXAMPLE_CONNECT_WIFI=y +# CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN is not set +CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD=y +CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY=6 +# CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST is not set +CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL=y + +# +# WiFi Scan threshold +# +CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD=-127 +CONFIG_EXAMPLE_WIFI_AUTH_OPEN=y +# CONFIG_EXAMPLE_WIFI_AUTH_WEP is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK is not set +# CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK is not set +# end of WiFi Scan threshold + +CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL=y +# CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY is not set # CONFIG_EXAMPLE_CONNECT_ETHERNET is not set +# CONFIG_EXAMPLE_CONNECT_PPP is not set +CONFIG_EXAMPLE_CONNECT_IPV4=y CONFIG_EXAMPLE_CONNECT_IPV6=y -CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y -# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK=y +# CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL is not set +# CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL is not set +# CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL is not set +# end of Example Connection Configuration + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y # CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# CONFIG_COMPILER_STACK_CHECK is not set +# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set CONFIG_COMPILER_WARN_WRITE_STRINGS=y -# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set -# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set -CONFIG_ESP32_APPTRACE_DEST_NONE=y -# CONFIG_ESP32_APPTRACE_ENABLE is not set -CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y +# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set +# CONFIG_COMPILER_STATIC_ANALYZER is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# # CONFIG_BT_ENABLED is not set -CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 -# CONFIG_BTDM_CTRL_AUTO_LATENCY_EFF is not set -# CONFIG_BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT_EFF is not set -CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 -CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 -CONFIG_BT_RESERVE_DRAM=0 -# CONFIG_BLE_MESH is not set -# CONFIG_ADC_FORCE_XPD_FSM is not set + +# +# Common Options +# +# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set +# CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED is not set +# end of Common Options +# end of Bluetooth + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# Legacy TWAI Driver Configurations +# +# CONFIG_TWAI_SKIP_LEGACY_CONFLICT_CHECK is not set +CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y +CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y +CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y +CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of Legacy TWAI Driver Configurations + +# +# Legacy ADC Driver Configuration +# CONFIG_ADC_DISABLE_DAC=y -# CONFIG_SPI_MASTER_IN_IRAM is not set -CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# CONFIG_SPI_SLAVE_IN_IRAM is not set -CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set + +# +# Legacy ADC Calibration Configuration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy MCPWM Driver Configurations +# +# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy MCPWM Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy I2C Driver Configurations +# +# CONFIG_I2C_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy I2C Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy SDM Driver Configurations + +# +# Legacy Touch Sensor Driver Configurations +# +# CONFIG_TOUCH_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_TOUCH_SKIP_LEGACY_CONFLICT_CHECK is not set +# end of Legacy Touch Sensor Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# # CONFIG_EFUSE_CUSTOM_TABLE is not set # CONFIG_EFUSE_VIRTUAL is not set # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y # CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set CONFIG_EFUSE_MAX_BLK_LEN=192 -# CONFIG_ESP_TLS_SERVER is not set +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +CONFIG_ESP_TLS_DYN_BUF_STRATEGY_SUPPORTED=y +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set + +# +# ADC Calibration Configurations +# +CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y +CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CALI_LUT_ENABLE=y +# end of ADC Calibration Configurations + +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +# CONFIG_ESP_COEX_GPIO_DEBUG is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_CACHE_SAFE is not set +CONFIG_GPTIMER_OBJ_CACHE_SAFE=y +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set +CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM=y +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:MCPWM Configurations +# +CONFIG_MCPWM_ISR_HANDLER_IN_IRAM=y +# CONFIG_MCPWM_ISR_CACHE_SAFE is not set +# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +CONFIG_MCPWM_OBJ_CACHE_SAFE=y +# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:MCPWM Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +CONFIG_RMT_ENCODER_FUNC_IN_IRAM=y +CONFIG_RMT_TX_ISR_HANDLER_IN_IRAM=y +CONFIG_RMT_RX_ISR_HANDLER_IN_IRAM=y +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_TX_ISR_CACHE_SAFE is not set +# CONFIG_RMT_RX_ISR_CACHE_SAFE is not set +CONFIG_RMT_OBJ_CACHE_SAFE=y +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# CONFIG_TOUCH_SKIP_FSM_CHECK is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:TWAI Configurations +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +# CONFIG_TWAI_ISR_CACHE_SAFE is not set +# CONFIG_TWAI_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:TWAI Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# ESP-Driver:UHCI Configurations +# +# CONFIG_UHCI_ISR_HANDLER_IN_IRAM is not set +# CONFIG_UHCI_ISR_CACHE_SAFE is not set +# CONFIG_UHCI_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:UHCI Configurations + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y +CONFIG_ETH_PHY_INTERFACE_RMII=y +CONFIG_ETH_RMII_CLK_INPUT=y +# CONFIG_ETH_RMII_CLK_OUTPUT is not set +CONFIG_ETH_RMII_CLK_IN_GPIO=0 +CONFIG_ETH_DMA_BUFFER_SIZE=512 +CONFIG_ETH_DMA_RX_BUFFER_NUM=10 +CONFIG_ETH_DMA_TX_BUFFER_NUM=10 +# CONFIG_ETH_IRAM_OPTIMIZATION is not set +CONFIG_ETH_USE_SPI_ETHERNET=y +CONFIG_ETH_SPI_ETHERNET_DM9051=y +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_OPENETH is not set +# CONFIG_ETH_TRANSMIT_MUTEX is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HID +# +CONFIG_ESPHID_TASK_SIZE_BT=2048 +CONFIG_ESPHID_TASK_SIZE_BLE=4096 +# end of ESP HID + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 +# CONFIG_ESP_HTTPS_SERVER_CERT_SELECT_HOOK is not set +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# CONFIG_ESP32_REV_MIN_0=y # CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_1_1 is not set # CONFIG_ESP32_REV_MIN_2 is not set # CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set CONFIG_ESP32_REV_MIN=0 -CONFIG_ESP32_DPORT_WORKAROUND=y -# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set -# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y -CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 -# CONFIG_ESP32_SPIRAM_SUPPORT is not set -# CONFIG_ESP32_MEMMAP_TRACEMEM is not set -# CONFIG_ESP32_MEMMAP_TRACEMEM_TWOBANKS is not set -# CONFIG_ESP32_TRAX is not set -CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +CONFIG_ESP32_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32 Revision (Rev v3.99) +# +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 +CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 +CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 + +# +# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) +# +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 -# CONFIG_ESP32_ULP_COPROC_ENABLED is not set -CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0 -# CONFIG_ESP32_PANIC_PRINT_HALT is not set -CONFIG_ESP32_PANIC_PRINT_REBOOT=y -# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP32_PANIC_GDBSTUB is not set -CONFIG_ESP32_DEBUG_OCDAWARE=y -CONFIG_ESP32_DEBUG_STUBS_ENABLE=y -CONFIG_ESP32_BROWNOUT_DET=y -CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set -CONFIG_ESP32_BROWNOUT_DET_LVL=0 -CONFIG_ESP32_REDUCE_PHY_TX_POWER=y -CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set -CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y -# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 -CONFIG_ESP32_RTC_XTAL_CAL_RETRY=1 -CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 -CONFIG_ESP32_XTAL_FREQ_40=y -# CONFIG_ESP32_XTAL_FREQ_26 is not set -# CONFIG_ESP32_XTAL_FREQ_AUTO is not set -CONFIG_ESP32_XTAL_FREQ=40 -# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set -# CONFIG_ESP32_NO_BLOBS is not set -# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set -CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_ESP_PERIPH_CTRL_FUNC_IN_IRAM=y +CONFIG_ESP_REGI2C_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +# CONFIG_XTAL_FREQ_26 is not set +# CONFIG_XTAL_FREQ_32 is not set +CONFIG_XTAL_FREQ_40=y +# CONFIG_XTAL_FREQ_AUTO is not set +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +# +# Power Supplier +# + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=0 +CONFIG_ESP_BROWNOUT_USE_INTR=y +# end of Brownout Detector +# end of Power Supplier + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +CONFIG_ESP_INTR_IN_IRAM=y +# end of Hardware Settings + +# +# ESP-Driver:LCD Controller Configurations +# +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:LCD Controller Configurations + +# +# ESP-MM: Memory Management Configurations +# +# end of ESP-MM: Memory Management Configurations + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +CONFIG_ESP_PHY_REDUCE_TX_POWER=y +# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +CONFIG_ESP_PHY_PLL_TRACK_PERIOD_MS=1000 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# CONFIG_ESP_PHY_RECORD_USED_TIME is not set +CONFIG_ESP_PHY_IRAM_OPT=y +# CONFIG_ESP_PHY_DEBUG is not set +# end of PHY + +# +# Power Management +# +CONFIG_PM_SLEEP_FUNC_IN_IRAM=y # CONFIG_PM_ENABLE is not set -CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y -CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CAL_LUT_ENABLE=y -# CONFIG_ESP_TIMER_PROFILING is not set -CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +CONFIG_PM_SLP_IRAM_OPT=y +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP-ROM +# +CONFIG_ESP_ROM_PRINT_IN_IRAM=y +# end of ESP-ROM + +# +# ESP Security Specific +# +# end of ESP Security Specific + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240 + +# +# Memory +# +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set + +# +# Non-backward compatible options +# +# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set +# end of Non-backward compatible options +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +CONFIG_ESP_SYSTEM_IN_IRAM=y +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 + +# +# Memory protection +# +# end of Memory protection + CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 CONFIG_ESP_CONSOLE_UART_DEFAULT=y # CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 CONFIG_ESP_INT_WDT=y CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y -CONFIG_ESP_TASK_WDT=y +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y # CONFIG_ESP_TASK_WDT_PANIC is not set CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -CONFIG_ETH_USE_ESP32_EMAC=y -CONFIG_ETH_PHY_INTERFACE_RMII=y -# CONFIG_ETH_PHY_INTERFACE_MII is not set -CONFIG_ETH_RMII_CLK_INPUT=y -# CONFIG_ETH_RMII_CLK_OUTPUT is not set -CONFIG_ETH_RMII_CLK_IN_GPIO=0 -CONFIG_ETH_DMA_BUFFER_SIZE=512 -CONFIG_ETH_DMA_RX_BUFFER_NUM=10 -CONFIG_ETH_DMA_TX_BUFFER_NUM=10 -CONFIG_ETH_USE_SPI_ETHERNET=y -CONFIG_ETH_SPI_ETHERNET_DM9051=y -# CONFIG_ESP_EVENT_LOOP_PROFILING is not set -CONFIG_ESP_EVENT_POST_FROM_ISR=y -CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y -CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 -CONFIG_HTTPD_MAX_URI_LEN=512 -CONFIG_HTTPD_ERR_RESP_NO_DELAY=y -CONFIG_HTTPD_PURGE_BUF_LEN=32 -# CONFIG_HTTPD_LOG_PURGE_DATA is not set -# CONFIG_OTA_ALLOW_HTTP is not set -# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set -CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_CSI_ENABLED is not set -CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP32_WIFI_TX_BA_WIN=6 -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -CONFIG_ESP32_WIFI_NVS_ENABLED=y -CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -# CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE is not set -CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y -CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set -CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y -# CONFIG_ESP32_ENABLE_COREDUMP is not set +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +CONFIG_ESP_DEBUG_STUBS_ENABLE=y +CONFIG_ESP_DEBUG_OCDAWARE=y +# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_ENABLE=y +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +CONFIG_ESP_TIMER_IN_IRAM=y +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=6 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP_WIFI_IRAM_OPT=y +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_ENABLE_SAE_H2E=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +# CONFIG_ESP_WIFI_BSS_MAX_IDLE_SUPPORT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y +CONFIG_ESP_WIFI_GMAC_SUPPORT=y +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y # CONFIG_FATFS_CODEPAGE_DYNAMIC is not set CONFIG_FATFS_CODEPAGE_437=y # CONFIG_FATFS_CODEPAGE_720 is not set @@ -273,63 +1309,133 @@ CONFIG_FATFS_CODEPAGE_437=y # CONFIG_FATFS_CODEPAGE_949 is not set # CONFIG_FATFS_CODEPAGE_950 is not set CONFIG_FATFS_CODEPAGE=437 -CONFIG_FATFS_LFN_NONE=y -# CONFIG_FATFS_LFN_HEAP is not set -# CONFIG_FATFS_LFN_STACK is not set CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y -CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 -CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_FMB_QUEUE_LENGTH=20 -CONFIG_FMB_SERIAL_TASK_STACK_SIZE=2048 -CONFIG_FMB_SERIAL_BUF_SIZE=256 -CONFIG_FMB_SERIAL_TASK_PRIO=10 -# CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT is not set -CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 -CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 -CONFIG_FMB_TIMER_PORT_ENABLED=y -CONFIG_FMB_TIMER_GROUP=0 -CONFIG_FMB_TIMER_INDEX=0 +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_USE_STRFUNC_NONE=y +# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set +# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# CONFIG_FATFS_USE_DYN_BUFFERS is not set + +# +# File system free space calculation behavior +# +CONFIG_FATFS_DONT_TRUST_FREE_CLUSTER_CNT=0 +CONFIG_FATFS_DONT_TRUST_LAST_ALLOC=0 +# end of File system free space calculation behavior +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set # CONFIG_FREERTOS_UNICORE is not set -CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_CORETIMER_0=y -# CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_HZ=100 -CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 -CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y -# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set -# CONFIG_FREERTOS_ASSERT_DISABLE is not set CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -CONFIG_FREERTOS_ISR_STACKSIZE=1536 -# CONFIG_FREERTOS_LEGACY_HOOKS is not set +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -# CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION is not set +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_USE_TIMERS=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -# CONFIG_FREERTOS_DEBUG_INTERNALS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +# +# Extra +# +# end of Extra + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=2 +CONFIG_FREERTOS_IN_IRAM=y +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# CONFIG_HEAP_POISONING_DISABLED=y # CONFIG_HEAP_POISONING_LIGHT is not set # CONFIG_HEAP_POISONING_COMPREHENSIVE is not set CONFIG_HEAP_TRACING_OFF=y # CONFIG_HEAP_TRACING_STANDALONE is not set # CONFIG_HEAP_TRACING_TOHOST is not set -# CONFIG_HEAP_TRACING is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log +# +CONFIG_LOG_VERSION_1=y +# CONFIG_LOG_VERSION_2 is not set +CONFIG_LOG_VERSION=1 + +# +# Log Level +# # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set # CONFIG_LOG_DEFAULT_LEVEL_WARN is not set @@ -337,78 +1443,281 @@ CONFIG_HEAP_TRACING_OFF=y CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y # CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_LOG_DEFAULT_LEVEL=4 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=4 + +# +# Level Settings +# +# CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y +# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set +# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y +# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set +CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y +CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 +# end of Level Settings +# end of Log Level + +# +# Format +# CONFIG_LOG_COLORS=y +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Format + +# +# Settings +# +CONFIG_LOG_MODE_TEXT_EN=y +CONFIG_LOG_MODE_TEXT=y +# end of Settings + +CONFIG_LOG_IN_IRAM=y +# end of Log + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y # CONFIG_LWIP_L2_TO_L3_COPY is not set # CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_ND6=y +# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set CONFIG_LWIP_MAX_SOCKETS=10 # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set # CONFIG_LWIP_SO_LINGER is not set CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y # CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 CONFIG_LWIP_IP4_FRAG=y CONFIG_LWIP_IP6_FRAG=y # CONFIG_LWIP_IP4_REASSEMBLY is not set # CONFIG_LWIP_IP6_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set # CONFIG_LWIP_STATS is not set -# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set CONFIG_LWIP_ESP_GRATUITOUS_ARP=y CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_ESP_MLDV6_REPORT=y +CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set +# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=69 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y CONFIG_LWIP_DHCPS_LEASE_UNIT=60 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +CONFIG_LWIP_DHCPS_ADD_DNS=y +# end of DHCP server + # CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +CONFIG_LWIP_IPV6=y # CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 +# CONFIG_LWIP_IPV6_FORWARD is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# CONFIG_LWIP_MAX_ACTIVE_TCP=16 CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y CONFIG_LWIP_TCP_MAXRTX=12 CONFIG_LWIP_TCP_SYNMAXRTX=6 CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 CONFIG_LWIP_TCP_WND_DEFAULT=5744 CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set CONFIG_LWIP_TCP_OVERSIZE_MSS=y # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set # CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set CONFIG_LWIP_TCP_RTO_TIME=3000 +# end of TCP + +# +# UDP +# CONFIG_LWIP_MAX_UDP_PCBS=16 CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_LWIP_PPP_SUPPORT is not set CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 +CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 +CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y # CONFIG_LWIP_MULTICAST_PING is not set # CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# CONFIG_LWIP_MAX_RAW_PCBS=16 -CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_HOST_IP=1 +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set +# CONFIG_LWIP_USE_ESP_GETADDRINFO is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y +# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set +# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set +CONFIG_LWIP_HOOK_DHCP_EXTRA_OPTION_NONE=y +# CONFIG_LWIP_HOOK_DHCP_EXTRA_OPTION_DEFAULT is not set +# CONFIG_LWIP_HOOK_DHCP_EXTRA_OPTION_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set +# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set +CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y +# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y # CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set # CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set # CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +# CONFIG_MBEDTLS_SSL_KEYING_MATERIAL_EXPORT is not set +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set -# CONFIG_MBEDTLS_CMAC_C is not set +CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y # CONFIG_MBEDTLS_HARDWARE_MPI is not set CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA1_C=y +CONFIG_MBEDTLS_SHA512_C=y +# CONFIG_MBEDTLS_SHA3_C is not set CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set # CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set @@ -416,41 +1725,58 @@ CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y CONFIG_MBEDTLS_TLS_SERVER=y CONFIG_MBEDTLS_TLS_CLIENT=y CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# # CONFIG_MBEDTLS_PSK_MODES is not set CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set -CONFIG_MBEDTLS_SSL_PROTO_TLS1=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# CONFIG_MBEDTLS_AES_C=y # CONFIG_MBEDTLS_CAMELLIA_C is not set # CONFIG_MBEDTLS_DES_C is not set -CONFIG_MBEDTLS_RC4_DISABLED=y -# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set -# CONFIG_MBEDTLS_RC4_ENABLED is not set # CONFIG_MBEDTLS_BLOWFISH_C is not set # CONFIG_MBEDTLS_XTEA_C is not set CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + # CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# CONFIG_MBEDTLS_PEM_PARSE_C=y CONFIG_MBEDTLS_PEM_WRITE_C=y CONFIG_MBEDTLS_X509_CRL_PARSE_C=y CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y +CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y +# CONFIG_MBEDTLS_DHM_C is not set CONFIG_MBEDTLS_ECDH_C=y CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y @@ -464,24 +1790,82 @@ CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -CONFIG_MDNS_MAX_SERVICES=10 +# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +CONFIG_MBEDTLS_FS_IO=y +# CONFIG_MBEDTLS_ALLOW_WEAK_CERTIFICATE_VERIFICATION is not set +# end of mbedTLS + +# +# ESP-MQTT Configurations +# CONFIG_MQTT_PROTOCOL_311=y +# CONFIG_MQTT_PROTOCOL_5 is not set CONFIG_MQTT_TRANSPORT_SSL=y CONFIG_MQTT_TRANSPORT_WEBSOCKET=y CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set # CONFIG_MQTT_CUSTOM_OUTBOX is not set -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# CONFIG_NEWLIB_NANO_FORMAT is not set -# CONFIG_OPENSSL_DEBUG is not set -# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set -CONFIG_OPENSSL_ASSERT_EXIT=y +# end of ESP-MQTT Configurations + +# +# LibC +# +CONFIG_LIBC_NEWLIB=y +CONFIG_LIBC_MISC_IN_IRAM=y +CONFIG_LIBC_LOCKS_PLACE_IN_IRAM=y +CONFIG_LIBC_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_LIBC_STDOUT_LINE_ENDING_LF is not set +# CONFIG_LIBC_STDOUT_LINE_ENDING_CR is not set +# CONFIG_LIBC_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_LIBC_STDIN_LINE_ENDING_LF is not set +CONFIG_LIBC_STDIN_LINE_ENDING_CR=y +# CONFIG_LIBC_NEWLIB_NANO_FORMAT is not set +CONFIG_LIBC_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_LIBC_TIME_SYSCALL_USE_RTC is not set +# CONFIG_LIBC_TIME_SYSCALL_USE_HRT is not set +# CONFIG_LIBC_TIME_SYSCALL_USE_NONE is not set +# end of LibC + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# OpenThread Spinel +# +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +# end of OpenThread Spinel +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y +# end of Protocomm + +# +# PThreads +# CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 CONFIG_PTHREAD_STACK_MIN=768 @@ -490,62 +1874,199 @@ CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y # CONFIG_PTHREAD_DEFAULT_CORE_1 is not set CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set +# CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND is not set +CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM=y +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# # CONFIG_SPI_FLASH_VERIFY_WRITE is not set # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORT_ENABLED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORT_ENABLED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORT_ENABLED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORT_ENABLED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORT_ENABLED=y CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y # CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y CONFIG_SPIFFS_META_LENGTH=4 CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# # CONFIG_SPIFFS_DBG is not set # CONFIG_SPIFFS_API_DBG is not set # CONFIG_SPIFFS_GC_DBG is not set # CONFIG_SPIFFS_CACHE_DBG is not set # CONFIG_SPIFFS_CHECK_DBG is not set # CONFIG_SPIFFS_TEST_VISUALISATION is not set -CONFIG_NETIF_IP_LOST_TIMER_INTERVAL=120 -CONFIG_TCPIP_LWIP=y +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +# CONFIG_ULP_COPROC_ENABLED is not set + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# CONFIG_UNITY_ENABLE_FLOAT=y CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set # CONFIG_UNITY_ENABLE_COLOR is not set CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y # CONFIG_UNITY_ENABLE_FIXTURE is not set # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# CONFIG_UNITY_TEST_ORDER_BY_FILE_PATH_AND_LINE is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set CONFIG_VFS_SUPPORT_TERMIOS=y -CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) + +CONFIG_VFS_INITIALIZE_DEV_NULL=y +# end of Virtual file system + +# +# Wear Levelling +# # CONFIG_WL_SECTOR_SIZE_512 is not set CONFIG_WL_SECTOR_SIZE_4096=y CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -CONFIG_WPA_MBEDTLS_CRYPTO=y -# CONFIG_WPA_TLS_V12 is not set -# CONFIG_WPA_WPS_WARS is not set -# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set # Deprecated options for backward compatibility -CONFIG_TOOLPREFIX="xtensa-esp32-elf-" +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set # CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set @@ -553,107 +2074,162 @@ CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set CONFIG_LOG_BOOTLOADER_LEVEL=3 -# CONFIG_APP_ROLLBACK_ENABLE is not set # CONFIG_FLASH_ENCRYPTION_ENABLED is not set # CONFIG_FLASHMODE_QIO is not set # CONFIG_FLASHMODE_QOUT is not set CONFIG_FLASHMODE_DIO=y # CONFIG_FLASHMODE_DOUT is not set -# CONFIG_MONITOR_BAUD_9600B is not set -# CONFIG_MONITOR_BAUD_57600B is not set -CONFIG_MONITOR_BAUD_115200B=y -# CONFIG_MONITOR_BAUD_230400B is not set -# CONFIG_MONITOR_BAUD_921600B is not set -# CONFIG_MONITOR_BAUD_2MB is not set -# CONFIG_MONITOR_BAUD_OTHER is not set -CONFIG_MONITOR_BAUD_OTHER_VAL=115200 CONFIG_MONITOR_BAUD=115200 CONFIG_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y # CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 # CONFIG_CXX_EXCEPTIONS is not set CONFIG_STACK_CHECK_NONE=y # CONFIG_STACK_CHECK_NORM is not set # CONFIG_STACK_CHECK_STRONG is not set # CONFIG_STACK_CHECK_ALL is not set -# CONFIG_STACK_CHECK is not set CONFIG_WARN_WRITE_STRINGS=y -# CONFIG_DISABLE_GCC8_WARNINGS is not set -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=0 -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 -CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y CONFIG_ADC2_DISABLE_DAC=y -# CONFIG_SPIRAM_SUPPORT is not set -# CONFIG_MEMMAP_TRACEMEM is not set -# CONFIG_MEMMAP_TRACEMEM_TWOBANKS is not set -CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 -# CONFIG_ULP_COPROC_ENABLED is not set -CONFIG_ULP_COPROC_RESERVE_MEM=0 +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# CONFIG_ESP32_XTAL_FREQ_26 is not set +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 CONFIG_BROWNOUT_DET=y +CONFIG_ESP32_BROWNOUT_DET=y CONFIG_BROWNOUT_DET_LVL_SEL_0=y +CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y # CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set # CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set # CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set # CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set # CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set # CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set # CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_ESP32_BROWNOUT_DET_LVL=0 +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 CONFIG_REDUCE_PHY_TX_POWER=y -CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y -# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set -# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set -# CONFIG_NO_BLOBS is not set -# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +CONFIG_ESP32_REDUCE_PHY_TX_POWER=y +# CONFIG_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 CONFIG_MAIN_TASK_STACK_SIZE=3584 -CONFIG_IPC_TASK_STACK_SIZE=1024 -CONFIG_TIMER_TASK_STACK_SIZE=3584 CONFIG_CONSOLE_UART_DEFAULT=y # CONFIG_CONSOLE_UART_CUSTOM is not set # CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y CONFIG_CONSOLE_UART_NUM=0 CONFIG_CONSOLE_UART_BAUDRATE=115200 CONFIG_INT_WDT=y CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y # CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_EVENT_LOOP_PROFILING is not set -CONFIG_POST_EVENTS_FROM_ISR=y -CONFIG_POST_EVENTS_FROM_IRAM_ISR=y -CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 -CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_MB_QUEUE_LENGTH=20 -CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048 -CONFIG_MB_SERIAL_BUF_SIZE=256 -CONFIG_MB_SERIAL_TASK_PRIO=10 -# CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT is not set -CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_MB_CONTROLLER_STACK_SIZE=4096 -CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 -CONFIG_MB_TIMER_PORT_ENABLED=y -CONFIG_MB_TIMER_GROUP=0 -CONFIG_MB_TIMER_INDEX=0 -# CONFIG_SUPPORT_STATIC_ALLOCATION is not set +CONFIG_ESP32_DEBUG_STUBS_ENABLE=y +CONFIG_ESP32_DEBUG_OCDAWARE=y +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set # CONFIG_L2_TO_L3_COPY is not set -# CONFIG_USE_ONLY_LWIP_SELECT is not set CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 CONFIG_TCPIP_RECVMBOX_SIZE=32 @@ -665,7 +2241,6 @@ CONFIG_TCP_SND_BUF_DEFAULT=5744 CONFIG_TCP_WND_DEFAULT=5744 CONFIG_TCP_RECVMBOX_SIZE=6 CONFIG_TCP_QUEUE_OOSEQ=y -# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set CONFIG_TCP_OVERSIZE_MSS=y # CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set # CONFIG_TCP_OVERSIZE_DISABLE is not set @@ -676,6 +2251,23 @@ CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF # CONFIG_PPP_SUPPORT is not set +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 CONFIG_ESP32_PTHREAD_STACK_MIN=768 @@ -687,7 +2279,8 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -CONFIG_IP_LOST_TIMER_INTERVAL=120 +# CONFIG_ESP32_ULP_COPROC_ENABLED is not set CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 # End of deprecated options diff --git a/src/nesper/esp/esp_event.nim b/src/nesper/esp/esp_event.nim index e5bd3099..d39ba05d 100644 --- a/src/nesper/esp/esp_event.nim +++ b/src/nesper/esp/esp_event.nim @@ -247,9 +247,12 @@ proc esp_event_handler_instance_register_with*( ## - Others: Fail ## -proc esp_event_handler_instance_register*(event_base: esp_event_base_t; - event_id: int32; event_handler: esp_event_handler_t; - event_handler_arg: pointer; instance: ptr esp_event_handler_instance_t): esp_err_t {. +proc esp_event_handler_instance_register*( + event_base: esp_event_base_t; + event_id: int32; + event_handler: esp_event_handler_t; + event_handler_arg: pointer; + instance: ptr esp_event_handler_instance_t): esp_err_t {. cdecl, importc: "esp_event_handler_instance_register", header: "esp_event.h".} ## ## diff --git a/src/nesper/events.nim b/src/nesper/events.nim index 193f6361..22955e79 100644 --- a/src/nesper/events.nim +++ b/src/nesper/events.nim @@ -27,60 +27,51 @@ type event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} + EventHandlerInstance* = ptr esp_event_handler_instance_t -template eventRegister*[EVT; T: pointer]( - evt_id: EVT; - evt_handler: EventHandlerCb[T]; +proc eventRegister*[E; T]( + evt_base: esp_event_base_t, + evt_id: E, + evt_handler: EventHandlerCb[T], evt_handler_arg: T = nil, - handler_instance: ptr esp_event_handler_instance_t = nil + instance: EventHandlerInstance = nil ) = ## Register event with the default event loop. Understand WIFI & IP Events - let evt_base = - when typeof(EVT) is wifi_event_t: - WIFI_EVENT - elif typeof(EVT) is ip_event_t: - IP_EVENT - elif typeof(EVT) is eth_event_t: - ETH_EVENT - else: - {.fatal: "Uknown event type, don't know how to unregister automatically".} - let handler: esp_event_handler_t = cast[esp_event_handler_t](evt_handler) let ret = esp_event_handler_instance_register( event_base = evt_base, event_id = int32(evt_id), event_handler = handler, - event_handler_arg = evt_handler_arg, - handler_instance = handler_instance) - - if ret != ESP_OK: - raise newEspError[EventError]("register: " & $esp_err_to_name(ret), ret) - -template eventRegister*[EVT; T: pointer]( - event_base: esp_event_base_t; - event_id: EVT; - event_handler: EventHandlerCb[T]; - event_handler_arg: T = nil, - handler_instance: ptr esp_event_handler_instance_t = nil - ) = - ## Register event for an event base on the default loop. - let handler: esp_event_handler_t = cast[esp_event_handler_t](event_handler) - let ret = esp_event_handler_instance_register( - event_base, - event_id.cint, - handler, - event_handler_arg, - handler_instance) + event_handler_arg = cast[pointer](evt_handler_arg), + instance = instance) if ret != ESP_OK: raise newEspError[EventError]("register: " & $esp_err_to_name(ret), ret) -template eventRegisterWith*[EVT, TP]( +# template eventRegister*[E; T: pointer]( +# event_base: esp_event_base_t; +# event_id: E; +# event_handler: EventHandlerCb[T]; +# event_handler_arg: T = nil, +# instance: ptr esp_event_handler_instance_t = nil +# ) = +# ## Register event for an event base on the default loop. +# let handler: esp_event_handler_t = cast[esp_event_handler_t](event_handler) +# let ret = esp_event_handler_instance_register( +# event_base, +# event_id.cint, +# handler, +# event_handler_arg, +# instance = instance) +# if ret != ESP_OK: +# raise newEspError[EventError]("register: " & $esp_err_to_name(ret), ret) + +template eventRegisterWith*[E; TP]( event_loop: esp_event_loop_handle_t; event_base: esp_event_base_t; - event_id: EVT; + event_id: E; event_handler: TP; event_handler_arg: pointer = nil ) = From 9d27198fe402f25ab01f9fc43befb002c4490d99 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 22:44:46 -0600 Subject: [PATCH 111/142] fixing types --- esp-idf-examples/simplewifi/main/CMakeLists.txt | 3 ++- src/nesper/esp/esp_event.nim | 2 +- src/nesper/events.nim | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/esp-idf-examples/simplewifi/main/CMakeLists.txt b/esp-idf-examples/simplewifi/main/CMakeLists.txt index b144d1b8..12f8ce0d 100644 --- a/esp-idf-examples/simplewifi/main/CMakeLists.txt +++ b/esp-idf-examples/simplewifi/main/CMakeLists.txt @@ -1,7 +1,7 @@ idf_component_register(SRC_DIRS "./nimcache" INCLUDE_DIRS "" - REQUIRES lwip newlib nvs_flash) + ) # set(C_COMPILE_OPTIONS "${C_COMPILE_OPTIONS} -Wno-error=unused-label") # list(APPEND C_COMPILE_OPTIONS "-Wno-error=unused-label ") @@ -16,3 +16,4 @@ idf_build_set_property(C_COMPILE_OPTIONS -Wno-error=maybe-uninitialized APPEND) idf_build_set_property(C_COMPILE_OPTIONS -Wno-error=nonnull APPEND) idf_build_set_property(C_COMPILE_OPTIONS -Wno-error=address APPEND) idf_build_set_property(C_COMPILE_OPTIONS -Wno-unused-but-set-variable APPEND) +idf_build_set_property(C_COMPILE_OPTIONS -Wno-discarded-qualifiers APPEND) diff --git a/src/nesper/esp/esp_event.nim b/src/nesper/esp/esp_event.nim index d39ba05d..d2d53a7a 100644 --- a/src/nesper/esp/esp_event.nim +++ b/src/nesper/esp/esp_event.nim @@ -13,7 +13,7 @@ when ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0): export esp_event_legacy type - esp_event_base_t* = cstring + esp_event_base_t* {.importc: "esp_event_base_t", header: "esp_event.h".} = pointer type ## *< unique pointer to a subsystem that exposes events diff --git a/src/nesper/events.nim b/src/nesper/events.nim index 22955e79..a9ba4f27 100644 --- a/src/nesper/events.nim +++ b/src/nesper/events.nim @@ -38,7 +38,7 @@ proc eventRegister*[E; T]( ) = ## Register event with the default event loop. Understand WIFI & IP Events - let handler: esp_event_handler_t = cast[esp_event_handler_t](evt_handler) + var handler: esp_event_handler_t = cast[esp_event_handler_t](evt_handler) let ret = esp_event_handler_instance_register( event_base = evt_base, From 60519a151446bd0e64ad0fbab81d6ef76104d430 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 4 Sep 2025 23:21:28 -0600 Subject: [PATCH 112/142] fixing types --- esp-idf-examples/simplewifi/.gitignore | 2 + esp-idf-examples/simplewifi/main/main.nim | 11 +- .../simplewifi/main/station_example_main.c | 179 ++ esp-idf-examples/simplewifi/sdkconfig | 2286 ----------------- esp-idf-examples/simplewifi/sdkconfig.old | 955 ------- 5 files changed, 191 insertions(+), 3242 deletions(-) create mode 100644 esp-idf-examples/simplewifi/main/station_example_main.c delete mode 100644 esp-idf-examples/simplewifi/sdkconfig delete mode 100644 esp-idf-examples/simplewifi/sdkconfig.old diff --git a/esp-idf-examples/simplewifi/.gitignore b/esp-idf-examples/simplewifi/.gitignore index da0a7506..132287db 100644 --- a/esp-idf-examples/simplewifi/.gitignore +++ b/esp-idf-examples/simplewifi/.gitignore @@ -3,3 +3,5 @@ src/nimcache/ src/server src/localnim/ .env +sdkconfig +sdkconfig.old diff --git a/esp-idf-examples/simplewifi/main/main.nim b/esp-idf-examples/simplewifi/main/main.nim index 4a8f8910..fc4c9369 100644 --- a/esp-idf-examples/simplewifi/main/main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -4,11 +4,12 @@ import nesper/nvs_utils import nesper/events import nesper/wifi import nesper/tasks +import nesper/timers import server # Get Password -const WIFI_SSID {.strdefine.}: string = "NOSSID" +const WIFI_SSID {.strdefine.}: string = "" const WIFI_PASSWORD {.strdefine.}: string = "" # const CONFIG_EXAMPLE_WIFI_SSID = getEnv("WIFI_SSID") @@ -51,6 +52,11 @@ proc wifiStart*() = check: esp_wifi_set_storage(WIFI_STORAGE_RAM) + when WIFI_SSID == "": + {.error: "WIFI_SSID is not set".} + when WIFI_PASSWORD == "": + {.error: "WIFI_PASSWORD is not set".} + var wifi_config: wifi_config_t wifi_config.sta.ssid.setFromString(WIFI_SSID) wifi_config.sta.password.setFromString(WIFI_PASSWORD) @@ -122,3 +128,6 @@ app_main(): echo("Wait done\n") # vTaskDelay(10000 div portTICK_PERIOD_MS) + while true: + echo "looping..." + delayMillis(1000) diff --git a/esp-idf-examples/simplewifi/main/station_example_main.c b/esp-idf-examples/simplewifi/main/station_example_main.c new file mode 100644 index 00000000..d5ed5eb1 --- /dev/null +++ b/esp-idf-examples/simplewifi/main/station_example_main.c @@ -0,0 +1,179 @@ +/* WiFi station Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_log.h" +#include "nvs_flash.h" + +#include "lwip/err.h" +#include "lwip/sys.h" + +/* The examples use WiFi configuration that you can set via project configuration menu + + If you'd rather not, just change the below entries to strings with + the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" +*/ +#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID +#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD +#define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY + +#if CONFIG_ESP_STATION_EXAMPLE_WPA3_SAE_PWE_HUNT_AND_PECK +#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_HUNT_AND_PECK +#define EXAMPLE_H2E_IDENTIFIER "" +#elif CONFIG_ESP_STATION_EXAMPLE_WPA3_SAE_PWE_HASH_TO_ELEMENT +#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_HASH_TO_ELEMENT +#define EXAMPLE_H2E_IDENTIFIER CONFIG_ESP_WIFI_PW_ID +#elif CONFIG_ESP_STATION_EXAMPLE_WPA3_SAE_PWE_BOTH +#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_BOTH +#define EXAMPLE_H2E_IDENTIFIER CONFIG_ESP_WIFI_PW_ID +#endif +#if CONFIG_ESP_WIFI_AUTH_OPEN +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN +#elif CONFIG_ESP_WIFI_AUTH_WEP +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP +#elif CONFIG_ESP_WIFI_AUTH_WPA_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK +#elif CONFIG_ESP_WIFI_AUTH_WPA2_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK +#elif CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK +#elif CONFIG_ESP_WIFI_AUTH_WPA3_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK +#elif CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK +#elif CONFIG_ESP_WIFI_AUTH_WAPI_PSK +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK +#endif + +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; + +/* The event group allows multiple bits for each event, but we only care about two events: + * - we are connected to the AP with an IP + * - we failed to connect after the maximum amount of retries */ +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static const char *TAG = "wifi station"; + +static int s_retry_num = 0; + + +static void event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + esp_wifi_connect(); + } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { + if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { + esp_wifi_connect(); + s_retry_num++; + ESP_LOGI(TAG, "retry to connect to the AP"); + } else { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + ESP_LOGI(TAG,"connect to the AP fail"); + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } +} + +void wifi_init_sta(void) +{ + s_wifi_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_netif_init()); + + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + esp_event_handler_instance_t instance_any_id; + esp_event_handler_instance_t instance_got_ip; + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &event_handler, + NULL, + &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &event_handler, + NULL, + &instance_got_ip)); + + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_ESP_WIFI_SSID, + .password = EXAMPLE_ESP_WIFI_PASS, + /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (password len => 8). + * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value + * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to + * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards. + */ + .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD, + .sae_pwe_h2e = ESP_WIFI_SAE_MODE, + .sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER, + }, + }; + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_wifi_start() ); + + ESP_LOGI(TAG, "wifi_init_sta finished."); + + /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum + * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually + * happened. */ + if (bits & WIFI_CONNECTED_BIT) { + ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", + EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); + } else if (bits & WIFI_FAIL_BIT) { + ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", + EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); + } else { + ESP_LOGE(TAG, "UNEXPECTED EVENT"); + } +} + +void app_main(void) +{ + //Initialize NVS + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + if (CONFIG_LOG_MAXIMUM_LEVEL > CONFIG_LOG_DEFAULT_LEVEL) { + /* If you only want to open more logs in the wifi module, you need to make the max level greater than the default level, + * and call esp_log_level_set() before esp_wifi_init() to improve the log level of the wifi module. */ + esp_log_level_set("wifi", CONFIG_LOG_MAXIMUM_LEVEL); + } + + ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); + wifi_init_sta(); +} diff --git a/esp-idf-examples/simplewifi/sdkconfig b/esp-idf-examples/simplewifi/sdkconfig deleted file mode 100644 index 7b29707d..00000000 --- a/esp-idf-examples/simplewifi/sdkconfig +++ /dev/null @@ -1,2286 +0,0 @@ -# -# Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) 5.5.0 Project Configuration -# -CONFIG_SOC_CAPS_ECO_VER_MAX=301 -CONFIG_SOC_ADC_SUPPORTED=y -CONFIG_SOC_DAC_SUPPORTED=y -CONFIG_SOC_UART_SUPPORTED=y -CONFIG_SOC_MCPWM_SUPPORTED=y -CONFIG_SOC_GPTIMER_SUPPORTED=y -CONFIG_SOC_SDMMC_HOST_SUPPORTED=y -CONFIG_SOC_BT_SUPPORTED=y -CONFIG_SOC_PCNT_SUPPORTED=y -CONFIG_SOC_PHY_SUPPORTED=y -CONFIG_SOC_WIFI_SUPPORTED=y -CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y -CONFIG_SOC_TWAI_SUPPORTED=y -CONFIG_SOC_EFUSE_SUPPORTED=y -CONFIG_SOC_EMAC_SUPPORTED=y -CONFIG_SOC_ULP_SUPPORTED=y -CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y -CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y -CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y -CONFIG_SOC_RTC_MEM_SUPPORTED=y -CONFIG_SOC_I2S_SUPPORTED=y -CONFIG_SOC_RMT_SUPPORTED=y -CONFIG_SOC_SDM_SUPPORTED=y -CONFIG_SOC_GPSPI_SUPPORTED=y -CONFIG_SOC_LEDC_SUPPORTED=y -CONFIG_SOC_I2C_SUPPORTED=y -CONFIG_SOC_SUPPORT_COEXISTENCE=y -CONFIG_SOC_AES_SUPPORTED=y -CONFIG_SOC_MPI_SUPPORTED=y -CONFIG_SOC_SHA_SUPPORTED=y -CONFIG_SOC_FLASH_ENC_SUPPORTED=y -CONFIG_SOC_SECURE_BOOT_SUPPORTED=y -CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y -CONFIG_SOC_BOD_SUPPORTED=y -CONFIG_SOC_ULP_FSM_SUPPORTED=y -CONFIG_SOC_CLK_TREE_SUPPORTED=y -CONFIG_SOC_MPU_SUPPORTED=y -CONFIG_SOC_WDT_SUPPORTED=y -CONFIG_SOC_SPI_FLASH_SUPPORTED=y -CONFIG_SOC_RNG_SUPPORTED=y -CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y -CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y -CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y -CONFIG_SOC_PM_SUPPORTED=y -CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 -CONFIG_SOC_XTAL_SUPPORT_26M=y -CONFIG_SOC_XTAL_SUPPORT_40M=y -CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y -CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y -CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y -CONFIG_SOC_ADC_DMA_SUPPORTED=y -CONFIG_SOC_ADC_PERIPH_NUM=2 -CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 -CONFIG_SOC_ADC_ATTEN_NUM=4 -CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 -CONFIG_SOC_ADC_PATT_LEN_MAX=16 -CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 -CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 -CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 -CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 -CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 -CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 -CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 -CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 -CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 -CONFIG_SOC_ADC_SHARED_POWER=y -CONFIG_SOC_BROWNOUT_RESET_SUPPORTED=y -CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y -CONFIG_SOC_IDCACHE_PER_CORE=y -CONFIG_SOC_CPU_CORES_NUM=2 -CONFIG_SOC_CPU_INTR_NUM=32 -CONFIG_SOC_CPU_HAS_FPU=y -CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y -CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=0x40 -CONFIG_SOC_DAC_CHAN_NUM=2 -CONFIG_SOC_DAC_RESOLUTION=8 -CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y -CONFIG_SOC_GPIO_PORT=1 -CONFIG_SOC_GPIO_PIN_COUNT=40 -CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF -CONFIG_SOC_GPIO_IN_RANGE_MAX=39 -CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 -CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA -CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y -CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 -CONFIG_SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP=y -CONFIG_SOC_I2C_NUM=2 -CONFIG_SOC_HP_I2C_NUM=2 -CONFIG_SOC_I2C_FIFO_LEN=32 -CONFIG_SOC_I2C_CMD_REG_NUM=16 -CONFIG_SOC_I2C_SUPPORT_SLAVE=y -CONFIG_SOC_I2C_SUPPORT_APB=y -CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR=y -CONFIG_SOC_I2C_STOP_INDEPENDENT=y -CONFIG_SOC_I2S_NUM=2 -CONFIG_SOC_I2S_HW_VERSION_1=y -CONFIG_SOC_I2S_SUPPORTS_APLL=y -CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y -CONFIG_SOC_I2S_SUPPORTS_PDM=y -CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y -CONFIG_SOC_I2S_SUPPORTS_PCM2PDM=y -CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y -CONFIG_SOC_I2S_SUPPORTS_PDM2PCM=y -CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 -CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 -CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y -CONFIG_SOC_I2S_SUPPORTS_ADC=y -CONFIG_SOC_I2S_SUPPORTS_DAC=y -CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y -CONFIG_SOC_I2S_MAX_DATA_WIDTH=24 -CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y -CONFIG_SOC_I2S_LCD_I80_VARIANT=y -CONFIG_SOC_LCD_I80_SUPPORTED=y -CONFIG_SOC_LCD_I80_BUSES=2 -CONFIG_SOC_LCD_I80_BUS_WIDTH=24 -CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y -CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y -CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y -CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y -CONFIG_SOC_LEDC_TIMER_NUM=4 -CONFIG_SOC_LEDC_CHANNEL_NUM=8 -CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 -CONFIG_SOC_MCPWM_GROUPS=2 -CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 -CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 -CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 -CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 -CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y -CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 -CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 -CONFIG_SOC_MMU_PERIPH_NUM=2 -CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 -CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 -CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 -CONFIG_SOC_PCNT_GROUPS=1 -CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 -CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 -CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 -CONFIG_SOC_RMT_GROUPS=1 -CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 -CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 -CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 -CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 -CONFIG_SOC_RMT_SUPPORT_REF_TICK=y -CONFIG_SOC_RMT_SUPPORT_APB=y -CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y -CONFIG_SOC_RTCIO_PIN_COUNT=18 -CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y -CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y -CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y -CONFIG_SOC_SDM_GROUPS=1 -CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 -CONFIG_SOC_SDM_CLK_SUPPORT_APB=y -CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y -CONFIG_SOC_SPI_AS_CS_SUPPORTED=y -CONFIG_SOC_SPI_PERIPH_NUM=3 -CONFIG_SOC_SPI_DMA_CHAN_NUM=2 -CONFIG_SOC_SPI_MAX_CS_NUM=3 -CONFIG_SOC_SPI_SUPPORT_CLK_APB=y -CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 -CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 -CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y -CONFIG_SOC_TIMER_GROUPS=2 -CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 -CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 -CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 -CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y -CONFIG_SOC_LP_TIMER_BIT_WIDTH_LO=32 -CONFIG_SOC_LP_TIMER_BIT_WIDTH_HI=16 -CONFIG_SOC_TOUCH_SENSOR_VERSION=1 -CONFIG_SOC_TOUCH_SENSOR_NUM=10 -CONFIG_SOC_TOUCH_MIN_CHAN_ID=0 -CONFIG_SOC_TOUCH_MAX_CHAN_ID=9 -CONFIG_SOC_TOUCH_SUPPORT_SLEEP_WAKEUP=y -CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 -CONFIG_SOC_TWAI_CONTROLLER_NUM=1 -CONFIG_SOC_TWAI_MASK_FILTER_NUM=1 -CONFIG_SOC_TWAI_BRP_MIN=2 -CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y -CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y -CONFIG_SOC_UART_NUM=3 -CONFIG_SOC_UART_HP_NUM=3 -CONFIG_SOC_UART_SUPPORT_APB_CLK=y -CONFIG_SOC_UART_SUPPORT_REF_TICK=y -CONFIG_SOC_UART_FIFO_LEN=128 -CONFIG_SOC_UART_BITRATE_MAX=5000000 -CONFIG_SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE=y -CONFIG_SOC_SPIRAM_SUPPORTED=y -CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y -CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y -CONFIG_SOC_SHA_ENDIANNESS_BE=y -CONFIG_SOC_SHA_SUPPORT_SHA1=y -CONFIG_SOC_SHA_SUPPORT_SHA256=y -CONFIG_SOC_SHA_SUPPORT_SHA384=y -CONFIG_SOC_SHA_SUPPORT_SHA512=y -CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 -CONFIG_SOC_MPI_OPERATIONS_NUM=1 -CONFIG_SOC_RSA_MAX_BIT_LEN=4096 -CONFIG_SOC_AES_SUPPORT_AES_128=y -CONFIG_SOC_AES_SUPPORT_AES_192=y -CONFIG_SOC_AES_SUPPORT_AES_256=y -CONFIG_SOC_SECURE_BOOT_V1=y -CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=1 -CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 -CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 -CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y -CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y -CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y -CONFIG_SOC_PM_SUPPORT_MODEM_PD=y -CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y -CONFIG_SOC_PM_MODEM_PD_BY_SW=y -CONFIG_SOC_CLK_APLL_SUPPORTED=y -CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y -CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y -CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y -CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y -CONFIG_SOC_CLK_LP_FAST_SUPPORT_XTAL_D4=y -CONFIG_SOC_SDMMC_USE_IOMUX=y -CONFIG_SOC_SDMMC_NUM_SLOTS=2 -CONFIG_SOC_WIFI_WAPI_SUPPORT=y -CONFIG_SOC_WIFI_CSI_SUPPORT=y -CONFIG_SOC_WIFI_MESH_SUPPORT=y -CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y -CONFIG_SOC_WIFI_NAN_SUPPORT=y -CONFIG_SOC_BLE_SUPPORTED=y -CONFIG_SOC_BLE_MESH_SUPPORTED=y -CONFIG_SOC_BT_CLASSIC_SUPPORTED=y -CONFIG_SOC_BLUFI_SUPPORTED=y -CONFIG_SOC_BT_H2C_ENC_KEY_CTRL_ENH_VSC_SUPPORTED=y -CONFIG_SOC_BLE_MULTI_CONN_OPTIMIZATION=y -CONFIG_SOC_ULP_HAS_ADC=y -CONFIG_SOC_PHY_COMBO_MODULE=y -CONFIG_SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK=y -CONFIG_IDF_CMAKE=y -CONFIG_IDF_TOOLCHAIN="gcc" -CONFIG_IDF_TOOLCHAIN_GCC=y -CONFIG_IDF_TARGET_ARCH_XTENSA=y -CONFIG_IDF_TARGET_ARCH="xtensa" -CONFIG_IDF_TARGET="esp32" -CONFIG_IDF_INIT_VERSION="5.5.0" -CONFIG_IDF_TARGET_ESP32=y -CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 - -# -# Build type -# -CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y -# CONFIG_APP_BUILD_TYPE_RAM is not set -CONFIG_APP_BUILD_GENERATE_BINARIES=y -CONFIG_APP_BUILD_BOOTLOADER=y -CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# CONFIG_APP_REPRODUCIBLE_BUILD is not set -# CONFIG_APP_NO_BLOBS is not set -# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set -# end of Build type - -# -# Bootloader config -# - -# -# Bootloader manager -# -CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y -CONFIG_BOOTLOADER_PROJECT_VER=1 -# end of Bootloader manager - -# -# Application Rollback -# -# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# end of Application Rollback - -# -# Recovery Bootloader and Rollback -# -# end of Recovery Bootloader and Rollback - -CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set - -# -# Log -# -CONFIG_BOOTLOADER_LOG_VERSION_1=y -CONFIG_BOOTLOADER_LOG_VERSION=1 -# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set -CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y -# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set -CONFIG_BOOTLOADER_LOG_LEVEL=3 - -# -# Format -# -# CONFIG_BOOTLOADER_LOG_COLORS is not set -CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS=y -# end of Format - -# -# Settings -# -CONFIG_BOOTLOADER_LOG_MODE_TEXT_EN=y -CONFIG_BOOTLOADER_LOG_MODE_TEXT=y -# end of Settings -# end of Log - -# -# Serial Flash Configurations -# -# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set -CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y -# end of Serial Flash Configurations - -# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set -CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# CONFIG_BOOTLOADER_FACTORY_RESET is not set -# CONFIG_BOOTLOADER_APP_TEST is not set -CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y -CONFIG_BOOTLOADER_WDT_ENABLE=y -# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set -CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set -CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -# end of Bootloader config - -# -# Security features -# -CONFIG_SECURE_BOOT_V1_SUPPORTED=y -# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# CONFIG_SECURE_BOOT is not set -# CONFIG_SECURE_FLASH_ENC_ENABLED is not set -# end of Security features - -# -# Application manager -# -CONFIG_APP_COMPILE_TIME_DATE=y -# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set -CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 -# end of Application manager - -CONFIG_ESP_ROM_HAS_CRC_LE=y -CONFIG_ESP_ROM_HAS_CRC_BE=y -CONFIG_ESP_ROM_HAS_MZ_CRC32=y -CONFIG_ESP_ROM_HAS_JPEG_DECODE=y -CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y -CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y -CONFIG_ESP_ROM_HAS_NEWLIB=y -CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y -CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y -CONFIG_ESP_ROM_HAS_SW_FLOAT=y -CONFIG_ESP_ROM_USB_OTG_NUM=-1 -CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 -CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y -CONFIG_ESP_ROM_HAS_OUTPUT_PUTC_FUNC=y - -# -# Serial flasher config -# -# CONFIG_ESPTOOLPY_NO_STUB is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y -# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set -CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y -CONFIG_ESPTOOLPY_FLASHMODE="dio" -# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_40M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ="40m" -# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set -CONFIG_ESPTOOLPY_BEFORE_RESET=y -# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set -CONFIG_ESPTOOLPY_BEFORE="default_reset" -CONFIG_ESPTOOLPY_AFTER_RESET=y -# CONFIG_ESPTOOLPY_AFTER_NORESET is not set -CONFIG_ESPTOOLPY_AFTER="hard_reset" -CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 -# end of Serial flasher config - -# -# Partition Table -# -CONFIG_PARTITION_TABLE_SINGLE_APP=y -# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set -# CONFIG_PARTITION_TABLE_TWO_OTA is not set -# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set -# CONFIG_PARTITION_TABLE_CUSTOM is not set -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 -CONFIG_PARTITION_TABLE_MD5=y -# end of Partition Table - -# -# Wifi Example Configuration -# -CONFIG_EXAMPLE_WIFI_SSID="myssid" -CONFIG_EXAMPLE_WIFI_PASSWORD="mypassword" -# end of Wifi Example Configuration - -# -# Example Connection Configuration -# -CONFIG_ENV_GPIO_RANGE_MIN=0 -CONFIG_ENV_GPIO_RANGE_MAX=39 -CONFIG_ENV_GPIO_IN_RANGE_MAX=39 -CONFIG_ENV_GPIO_OUT_RANGE_MAX=33 -CONFIG_EXAMPLE_CONNECT_WIFI=y -# CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN is not set -CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD=y -CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY=6 -# CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST is not set -CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL=y - -# -# WiFi Scan threshold -# -CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD=-127 -CONFIG_EXAMPLE_WIFI_AUTH_OPEN=y -# CONFIG_EXAMPLE_WIFI_AUTH_WEP is not set -# CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK is not set -# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK is not set -# CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK is not set -# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE is not set -# CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK is not set -# CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK is not set -# CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK is not set -# end of WiFi Scan threshold - -CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL=y -# CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY is not set -# CONFIG_EXAMPLE_CONNECT_ETHERNET is not set -# CONFIG_EXAMPLE_CONNECT_PPP is not set -CONFIG_EXAMPLE_CONNECT_IPV4=y -CONFIG_EXAMPLE_CONNECT_IPV6=y -CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK=y -# CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL is not set -# CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL is not set -# CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL is not set -# end of Example Connection Configuration - -# -# Compiler options -# -CONFIG_COMPILER_OPTIMIZATION_DEBUG=y -# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set -# CONFIG_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_COMPILER_OPTIMIZATION_NONE is not set -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set -CONFIG_COMPILER_ASSERT_NDEBUG_EVALUATE=y -CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 -# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set -CONFIG_COMPILER_HIDE_PATHS_MACROS=y -# CONFIG_COMPILER_CXX_EXCEPTIONS is not set -# CONFIG_COMPILER_CXX_RTTI is not set -CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y -# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# CONFIG_COMPILER_NO_MERGE_CONSTANTS is not set -CONFIG_COMPILER_WARN_WRITE_STRINGS=y -CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS=y -# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set -# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set -# CONFIG_COMPILER_DISABLE_GCC14_WARNINGS is not set -# CONFIG_COMPILER_DUMP_RTL_FILES is not set -CONFIG_COMPILER_RT_LIB_GCCLIB=y -CONFIG_COMPILER_RT_LIB_NAME="gcc" -CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y -# CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE is not set -# CONFIG_COMPILER_STATIC_ANALYZER is not set -# end of Compiler options - -# -# Component config -# - -# -# Application Level Tracing -# -# CONFIG_APPTRACE_DEST_JTAG is not set -CONFIG_APPTRACE_DEST_NONE=y -# CONFIG_APPTRACE_DEST_UART1 is not set -# CONFIG_APPTRACE_DEST_UART2 is not set -CONFIG_APPTRACE_DEST_UART_NONE=y -CONFIG_APPTRACE_UART_TASK_PRIO=1 -CONFIG_APPTRACE_LOCK_ENABLE=y -# end of Application Level Tracing - -# -# Bluetooth -# -# CONFIG_BT_ENABLED is not set - -# -# Common Options -# -# CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED is not set -# CONFIG_BT_BLE_LOG_UHCI_OUT_ENABLED is not set -# end of Common Options -# end of Bluetooth - -# -# Console Library -# -# CONFIG_CONSOLE_SORTED_HELP is not set -# end of Console Library - -# -# Driver Configurations -# - -# -# Legacy TWAI Driver Configurations -# -# CONFIG_TWAI_SKIP_LEGACY_CONFLICT_CHECK is not set -CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC=y -CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST=y -CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID=y -CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT=y -CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y -# end of Legacy TWAI Driver Configurations - -# -# Legacy ADC Driver Configuration -# -CONFIG_ADC_DISABLE_DAC=y -# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_ADC_SKIP_LEGACY_CONFLICT_CHECK is not set - -# -# Legacy ADC Calibration Configuration -# -CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y -CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CAL_LUT_ENABLE=y -# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set -# end of Legacy ADC Calibration Configuration -# end of Legacy ADC Driver Configuration - -# -# Legacy DAC Driver Configurations -# -# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_DAC_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy DAC Driver Configurations - -# -# Legacy MCPWM Driver Configurations -# -# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy MCPWM Driver Configurations - -# -# Legacy Timer Group Driver Configurations -# -# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_GPTIMER_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy Timer Group Driver Configurations - -# -# Legacy RMT Driver Configurations -# -# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_RMT_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy RMT Driver Configurations - -# -# Legacy I2S Driver Configurations -# -# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_I2S_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy I2S Driver Configurations - -# -# Legacy I2C Driver Configurations -# -# CONFIG_I2C_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy I2C Driver Configurations - -# -# Legacy PCNT Driver Configurations -# -# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_PCNT_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy PCNT Driver Configurations - -# -# Legacy SDM Driver Configurations -# -# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_SDM_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy SDM Driver Configurations - -# -# Legacy Touch Sensor Driver Configurations -# -# CONFIG_TOUCH_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_TOUCH_SKIP_LEGACY_CONFLICT_CHECK is not set -# end of Legacy Touch Sensor Driver Configurations -# end of Driver Configurations - -# -# eFuse Bit Manager -# -# CONFIG_EFUSE_CUSTOM_TABLE is not set -# CONFIG_EFUSE_VIRTUAL is not set -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set -CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set -CONFIG_EFUSE_MAX_BLK_LEN=192 -# end of eFuse Bit Manager - -# -# ESP-TLS -# -CONFIG_ESP_TLS_USING_MBEDTLS=y -# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set -# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set -# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set -# CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# CONFIG_ESP_TLS_INSECURE is not set -CONFIG_ESP_TLS_DYN_BUF_STRATEGY_SUPPORTED=y -# end of ESP-TLS - -# -# ADC and ADC Calibration -# -# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set -# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set - -# -# ADC Calibration Configurations -# -CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y -CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CALI_LUT_ENABLE=y -# end of ADC Calibration Configurations - -CONFIG_ADC_DISABLE_DAC_OUTPUT=y -# CONFIG_ADC_ENABLE_DEBUG_LOG is not set -# end of ADC and ADC Calibration - -# -# Wireless Coexistence -# -CONFIG_ESP_COEX_ENABLED=y -# CONFIG_ESP_COEX_GPIO_DEBUG is not set -# end of Wireless Coexistence - -# -# Common ESP-related -# -CONFIG_ESP_ERR_TO_NAME_LOOKUP=y -# end of Common ESP-related - -# -# ESP-Driver:DAC Configurations -# -# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set -# CONFIG_DAC_ISR_IRAM_SAFE is not set -# CONFIG_DAC_ENABLE_DEBUG_LOG is not set -CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y -# end of ESP-Driver:DAC Configurations - -# -# ESP-Driver:GPIO Configurations -# -# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set -# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set -# end of ESP-Driver:GPIO Configurations - -# -# ESP-Driver:GPTimer Configurations -# -CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y -# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set -# CONFIG_GPTIMER_ISR_CACHE_SAFE is not set -CONFIG_GPTIMER_OBJ_CACHE_SAFE=y -# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:GPTimer Configurations - -# -# ESP-Driver:I2C Configurations -# -# CONFIG_I2C_ISR_IRAM_SAFE is not set -# CONFIG_I2C_ENABLE_DEBUG_LOG is not set -# CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2 is not set -CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM=y -# end of ESP-Driver:I2C Configurations - -# -# ESP-Driver:I2S Configurations -# -# CONFIG_I2S_ISR_IRAM_SAFE is not set -# CONFIG_I2S_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:I2S Configurations - -# -# ESP-Driver:LEDC Configurations -# -# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set -# end of ESP-Driver:LEDC Configurations - -# -# ESP-Driver:MCPWM Configurations -# -CONFIG_MCPWM_ISR_HANDLER_IN_IRAM=y -# CONFIG_MCPWM_ISR_CACHE_SAFE is not set -# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set -CONFIG_MCPWM_OBJ_CACHE_SAFE=y -# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:MCPWM Configurations - -# -# ESP-Driver:PCNT Configurations -# -# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set -# CONFIG_PCNT_ISR_IRAM_SAFE is not set -# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:PCNT Configurations - -# -# ESP-Driver:RMT Configurations -# -CONFIG_RMT_ENCODER_FUNC_IN_IRAM=y -CONFIG_RMT_TX_ISR_HANDLER_IN_IRAM=y -CONFIG_RMT_RX_ISR_HANDLER_IN_IRAM=y -# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set -# CONFIG_RMT_TX_ISR_CACHE_SAFE is not set -# CONFIG_RMT_RX_ISR_CACHE_SAFE is not set -CONFIG_RMT_OBJ_CACHE_SAFE=y -# CONFIG_RMT_ENABLE_DEBUG_LOG is not set -# CONFIG_RMT_ISR_IRAM_SAFE is not set -# end of ESP-Driver:RMT Configurations - -# -# ESP-Driver:Sigma Delta Modulator Configurations -# -# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set -# CONFIG_SDM_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:Sigma Delta Modulator Configurations - -# -# ESP-Driver:SPI Configurations -# -# CONFIG_SPI_MASTER_IN_IRAM is not set -CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# CONFIG_SPI_SLAVE_IN_IRAM is not set -CONFIG_SPI_SLAVE_ISR_IN_IRAM=y -# end of ESP-Driver:SPI Configurations - -# -# ESP-Driver:Touch Sensor Configurations -# -# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set -# CONFIG_TOUCH_ISR_IRAM_SAFE is not set -# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set -# CONFIG_TOUCH_SKIP_FSM_CHECK is not set -# end of ESP-Driver:Touch Sensor Configurations - -# -# ESP-Driver:TWAI Configurations -# -# CONFIG_TWAI_ISR_IN_IRAM is not set -# CONFIG_TWAI_ISR_CACHE_SAFE is not set -# CONFIG_TWAI_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:TWAI Configurations - -# -# ESP-Driver:UART Configurations -# -# CONFIG_UART_ISR_IN_IRAM is not set -# end of ESP-Driver:UART Configurations - -# -# ESP-Driver:UHCI Configurations -# -# CONFIG_UHCI_ISR_HANDLER_IN_IRAM is not set -# CONFIG_UHCI_ISR_CACHE_SAFE is not set -# CONFIG_UHCI_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:UHCI Configurations - -# -# Ethernet -# -CONFIG_ETH_ENABLED=y -CONFIG_ETH_USE_ESP32_EMAC=y -CONFIG_ETH_PHY_INTERFACE_RMII=y -CONFIG_ETH_RMII_CLK_INPUT=y -# CONFIG_ETH_RMII_CLK_OUTPUT is not set -CONFIG_ETH_RMII_CLK_IN_GPIO=0 -CONFIG_ETH_DMA_BUFFER_SIZE=512 -CONFIG_ETH_DMA_RX_BUFFER_NUM=10 -CONFIG_ETH_DMA_TX_BUFFER_NUM=10 -# CONFIG_ETH_IRAM_OPTIMIZATION is not set -CONFIG_ETH_USE_SPI_ETHERNET=y -CONFIG_ETH_SPI_ETHERNET_DM9051=y -# CONFIG_ETH_SPI_ETHERNET_W5500 is not set -# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set -# CONFIG_ETH_USE_OPENETH is not set -# CONFIG_ETH_TRANSMIT_MUTEX is not set -# end of Ethernet - -# -# Event Loop Library -# -# CONFIG_ESP_EVENT_LOOP_PROFILING is not set -CONFIG_ESP_EVENT_POST_FROM_ISR=y -CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y -# end of Event Loop Library - -# -# GDB Stub -# -CONFIG_ESP_GDBSTUB_ENABLED=y -# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set -CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y -CONFIG_ESP_GDBSTUB_MAX_TASKS=32 -# end of GDB Stub - -# -# ESP HID -# -CONFIG_ESPHID_TASK_SIZE_BT=2048 -CONFIG_ESPHID_TASK_SIZE_BLE=4096 -# end of ESP HID - -# -# ESP HTTP client -# -CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set -# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set -CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT=2000 -# end of ESP HTTP client - -# -# HTTP Server -# -CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 -CONFIG_HTTPD_MAX_URI_LEN=512 -CONFIG_HTTPD_ERR_RESP_NO_DELAY=y -CONFIG_HTTPD_PURGE_BUF_LEN=32 -# CONFIG_HTTPD_LOG_PURGE_DATA is not set -# CONFIG_HTTPD_WS_SUPPORT is not set -# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set -CONFIG_HTTPD_SERVER_EVENT_POST_TIMEOUT=2000 -# end of HTTP Server - -# -# ESP HTTPS OTA -# -# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set -# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set -CONFIG_ESP_HTTPS_OTA_EVENT_POST_TIMEOUT=2000 -# end of ESP HTTPS OTA - -# -# ESP HTTPS server -# -# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set -CONFIG_ESP_HTTPS_SERVER_EVENT_POST_TIMEOUT=2000 -# CONFIG_ESP_HTTPS_SERVER_CERT_SELECT_HOOK is not set -# end of ESP HTTPS server - -# -# Hardware Settings -# - -# -# Chip revision -# -CONFIG_ESP32_REV_MIN_0=y -# CONFIG_ESP32_REV_MIN_1 is not set -# CONFIG_ESP32_REV_MIN_1_1 is not set -# CONFIG_ESP32_REV_MIN_2 is not set -# CONFIG_ESP32_REV_MIN_3 is not set -# CONFIG_ESP32_REV_MIN_3_1 is not set -CONFIG_ESP32_REV_MIN=0 -CONFIG_ESP32_REV_MIN_FULL=0 -CONFIG_ESP_REV_MIN_FULL=0 - -# -# Maximum Supported ESP32 Revision (Rev v3.99) -# -CONFIG_ESP32_REV_MAX_FULL=399 -CONFIG_ESP_REV_MAX_FULL=399 -CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL=0 -CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL=99 - -# -# Maximum Supported ESP32 eFuse Block Revision (eFuse Block Rev v0.99) -# -# end of Chip revision - -# -# MAC Config -# -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y -CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=4 -# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 -# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set -# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set -# end of MAC Config - -# -# Sleep Config -# -# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set -CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set -CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set -CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 -# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set -# CONFIG_ESP_SLEEP_DEBUG is not set -CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y -# end of Sleep Config - -# -# RTC Clock Config -# -CONFIG_RTC_CLK_SRC_INT_RC=y -# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_RTC_CLK_CAL_CYCLES=1024 -# end of RTC Clock Config - -# -# Peripheral Control -# -CONFIG_ESP_PERIPH_CTRL_FUNC_IN_IRAM=y -CONFIG_ESP_REGI2C_CTRL_FUNC_IN_IRAM=y -# end of Peripheral Control - -# -# Main XTAL Config -# -# CONFIG_XTAL_FREQ_26 is not set -# CONFIG_XTAL_FREQ_32 is not set -CONFIG_XTAL_FREQ_40=y -# CONFIG_XTAL_FREQ_AUTO is not set -CONFIG_XTAL_FREQ=40 -# end of Main XTAL Config - -# -# Power Supplier -# - -# -# Brownout Detector -# -CONFIG_ESP_BROWNOUT_DET=y -CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set -CONFIG_ESP_BROWNOUT_DET_LVL=0 -CONFIG_ESP_BROWNOUT_USE_INTR=y -# end of Brownout Detector -# end of Power Supplier - -CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y -CONFIG_ESP_INTR_IN_IRAM=y -# end of Hardware Settings - -# -# ESP-Driver:LCD Controller Configurations -# -# CONFIG_LCD_ENABLE_DEBUG_LOG is not set -# end of ESP-Driver:LCD Controller Configurations - -# -# ESP-MM: Memory Management Configurations -# -# end of ESP-MM: Memory Management Configurations - -# -# ESP NETIF Adapter -# -CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -# CONFIG_ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION is not set -CONFIG_ESP_NETIF_TCPIP_LWIP=y -# CONFIG_ESP_NETIF_LOOPBACK is not set -CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y -CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y -# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set -# CONFIG_ESP_NETIF_L2_TAP is not set -# CONFIG_ESP_NETIF_BRIDGE_EN is not set -# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set -# end of ESP NETIF Adapter - -# -# Partition API Configuration -# -# end of Partition API Configuration - -# -# PHY -# -CONFIG_ESP_PHY_ENABLED=y -CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP_PHY_MAX_TX_POWER=20 -CONFIG_ESP_PHY_REDUCE_TX_POWER=y -# CONFIG_ESP_PHY_ENABLE_CERT_TEST is not set -CONFIG_ESP_PHY_RF_CAL_PARTIAL=y -# CONFIG_ESP_PHY_RF_CAL_NONE is not set -# CONFIG_ESP_PHY_RF_CAL_FULL is not set -CONFIG_ESP_PHY_CALIBRATION_MODE=0 -CONFIG_ESP_PHY_PLL_TRACK_PERIOD_MS=1000 -# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set -# CONFIG_ESP_PHY_RECORD_USED_TIME is not set -CONFIG_ESP_PHY_IRAM_OPT=y -# CONFIG_ESP_PHY_DEBUG is not set -# end of PHY - -# -# Power Management -# -CONFIG_PM_SLEEP_FUNC_IN_IRAM=y -# CONFIG_PM_ENABLE is not set -CONFIG_PM_SLP_IRAM_OPT=y -# end of Power Management - -# -# ESP PSRAM -# -# CONFIG_SPIRAM is not set -# end of ESP PSRAM - -# -# ESP Ringbuf -# -# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set -# end of ESP Ringbuf - -# -# ESP-ROM -# -CONFIG_ESP_ROM_PRINT_IN_IRAM=y -# end of ESP-ROM - -# -# ESP Security Specific -# -# end of ESP Security Specific - -# -# ESP System Settings -# -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240 - -# -# Memory -# -# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set - -# -# Non-backward compatible options -# -# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set -# end of Non-backward compatible options -# end of Memory - -# -# Trace memory -# -# CONFIG_ESP32_TRAX is not set -CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 -# end of Trace memory - -CONFIG_ESP_SYSTEM_IN_IRAM=y -# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set -CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y -# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set -CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 - -# -# Memory protection -# -# end of Memory protection - -CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y -# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set -# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 -CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 -CONFIG_ESP_CONSOLE_UART_DEFAULT=y -# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_NONE is not set -CONFIG_ESP_CONSOLE_UART=y -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 -CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 -CONFIG_ESP_INT_WDT_CHECK_CPU1=y -CONFIG_ESP_TASK_WDT_EN=y -CONFIG_ESP_TASK_WDT_INIT=y -# CONFIG_ESP_TASK_WDT_PANIC is not set -CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP_PANIC_HANDLER_IRAM is not set -CONFIG_ESP_DEBUG_STUBS_ENABLE=y -CONFIG_ESP_DEBUG_OCDAWARE=y -# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y -# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set -# end of ESP System Settings - -# -# IPC (Inter-Processor Call) -# -CONFIG_ESP_IPC_ENABLE=y -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y -CONFIG_ESP_IPC_ISR_ENABLE=y -# end of IPC (Inter-Processor Call) - -# -# ESP Timer (High Resolution Timer) -# -CONFIG_ESP_TIMER_IN_IRAM=y -# CONFIG_ESP_TIMER_PROFILING is not set -CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y -CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y -CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 -# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set -CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 -CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y -CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y -# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set -CONFIG_ESP_TIMER_IMPL_TG0_LAC=y -# end of ESP Timer (High Resolution Timer) - -# -# Wi-Fi -# -CONFIG_ESP_WIFI_ENABLED=y -CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y -# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set -CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 -CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 -# CONFIG_ESP_WIFI_CSI_ENABLED is not set -CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP_WIFI_TX_BA_WIN=6 -CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP_WIFI_RX_BA_WIN=6 -CONFIG_ESP_WIFI_NVS_ENABLED=y -CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 -CONFIG_ESP_WIFI_IRAM_OPT=y -# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set -CONFIG_ESP_WIFI_RX_IRAM_OPT=y -CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y -CONFIG_ESP_WIFI_ENABLE_SAE_PK=y -CONFIG_ESP_WIFI_ENABLE_SAE_H2E=y -CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y -CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y -# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set -CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 -# CONFIG_ESP_WIFI_BSS_MAX_IDLE_SUPPORT is not set -CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 -CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 -CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y -CONFIG_ESP_WIFI_GMAC_SUPPORT=y -CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y -# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set -CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 -# CONFIG_ESP_WIFI_NAN_ENABLE is not set -CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y -CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y -# CONFIG_ESP_WIFI_WAPI_PSK is not set -# CONFIG_ESP_WIFI_11KV_SUPPORT is not set -# CONFIG_ESP_WIFI_MBO_SUPPORT is not set -# CONFIG_ESP_WIFI_DPP_SUPPORT is not set -# CONFIG_ESP_WIFI_11R_SUPPORT is not set -# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set - -# -# WPS Configuration Options -# -# CONFIG_ESP_WIFI_WPS_STRICT is not set -# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set -# end of WPS Configuration Options - -# CONFIG_ESP_WIFI_DEBUG_PRINT is not set -# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set -CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y -# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set -# end of Wi-Fi - -# -# Core dump -# -# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set -# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set -CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y -# end of Core dump - -# -# FAT Filesystem support -# -CONFIG_FATFS_VOLUME_COUNT=2 -CONFIG_FATFS_LFN_NONE=y -# CONFIG_FATFS_LFN_HEAP is not set -# CONFIG_FATFS_LFN_STACK is not set -# CONFIG_FATFS_SECTOR_512 is not set -CONFIG_FATFS_SECTOR_4096=y -# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set -CONFIG_FATFS_CODEPAGE_437=y -# CONFIG_FATFS_CODEPAGE_720 is not set -# CONFIG_FATFS_CODEPAGE_737 is not set -# CONFIG_FATFS_CODEPAGE_771 is not set -# CONFIG_FATFS_CODEPAGE_775 is not set -# CONFIG_FATFS_CODEPAGE_850 is not set -# CONFIG_FATFS_CODEPAGE_852 is not set -# CONFIG_FATFS_CODEPAGE_855 is not set -# CONFIG_FATFS_CODEPAGE_857 is not set -# CONFIG_FATFS_CODEPAGE_860 is not set -# CONFIG_FATFS_CODEPAGE_861 is not set -# CONFIG_FATFS_CODEPAGE_862 is not set -# CONFIG_FATFS_CODEPAGE_863 is not set -# CONFIG_FATFS_CODEPAGE_864 is not set -# CONFIG_FATFS_CODEPAGE_865 is not set -# CONFIG_FATFS_CODEPAGE_866 is not set -# CONFIG_FATFS_CODEPAGE_869 is not set -# CONFIG_FATFS_CODEPAGE_932 is not set -# CONFIG_FATFS_CODEPAGE_936 is not set -# CONFIG_FATFS_CODEPAGE_949 is not set -# CONFIG_FATFS_CODEPAGE_950 is not set -CONFIG_FATFS_CODEPAGE=437 -CONFIG_FATFS_FS_LOCK=0 -CONFIG_FATFS_TIMEOUT_MS=10000 -CONFIG_FATFS_PER_FILE_CACHE=y -# CONFIG_FATFS_USE_FASTSEEK is not set -CONFIG_FATFS_USE_STRFUNC_NONE=y -# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set -# CONFIG_FATFS_USE_STRFUNC_WITH_CRLF_CONV is not set -CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 -# CONFIG_FATFS_IMMEDIATE_FSYNC is not set -# CONFIG_FATFS_USE_LABEL is not set -CONFIG_FATFS_LINK_LOCK=y -# CONFIG_FATFS_USE_DYN_BUFFERS is not set - -# -# File system free space calculation behavior -# -CONFIG_FATFS_DONT_TRUST_FREE_CLUSTER_CNT=0 -CONFIG_FATFS_DONT_TRUST_LAST_ALLOC=0 -# end of File system free space calculation behavior -# end of FAT Filesystem support - -# -# FreeRTOS -# - -# -# Kernel -# -# CONFIG_FREERTOS_SMP is not set -# CONFIG_FREERTOS_UNICORE is not set -CONFIG_FREERTOS_HZ=100 -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 -CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -# CONFIG_FREERTOS_USE_IDLE_HOOK is not set -# CONFIG_FREERTOS_USE_TICK_HOOK is not set -CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set -CONFIG_FREERTOS_USE_TIMERS=y -CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" -# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set -# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1 is not set -CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y -CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 -CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 -CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 -CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 -CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 -# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set -# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set -# end of Kernel - -# -# Port -# -CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y -# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set -CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y -# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set -# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set -CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -CONFIG_FREERTOS_ISR_STACKSIZE=1536 -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -# CONFIG_FREERTOS_FPU_IN_ISR is not set -CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y -CONFIG_FREERTOS_CORETIMER_0=y -# CONFIG_FREERTOS_CORETIMER_1 is not set -CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y -# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set -# end of Port - -# -# Extra -# -# end of Extra - -CONFIG_FREERTOS_PORT=y -CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y -CONFIG_FREERTOS_DEBUG_OCDAWARE=y -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y -CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y -CONFIG_FREERTOS_NUMBER_OF_CORES=2 -CONFIG_FREERTOS_IN_IRAM=y -# end of FreeRTOS - -# -# Hardware Abstraction Layer (HAL) and Low Level (LL) -# -CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y -# CONFIG_HAL_ASSERTION_DISABLE is not set -# CONFIG_HAL_ASSERTION_SILENT is not set -# CONFIG_HAL_ASSERTION_ENABLE is not set -CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 -# end of Hardware Abstraction Layer (HAL) and Low Level (LL) - -# -# Heap memory debugging -# -CONFIG_HEAP_POISONING_DISABLED=y -# CONFIG_HEAP_POISONING_LIGHT is not set -# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set -CONFIG_HEAP_TRACING_OFF=y -# CONFIG_HEAP_TRACING_STANDALONE is not set -# CONFIG_HEAP_TRACING_TOHOST is not set -# CONFIG_HEAP_USE_HOOKS is not set -# CONFIG_HEAP_TASK_TRACKING is not set -# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set -# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set -# end of Heap memory debugging - -# -# Log -# -CONFIG_LOG_VERSION_1=y -# CONFIG_LOG_VERSION_2 is not set -CONFIG_LOG_VERSION=1 - -# -# Log Level -# -# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set -# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set -CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y -# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=4 -CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y -# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set -CONFIG_LOG_MAXIMUM_LEVEL=4 - -# -# Level Settings -# -# CONFIG_LOG_MASTER_LEVEL is not set -CONFIG_LOG_DYNAMIC_LEVEL_CONTROL=y -# CONFIG_LOG_TAG_LEVEL_IMPL_NONE is not set -# CONFIG_LOG_TAG_LEVEL_IMPL_LINKED_LIST is not set -CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST=y -# CONFIG_LOG_TAG_LEVEL_CACHE_ARRAY is not set -CONFIG_LOG_TAG_LEVEL_CACHE_BINARY_MIN_HEAP=y -CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_SIZE=31 -# end of Level Settings -# end of Log Level - -# -# Format -# -CONFIG_LOG_COLORS=y -CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y -# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Format - -# -# Settings -# -CONFIG_LOG_MODE_TEXT_EN=y -CONFIG_LOG_MODE_TEXT=y -# end of Settings - -CONFIG_LOG_IN_IRAM=y -# end of Log - -# -# LWIP -# -CONFIG_LWIP_ENABLE=y -CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -CONFIG_LWIP_TCPIP_TASK_PRIO=18 -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set -# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# CONFIG_LWIP_L2_TO_L3_COPY is not set -# CONFIG_LWIP_IRAM_OPTIMIZATION is not set -# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set -CONFIG_LWIP_TIMERS_ONDEMAND=y -CONFIG_LWIP_ND6=y -# CONFIG_LWIP_FORCE_ROUTER_FORWARDING is not set -CONFIG_LWIP_MAX_SOCKETS=10 -# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -# CONFIG_LWIP_SO_RCVBUF is not set -# CONFIG_LWIP_NETBUF_RECVINFO is not set -CONFIG_LWIP_IP_DEFAULT_TTL=64 -CONFIG_LWIP_IP4_FRAG=y -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP4_REASSEMBLY is not set -# CONFIG_LWIP_IP6_REASSEMBLY is not set -CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 -# CONFIG_LWIP_IP_FORWARD is not set -# CONFIG_LWIP_STATS is not set -CONFIG_LWIP_ESP_GRATUITOUS_ARP=y -CONFIG_LWIP_GARP_TMR_INTERVAL=60 -CONFIG_LWIP_ESP_MLDV6_REPORT=y -CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 -CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set -# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=69 -CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 -CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 - -# -# DHCP server -# -CONFIG_LWIP_DHCPS=y -CONFIG_LWIP_DHCPS_LEASE_UNIT=60 -CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 -CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y -CONFIG_LWIP_DHCPS_ADD_DNS=y -# end of DHCP server - -# CONFIG_LWIP_AUTOIP is not set -CONFIG_LWIP_IPV4=y -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=6 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 -CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -CONFIG_LWIP_TCP_RTO_TIME=3000 -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# end of UDP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -CONFIG_LWIP_IPV6_ND6_NUM_PREFIXES=5 -CONFIG_LWIP_IPV6_ND6_NUM_ROUTERS=3 -CONFIG_LWIP_IPV6_ND6_NUM_DESTINATIONS=10 -# CONFIG_LWIP_PPP_SUPPORT is not set -# CONFIG_LWIP_SLIP_SUPPORT is not set - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# SNTP -# -CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 -CONFIG_LWIP_SNTP_STARTUP_DELAY=y -CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 -# end of SNTP - -# -# DNS -# -CONFIG_LWIP_DNS_MAX_HOST_IP=1 -CONFIG_LWIP_DNS_MAX_SERVERS=3 -# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set -# CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF is not set -# CONFIG_LWIP_USE_ESP_GETADDRINFO is not set -# end of DNS - -CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 -CONFIG_LWIP_ESP_LWIP_ASSERT=y - -# -# Hooks -# -# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set -CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y -# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set -CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y -# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set -# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set -CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y -# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set -# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set -CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_NONE=y -# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_DEFAULT is not set -# CONFIG_LWIP_HOOK_IP6_SELECT_SRC_ADDR_CUSTOM is not set -CONFIG_LWIP_HOOK_DHCP_EXTRA_OPTION_NONE=y -# CONFIG_LWIP_HOOK_DHCP_EXTRA_OPTION_DEFAULT is not set -# CONFIG_LWIP_HOOK_DHCP_EXTRA_OPTION_CUSTOM is not set -CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set -CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_DNS_EXT_RESOLVE_CUSTOM is not set -# CONFIG_LWIP_HOOK_IP6_INPUT_NONE is not set -CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y -# CONFIG_LWIP_HOOK_IP6_INPUT_CUSTOM is not set -# end of Hooks - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP - -# -# mbedTLS -# -CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set -# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set -CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y -CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 -CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set -# CONFIG_MBEDTLS_DEBUG is not set - -# -# mbedTLS v3.x related -# -# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set -# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set -# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set -# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set -CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y -# CONFIG_MBEDTLS_SSL_KEYING_MATERIAL_EXPORT is not set -CONFIG_MBEDTLS_PKCS7_C=y -# end of mbedTLS v3.x related - -# -# Certificate Bundle -# -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 -# end of Certificate Bundle - -# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set -CONFIG_MBEDTLS_CMAC_C=y -CONFIG_MBEDTLS_HARDWARE_AES=y -CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y -# CONFIG_MBEDTLS_HARDWARE_MPI is not set -CONFIG_MBEDTLS_HARDWARE_SHA=y -CONFIG_MBEDTLS_ROM_MD5=y -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set -CONFIG_MBEDTLS_HAVE_TIME=y -# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set -# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set -CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y -CONFIG_MBEDTLS_SHA1_C=y -CONFIG_MBEDTLS_SHA512_C=y -# CONFIG_MBEDTLS_SHA3_C is not set -CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y -# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set -# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set -# CONFIG_MBEDTLS_TLS_DISABLED is not set -CONFIG_MBEDTLS_TLS_SERVER=y -CONFIG_MBEDTLS_TLS_CLIENT=y -CONFIG_MBEDTLS_TLS_ENABLED=y - -# -# TLS Key Exchange Methods -# -# CONFIG_MBEDTLS_PSK_MODES is not set -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y -# end of TLS Key Exchange Methods - -CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set -# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set -CONFIG_MBEDTLS_SSL_ALPN=y -CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y -CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y - -# -# Symmetric Ciphers -# -CONFIG_MBEDTLS_AES_C=y -# CONFIG_MBEDTLS_CAMELLIA_C is not set -# CONFIG_MBEDTLS_DES_C is not set -# CONFIG_MBEDTLS_BLOWFISH_C is not set -# CONFIG_MBEDTLS_XTEA_C is not set -CONFIG_MBEDTLS_CCM_C=y -CONFIG_MBEDTLS_GCM_C=y -# CONFIG_MBEDTLS_NIST_KW_C is not set -# end of Symmetric Ciphers - -# CONFIG_MBEDTLS_RIPEMD160_C is not set - -# -# Certificates -# -CONFIG_MBEDTLS_PEM_PARSE_C=y -CONFIG_MBEDTLS_PEM_WRITE_C=y -CONFIG_MBEDTLS_X509_CRL_PARSE_C=y -CONFIG_MBEDTLS_X509_CSR_PARSE_C=y -# end of Certificates - -CONFIG_MBEDTLS_ECP_C=y -CONFIG_MBEDTLS_PK_PARSE_EC_EXTENDED=y -CONFIG_MBEDTLS_PK_PARSE_EC_COMPRESSED=y -# CONFIG_MBEDTLS_DHM_C is not set -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -# CONFIG_MBEDTLS_ECJPAKE_C is not set -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y -CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set -# CONFIG_MBEDTLS_POLY1305_C is not set -# CONFIG_MBEDTLS_CHACHA20_C is not set -# CONFIG_MBEDTLS_HKDF_C is not set -# CONFIG_MBEDTLS_THREADING_C is not set -CONFIG_MBEDTLS_ERROR_STRINGS=y -CONFIG_MBEDTLS_FS_IO=y -# CONFIG_MBEDTLS_ALLOW_WEAK_CERTIFICATE_VERIFICATION is not set -# end of mbedTLS - -# -# ESP-MQTT Configurations -# -CONFIG_MQTT_PROTOCOL_311=y -# CONFIG_MQTT_PROTOCOL_5 is not set -CONFIG_MQTT_TRANSPORT_SSL=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y -# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set -# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set -# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# CONFIG_MQTT_CUSTOM_OUTBOX is not set -# end of ESP-MQTT Configurations - -# -# LibC -# -CONFIG_LIBC_NEWLIB=y -CONFIG_LIBC_MISC_IN_IRAM=y -CONFIG_LIBC_LOCKS_PLACE_IN_IRAM=y -CONFIG_LIBC_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_LIBC_STDOUT_LINE_ENDING_LF is not set -# CONFIG_LIBC_STDOUT_LINE_ENDING_CR is not set -# CONFIG_LIBC_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_LIBC_STDIN_LINE_ENDING_LF is not set -CONFIG_LIBC_STDIN_LINE_ENDING_CR=y -# CONFIG_LIBC_NEWLIB_NANO_FORMAT is not set -CONFIG_LIBC_TIME_SYSCALL_USE_RTC_HRT=y -# CONFIG_LIBC_TIME_SYSCALL_USE_RTC is not set -# CONFIG_LIBC_TIME_SYSCALL_USE_HRT is not set -# CONFIG_LIBC_TIME_SYSCALL_USE_NONE is not set -# end of LibC - -# -# NVS -# -# CONFIG_NVS_ASSERT_ERROR_CHECK is not set -# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set -# end of NVS - -# -# OpenThread -# -# CONFIG_OPENTHREAD_ENABLED is not set - -# -# OpenThread Spinel -# -# CONFIG_OPENTHREAD_SPINEL_ONLY is not set -# end of OpenThread Spinel -# end of OpenThread - -# -# Protocomm -# -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_PATCH_VERSION=y -# end of Protocomm - -# -# PThreads -# -CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_PTHREAD_STACK_MIN=768 -CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y -# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set -# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set -CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" -# end of PThreads - -# -# MMU Config -# -CONFIG_MMU_PAGE_SIZE_64KB=y -CONFIG_MMU_PAGE_MODE="64KB" -CONFIG_MMU_PAGE_SIZE=0x10000 -# end of MMU Config - -# -# Main Flash configuration -# - -# -# SPI Flash behavior when brownout -# -CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y -CONFIG_SPI_FLASH_BROWNOUT_RESET=y -# end of SPI Flash behavior when brownout - -# -# Optional and Experimental Features (READ DOCS FIRST) -# - -# -# Features here require specific hardware (READ DOCS FIRST!) -# -CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 -# CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND is not set -# CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND is not set -CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM=y -# end of Optional and Experimental Features (READ DOCS FIRST) -# end of Main Flash configuration - -# -# SPI Flash driver -# -# CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set -CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y -CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set -# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set -CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y -CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 -CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 -CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 -# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set -# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set -# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set - -# -# Auto-detect flash chips -# -CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_VENDOR_GD_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORT_ENABLED=y -CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y -# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set -# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set -# end of Auto-detect flash chips - -CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y -# end of SPI Flash driver - -# -# SPIFFS Configuration -# -CONFIG_SPIFFS_MAX_PARTITIONS=3 - -# -# SPIFFS Cache Configuration -# -CONFIG_SPIFFS_CACHE=y -CONFIG_SPIFFS_CACHE_WR=y -# CONFIG_SPIFFS_CACHE_STATS is not set -# end of SPIFFS Cache Configuration - -CONFIG_SPIFFS_PAGE_CHECK=y -CONFIG_SPIFFS_GC_MAX_RUNS=10 -# CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 -# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set -CONFIG_SPIFFS_USE_MAGIC=y -CONFIG_SPIFFS_USE_MAGIC_LENGTH=y -CONFIG_SPIFFS_META_LENGTH=4 -CONFIG_SPIFFS_USE_MTIME=y - -# -# Debug Configuration -# -# CONFIG_SPIFFS_DBG is not set -# CONFIG_SPIFFS_API_DBG is not set -# CONFIG_SPIFFS_GC_DBG is not set -# CONFIG_SPIFFS_CACHE_DBG is not set -# CONFIG_SPIFFS_CHECK_DBG is not set -# CONFIG_SPIFFS_TEST_VISUALISATION is not set -# end of Debug Configuration -# end of SPIFFS Configuration - -# -# TCP Transport -# - -# -# Websocket -# -CONFIG_WS_TRANSPORT=y -CONFIG_WS_BUFFER_SIZE=1024 -# CONFIG_WS_DYNAMIC_BUFFER is not set -# end of Websocket -# end of TCP Transport - -# -# Ultra Low Power (ULP) Co-processor -# -# CONFIG_ULP_COPROC_ENABLED is not set - -# -# ULP Debugging Options -# -# end of ULP Debugging Options -# end of Ultra Low Power (ULP) Co-processor - -# -# Unity unit testing library -# -CONFIG_UNITY_ENABLE_FLOAT=y -CONFIG_UNITY_ENABLE_DOUBLE=y -# CONFIG_UNITY_ENABLE_64BIT is not set -# CONFIG_UNITY_ENABLE_COLOR is not set -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# CONFIG_UNITY_ENABLE_FIXTURE is not set -# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set -# CONFIG_UNITY_TEST_ORDER_BY_FILE_PATH_AND_LINE is not set -# end of Unity unit testing library - -# -# Virtual file system -# -CONFIG_VFS_SUPPORT_IO=y -CONFIG_VFS_SUPPORT_DIR=y -CONFIG_VFS_SUPPORT_SELECT=y -CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -# CONFIG_VFS_SELECT_IN_RAM is not set -CONFIG_VFS_SUPPORT_TERMIOS=y -CONFIG_VFS_MAX_COUNT=8 - -# -# Host File System I/O (Semihosting) -# -CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# end of Host File System I/O (Semihosting) - -CONFIG_VFS_INITIALIZE_DEV_NULL=y -# end of Virtual file system - -# -# Wear Levelling -# -# CONFIG_WL_SECTOR_SIZE_512 is not set -CONFIG_WL_SECTOR_SIZE_4096=y -CONFIG_WL_SECTOR_SIZE=4096 -# end of Wear Levelling - -# -# Wi-Fi Provisioning Manager -# -CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y -# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set -# end of Wi-Fi Provisioning Manager -# end of Component config - -# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set - -# Deprecated options for backward compatibility -# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set -# CONFIG_NO_BLOBS is not set -# CONFIG_ESP32_NO_BLOBS is not set -# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set -# CONFIG_APP_ROLLBACK_ENABLE is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set -CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y -# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set -CONFIG_LOG_BOOTLOADER_LEVEL=3 -# CONFIG_FLASH_ENCRYPTION_ENABLED is not set -# CONFIG_FLASHMODE_QIO is not set -# CONFIG_FLASHMODE_QOUT is not set -CONFIG_FLASHMODE_DIO=y -# CONFIG_FLASHMODE_DOUT is not set -CONFIG_MONITOR_BAUD=115200 -CONFIG_OPTIMIZATION_LEVEL_DEBUG=y -CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y -CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y -# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set -# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set -CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y -# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set -CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 -# CONFIG_CXX_EXCEPTIONS is not set -CONFIG_STACK_CHECK_NONE=y -# CONFIG_STACK_CHECK_NORM is not set -# CONFIG_STACK_CHECK_STRONG is not set -# CONFIG_STACK_CHECK_ALL is not set -CONFIG_WARN_WRITE_STRINGS=y -# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set -CONFIG_ESP32_APPTRACE_DEST_NONE=y -CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -CONFIG_ADC2_DISABLE_DAC=y -# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set -# CONFIG_MCPWM_ISR_IRAM_SAFE is not set -# CONFIG_EVENT_LOOP_PROFILING is not set -CONFIG_POST_EVENTS_FROM_ISR=y -CONFIG_POST_EVENTS_FROM_IRAM_ISR=y -CONFIG_GDBSTUB_SUPPORT_TASKS=y -CONFIG_GDBSTUB_MAX_TASKS=32 -# CONFIG_OTA_ALLOW_HTTP is not set -# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set -CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y -CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 -# CONFIG_ESP_SYSTEM_PD_FLASH is not set -CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 -CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 -CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y -CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y -# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set -# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set -# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set -# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set -CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 -CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y -# CONFIG_ESP32_XTAL_FREQ_26 is not set -CONFIG_ESP32_XTAL_FREQ_40=y -# CONFIG_ESP32_XTAL_FREQ_AUTO is not set -CONFIG_ESP32_XTAL_FREQ=40 -CONFIG_BROWNOUT_DET=y -CONFIG_ESP32_BROWNOUT_DET=y -CONFIG_BROWNOUT_DET_LVL_SEL_0=y -CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y -# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set -CONFIG_BROWNOUT_DET_LVL=0 -CONFIG_ESP32_BROWNOUT_DET_LVL=0 -CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y -CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP32_PHY_MAX_TX_POWER=20 -CONFIG_REDUCE_PHY_TX_POWER=y -CONFIG_ESP32_REDUCE_PHY_TX_POWER=y -# CONFIG_SPIRAM_SUPPORT is not set -# CONFIG_ESP32_SPIRAM_SUPPORT is not set -# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set -# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y -CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 -CONFIG_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32_PANIC_PRINT_HALT is not set -CONFIG_ESP32_PANIC_PRINT_REBOOT=y -# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP32_PANIC_GDBSTUB is not set -CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=3584 -CONFIG_CONSOLE_UART_DEFAULT=y -# CONFIG_CONSOLE_UART_CUSTOM is not set -# CONFIG_CONSOLE_UART_NONE is not set -# CONFIG_ESP_CONSOLE_UART_NONE is not set -CONFIG_CONSOLE_UART=y -CONFIG_CONSOLE_UART_NUM=0 -CONFIG_CONSOLE_UART_BAUDRATE=115200 -CONFIG_INT_WDT=y -CONFIG_INT_WDT_TIMEOUT_MS=300 -CONFIG_INT_WDT_CHECK_CPU1=y -CONFIG_TASK_WDT=y -CONFIG_ESP_TASK_WDT=y -# CONFIG_TASK_WDT_PANIC is not set -CONFIG_TASK_WDT_TIMEOUT_S=5 -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -CONFIG_ESP32_DEBUG_STUBS_ENABLE=y -CONFIG_ESP32_DEBUG_OCDAWARE=y -# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set -CONFIG_IPC_TASK_STACK_SIZE=1024 -CONFIG_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP32_WIFI_ENABLED=y -CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_CSI_ENABLED is not set -CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP32_WIFI_TX_BA_WIN=6 -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -CONFIG_ESP32_WIFI_NVS_ENABLED=y -CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y -CONFIG_WPA_MBEDTLS_CRYPTO=y -CONFIG_WPA_MBEDTLS_TLS_CLIENT=y -# CONFIG_WPA_WAPI_PSK is not set -# CONFIG_WPA_11KV_SUPPORT is not set -# CONFIG_WPA_MBO_SUPPORT is not set -# CONFIG_WPA_DPP_SUPPORT is not set -# CONFIG_WPA_11R_SUPPORT is not set -# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set -# CONFIG_WPA_WPS_STRICT is not set -# CONFIG_WPA_DEBUG_PRINT is not set -# CONFIG_WPA_TESTING_OPTIONS is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set -CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y -CONFIG_TIMER_TASK_PRIORITY=1 -CONFIG_TIMER_TASK_STACK_DEPTH=2048 -CONFIG_TIMER_QUEUE_LENGTH=10 -# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set -# CONFIG_HAL_ASSERTION_SILIENT is not set -# CONFIG_L2_TO_L3_COPY is not set -CONFIG_ESP_GRATUITOUS_ARP=y -CONFIG_GARP_TMR_INTERVAL=60 -CONFIG_TCPIP_RECVMBOX_SIZE=32 -CONFIG_TCP_MAXRTX=12 -CONFIG_TCP_SYNMAXRTX=6 -CONFIG_TCP_MSS=1440 -CONFIG_TCP_MSL=60000 -CONFIG_TCP_SND_BUF_DEFAULT=5744 -CONFIG_TCP_WND_DEFAULT=5744 -CONFIG_TCP_RECVMBOX_SIZE=6 -CONFIG_TCP_QUEUE_OOSEQ=y -CONFIG_TCP_OVERSIZE_MSS=y -# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_TCP_OVERSIZE_DISABLE is not set -CONFIG_UDP_RECVMBOX_SIZE=6 -CONFIG_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_PPP_SUPPORT is not set -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# CONFIG_NEWLIB_NANO_FORMAT is not set -CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y -CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y -CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set -CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_ESP32_PTHREAD_STACK_MIN=768 -CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y -# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set -# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set -CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -# CONFIG_ESP32_ULP_COPROC_ENABLED is not set -CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y -CONFIG_SUPPORT_TERMIOS=y -CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# End of deprecated options diff --git a/esp-idf-examples/simplewifi/sdkconfig.old b/esp-idf-examples/simplewifi/sdkconfig.old deleted file mode 100644 index aba46562..00000000 --- a/esp-idf-examples/simplewifi/sdkconfig.old +++ /dev/null @@ -1,955 +0,0 @@ -# -# Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) Project Configuration -# -CONFIG_IDF_CMAKE=y -CONFIG_IDF_TARGET="esp32" -CONFIG_IDF_TARGET_ESP32=y -CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 - -# -# SDK tool configuration -# -CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-" -# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set -# end of SDK tool configuration - -# -# Build type -# -CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y -# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set -CONFIG_APP_BUILD_GENERATE_BINARIES=y -CONFIG_APP_BUILD_BOOTLOADER=y -CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# end of Build type - -# -# Application manager -# -CONFIG_APP_COMPILE_TIME_DATE=y -# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 -# end of Application manager - -# -# Bootloader config -# -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set -CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y -# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set -CONFIG_BOOTLOADER_LOG_LEVEL=3 -# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set -CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# CONFIG_BOOTLOADER_FACTORY_RESET is not set -# CONFIG_BOOTLOADER_APP_TEST is not set -CONFIG_BOOTLOADER_WDT_ENABLE=y -# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set -CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -# end of Bootloader config - -# -# Security features -# -# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# CONFIG_SECURE_BOOT is not set -# CONFIG_SECURE_FLASH_ENC_ENABLED is not set -# end of Security features - -# -# Serial flasher config -# -CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y -# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE="dio" -# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_40M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ="40m" -# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y -CONFIG_ESPTOOLPY_BEFORE_RESET=y -# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set -CONFIG_ESPTOOLPY_BEFORE="default_reset" -CONFIG_ESPTOOLPY_AFTER_RESET=y -# CONFIG_ESPTOOLPY_AFTER_NORESET is not set -CONFIG_ESPTOOLPY_AFTER="hard_reset" -# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set -CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y -# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set -CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 -CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 -# end of Serial flasher config - -# -# Partition Table -# -CONFIG_PARTITION_TABLE_SINGLE_APP=y -# CONFIG_PARTITION_TABLE_TWO_OTA is not set -# CONFIG_PARTITION_TABLE_CUSTOM is not set -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 -CONFIG_PARTITION_TABLE_MD5=y -# end of Partition Table - -# -# Wifi Example Configuration -# -CONFIG_EXAMPLE_WIFI_SSID="myssid" -CONFIG_EXAMPLE_WIFI_PASSWORD="mypassword" -# end of Wifi Example Configuration - -# -# Example Connection Configuration -# -CONFIG_EXAMPLE_CONNECT_WIFI=y -# CONFIG_EXAMPLE_CONNECT_ETHERNET is not set -CONFIG_EXAMPLE_CONNECT_IPV6=y -# end of Example Connection Configuration - -# -# Compiler options -# -CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y -# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set -# CONFIG_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_COMPILER_OPTIMIZATION_NONE is not set -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set -# CONFIG_COMPILER_CXX_EXCEPTIONS is not set -# CONFIG_COMPILER_CXX_RTTI is not set -CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y -# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set -# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set -# end of Compiler options - -# -# Component config -# - -# -# Application Level Tracing -# -# CONFIG_APPTRACE_DEST_TRAX is not set -CONFIG_APPTRACE_DEST_NONE=y -CONFIG_APPTRACE_LOCK_ENABLE=y -# end of Application Level Tracing - -# -# Bluetooth -# -# CONFIG_BT_ENABLED is not set -CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 -CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 -CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 -CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 -CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 -CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 -CONFIG_BT_RESERVE_DRAM=0 -# end of Bluetooth - -# CONFIG_BLE_MESH is not set - -# -# CoAP Configuration -# -CONFIG_COAP_MBEDTLS_PSK=y -# CONFIG_COAP_MBEDTLS_PKI is not set -# CONFIG_COAP_MBEDTLS_DEBUG is not set -CONFIG_COAP_LOG_DEFAULT_LEVEL=0 -# end of CoAP Configuration - -# -# Driver configurations -# - -# -# ADC configuration -# -# CONFIG_ADC_FORCE_XPD_FSM is not set -CONFIG_ADC_DISABLE_DAC=y -# end of ADC configuration - -# -# SPI configuration -# -# CONFIG_SPI_MASTER_IN_IRAM is not set -CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# CONFIG_SPI_SLAVE_IN_IRAM is not set -CONFIG_SPI_SLAVE_ISR_IN_IRAM=y -# end of SPI configuration - -# -# UART configuration -# -# CONFIG_UART_ISR_IN_IRAM is not set -# end of UART configuration - -# -# RTCIO configuration -# -# CONFIG_RTCIO_SUPPORT_RTC_GPIO_DESC is not set -# end of RTCIO configuration -# end of Driver configurations - -# -# eFuse Bit Manager -# -# CONFIG_EFUSE_CUSTOM_TABLE is not set -# CONFIG_EFUSE_VIRTUAL is not set -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set -CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y -# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set -CONFIG_EFUSE_MAX_BLK_LEN=192 -# end of eFuse Bit Manager - -# -# ESP-TLS -# -CONFIG_ESP_TLS_USING_MBEDTLS=y -# CONFIG_ESP_TLS_SERVER is not set -# CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# end of ESP-TLS - -# -# ESP32-specific -# -CONFIG_ESP32_REV_MIN_0=y -# CONFIG_ESP32_REV_MIN_1 is not set -# CONFIG_ESP32_REV_MIN_2 is not set -# CONFIG_ESP32_REV_MIN_3 is not set -CONFIG_ESP32_REV_MIN=0 -CONFIG_ESP32_DPORT_WORKAROUND=y -# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set -# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set -CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y -CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 -# CONFIG_ESP32_SPIRAM_SUPPORT is not set -# CONFIG_ESP32_TRAX is not set -CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 -# CONFIG_ESP32_ULP_COPROC_ENABLED is not set -CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0 -# CONFIG_ESP32_PANIC_PRINT_HALT is not set -CONFIG_ESP32_PANIC_PRINT_REBOOT=y -# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP32_PANIC_GDBSTUB is not set -CONFIG_ESP32_DEBUG_OCDAWARE=y -CONFIG_ESP32_BROWNOUT_DET=y -CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set -CONFIG_ESP32_BROWNOUT_DET_LVL=0 -CONFIG_ESP32_REDUCE_PHY_TX_POWER=y -CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set -# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set -CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y -# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 -CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 -CONFIG_ESP32_XTAL_FREQ_40=y -# CONFIG_ESP32_XTAL_FREQ_26 is not set -# CONFIG_ESP32_XTAL_FREQ_AUTO is not set -CONFIG_ESP32_XTAL_FREQ=40 -# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set -# CONFIG_ESP32_NO_BLOBS is not set -# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set -# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set -CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5 -# end of ESP32-specific - -# -# Power Management -# -# CONFIG_PM_ENABLE is not set -# end of Power Management - -# -# ADC-Calibration -# -CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y -CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CAL_LUT_ENABLE=y -# end of ADC-Calibration - -# -# Common ESP-related -# -# CONFIG_ESP_TIMER_PROFILING is not set -CONFIG_ESP_ERR_TO_NAME_LOOKUP=y -CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y -CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 -CONFIG_ESP_CONSOLE_UART_DEFAULT=y -# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_UART_NONE is not set -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 -CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 -CONFIG_ESP_INT_WDT_CHECK_CPU1=y -CONFIG_ESP_TASK_WDT=y -# CONFIG_ESP_TASK_WDT_PANIC is not set -CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# end of Common ESP-related - -# -# Ethernet -# -CONFIG_ETH_ENABLED=y -CONFIG_ETH_USE_ESP32_EMAC=y -CONFIG_ETH_PHY_INTERFACE_RMII=y -# CONFIG_ETH_PHY_INTERFACE_MII is not set -CONFIG_ETH_RMII_CLK_INPUT=y -# CONFIG_ETH_RMII_CLK_OUTPUT is not set -CONFIG_ETH_RMII_CLK_IN_GPIO=0 -CONFIG_ETH_DMA_BUFFER_SIZE=512 -CONFIG_ETH_DMA_RX_BUFFER_NUM=10 -CONFIG_ETH_DMA_TX_BUFFER_NUM=10 -CONFIG_ETH_USE_SPI_ETHERNET=y -CONFIG_ETH_SPI_ETHERNET_DM9051=y -# CONFIG_ETH_USE_OPENETH is not set -# end of Ethernet - -# -# Event Loop Library -# -# CONFIG_ESP_EVENT_LOOP_PROFILING is not set -CONFIG_ESP_EVENT_POST_FROM_ISR=y -CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y -# end of Event Loop Library - -# -# GDB Stub -# -# end of GDB Stub - -# -# ESP HTTP client -# -CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -# end of ESP HTTP client - -# -# HTTP Server -# -CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 -CONFIG_HTTPD_MAX_URI_LEN=512 -CONFIG_HTTPD_ERR_RESP_NO_DELAY=y -CONFIG_HTTPD_PURGE_BUF_LEN=32 -# CONFIG_HTTPD_LOG_PURGE_DATA is not set -# end of HTTP Server - -# -# ESP HTTPS OTA -# -# CONFIG_OTA_ALLOW_HTTP is not set -# end of ESP HTTPS OTA - -# -# ESP HTTPS server -# -# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set -# end of ESP HTTPS server - -# -# ESP NETIF Adapter -# -CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -CONFIG_ESP_NETIF_TCPIP_LWIP=y -# CONFIG_ESP_NETIF_LOOPBACK is not set -CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y -# end of ESP NETIF Adapter - -# -# Wi-Fi -# -CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 -CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_CSI_ENABLED is not set -CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP32_WIFI_TX_BA_WIN=6 -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -CONFIG_ESP32_WIFI_NVS_ENABLED=y -CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -# CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE is not set -CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y -# end of Wi-Fi - -# -# PHY -# -CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# end of PHY - -# -# Core dump -# -# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set -CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y -# end of Core dump - -# -# FAT Filesystem support -# -# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set -CONFIG_FATFS_CODEPAGE_437=y -# CONFIG_FATFS_CODEPAGE_720 is not set -# CONFIG_FATFS_CODEPAGE_737 is not set -# CONFIG_FATFS_CODEPAGE_771 is not set -# CONFIG_FATFS_CODEPAGE_775 is not set -# CONFIG_FATFS_CODEPAGE_850 is not set -# CONFIG_FATFS_CODEPAGE_852 is not set -# CONFIG_FATFS_CODEPAGE_855 is not set -# CONFIG_FATFS_CODEPAGE_857 is not set -# CONFIG_FATFS_CODEPAGE_860 is not set -# CONFIG_FATFS_CODEPAGE_861 is not set -# CONFIG_FATFS_CODEPAGE_862 is not set -# CONFIG_FATFS_CODEPAGE_863 is not set -# CONFIG_FATFS_CODEPAGE_864 is not set -# CONFIG_FATFS_CODEPAGE_865 is not set -# CONFIG_FATFS_CODEPAGE_866 is not set -# CONFIG_FATFS_CODEPAGE_869 is not set -# CONFIG_FATFS_CODEPAGE_932 is not set -# CONFIG_FATFS_CODEPAGE_936 is not set -# CONFIG_FATFS_CODEPAGE_949 is not set -# CONFIG_FATFS_CODEPAGE_950 is not set -CONFIG_FATFS_CODEPAGE=437 -CONFIG_FATFS_LFN_NONE=y -# CONFIG_FATFS_LFN_HEAP is not set -# CONFIG_FATFS_LFN_STACK is not set -CONFIG_FATFS_FS_LOCK=0 -CONFIG_FATFS_TIMEOUT_MS=10000 -CONFIG_FATFS_PER_FILE_CACHE=y -# end of FAT Filesystem support - -# -# Modbus configuration -# -CONFIG_FMB_COMM_MODE_RTU_EN=y -CONFIG_FMB_COMM_MODE_ASCII_EN=y -CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 -CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_FMB_QUEUE_LENGTH=20 -CONFIG_FMB_SERIAL_TASK_STACK_SIZE=2048 -CONFIG_FMB_SERIAL_BUF_SIZE=256 -CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 -CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 -CONFIG_FMB_SERIAL_TASK_PRIO=10 -# CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT is not set -CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 -CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 -CONFIG_FMB_TIMER_PORT_ENABLED=y -CONFIG_FMB_TIMER_GROUP=0 -CONFIG_FMB_TIMER_INDEX=0 -# CONFIG_FMB_TIMER_ISR_IN_IRAM is not set -# end of Modbus configuration - -# -# FreeRTOS -# -# CONFIG_FREERTOS_UNICORE is not set -CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_CORETIMER_0=y -# CONFIG_FREERTOS_CORETIMER_1 is not set -CONFIG_FREERTOS_HZ=100 -CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 -CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y -# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set -# CONFIG_FREERTOS_ASSERT_DISABLE is not set -CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -CONFIG_FREERTOS_ISR_STACKSIZE=1536 -# CONFIG_FREERTOS_LEGACY_HOOKS is not set -CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -# CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION is not set -CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 -CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 -CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 -CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 -# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -# CONFIG_FREERTOS_DEBUG_INTERNALS is not set -CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y -CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set -CONFIG_FREERTOS_DEBUG_OCDAWARE=y -# end of FreeRTOS - -# -# Heap memory debugging -# -CONFIG_HEAP_POISONING_DISABLED=y -# CONFIG_HEAP_POISONING_LIGHT is not set -# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set -CONFIG_HEAP_TRACING_OFF=y -# CONFIG_HEAP_TRACING_STANDALONE is not set -# CONFIG_HEAP_TRACING_TOHOST is not set -# end of Heap memory debugging - -# -# jsmn -# -# CONFIG_JSMN_PARENT_LINKS is not set -# CONFIG_JSMN_STRICT is not set -# end of jsmn - -# -# libsodium -# -# end of libsodium - -# -# Log output -# -# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set -# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set -CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y -# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=4 -CONFIG_LOG_COLORS=y -CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y -# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output - -# -# LWIP -# -CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# CONFIG_LWIP_L2_TO_L3_COPY is not set -# CONFIG_LWIP_IRAM_OPTIMIZATION is not set -CONFIG_LWIP_TIMERS_ONDEMAND=y -CONFIG_LWIP_MAX_SOCKETS=10 -# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -# CONFIG_LWIP_SO_RCVBUF is not set -# CONFIG_LWIP_NETBUF_RECVINFO is not set -CONFIG_LWIP_IP4_FRAG=y -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP4_REASSEMBLY is not set -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# CONFIG_LWIP_STATS is not set -# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set -CONFIG_LWIP_ESP_GRATUITOUS_ARP=y -CONFIG_LWIP_GARP_TMR_INTERVAL=60 -CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set - -# -# DHCP server -# -CONFIG_LWIP_DHCPS_LEASE_UNIT=60 -CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 -# end of DHCP server - -# CONFIG_LWIP_AUTOIP is not set -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=6 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -CONFIG_LWIP_TCP_RTO_TIME=3000 -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# end of UDP - -CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 - -# -# ICMP -# -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# SNTP -# -CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 -CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 -# end of SNTP -# end of LWIP - -# -# mbedTLS -# -CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set -# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set -CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y -CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 -CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# CONFIG_MBEDTLS_DEBUG is not set -# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set -# CONFIG_MBEDTLS_CMAC_C is not set -CONFIG_MBEDTLS_HARDWARE_AES=y -# CONFIG_MBEDTLS_HARDWARE_MPI is not set -CONFIG_MBEDTLS_HARDWARE_SHA=y -CONFIG_MBEDTLS_HAVE_TIME=y -# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set -CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y -# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set -# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set -# CONFIG_MBEDTLS_TLS_DISABLED is not set -CONFIG_MBEDTLS_TLS_SERVER=y -CONFIG_MBEDTLS_TLS_CLIENT=y -CONFIG_MBEDTLS_TLS_ENABLED=y - -# -# TLS Key Exchange Methods -# -# CONFIG_MBEDTLS_PSK_MODES is not set -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y -# end of TLS Key Exchange Methods - -CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set -CONFIG_MBEDTLS_SSL_PROTO_TLS1=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set -CONFIG_MBEDTLS_SSL_ALPN=y -CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y -CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y - -# -# Symmetric Ciphers -# -CONFIG_MBEDTLS_AES_C=y -# CONFIG_MBEDTLS_CAMELLIA_C is not set -# CONFIG_MBEDTLS_DES_C is not set -CONFIG_MBEDTLS_RC4_DISABLED=y -# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set -# CONFIG_MBEDTLS_RC4_ENABLED is not set -# CONFIG_MBEDTLS_BLOWFISH_C is not set -# CONFIG_MBEDTLS_XTEA_C is not set -CONFIG_MBEDTLS_CCM_C=y -CONFIG_MBEDTLS_GCM_C=y -# end of Symmetric Ciphers - -# CONFIG_MBEDTLS_RIPEMD160_C is not set - -# -# Certificates -# -CONFIG_MBEDTLS_PEM_PARSE_C=y -CONFIG_MBEDTLS_PEM_WRITE_C=y -CONFIG_MBEDTLS_X509_CRL_PARSE_C=y -CONFIG_MBEDTLS_X509_CSR_PARSE_C=y -# end of Certificates - -CONFIG_MBEDTLS_ECP_C=y -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y -CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# CONFIG_MBEDTLS_SECURITY_RISKS is not set -# end of mbedTLS - -# -# mDNS -# -CONFIG_MDNS_MAX_SERVICES=10 -CONFIG_MDNS_TASK_PRIORITY=1 -# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_MDNS_TASK_AFFINITY_CPU0=y -# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set -CONFIG_MDNS_TASK_AFFINITY=0x0 -CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 -CONFIG_MDNS_TIMER_PERIOD_MS=100 -# end of mDNS - -# -# ESP-MQTT Configurations -# -CONFIG_MQTT_PROTOCOL_311=y -CONFIG_MQTT_TRANSPORT_SSL=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y -# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# CONFIG_MQTT_CUSTOM_OUTBOX is not set -# end of ESP-MQTT Configurations - -# -# Newlib -# -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# CONFIG_NEWLIB_NANO_FORMAT is not set -# end of Newlib - -# -# NVS -# -# end of NVS - -# -# OpenSSL -# -# CONFIG_OPENSSL_DEBUG is not set -# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set -CONFIG_OPENSSL_ASSERT_EXIT=y -# end of OpenSSL - -# -# PThreads -# -CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_PTHREAD_STACK_MIN=768 -CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y -# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set -# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set -CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" -# end of PThreads - -# -# SPI Flash driver -# -# CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set -CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y -CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set -# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set -CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y -CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 -CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 - -# -# Auto-detect flash chips -# -CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y -# end of Auto-detect flash chips -# end of SPI Flash driver - -# -# SPIFFS Configuration -# -CONFIG_SPIFFS_MAX_PARTITIONS=3 - -# -# SPIFFS Cache Configuration -# -CONFIG_SPIFFS_CACHE=y -CONFIG_SPIFFS_CACHE_WR=y -# CONFIG_SPIFFS_CACHE_STATS is not set -# end of SPIFFS Cache Configuration - -CONFIG_SPIFFS_PAGE_CHECK=y -CONFIG_SPIFFS_GC_MAX_RUNS=10 -# CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 -# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set -CONFIG_SPIFFS_USE_MAGIC=y -CONFIG_SPIFFS_USE_MAGIC_LENGTH=y -CONFIG_SPIFFS_META_LENGTH=4 -CONFIG_SPIFFS_USE_MTIME=y - -# -# Debug Configuration -# -# CONFIG_SPIFFS_DBG is not set -# CONFIG_SPIFFS_API_DBG is not set -# CONFIG_SPIFFS_GC_DBG is not set -# CONFIG_SPIFFS_CACHE_DBG is not set -# CONFIG_SPIFFS_CHECK_DBG is not set -# CONFIG_SPIFFS_TEST_VISUALISATION is not set -# end of Debug Configuration -# end of SPIFFS Configuration - -# -# Unity unit testing library -# -CONFIG_UNITY_ENABLE_FLOAT=y -CONFIG_UNITY_ENABLE_DOUBLE=y -# CONFIG_UNITY_ENABLE_COLOR is not set -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# CONFIG_UNITY_ENABLE_FIXTURE is not set -# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set -# end of Unity unit testing library - -# -# Virtual file system -# -CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -CONFIG_VFS_SUPPORT_TERMIOS=y - -# -# Host File System I/O (Semihosting) -# -CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 -# end of Host File System I/O (Semihosting) -# end of Virtual file system - -# -# Wear Levelling -# -# CONFIG_WL_SECTOR_SIZE_512 is not set -CONFIG_WL_SECTOR_SIZE_4096=y -CONFIG_WL_SECTOR_SIZE=4096 -# end of Wear Levelling - -# -# Wi-Fi Provisioning Manager -# -CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# end of Wi-Fi Provisioning Manager - -# -# Supplicant -# -CONFIG_WPA_MBEDTLS_CRYPTO=y -# CONFIG_WPA_TLS_V12 is not set -# CONFIG_WPA_WPS_WARS is not set -# end of Supplicant -# end of Component config - -# -# Compatibility options -# -# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set -# end of Compatibility options From a474e5389a8286a2564707546d63d39ecb7e4bc6 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 00:23:33 -0600 Subject: [PATCH 113/142] update wifi example --- esp-idf-examples/simplewifi/config.nims | 4 +- esp-idf-examples/simplewifi/main/main.nim | 185 +++++++++------------- 2 files changed, 76 insertions(+), 113 deletions(-) diff --git a/esp-idf-examples/simplewifi/config.nims b/esp-idf-examples/simplewifi/config.nims index 94d6132b..bd5706dd 100644 --- a/esp-idf-examples/simplewifi/config.nims +++ b/esp-idf-examples/simplewifi/config.nims @@ -7,8 +7,8 @@ switch("define", "McuUtilsLoggingLevel:lvlTrace") patchFile("stdlib", "ioselectors_select", "main/ioselectors_select.nim") -switch("define", "WIFI_SSID=" & getEnv("WIFI_SSID")) -switch("define", "WIFI_PASSWORD=" & getEnv("WIFI_PASSWORD")) +switch("define", "EXAMPLE_ESP_WIFI_SSID=" & getEnv("WIFI_SSID")) +switch("define", "EXAMPLE_ESP_WIFI_PASS=" & getEnv("WIFI_PASSWORD")) include nesper/build_utils/builds diff --git a/esp-idf-examples/simplewifi/main/main.nim b/esp-idf-examples/simplewifi/main/main.nim index fc4c9369..4eb00c8c 100644 --- a/esp-idf-examples/simplewifi/main/main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -1,133 +1,96 @@ import nesper -import nesper/net_utils -import nesper/nvs_utils +import nesper/general +import nesper/timers import nesper/events import nesper/wifi -import nesper/tasks -import nesper/timers - -import server - -# Get Password -const WIFI_SSID {.strdefine.}: string = "" -const WIFI_PASSWORD {.strdefine.}: string = "" - -# const CONFIG_EXAMPLE_WIFI_SSID = getEnv("WIFI_SSID") -# const CONFIG_EXAMPLE_WIFI_PASSWORD = getEnv("WIFI_PASSWORD") - -const - GOT_IPV4_BIT* = EventBits_t(BIT(1)) - CONNECTED_BITS* = (GOT_IPV4_BIT) - -const TAG*: cstring = "simplewifi" -var sConnectEventGroup*: EventGroupHandle_t -var sIpAddr*: IpAddress -var sConnectionName*: cstring - -proc ipReceivedHandler*(arg: pointer; event_base: esp_event_base_t; event_id: int32; - event_data: pointer) {.cdecl.} = - var event: ptr ip_event_got_ip_t = cast[ptr ip_event_got_ip_t](event_data) - logi TAG, "event.ip_info.ip: %s", $(event.ip_info.ip) - - sIpAddr = toIpAddress(event.ip_info.ip) - # memcpy(addr(sIpAddr), addr(event.ip_info.ip), sizeof((sIpAddr))) - logw TAG, "got event ip: %s", $sIpAddr - discard xEventGroupSetBits(sConnectEventGroup, GOT_IPV4_BIT) - -proc onWifiDisconnect*(arg: pointer; - event_base: esp_event_base_t; - event_id: int32; - event_data: pointer) {.cdecl.} = - logi(TAG, "Wi-Fi disconnected, trying to reconnect...") - check: esp_wifi_connect() +import nesper/net_utils +import nesper/esp/nvs +import nesper/esp/nvs_flash +import nesper/nvs_utils -proc wifiStart*() = - ## set up connection, Wi-Fi or Ethernet - let wcfg: wifi_init_config_t = wifi_init_config_default() +# Config (match the C example names) +const EXAMPLE_ESP_WIFI_SSID* {.strdefine.}: string = "" +const EXAMPLE_ESP_WIFI_PASS* {.strdefine.}: string = "" +const EXAMPLE_ESP_MAXIMUM_RETRY* {.intdefine.}: int = 5 + +const TAG: cstring = "wifi station" + +const WIFI_CONNECTED = 1 shl 0 +const WIFI_FAIL = 1 shl 1 + +var sWifiEventGroup: EventGroupHandle_t +var sRetryNum = 0 + +proc eventHandler(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = + if event_base == WIFI_EVENT and wifi_event_t(event_id) == WIFI_EVENT_STA_START: + discard esp_wifi_connect() + elif event_base == WIFI_EVENT and wifi_event_t(event_id) == WIFI_EVENT_STA_DISCONNECTED: + if sRetryNum < EXAMPLE_ESP_MAXIMUM_RETRY: + discard esp_wifi_connect() + inc sRetryNum + logi(TAG, "retry to connect to the AP") + else: + discard xEventGroupSetBits(sWifiEventGroup, EventBits_t(WIFI_FAIL)) + logi(TAG, "connect to the AP fail") + elif event_base == IP_EVENT and ip_event_t(event_id) == IP_EVENT_STA_GOT_IP: + let ev = cast[ptr ip_event_got_ip_t](event_data) + logi(TAG, "got ip: %s", $ev.ip_info.ip) + sRetryNum = 0 + discard xEventGroupSetBits(sWifiEventGroup, EventBits_t(WIFI_CONNECTED)) + +proc wifiInitSta() = + sWifiEventGroup = xEventGroupCreate() - discard esp_wifi_init(unsafeAddr(wcfg)) + when defined(ESP_IDF_V4_0): + tcpip_adapter_init() + else: + check: esp_netif_init() - eventRegister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, onWifiDisconnect, nil) - eventRegister(IP_EVENT, IP_EVENT_STA_GOT_IP, ipReceivedHandler) + check: esp_event_loop_create_default() - check: esp_wifi_set_storage(WIFI_STORAGE_RAM) + let cfg = wifi_init_config_default() + check: esp_wifi_init(unsafeAddr cfg) - when WIFI_SSID == "": - {.error: "WIFI_SSID is not set".} - when WIFI_PASSWORD == "": - {.error: "WIFI_PASSWORD is not set".} + # Register for all WIFI_EVENT IDs and for IP_EVENT_STA_GOT_IP + check: esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID.cint, cast[esp_event_handler_t](eventHandler), nil, nil) + check: esp_event_handler_instance_register(IP_EVENT, int32(IP_EVENT_STA_GOT_IP), cast[esp_event_handler_t](eventHandler), nil, nil) var wifi_config: wifi_config_t - wifi_config.sta.ssid.setFromString(WIFI_SSID) - wifi_config.sta.password.setFromString(WIFI_PASSWORD) + wifi_config.sta.ssid.setFromString(EXAMPLE_ESP_WIFI_SSID) + wifi_config.sta.password.setFromString(EXAMPLE_ESP_WIFI_PASS) - logi(TAG, "Connecting to %s...", wifi_config.sta.ssid) check: esp_wifi_set_mode(WIFI_MODE_STA) - check: esp_wifi_set_config(ESP_IF_WIFI_STA, addr(wifi_config)) + check: esp_wifi_set_config(ESP_IF_WIFI_STA, addr wifi_config) check: esp_wifi_start() - check: esp_wifi_connect() - sConnectionName = WIFI_SSID + logi(TAG, "wifi_init_sta finished.") -proc wifiStop*() = - ## tear down connection, release resources - WIFI_EVENT_STA_DISCONNECTED.eventUnregister(onWifiDisconnect) - IP_EVENT_STA_GOT_IP.eventUnregister(ipReceivedHandler) + let bits = xEventGroupWaitBits(sWifiEventGroup, EventBits_t(WIFI_CONNECTED or WIFI_FAIL), pdFALSE, pdFALSE, portMAX_DELAY) - check: esp_wifiStop() - check: esp_wifi_deinit() - -proc exampleConnect*(): esp_err_t = - if sConnectEventGroup != nil: - return ESP_ERR_INVALID_STATE - - sConnectEventGroup = xEventGroupCreate() - - wifiStart() - discard xEventGroupWaitBits(sConnectEventGroup, CONNECTED_BITS, 1, 1, portMAX_DELAY) - - logi(TAG, "Connected to %s", sConnectionName) - logi(TAG, "IPv4 address: %s", $sIpAddr) - - echo("run_http_server\n") - run_http_server() - - return ESP_OK - -proc exampleDisconnect*(): esp_err_t = - if sConnectEventGroup == nil: - return ESP_ERR_INVALID_STATE - - vEventGroupDelete(sConnectEventGroup) - sConnectEventGroup = nil - wifiStop() - logi(TAG, "Disconnected from %s", sConnectionName) - sConnectionName = nil - - return ESP_OK + if (bits and EventBits_t(WIFI_CONNECTED)) != 0: + logi(TAG, "connected to ap SSID:%s password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS) + elif (bits and EventBits_t(WIFI_FAIL)) != 0: + logi(TAG, "Failed to connect to SSID:%s, password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS) + else: + loge(TAG, "UNEXPECTED EVENT") app_main(): - initNvs() - when defined(ESP_IDF_V4_0): - tcpip_adapter_init() + logi(TAG, "Running main app...") + + logi(TAG, "Initializing NVS...") + initNVS() + # var ret = nvs_flash_init() + # if ret == ESP_ERR_NVS_NO_FREE_PAGES or ret == ESP_ERR_NVS_NEW_VERSION_FOUND: + # check: nvs_flash_erase() + # ret = nvs_flash_init() + # check: ret + + logi(TAG, "ESP_WIFI_MODE_STA") + when EXAMPLE_ESP_WIFI_SSID == "" or EXAMPLE_ESP_WIFI_PASS == "": + {.error: "EXAMPLE_ESP_WIFI_SSID and EXAMPLE_ESP_WIFI_PASS are not set".} else: - # Initialize TCP/IP network interface (should be called only once in application) - check: esp_netif_init() - - - # Create default event loop that running in background - check: esp_event_loop_create_default() - - logi(TAG, "wifi setup!\n") - check: exampleConnect() - - ## Register event handlers to stop the server when Wi-Fi or Ethernet is disconnected, - ## and re-start it upon connection. - ## - # IP_EVENT_STA_GOT_IP.eventRegister(ipReceivedHandler, nil) - - echo("Wait done\n") - # vTaskDelay(10000 div portTICK_PERIOD_MS) + wifiInitSta() + while true: echo "looping..." delayMillis(1000) From 870bf46b99f9e5a34911177b8115e3c4b33bd16c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 01:22:36 -0600 Subject: [PATCH 114/142] update wifi example --- .../simplewifi/main/CMakeLists.txt | 1 + esp-idf-examples/simplewifi/main/main.nim | 41 +- src/nesper/esp/esp_event.nim | 3 + src/nesper/esp/net/esp_wifi.nim | 8 +- src/nesper/esp/net/esp_wifi_default.nim | 166 ++ src/nesper/esp/net/esp_wifi_types_generic.nim | 1899 +++++++++++++++++ src/nesper/wifi.nim | 4 +- 7 files changed, 2104 insertions(+), 18 deletions(-) create mode 100644 src/nesper/esp/net/esp_wifi_default.nim create mode 100644 src/nesper/esp/net/esp_wifi_types_generic.nim diff --git a/esp-idf-examples/simplewifi/main/CMakeLists.txt b/esp-idf-examples/simplewifi/main/CMakeLists.txt index 12f8ce0d..7676b03b 100644 --- a/esp-idf-examples/simplewifi/main/CMakeLists.txt +++ b/esp-idf-examples/simplewifi/main/CMakeLists.txt @@ -1,6 +1,7 @@ idf_component_register(SRC_DIRS "./nimcache" INCLUDE_DIRS "" + PRIV_REQUIRES esp_wifi nvs_flash esp_timer ) # set(C_COMPILE_OPTIONS "${C_COMPILE_OPTIONS} -Wno-error=unused-label") diff --git a/esp-idf-examples/simplewifi/main/main.nim b/esp-idf-examples/simplewifi/main/main.nim index 4eb00c8c..e9ffa614 100644 --- a/esp-idf-examples/simplewifi/main/main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -13,7 +13,7 @@ const EXAMPLE_ESP_WIFI_SSID* {.strdefine.}: string = "" const EXAMPLE_ESP_WIFI_PASS* {.strdefine.}: string = "" const EXAMPLE_ESP_MAXIMUM_RETRY* {.intdefine.}: int = 5 -const TAG: cstring = "wifi station" +const TAG: cstring = "Wifi Example" const WIFI_CONNECTED = 1 shl 0 const WIFI_FAIL = 1 shl 1 @@ -22,49 +22,63 @@ var sWifiEventGroup: EventGroupHandle_t var sRetryNum = 0 proc eventHandler(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = + logi(TAG, "Wifi Event Handler called: base: %s eventid: %s wifiEvent: %s ipEvent: %s", + $event_base, $event_id, $(event_base == WIFI_EVENT), $(event_base == IP_EVENT)) if event_base == WIFI_EVENT and wifi_event_t(event_id) == WIFI_EVENT_STA_START: discard esp_wifi_connect() elif event_base == WIFI_EVENT and wifi_event_t(event_id) == WIFI_EVENT_STA_DISCONNECTED: if sRetryNum < EXAMPLE_ESP_MAXIMUM_RETRY: discard esp_wifi_connect() inc sRetryNum - logi(TAG, "retry to connect to the AP") + loge(TAG, "retry to connect to the AP") else: discard xEventGroupSetBits(sWifiEventGroup, EventBits_t(WIFI_FAIL)) - logi(TAG, "connect to the AP fail") + loge(TAG, "Connect to the AP failed") elif event_base == IP_EVENT and ip_event_t(event_id) == IP_EVENT_STA_GOT_IP: let ev = cast[ptr ip_event_got_ip_t](event_data) - logi(TAG, "got ip: %s", $ev.ip_info.ip) + logi(TAG, "Wifi Got IP: %s", $ev.ip_info.ip) sRetryNum = 0 discard xEventGroupSetBits(sWifiEventGroup, EventBits_t(WIFI_CONNECTED)) proc wifiInitSta() = + logw(TAG, "Wifi Init Sta starting...") sWifiEventGroup = xEventGroupCreate() - when defined(ESP_IDF_V4_0): - tcpip_adapter_init() - else: - check: esp_netif_init() + check: esp_netif_init() check: esp_event_loop_create_default() + let netif = esp_netif_create_default_wifi_sta() - let cfg = wifi_init_config_default() + let cfg = WIFI_INIT_CONFIG_DEFAULT() check: esp_wifi_init(unsafeAddr cfg) # Register for all WIFI_EVENT IDs and for IP_EVENT_STA_GOT_IP - check: esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID.cint, cast[esp_event_handler_t](eventHandler), nil, nil) - check: esp_event_handler_instance_register(IP_EVENT, int32(IP_EVENT_STA_GOT_IP), cast[esp_event_handler_t](eventHandler), nil, nil) + var instance_any_id: esp_event_handler_instance_t + var instance_got_ip: esp_event_handler_instance_t + + eventRegister(WIFI_EVENT, + ESP_EVENT_ANY_ID.int32, + eventHandler, + nil, addr instance_any_id) + eventRegister(IP_EVENT, + ESP_EVENT_ANY_ID.int32, + eventHandler, + nil, addr instance_got_ip) var wifi_config: wifi_config_t wifi_config.sta.ssid.setFromString(EXAMPLE_ESP_WIFI_SSID) wifi_config.sta.password.setFromString(EXAMPLE_ESP_WIFI_PASS) + wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA3_PSK + wifi_config.sta.sae_pwe_h2e = WPA3_SAE_PWE_HUNT_AND_PECK + wifi_config.sta.sae_h2e_identifier.setFromString("") check: esp_wifi_set_mode(WIFI_MODE_STA) check: esp_wifi_set_config(ESP_IF_WIFI_STA, addr wifi_config) check: esp_wifi_start() - logi(TAG, "wifi_init_sta finished.") + logw(TAG, "Wifi Init Sta finished.") + logw(TAG, "Wifi Init Sta waiting for events...") let bits = xEventGroupWaitBits(sWifiEventGroup, EventBits_t(WIFI_CONNECTED or WIFI_FAIL), pdFALSE, pdFALSE, portMAX_DELAY) if (bits and EventBits_t(WIFI_CONNECTED)) != 0: @@ -75,7 +89,7 @@ proc wifiInitSta() = loge(TAG, "UNEXPECTED EVENT") app_main(): - logi(TAG, "Running main app...") + logw(TAG, "Running main app...") logi(TAG, "Initializing NVS...") initNVS() @@ -85,7 +99,6 @@ app_main(): # ret = nvs_flash_init() # check: ret - logi(TAG, "ESP_WIFI_MODE_STA") when EXAMPLE_ESP_WIFI_SSID == "" or EXAMPLE_ESP_WIFI_PASS == "": {.error: "EXAMPLE_ESP_WIFI_SSID and EXAMPLE_ESP_WIFI_PASS are not set".} else: diff --git a/src/nesper/esp/esp_event.nim b/src/nesper/esp/esp_event.nim index d2d53a7a..c3094d61 100644 --- a/src/nesper/esp/esp_event.nim +++ b/src/nesper/esp/esp_event.nim @@ -15,6 +15,9 @@ when ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0): type esp_event_base_t* {.importc: "esp_event_base_t", header: "esp_event.h".} = pointer +proc `$`*(base: esp_event_base_t): string = + $(cast[cstring](base)) + type ## *< unique pointer to a subsystem that exposes events esp_event_loop_handle_t* = pointer diff --git a/src/nesper/esp/net/esp_wifi.nim b/src/nesper/esp/net/esp_wifi.nim index b67beee3..e600c919 100644 --- a/src/nesper/esp/net/esp_wifi.nim +++ b/src/nesper/esp/net/esp_wifi.nim @@ -141,9 +141,11 @@ type # proc wifi_init_config_default*(): wifi_init_config_t {.importc:"_wifi_init_config_default", header: "esp_wifi.h".} -proc wifi_init_config_default*(): wifi_init_config_t = - {.emit: ["wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); "].} - {.emit: ["result = cfg; "].} +proc WIFI_INIT_CONFIG_DEFAULT*(): wifi_init_config_t = + {.emit: """ + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + `result` = cfg; + """.} # when defined(CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM): # const diff --git a/src/nesper/esp/net/esp_wifi_default.nim b/src/nesper/esp/net/esp_wifi_default.nim new file mode 100644 index 00000000..a22c055b --- /dev/null +++ b/src/nesper/esp/net/esp_wifi_default.nim @@ -0,0 +1,166 @@ +## +## SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD +## +## SPDX-License-Identifier: Apache-2.0 +## + +import ../../consts +import ../../net_utils +import ./esp_netif_types + +proc esp_netif_attach_wifi_station*(esp_netif: ptr esp_netif_t): esp_err_t {. + cdecl, importc: "esp_netif_attach_wifi_station", + header: "esp_wifi_default.h".} + ## + ## @brief Attaches wifi station interface to supplied netif + ## + ## @param esp_netif instance to attach the wifi station to + ## + ## @return + ## - ESP_OK on success + ## - ESP_FAIL if attach failed + ## + +proc esp_netif_attach_wifi_ap*(esp_netif: ptr esp_netif_t): esp_err_t {.cdecl, + importc: "esp_netif_attach_wifi_ap", header: "esp_wifi_default.h".} + ## + ## + ## @brief Attaches wifi soft AP interface to supplied netif + ## + ## @param esp_netif instance to attach the wifi AP to + ## + ## @return + ## - ESP_OK on success + ## - ESP_FAIL if attach failed + ## + +proc esp_wifi_set_default_wifi_sta_handlers*(): esp_err_t {.cdecl, + importc: "esp_wifi_set_default_wifi_sta_handlers", + header: "esp_wifi_default.h".} + ## + ## @brief Sets default wifi event handlers for STA interface + ## + ## @return + ## - ESP_OK on success, error returned from esp_event_handler_register if failed + ## + +proc esp_wifi_set_default_wifi_ap_handlers*(): esp_err_t {.cdecl, + importc: "esp_wifi_set_default_wifi_ap_handlers", + header: "esp_wifi_default.h".} + ## + ## @brief Sets default wifi event handlers for AP interface + ## + ## @return + ## - ESP_OK on success, error returned from esp_event_handler_register if failed + ## + +proc esp_wifi_set_default_wifi_nan_handlers*(): esp_err_t {.cdecl, + importc: "esp_wifi_set_default_wifi_nan_handlers", + header: "esp_wifi_default.h".} + ## + ## @brief Sets default wifi event handlers for NAN interface + ## + ## @return + ## - ESP_OK on success, error returned from esp_event_handler_register if failed + ## + +proc esp_wifi_clear_default_wifi_driver_and_handlers*(esp_netif: pointer): esp_err_t {. + cdecl, importc: "esp_wifi_clear_default_wifi_driver_and_handlers", + header: "esp_wifi_default.h".} + ## + ## @brief Clears default wifi event handlers for supplied network interface + ## + ## @param esp_netif instance of corresponding if object + ## + ## @return + ## - ESP_OK on success, error returned from esp_event_handler_register if failed + ## + +proc esp_netif_create_default_wifi_ap*(): ptr esp_netif_t {.cdecl, + importc: "esp_netif_create_default_wifi_ap", header: "esp_wifi_default.h".} + ## + ## + ## @brief Creates default WIFI AP. In case of any init error this API aborts. + ## + ## @note The API creates esp_netif object with default WiFi access point config, + ## attaches the netif to wifi and registers wifi handlers to the default event loop. + ## This API uses assert() to check for potential errors, so it could abort the program. + ## (Note that the default event loop needs to be created prior to calling this API) + ## + ## @return pointer to esp-netif instance + ## + +proc esp_netif_create_default_wifi_sta*(): ptr esp_netif_t {.cdecl, + importc: "esp_netif_create_default_wifi_sta", header: "esp_wifi_default.h".} + ## + ## + ## @brief Creates default WIFI STA. In case of any init error this API aborts. + ## + ## @note The API creates esp_netif object with default WiFi station config, + ## attaches the netif to wifi and registers wifi handlers to the default event loop. + ## This API uses assert() to check for potential errors, so it could abort the program. + ## (Note that the default event loop needs to be created prior to calling this API) + ## + ## @return pointer to esp-netif instance + ## + +proc esp_netif_create_default_wifi_nan*(): ptr esp_netif_t {.cdecl, + importc: "esp_netif_create_default_wifi_nan", header: "esp_wifi_default.h".} + ## + ## + ## @brief Creates default WIFI NAN. In case of any init error this API aborts. + ## + ## @note The API creates esp_netif object with default WiFi station config, + ## attaches the netif to wifi and registers wifi handlers to the default event loop. + ## (Note that the default event loop needs to be created prior to calling this API) + ## + ## @return pointer to esp-netif instance + ## + +proc esp_netif_destroy_default_wifi*(esp_netif: pointer) {.cdecl, + importc: "esp_netif_destroy_default_wifi", header: "esp_wifi_default.h".} + ## + ## + ## @brief Destroys default WIFI netif created with esp_netif_create_default_wifi_...() API. + ## + ## @param[in] esp_netif object to detach from WiFi and destroy + ## + ## @note This API unregisters wifi handlers and detaches the created object from the wifi. + ## (this function is a no-operation if esp_netif is NULL) + ## + +proc esp_netif_create_wifi*(wifi_if: wifi_interface_t; + esp_netif_config: ptr esp_netif_inherent_config_t): ptr esp_netif_t {. + cdecl, importc: "esp_netif_create_wifi", header: "esp_wifi_default.h".} + ## + ## + ## @brief Creates esp_netif WiFi object based on the custom configuration. + ## + ## @attention This API DOES NOT register default handlers! + ## + ## @param[in] wifi_if type of wifi interface + ## @param[in] esp_netif_config inherent esp-netif configuration pointer + ## + ## @return pointer to esp-netif instance + ## + +proc esp_netif_create_default_wifi_mesh_netifs*( + p_netif_sta: ptr ptr esp_netif_t; p_netif_ap: ptr ptr esp_netif_t): esp_err_t {. + cdecl, importc: "esp_netif_create_default_wifi_mesh_netifs", + header: "esp_wifi_default.h".} + ## + ## @brief Creates default STA and AP network interfaces for esp-mesh. + ## + ## Both netifs are almost identical to the default station and softAP, but with + ## DHCP client and server disabled. Please note that the DHCP client is typically + ## enabled only if the device is promoted to a root node. + ## + ## Returns created interfaces which could be ignored setting parameters to NULL + ## if an application code does not need to save the interface instances + ## for further processing. + ## + ## @param[out] p_netif_sta pointer where the resultant STA interface is saved (if non NULL) + ## @param[out] p_netif_ap pointer where the resultant AP interface is saved (if non NULL) + ## + ## @return ESP_OK on success + ## \ No newline at end of file diff --git a/src/nesper/esp/net/esp_wifi_types_generic.nim b/src/nesper/esp/net/esp_wifi_types_generic.nim new file mode 100644 index 00000000..b07a0c71 --- /dev/null +++ b/src/nesper/esp/net/esp_wifi_types_generic.nim @@ -0,0 +1,1899 @@ + + +import ../esp_event + +const hdr = "esp_wifi_types_generic.h" + +let + WIFI_AP_DEFAULT_MAX_IDLE_PERIOD* {.importc: "WIFI_AP_DEFAULT_MAX_IDLE_PERIOD", header: hdr.}: cint ## + ## SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + ## + ## SPDX-License-Identifier: Apache-2.0 + ## + +type + + wifi_mode_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi mode type + ## + WIFI_MODE_NULL = 0, ## < Null mode + WIFI_MODE_STA, ## < Wi-Fi station mode + WIFI_MODE_AP, ## < Wi-Fi soft-AP mode + WIFI_MODE_APSTA, ## < Wi-Fi station + soft-AP mode + WIFI_MODE_NAN, ## < Wi-Fi NAN mode + WIFI_MODE_MAX + + +type + + wifi_interface_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi interface type + ## + WIFI_IF_STA, ## < Station interface + WIFI_IF_AP, ## < Soft-AP interface + WIFI_IF_NAN ## < NAN interface + + wifi_action_tx_t* {.size: sizeof(cint).} = enum + WIFI_OFFCHAN_TX_CANCEL, ## < Cancel off-channel transmission + WIFI_OFFCHAN_TX_REQ ## < Request off-channel transmission + + wifi_roc_t* {.size: sizeof(cint).} = enum + WIFI_ROC_CANCEL, ## < Cancel remain on channel + WIFI_ROC_REQ ## < Request remain on channel + + +type + + wifi_country_policy_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi country policy + ## + WIFI_COUNTRY_POLICY_AUTO, ## < Country policy is auto, use the country info of AP to which the station is connected + WIFI_COUNTRY_POLICY_MANUAL ## < Country policy is manual, always use the configured country info + + +type + + wifi_country_t* {.importc: "wifi_country_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Structure describing Wi-Fi country-based regional restrictions. + ## + cc* {.importc: "cc".}: array[3, char] ## < Country code string + schan* {.importc: "schan".}: uint8 ## < Start channel of the allowed 2.4GHz Wi-Fi channels + nchan* {.importc: "nchan".}: uint8 ## < Total channel number of the allowed 2.4GHz Wi-Fi channels + max_tx_power* {.importc: "max_tx_power".}: int8 ## + ## < This field is used for getting Wi-Fi maximum transmitting power, call esp_wifi_set_max_tx_power to set the maximum transmitting power. + policy* {.importc: "policy".}: wifi_country_policy_t ## + ## < Country policy + when defined(CONFIG_SOC_WIFI_SUPPORT_5G): + wifi_5g_channel_mask* {.importc: "wifi_5g_channel_mask".}: uint32 + ## < A bitmask representing the allowed 5GHz Wi-Fi channels. + ## Each bit in the mask corresponds to a specific channel as wifi_5g_channel_bit_t shown. + ## Bitmask set to 0 indicates 5GHz channels are allowed according to local regulatory rules. + ## Please note that configured bitmask takes effect only when policy is manual. + + + wifi_auth_mode_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi authmode type + ## Strength of authmodes + ## Personal Networks : OPEN < WEP < WPA_PSK < OWE < WPA2_PSK = WPA_WPA2_PSK < WAPI_PSK < WPA3_PSK = WPA2_WPA3_PSK = DPP + ## Enterprise Networks : WIFI_AUTH_WPA_ENTERPRISE < WIFI_AUTH_WPA2_ENTERPRISE < WIFI_AUTH_WPA3_ENTERPRISE = WIFI_AUTH_WPA2_WPA3_ENTERPRISE < WIFI_AUTH_WPA3_ENT_192 + ## + WIFI_AUTH_OPEN = 0, ## < Authenticate mode : open + WIFI_AUTH_WEP, ## < Authenticate mode : WEP + WIFI_AUTH_WPA_PSK, ## < Authenticate mode : WPA_PSK + WIFI_AUTH_WPA2_PSK, ## < Authenticate mode : WPA2_PSK + WIFI_AUTH_WPA_WPA2_PSK, ## < Authenticate mode : WPA_WPA2_PSK + WIFI_AUTH_ENTERPRISE, ## < Authenticate mode : Wi-Fi EAP security, treated the same as WIFI_AUTH_WPA2_ENTERPRISE + WIFI_AUTH_WPA3_PSK, ## < Authenticate mode : WPA3_PSK + WIFI_AUTH_WPA2_WPA3_PSK, ## < Authenticate mode : WPA2_WPA3_PSK + WIFI_AUTH_WAPI_PSK, ## < Authenticate mode : WAPI_PSK + WIFI_AUTH_OWE, ## < Authenticate mode : OWE + WIFI_AUTH_WPA3_ENT_192, ## < Authenticate mode : WPA3_ENT_SUITE_B_192_BIT + WIFI_AUTH_WPA3_EXT_PSK, ## < This authentication mode will yield same result as WIFI_AUTH_WPA3_PSK and not recommended to be used. It will be deprecated in future, please use WIFI_AUTH_WPA3_PSK instead. + WIFI_AUTH_WPA3_EXT_PSK_MIXED_MODE, ## < This authentication mode will yield same result as WIFI_AUTH_WPA3_PSK and not recommended to be used. It will be deprecated in future, please use WIFI_AUTH_WPA3_PSK instead. + WIFI_AUTH_DPP, ## < Authenticate mode : DPP + WIFI_AUTH_WPA3_ENTERPRISE, ## < Authenticate mode : WPA3-Enterprise Only Mode + WIFI_AUTH_WPA2_WPA3_ENTERPRISE, ## < Authenticate mode : WPA3-Enterprise Transition Mode + WIFI_AUTH_WPA_ENTERPRISE, ## < Authenticate mode : WPA-Enterprise security + WIFI_AUTH_MAX + +const + WIFI_AUTH_WPA2_ENTERPRISE* = WIFI_AUTH_ENTERPRISE + +type + + wifi_err_reason_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi disconnection reason codes + ## + ## These reason codes are used to indicate the cause of disconnection. + ## + WIFI_REASON_UNSPECIFIED = 1, ## < Unspecified reason + WIFI_REASON_AUTH_EXPIRE = 2, ## < Authentication expired + WIFI_REASON_AUTH_LEAVE = 3, ## < Deauthentication due to leaving + WIFI_REASON_ASSOC_EXPIRE = 4, ## < Deprecated, will be removed in next IDF major release + WIFI_REASON_ASSOC_TOOMANY = 5, ## < Too many associated stations + WIFI_REASON_NOT_AUTHED = 6, ## < Deprecated, will be removed in next IDF major release + WIFI_REASON_NOT_ASSOCED = 7, ## < Deprecated, will be removed in next IDF major release + WIFI_REASON_ASSOC_LEAVE = 8, ## < Deassociated due to leaving + WIFI_REASON_ASSOC_NOT_AUTHED = 9, ## < Association but not authenticated + WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, ## < Disassociated due to poor power capability + WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11, ## < Disassociated due to unsupported channel + WIFI_REASON_BSS_TRANSITION_DISASSOC = 12, ## < Disassociated due to BSS transition + WIFI_REASON_IE_INVALID = 13, ## < Invalid Information Element (IE) + WIFI_REASON_MIC_FAILURE = 14, ## < MIC failure + WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, ## < 4-way handshake timeout + WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, ## < Group key update timeout + WIFI_REASON_IE_IN_4WAY_DIFFERS = 17, ## < IE differs in 4-way handshake + WIFI_REASON_GROUP_CIPHER_INVALID = 18, ## < Invalid group cipher + WIFI_REASON_PAIRWISE_CIPHER_INVALID = 19, ## < Invalid pairwise cipher + WIFI_REASON_AKMP_INVALID = 20, ## < Invalid AKMP + WIFI_REASON_UNSUPP_RSN_IE_VERSION = 21, ## < Unsupported RSN IE version + WIFI_REASON_INVALID_RSN_IE_CAP = 22, ## < Invalid RSN IE capabilities + WIFI_REASON_802_1X_AUTH_FAILED = 23, ## < 802.1X authentication failed + WIFI_REASON_CIPHER_SUITE_REJECTED = 24, ## < Cipher suite rejected + WIFI_REASON_TDLS_PEER_UNREACHABLE = 25, ## < TDLS peer unreachable + WIFI_REASON_TDLS_UNSPECIFIED = 26, ## < TDLS unspecified + WIFI_REASON_SSP_REQUESTED_DISASSOC = 27, ## < SSP requested disassociation + WIFI_REASON_NO_SSP_ROAMING_AGREEMENT = 28, ## < No SSP roaming agreement + WIFI_REASON_BAD_CIPHER_OR_AKM = 29, ## < Bad cipher or AKM + WIFI_REASON_NOT_AUTHORIZED_THIS_LOCATION = 30, ## + ## < Not authorized in this location + WIFI_REASON_SERVICE_CHANGE_PERCLUDES_TS = 31, ## + ## < Service change precludes TS + WIFI_REASON_UNSPECIFIED_QOS = 32, ## < Unspecified QoS reason + WIFI_REASON_NOT_ENOUGH_BANDWIDTH = 33, ## < Not enough bandwidth + WIFI_REASON_MISSING_ACKS = 34, ## < Missing ACKs + WIFI_REASON_EXCEEDED_TXOP = 35, ## < Exceeded TXOP + WIFI_REASON_STA_LEAVING = 36, ## < Station leaving + WIFI_REASON_END_BA = 37, ## < End of Block Ack (BA) + WIFI_REASON_UNKNOWN_BA = 38, ## < Unknown Block Ack (BA) + WIFI_REASON_TIMEOUT = 39, ## < Timeout + WIFI_REASON_PEER_INITIATED = 46, ## < Peer initiated disassociation + WIFI_REASON_AP_INITIATED = 47, ## < AP initiated disassociation + WIFI_REASON_INVALID_FT_ACTION_FRAME_COUNT = 48, ## + ## < Invalid FT action frame count + WIFI_REASON_INVALID_PMKID = 49, ## < Invalid PMKID + WIFI_REASON_INVALID_MDE = 50, ## < Invalid MDE + WIFI_REASON_INVALID_FTE = 51, ## < Invalid FTE + WIFI_REASON_TRANSMISSION_LINK_ESTABLISH_FAILED = 67, ## + ## < Transmission link establishment failed + WIFI_REASON_ALTERATIVE_CHANNEL_OCCUPIED = 68, ## + ## < Alternative channel occupied + WIFI_REASON_BEACON_TIMEOUT = 200, ## < Beacon timeout + WIFI_REASON_NO_AP_FOUND = 201, ## < No AP found + WIFI_REASON_AUTH_FAIL = 202, ## < Authentication failed + WIFI_REASON_ASSOC_FAIL = 203, ## < Association failed + WIFI_REASON_HANDSHAKE_TIMEOUT = 204, ## < Handshake timeout + WIFI_REASON_CONNECTION_FAIL = 205, ## < Connection failed + WIFI_REASON_AP_TSF_RESET = 206, ## < AP TSF reset + WIFI_REASON_ROAMING = 207, ## < Roaming + WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG = 208, ## + ## < Association comeback time too long + WIFI_REASON_SA_QUERY_TIMEOUT = 209, ## < SA query timeout + WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY = 210, ## + ## < No AP found with compatible security + WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD = 211, ## + ## < No AP found in auth mode threshold + WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD = 212 ## + ## < No AP found in RSSI threshold + +const + WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY = WIFI_REASON_ASSOC_EXPIRE + WIFI_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = WIFI_REASON_NOT_AUTHED + WIFI_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = WIFI_REASON_NOT_ASSOCED + +type + + wifi_second_chan_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi second channel type + ## + WIFI_SECOND_CHAN_NONE = 0, ## < The channel width is HT20 + WIFI_SECOND_CHAN_ABOVE, ## < The channel width is HT40 and the secondary channel is above the primary channel + WIFI_SECOND_CHAN_BELOW ## < The channel width is HT40 and the secondary channel is below the primary channel + +let + WIFI_ACTIVE_SCAN_MIN_DEFAULT_TIME* {.importc, header: hdr.}: cint + WIFI_ACTIVE_SCAN_MAX_DEFAULT_TIME* {.importc, header: hdr.}: cint + WIFI_PASSIVE_SCAN_DEFAULT_TIME* {.importc, header: hdr.}: cint + WIFI_SCAN_HOME_CHANNEL_DWELL_DEFAULT_TIME* {.importc, header: hdr.}: cint + +type + + wifi_scan_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi scan type + ## + WIFI_SCAN_TYPE_ACTIVE = 0, ## < Active scan + WIFI_SCAN_TYPE_PASSIVE ## < Passive scan + + +type + + wifi_active_scan_time_t* {.importc: "wifi_active_scan_time_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Range of active scan times per channel + ## + min* {.importc: "min".}: uint32 ## < Minimum active scan time per channel, units: millisecond + max* {.importc: "max".}: uint32 + ## < Maximum active scan time per channel, units: millisecond, values above 1500 ms may + ## cause station to disconnect from AP and are not recommended. + + + wifi_scan_time_t* {.importc: "wifi_scan_time_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Aggregate of active & passive scan time per channel + ## + active* {.importc: "active".}: wifi_active_scan_time_t ## + ## < Active scan time per channel, units: millisecond. + passive* {.importc: "passive".}: uint32 + ## < Passive scan time per channel, units: millisecond, values above 1500 ms may + ## cause station to disconnect from AP and are not recommended. + + + wifi_scan_channel_bitmap_t* {.importc: "wifi_scan_channel_bitmap_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Channel bitmap for setting specific channels to be scanned + ## + ghz_2_channels* {.importc: "ghz_2_channels".}: uint16 ## + ## < Represents 2.4 GHz channels, that bits can be set as wifi_2g_channel_bit_t shown. + ghz_5_channels* {.importc: "ghz_5_channels".}: uint32 + ## < Represents 5 GHz channels, that bits can be set as wifi_5g_channel_bit_t shown. + + + wifi_scan_config_t* {.importc: "wifi_scan_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Parameters for an SSID scan + ## + ssid* {.importc: "ssid".}: ptr uint8 ## < SSID of AP + bssid* {.importc: "bssid".}: ptr uint8 ## < MAC address of AP + channel* {.importc: "channel".}: uint8 ## < Channel, scan the specific channel + show_hidden* {.importc: "show_hidden".}: bool ## < Enable it to scan AP whose SSID is hidden + scan_type* {.importc: "scan_type".}: wifi_scan_type_t ## + ## < Scan type, active or passive + scan_time* {.importc: "scan_time".}: wifi_scan_time_t ## + ## < Scan time per channel + home_chan_dwell_time* {.importc: "home_chan_dwell_time".}: uint8 ## + ## < Time spent at home channel between scanning consecutive channels. + channel_bitmap* {.importc: "channel_bitmap".}: wifi_scan_channel_bitmap_t ## + ## < Channel bitmap for setting specific channels to be scanned. + ## Please note that the 'channel' parameter above needs to be set to 0 to allow scanning by bitmap. + ## Also, note that only allowed channels configured by wifi_country_t can be scanned. + coex_background_scan* {.importc: "coex_background_scan".}: bool + ## < Enable it to scan return home channel under coexist + + + wifi_scan_default_params_t* {.importc: "wifi_scan_default_params_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Parameters default scan configurations + ## + scan_time* {.importc: "scan_time".}: wifi_scan_time_t ## + ## < Scan time per channel + home_chan_dwell_time* {.importc: "home_chan_dwell_time".}: uint8 + ## < Time spent at home channel between scanning consecutive channels. + + + wifi_cipher_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi cipher type + ## + WIFI_CIPHER_TYPE_NONE = 0, ## < The cipher type is none + WIFI_CIPHER_TYPE_WEP40, ## < The cipher type is WEP40 + WIFI_CIPHER_TYPE_WEP104, ## < The cipher type is WEP104 + WIFI_CIPHER_TYPE_TKIP, ## < The cipher type is TKIP + WIFI_CIPHER_TYPE_CCMP, ## < The cipher type is CCMP + WIFI_CIPHER_TYPE_TKIP_CCMP, ## < The cipher type is TKIP and CCMP + WIFI_CIPHER_TYPE_AES_CMAC128, ## < The cipher type is AES-CMAC-128 + WIFI_CIPHER_TYPE_SMS4, ## < The cipher type is SMS4 + WIFI_CIPHER_TYPE_GCMP, ## < The cipher type is GCMP + WIFI_CIPHER_TYPE_GCMP256, ## < The cipher type is GCMP-256 + WIFI_CIPHER_TYPE_AES_GMAC128, ## < The cipher type is AES-GMAC-128 + WIFI_CIPHER_TYPE_AES_GMAC256, ## < The cipher type is AES-GMAC-256 + WIFI_CIPHER_TYPE_UNKNOWN ## < The cipher type is unknown + + +type + + wifi_bandwidth_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi bandwidth type + ## + WIFI_BW_HT20 = 1, ## < Bandwidth is HT20 + WIFI_BW_HT40 = 2, ## < Bandwidth is HT40 + WIFI_BW80 = 3, ## < Bandwidth is 80 MHz + WIFI_BW160 = 4, ## < Bandwidth is 160 MHz + WIFI_BW80_BW80 = 5 ## < Bandwidth is 80 + 80 MHz + +const + WIFI_BW20* = WIFI_BW_HT20 + WIFI_BW40* = WIFI_BW_HT40 + +type + + wifi_ant_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi antenna + ## + WIFI_ANT_ANT0, ## < Wi-Fi antenna 0 + WIFI_ANT_ANT1, ## < Wi-Fi antenna 1 + WIFI_ANT_MAX ## < Invalid Wi-Fi antenna + + +type + + wifi_he_ap_info_t* {.importc: "wifi_he_ap_info_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Description of a Wi-Fi AP HE Info + ## + bss_color* {.importc: "bss_color", bitsize: 6.}: uint8 ## + ## < The BSS Color value associated with the AP's corresponding BSS + partial_bss_color* {.importc: "partial_bss_color", bitsize: 1.}: uint8 ## + ## < Indicates whether an AID assignment rule is based on the BSS color + bss_color_disabled* {.importc: "bss_color_disabled", bitsize: 1.}: uint8 ## + ## < Indicates whether the BSS color usage is disabled + bssid_index* {.importc: "bssid_index".}: uint8 + ## < In a M-BSSID set, identifies the non-transmitted BSSID + + + wifi_ap_record_t* {.importc: "wifi_ap_record_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Description of a Wi-Fi AP + ## + bssid* {.importc: "bssid".}: array[6, uint8] ## < MAC address of AP + ssid* {.importc: "ssid".}: array[33, uint8] ## < SSID of AP + primary* {.importc: "primary".}: uint8 ## < Channel of AP + second* {.importc: "second".}: wifi_second_chan_t ## + ## < Secondary channel of AP + rssi* {.importc: "rssi".}: int8 ## < Signal strength of AP. Note that in some rare cases where signal strength is very strong, RSSI values can be slightly positive + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## + ## < Auth mode of AP + pairwise_cipher* {.importc: "pairwise_cipher".}: wifi_cipher_type_t ## + ## < Pairwise cipher of AP + group_cipher* {.importc: "group_cipher".}: wifi_cipher_type_t ## + ## < Group cipher of AP + ant* {.importc: "ant".}: wifi_ant_t ## < Antenna used to receive beacon from AP + phy_11b* {.importc: "phy_11b", bitsize: 1.}: uint32 ## + ## < Bit: 0 flag to identify if 11b mode is enabled or not + phy_11g* {.importc: "phy_11g", bitsize: 1.}: uint32 ## + ## < Bit: 1 flag to identify if 11g mode is enabled or not + phy_11n* {.importc: "phy_11n", bitsize: 1.}: uint32 ## + ## < Bit: 2 flag to identify if 11n mode is enabled or not + phy_lr* {.importc: "phy_lr", bitsize: 1.}: uint32 ## + ## < Bit: 3 flag to identify if low rate is enabled or not + phy_11a* {.importc: "phy_11a", bitsize: 1.}: uint32 ## + ## < Bit: 4 flag to identify if 11ax mode is enabled or not + phy_11ac* {.importc: "phy_11ac", bitsize: 1.}: uint32 ## + ## < Bit: 5 flag to identify if 11ax mode is enabled or not + phy_11ax* {.importc: "phy_11ax", bitsize: 1.}: uint32 ## + ## < Bit: 6 flag to identify if 11ax mode is enabled or not + wps* {.importc: "wps", bitsize: 1.}: uint32 ## < Bit: 7 flag to identify if WPS is supported or not + ftm_responder* {.importc: "ftm_responder", bitsize: 1.}: uint32 ## + ## < Bit: 8 flag to identify if FTM is supported in responder mode + ftm_initiator* {.importc: "ftm_initiator", bitsize: 1.}: uint32 ## + ## < Bit: 9 flag to identify if FTM is supported in initiator mode + reserved* {.importc: "reserved", bitsize: 22.}: uint32 ## + ## < Bit: 10..31 reserved + country* {.importc: "country".}: wifi_country_t ## + ## < Country information of AP + he_ap* {.importc: "he_ap".}: wifi_he_ap_info_t ## + ## < HE AP info + bandwidth* {.importc: "bandwidth".}: wifi_bandwidth_t ## + ## < Bandwidth of AP + vht_ch_freq1* {.importc: "vht_ch_freq1".}: uint8 ## + ## < This fields are used only AP bandwidth is 80 and 160 MHz, to transmit the center channel + ## frequency of the BSS. For AP bandwidth is 80 + 80 MHz, it is the center channel frequency + ## of the lower frequency segment. + vht_ch_freq2* {.importc: "vht_ch_freq2".}: uint8 + ## < this fields are used only AP bandwidth is 80 + 80 MHz, and is used to transmit the center + ## channel frequency of the second segment. + + + wifi_scan_method_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi scan method + ## + WIFI_FAST_SCAN = 0, ## < Do fast scan, scan will end after find SSID match AP + WIFI_ALL_CHANNEL_SCAN ## < All channel scan, scan will end after scan all the channel + + +type + + wifi_sort_method_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi sort AP method + ## + WIFI_CONNECT_AP_BY_SIGNAL = 0, ## < Sort match AP in scan list by RSSI + WIFI_CONNECT_AP_BY_SECURITY ## < Sort match AP in scan list by security mode + + +type + + wifi_scan_threshold_t* {.importc: "wifi_scan_threshold_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Structure describing parameters for a Wi-Fi fast scan + ## + rssi* {.importc: "rssi".}: int8 ## < The minimum rssi to accept in the fast scan mode. Defaults to -127 if set to >= 0 + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## + ## < The weakest auth mode to accept in the fast scan mode + ## Note: In case this value is not set and password is set as per WPA2 standards(password len >= 8), it will be defaulted to WPA2 and device won't connect to deprecated WEP/WPA networks. Please set auth mode threshold as WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK to connect to WEP/WPA networks + rssi_5g_adjustment* {.importc: "rssi_5g_adjustment".}: uint8 + ## < The RSSI value of the 5G AP is within the rssi_5g_adjustment range compared to the 2G AP, the 5G AP will be given priority for connection. + + + wifi_ps_type_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi power save type + ## + WIFI_PS_NONE, ## < No power save + WIFI_PS_MIN_MODEM, ## < Minimum modem power saving. In this mode, station wakes up to receive beacon every DTIM period + WIFI_PS_MAX_MODEM ## < Maximum modem power saving. In this mode, interval to receive beacons is determined by the listen_interval parameter in wifi_sta_config_t + + +type + + wifi_band_t* {.size: sizeof(cint).} = enum ## + ## @brief Argument structure for Wi-Fi band + ## + WIFI_BAND_2G = 1, ## < Band is 2.4 GHz + WIFI_BAND_5G = 2 ## < Band is 5 GHz + + +type + + wifi_band_mode_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Argument structure for Wi-Fi band mode + ## + WIFI_BAND_MODE_2G_ONLY = 1, ## < Wi-Fi band mode is 2.4 GHz only + WIFI_BAND_MODE_5G_ONLY = 2, ## < Wi-Fi band mode is 5 GHz only + WIFI_BAND_MODE_AUTO = 3 ## < Wi-Fi band mode is 2.4 GHz + 5 GHz + + +proc BIT(nr: cint): cint = (1.cint shl nr) + +type + + wifi_2g_channel_bit_t* {.size: sizeof(cint).} = enum ## + ## Argument structure for 2.4G channels + WIFI_CHANNEL_1 = BIT(1), ## < Wi-Fi channel 1 + WIFI_CHANNEL_2 = BIT(2), ## < Wi-Fi channel 2 + WIFI_CHANNEL_3 = BIT(3), ## < Wi-Fi channel 3 + WIFI_CHANNEL_4 = BIT(4), ## < Wi-Fi channel 4 + WIFI_CHANNEL_5 = BIT(5), ## < Wi-Fi channel 5 + WIFI_CHANNEL_6 = BIT(6), ## < Wi-Fi channel 6 + WIFI_CHANNEL_7 = BIT(7), ## < Wi-Fi channel 7 + WIFI_CHANNEL_8 = BIT(8), ## < Wi-Fi channel 8 + WIFI_CHANNEL_9 = BIT(9), ## < Wi-Fi channel 9 + WIFI_CHANNEL_10 = BIT(10), ## < Wi-Fi channel 10 + WIFI_CHANNEL_11 = BIT(11), ## < Wi-Fi channel 11 + WIFI_CHANNEL_12 = BIT(12), ## < Wi-Fi channel 12 + WIFI_CHANNEL_13 = BIT(13), ## < Wi-Fi channel 13 + WIFI_CHANNEL_14 = BIT(14) ## < Wi-Fi channel 14 + + +type + + wifi_5g_channel_bit_t* {.size: sizeof(cint).} = enum ## + ## Argument structure for 5G channels + WIFI_CHANNEL_36 = BIT(1), ## < Wi-Fi channel 36 + WIFI_CHANNEL_40 = BIT(2), ## < Wi-Fi channel 40 + WIFI_CHANNEL_44 = BIT(3), ## < Wi-Fi channel 44 + WIFI_CHANNEL_48 = BIT(4), ## < Wi-Fi channel 48 + WIFI_CHANNEL_52 = BIT(5), ## < Wi-Fi channel 52 + WIFI_CHANNEL_56 = BIT(6), ## < Wi-Fi channel 56 + WIFI_CHANNEL_60 = BIT(7), ## < Wi-Fi channel 60 + WIFI_CHANNEL_64 = BIT(8), ## < Wi-Fi channel 64 + WIFI_CHANNEL_100 = BIT(9), ## < Wi-Fi channel 100 + WIFI_CHANNEL_104 = BIT(10), ## < Wi-Fi channel 104 + WIFI_CHANNEL_108 = BIT(11), ## < Wi-Fi channel 108 + WIFI_CHANNEL_112 = BIT(12), ## < Wi-Fi channel 112 + WIFI_CHANNEL_116 = BIT(13), ## < Wi-Fi channel 116 + WIFI_CHANNEL_120 = BIT(14), ## < Wi-Fi channel 120 + WIFI_CHANNEL_124 = BIT(15), ## < Wi-Fi channel 124 + WIFI_CHANNEL_128 = BIT(16), ## < Wi-Fi channel 128 + WIFI_CHANNEL_132 = BIT(17), ## < Wi-Fi channel 132 + WIFI_CHANNEL_136 = BIT(18), ## < Wi-Fi channel 136 + WIFI_CHANNEL_140 = BIT(19), ## < Wi-Fi channel 140 + WIFI_CHANNEL_144 = BIT(20), ## < Wi-Fi channel 144 + WIFI_CHANNEL_149 = BIT(21), ## < Wi-Fi channel 149 + WIFI_CHANNEL_153 = BIT(22), ## < Wi-Fi channel 153 + WIFI_CHANNEL_157 = BIT(23), ## < Wi-Fi channel 157 + WIFI_CHANNEL_161 = BIT(24), ## < Wi-Fi channel 161 + WIFI_CHANNEL_165 = BIT(25), ## < Wi-Fi channel 165 + WIFI_CHANNEL_169 = BIT(26), ## < Wi-Fi channel 169 + WIFI_CHANNEL_173 = BIT(27), ## < Wi-Fi channel 173 + WIFI_CHANNEL_177 = BIT(28) ## < Wi-Fi channel 177 + +let + WIFI_PROTOCOL_11B* {.importc, header: hdr.}: uint16 = 0x1 + WIFI_PROTOCOL_11G* {.importc, header: hdr.}: uint16 = 0x2 + WIFI_PROTOCOL_11N* {.importc, header: hdr.}: uint16 = 0x4 + WIFI_PROTOCOL_LR* {.importc, header: hdr.}: uint16 = 0x8 + WIFI_PROTOCOL_11A* {.importc, header: hdr.}: uint16 = 0x10 + WIFI_PROTOCOL_11AC* {.importc, header: hdr.}: uint16 = 0x20 + WIFI_PROTOCOL_11AX* {.importc, header: hdr.}: uint16 = 0x40 + +type + + wifi_protocols_t* {.importc: "wifi_protocols_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Description of a Wi-Fi protocols + ## + ghz_2g* {.importc: "ghz_2g".}: uint16 ## < Represents 2.4 GHz protocol, support 802.11b or 802.11g or 802.11n or 802.11ax or LR mode + ghz_5g* {.importc: "ghz_5g".}: uint16 + ## < Represents 5 GHz protocol, support 802.11a or 802.11n or 802.11ac or 802.11ax + + + wifi_bandwidths_t* {.importc: "wifi_bandwidths_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Description of a Wi-Fi band bandwidths + ## + ghz_2g* {.importc: "ghz_2g".}: wifi_bandwidth_t ## + ## < Represents 2.4 GHz bandwidth + ghz_5g* {.importc: "ghz_5g".}: wifi_bandwidth_t + ## < Represents 5 GHz bandwidth + + + wifi_pmf_config_t* {.importc: "wifi_pmf_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Configuration structure for Protected Management Frame + ## + capable* {.importc: "capable".}: bool ## < Deprecated variable. Device will always connect in PMF mode if other device also advertises PMF capability. + required* {.importc: "required".}: bool + ## < Advertises that Protected Management Frame is required. Device will not associate to non-PMF capable devices. + + + wifi_sae_pwe_method_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Configuration for SAE PWE derivation + ## + WPA3_SAE_PWE_UNSPECIFIED, WPA3_SAE_PWE_HUNT_AND_PECK, + WPA3_SAE_PWE_HASH_TO_ELEMENT, WPA3_SAE_PWE_BOTH + + +type + + wifi_sae_pk_mode_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Configuration for SAE-PK + ## + WPA3_SAE_PK_MODE_AUTOMATIC = 0, WPA3_SAE_PK_MODE_ONLY = 1, + WPA3_SAE_PK_MODE_DISABLED = 2 + + +type + + wifi_bss_max_idle_config_t* {.importc: "wifi_bss_max_idle_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Configuration structure for BSS max idle + ## + period* {.importc: "period".}: uint16 ## < Sets BSS Max idle period (1 Unit = 1000TUs OR 1.024 Seconds). If there are no frames for this period from a STA, SoftAP will disassociate due to inactivity. Setting it to 0 disables the feature + protected_keep_alive* {.importc: "protected_keep_alive".}: bool + ## < Requires clients to use protected keep alive frames for BSS Max Idle period + + + wifi_ap_config_t* {.importc: "wifi_ap_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Soft-AP configuration settings for the device + ## + ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. + password* {.importc: "password".}: array[64, uint8] ## + ## < Password of soft-AP. + ssid_len* {.importc: "ssid_len".}: uint8 ## < Optional length of SSID field. + channel* {.importc: "channel".}: uint8 ## < Channel of soft-AP + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## + ## < Auth mode of soft-AP. Do not support AUTH_WEP, AUTH_WAPI_PSK and AUTH_OWE in soft-AP mode. When the auth mode is set to WPA2_PSK, WPA2_WPA3_PSK or WPA3_PSK, the pairwise cipher will be overwritten with WIFI_CIPHER_TYPE_CCMP by default, unless explicitly set. + ssid_hidden* {.importc: "ssid_hidden".}: uint8 ## + ## < Broadcast SSID or not, default 0, broadcast the SSID + max_connection* {.importc: "max_connection".}: uint8 ## + ## < Max number of stations allowed to connect in + beacon_interval* {.importc: "beacon_interval".}: uint16 ## + ## < Beacon interval which should be multiples of 100. Unit: TU(time unit, 1 TU = 1024 us). Range: 100 ~ 60000. Default value: 100 + csa_count* {.importc: "csa_count".}: uint8 ## < Channel Switch Announcement Count. Notify the station that the channel will switch after the csa_count beacon intervals. Default value: 3 + dtim_period* {.importc: "dtim_period".}: uint8 ## + ## < Dtim period of soft-AP. Range: 1 ~ 10. Default value: 1 + pairwise_cipher* {.importc: "pairwise_cipher".}: wifi_cipher_type_t ## + ## < Pairwise cipher of SoftAP, group cipher will be derived using this. Cipher values are valid starting from WIFI_CIPHER_TYPE_TKIP, enum values before that will be considered as invalid and default cipher suites(TKIP+CCMP) will be used. Valid cipher suites in softAP mode are WIFI_CIPHER_TYPE_TKIP, WIFI_CIPHER_TYPE_CCMP, WIFI_CIPHER_TYPE_TKIP_CCMP, WIFI_CIPHER_TYPE_GCMP and WIFI_CIPHER_TYPE_GCMP256. + ftm_responder* {.importc: "ftm_responder".}: bool ## + ## < Enable FTM Responder mode + pmf_cfg* {.importc: "pmf_cfg".}: wifi_pmf_config_t ## + ## < Configuration for Protected Management Frame + sae_pwe_h2e* {.importc: "sae_pwe_h2e".}: wifi_sae_pwe_method_t ## + ## < Configuration for SAE PWE derivation method + transition_disable* {.importc: "transition_disable".}: uint8 ## + ## < Whether to enable transition disable feature + sae_ext* {.importc: "sae_ext".}: uint8 ## < Enable SAE EXT feature. SOC_GCMP_SUPPORT is required for this feature. + bss_max_idle_cfg* {.importc: "bss_max_idle_cfg".}: wifi_bss_max_idle_config_t ## + ## < Configuration for bss max idle, effective if CONFIG_WIFI_BSS_MAX_IDLE_SUPPORT is enabled + gtk_rekey_interval* {.importc: "gtk_rekey_interval".}: uint16 + ## < GTK rekeying interval in seconds. If set to 0, GTK rekeying is disabled. Range: 60 ~ 65535 including 0. + + +const + SAE_H2E_IDENTIFIER_LEN* = 32 + +type + + wifi_sta_config_t* {.importc: "wifi_sta_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief STA configuration settings for the device + ## + ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of target AP. + password* {.importc: "password".}: array[64, uint8] ## + ## < Password of target AP. + scan_method* {.importc: "scan_method".}: wifi_scan_method_t ## + ## < Do all channel scan or fast scan + bssid_set* {.importc: "bssid_set".}: bool ## < Whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP. + bssid* {.importc: "bssid".}: array[6, uint8] ## < MAC address of target AP + channel* {.importc: "channel".}: uint8 ## < Channel hint for target AP. For 2.4G AP, set to 1~13 to scan starting from the specified channel before connecting to AP. For 5G AP, set to 36~177 (36, 40, 44 ... 177) to scan starting from the specified channel before connecting to AP. Set to 0 for no preference + listen_interval* {.importc: "listen_interval".}: uint16 ## + ## < Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. + sort_method* {.importc: "sort_method".}: wifi_sort_method_t ## + ## < Sort the connect AP in the list by rssi or security mode + threshold* {.importc: "threshold".}: wifi_scan_threshold_t ## + ## < When scan_threshold is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. + pmf_cfg* {.importc: "pmf_cfg".}: wifi_pmf_config_t ## + ## < Configuration for Protected Management Frame. Will be advertised in RSN Capabilities in RSN IE. + rm_enabled* {.importc: "rm_enabled", bitsize: 1.}: uint32 ## + ## < Whether Radio Measurements are enabled for the connection + btm_enabled* {.importc: "btm_enabled", bitsize: 1.}: uint32 ## + ## < Whether BSS Transition Management is enabled for the connection. Note that when btm is enabled, the application itself should not set specific bssid (i.e using bssid_set and bssid in this config)or channel to connect to. This defeats the purpose of a BTM supported network, and hence if btm is supported and a specific bssid or channel is set in this config, it will be cleared from the config at the first disconnection or connection so that the device can roam to other BSS. It is recommended not to set BSSID when BTM is enabled. + mbo_enabled* {.importc: "mbo_enabled", bitsize: 1.}: uint32 ## + ## < Whether MBO is enabled for the connection. Note that when mbo is enabled, the application itself should not set specific bssid (i.e using bssid_set and bssid in this config)or channel to connect to. This defeats the purpose of a MBO supported network, and hence if btm is supported and a specific bssid or channel is set in this config, it will be cleared from the config at the first disconnection or connection so that the device can roam to other BSS. It is recommended not to set BSSID when MBO is enabled. Enabling mbo here, automatically enables btm and rm above. + ft_enabled* {.importc: "ft_enabled", bitsize: 1.}: uint32 ## + ## < Whether FT is enabled for the connection + owe_enabled* {.importc: "owe_enabled", bitsize: 1.}: uint32 ## + ## < Whether OWE is enabled for the connection + transition_disable* {.importc: "transition_disable", bitsize: 1.}: uint32 ## + ## < Whether to enable transition disable feature + reserved1* {.importc: "reserved1", bitsize: 26.}: uint32 ## + ## < Reserved for future feature set + sae_pwe_h2e* {.importc: "sae_pwe_h2e".}: wifi_sae_pwe_method_t ## + ## < Configuration for SAE PWE derivation method + sae_pk_mode* {.importc: "sae_pk_mode".}: wifi_sae_pk_mode_t ## + ## < Configuration for SAE-PK (Public Key) Authentication method + failure_retry_cnt* {.importc: "failure_retry_cnt".}: uint8 ## + ## < Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config. + ## Note: Enabling this may cause connection time to increase in case best AP doesn't behave properly. + he_dcm_set* {.importc: "he_dcm_set", bitsize: 1.}: uint32 ## + ## < Whether DCM max.constellation for transmission and reception is set. + he_dcm_max_constellation_tx* {.importc: "he_dcm_max_constellation_tx", + bitsize: 2.}: uint32 ## + ## < Indicate the max.constellation for DCM in TB PPDU the STA supported. 0: not supported. 1: BPSK, 2: QPSK, 3: 16-QAM. The default value is 3. + he_dcm_max_constellation_rx* {.importc: "he_dcm_max_constellation_rx", + bitsize: 2.}: uint32 ## + ## < Indicate the max.constellation for DCM in both Data field and HE-SIG-B field the STA supported. 0: not supported. 1: BPSK, 2: QPSK, 3: 16-QAM. The default value is 3. + he_mcs9_enabled* {.importc: "he_mcs9_enabled", bitsize: 1.}: uint32 ## + ## < Whether to support HE-MCS8 and HE-MCS9. The default value is 0. + he_su_beamformee_disabled* {.importc: "he_su_beamformee_disabled", + bitsize: 1.}: uint32 ## + ## < Whether to disable support for operation as an SU beamformee. + he_trig_su_bmforming_feedback_disabled* + {.importc: "he_trig_su_bmforming_feedback_disabled", bitsize: 1.}: uint32 ## + ## < Whether to disable support the transmission of SU feedback in an HE TB sounding sequence. + he_trig_mu_bmforming_partial_feedback_disabled* {. + importc: "he_trig_mu_bmforming_partial_feedback_disabled", bitsize: 1.}: uint32 ## + ## < Whether to disable support the transmission of partial-bandwidth MU feedback in an HE TB sounding sequence. + he_trig_cqi_feedback_disabled* {.importc: "he_trig_cqi_feedback_disabled", + bitsize: 1.}: uint32 ## + ## < Whether to disable support the transmission of CQI feedback in an HE TB sounding sequence. + vht_su_beamformee_disabled* {.importc: "vht_su_beamformee_disabled", + bitsize: 1.}: uint32 ## + ## < Whether to disable support for operation as an VHT SU beamformee. + vht_mu_beamformee_disabled* {.importc: "vht_mu_beamformee_disabled", + bitsize: 1.}: uint32 ## + ## < Whether to disable support for operation as an VHT MU beamformee. + vht_mcs8_enabled* {.importc: "vht_mcs8_enabled", bitsize: 1.}: uint32 ## + ## < Whether to support VHT-MCS8. The default value is 0. + reserved2* {.importc: "reserved2", bitsize: 19.}: uint32 ## + ## < Reserved for future feature set + sae_h2e_identifier* {.importc: "sae_h2e_identifier".}: array[ + SAE_H2E_IDENTIFIER_LEN, uint8] + ## < Password identifier for H2E. this needs to be null terminated string + + + wifi_nan_config_t* {.importc: "wifi_nan_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Discovery start configuration + ## + op_channel* {.importc: "op_channel".}: uint8 ## < NAN Discovery operating channel + master_pref* {.importc: "master_pref".}: uint8 ## + ## < Device's preference value to serve as NAN Master + scan_time* {.importc: "scan_time".}: uint8 ## < Scan time in seconds while searching for a NAN cluster + warm_up_sec* {.importc: "warm_up_sec".}: uint16 + ## < Warm up time before assuming NAN Anchor Master role + + + wifi_config_t* {.importc: "wifi_config_t", header: hdr, + bycopy, union.} = object ## + ## @brief Configuration data for device's AP or STA or NAN. + ## + ## The usage of this union (for ap, sta or nan configuration) is determined by the accompanying + ## interface argument passed to esp_wifi_set_config() or esp_wifi_get_config() + ## + ## + ap* {.importc: "ap".}: wifi_ap_config_t ## < Configuration of AP + sta* {.importc: "sta".}: wifi_sta_config_t ## < Configuration of STA + nan* {.importc: "nan".}: wifi_nan_config_t + ## < Configuration of NAN + + + wifi_sta_info_t* {.importc: "wifi_sta_info_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Description of STA associated with AP + ## + mac* {.importc: "mac".}: array[6, uint8] ## < MAC address + rssi* {.importc: "rssi".}: int8 ## < Current average rssi of sta connected + phy_11b* {.importc: "phy_11b", bitsize: 1.}: uint32 ## + ## < Bit: 0 flag to identify if 11b mode is enabled or not + phy_11g* {.importc: "phy_11g", bitsize: 1.}: uint32 ## + ## < Bit: 1 flag to identify if 11g mode is enabled or not + phy_11n* {.importc: "phy_11n", bitsize: 1.}: uint32 ## + ## < Bit: 2 flag to identify if 11n mode is enabled or not + phy_lr* {.importc: "phy_lr", bitsize: 1.}: uint32 ## + ## < Bit: 3 flag to identify if low rate is enabled or not + phy_11a* {.importc: "phy_11a", bitsize: 1.}: uint32 ## + ## < Bit: 4 flag to identify if 11ax mode is enabled or not + phy_11ac* {.importc: "phy_11ac", bitsize: 1.}: uint32 ## + ## < Bit: 5 flag to identify if 11ax mode is enabled or not + phy_11ax* {.importc: "phy_11ax", bitsize: 1.}: uint32 ## + ## < Bit: 6 flag to identify if 11ax mode is enabled or not + is_mesh_child* {.importc: "is_mesh_child", bitsize: 1.}: uint32 ## + ## < Bit: 7 flag to identify mesh child + reserved* {.importc: "reserved", bitsize: 24.}: uint32 + ## < Bit: 8..31 reserved + + + wifi_storage_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi storage type + ## + WIFI_STORAGE_FLASH, ## < All configuration will store in both memory and flash + WIFI_STORAGE_RAM ## < All configuration will only store in the memory + + +type + + wifi_vendor_ie_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Vendor Information Element type + ## + ## Determines the frame type that the IE will be associated with. + ## + WIFI_VND_IE_TYPE_BEACON, ## < Beacon frame + WIFI_VND_IE_TYPE_PROBE_REQ, ## < Probe request frame + WIFI_VND_IE_TYPE_PROBE_RESP, ## < Probe response frame + WIFI_VND_IE_TYPE_ASSOC_REQ, ## < Association request frame + WIFI_VND_IE_TYPE_ASSOC_RESP ## < Association response frame + + +type + + wifi_vendor_ie_id_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Vendor Information Element index + ## + ## Each IE type can have up to two associated vendor ID elements. + ## + WIFI_VND_IE_ID_0, ## < Vendor ID element 0 + WIFI_VND_IE_ID_1 ## < Vendor ID element 1 + +let + WIFI_VENDOR_IE_ELEMENT_ID* {.importc, header: hdr.}: uint8 + +type + + wifi_phy_mode_t* {.size: sizeof(cint).} = enum ## + ## @brief Operation PHY mode + ## + WIFI_PHY_MODE_LR, ## < PHY mode for Low Rate + WIFI_PHY_MODE_11B, ## < PHY mode for 11b + WIFI_PHY_MODE_11G, ## < PHY mode for 11g + WIFI_PHY_MODE_11A, ## < PHY mode for 11a + WIFI_PHY_MODE_HT20, ## < PHY mode for Bandwidth HT20 + WIFI_PHY_MODE_HT40, ## < PHY mode for Bandwidth HT40 + WIFI_PHY_MODE_HE20, ## < PHY mode for Bandwidth HE20 + WIFI_PHY_MODE_VHT20 ## < PHY mode for Bandwidth VHT20 + + +type + + vendor_ie_data_t* {.importc: "vendor_ie_data_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Vendor Information Element header + ## + ## The first bytes of the Information Element will match this header. Payload follows. + ## + element_id* {.importc: "element_id".}: uint8 ## < Should be set to WIFI_VENDOR_IE_ELEMENT_ID (0xDD) + length* {.importc: "length".}: uint8 ## < Length of all bytes in the element data following this field. Minimum 4. + vendor_oui* {.importc: "vendor_oui".}: array[3, uint8] ## + ## < Vendor identifier (OUI). + vendor_oui_type* {.importc: "vendor_oui_type".}: uint8 ## + ## < Vendor-specific OUI type. + payload* {.importc: "payload".}: UncheckedArray[uint8] + ## < Payload. Length is equal to value in 'length' field, minus 4. + + + wifi_promiscuous_pkt_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Promiscuous frame type + ## + ## Passed to promiscuous mode RX callback to indicate the type of parameter in the buffer. + ## + ## + WIFI_PKT_MGMT, ## < Management frame, indicates 'buf' argument is wifi_promiscuous_pkt_t + WIFI_PKT_CTRL, ## < Control frame, indicates 'buf' argument is wifi_promiscuous_pkt_t + WIFI_PKT_DATA, ## < Data frame, indicates 'buf' argument is wifi_promiscuous_pkt_t + WIFI_PKT_MISC ## < Other type, such as MIMO etc. 'buf' argument is wifi_promiscuous_pkt_t but the payload is zero length. + +const + WIFI_PROMIS_FILTER_MASK_ALL* = (0xFFFFFFFF) ## < Filter all packets + WIFI_PROMIS_FILTER_MASK_MGMT* = (1) ## < Filter the packets with type of WIFI_PKT_MGMT + WIFI_PROMIS_FILTER_MASK_CTRL* = (1 shl 1) ## < Filter the packets with type of WIFI_PKT_CTRL + WIFI_PROMIS_FILTER_MASK_DATA* = (1 shl 2) ## < Filter the packets with type of WIFI_PKT_DATA + WIFI_PROMIS_FILTER_MASK_MISC* = (1 shl 3) ## < Filter the packets with type of WIFI_PKT_MISC + WIFI_PROMIS_FILTER_MASK_DATA_MPDU* = (1 shl 4) ## < Filter the MPDU which is a kind of WIFI_PKT_DATA + WIFI_PROMIS_FILTER_MASK_DATA_AMPDU* = (1 shl 5) ## < Filter the AMPDU which is a kind of WIFI_PKT_DATA + WIFI_PROMIS_FILTER_MASK_FCSFAIL* = (1 shl 6) ## < Filter the FCS failed packets, do not open it in general + WIFI_PROMIS_CTRL_FILTER_MASK_ALL* = (0xFF800000) ## + ## < Filter all control packets + WIFI_PROMIS_CTRL_FILTER_MASK_WRAPPER* = (1 shl 23) ## + ## < Filter the control packets with subtype of Control Wrapper + WIFI_PROMIS_CTRL_FILTER_MASK_BAR* = (1 shl 24) ## < Filter the control packets with subtype of Block Ack Request + WIFI_PROMIS_CTRL_FILTER_MASK_BA* = (1 shl 25) ## < Filter the control packets with subtype of Block Ack + WIFI_PROMIS_CTRL_FILTER_MASK_PSPOLL* = (1 shl 26) ## + ## < Filter the control packets with subtype of PS-Poll + WIFI_PROMIS_CTRL_FILTER_MASK_RTS* = (1 shl 27) ## < Filter the control packets with subtype of RTS + WIFI_PROMIS_CTRL_FILTER_MASK_CTS* = (1 shl 28) ## < Filter the control packets with subtype of CTS + WIFI_PROMIS_CTRL_FILTER_MASK_ACK* = (1 shl 29) ## < Filter the control packets with subtype of ACK + WIFI_PROMIS_CTRL_FILTER_MASK_CFEND* = (1 shl 30) ## + ## < Filter the control packets with subtype of CF-END + WIFI_PROMIS_CTRL_FILTER_MASK_CFENDACK* = (1 shl 31) ## + ## < Filter the control packets with subtype of CF-END+CF-ACK + +type + + wifi_promiscuous_filter_t* {.importc: "wifi_promiscuous_filter_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Mask for filtering different packet types in promiscuous mode + ## + filter_mask* {.importc: "filter_mask".}: uint32 + ## < OR of one or more filter values WIFI_PROMIS_FILTER_* + + +const + WIFI_EVENT_MASK_ALL* = (0xFFFFFFFF) ## < Mask all Wi-Fi events + WIFI_EVENT_MASK_NONE* = (0) ## < Mask none of the Wi-Fi events + WIFI_EVENT_MASK_AP_PROBEREQRECVED* = (BIT(0)) ## < Mask SYSTEM_EVENT_AP_PROBEREQRECVED event + +## +## @brief CSI data type +## +## + +type + + wifi_ant_gpio_t* {.importc: "wifi_ant_gpio_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Wi-Fi GPIO configuration for antenna selection + ## + ## + gpio_select* {.importc: "gpio_select", bitsize: 1.}: uint8 ## + ## < Whether this GPIO is connected to external antenna switch + gpio_num* {.importc: "gpio_num", bitsize: 7.}: uint8 + ## < The GPIO number that connects to external antenna switch + + + wifi_ant_gpio_config_t* {.importc: "wifi_ant_gpio_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Wi-Fi GPIOs configuration for antenna selection + ## + ## + gpio_cfg* {.importc: "gpio_cfg".}: array[4, wifi_ant_gpio_t] + ## < The configurations of GPIOs that connect to external antenna switch + + + wifi_ant_mode_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi antenna mode + ## + ## + WIFI_ANT_MODE_ANT0, ## < Enable Wi-Fi antenna 0 only + WIFI_ANT_MODE_ANT1, ## < Enable Wi-Fi antenna 1 only + WIFI_ANT_MODE_AUTO, ## < Enable Wi-Fi antenna 0 and 1, automatically select an antenna + WIFI_ANT_MODE_MAX ## < Invalid Wi-Fi enabled antenna + + +type + + wifi_ant_config_t* {.importc: "wifi_ant_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Wi-Fi antenna configuration + ## + ## + rx_ant_mode* {.importc: "rx_ant_mode".}: wifi_ant_mode_t ## + ## < Wi-Fi antenna mode for receiving + rx_ant_default* {.importc: "rx_ant_default".}: wifi_ant_t ## + ## < Default antenna mode for receiving, it's ignored if rx_ant_mode is not WIFI_ANT_MODE_AUTO + tx_ant_mode* {.importc: "tx_ant_mode".}: wifi_ant_mode_t ## + ## < Wi-Fi antenna mode for transmission, it can be set to WIFI_ANT_MODE_AUTO only if rx_ant_mode is set to WIFI_ANT_MODE_AUTO + enabled_ant0* {.importc: "enabled_ant0", bitsize: 4.}: uint8 ## + ## < Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT0 + enabled_ant1* {.importc: "enabled_ant1", bitsize: 4.}: uint8 + ## < Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT1 + + + wifi_action_rx_cb_t* = proc (hdr: ptr uint8; payload: ptr uint8; len: csize_t; + channel: uint8): cint {.cdecl.} ## + ## + ## @brief The Rx callback function of Action Tx operations + ## + ## @param hdr Pointer to the IEEE 802.11 Header structure + ## @param payload Pointer to the Payload following 802.11 Header + ## @param len Length of the Payload + ## @param channel Channel number the frame is received on + ## + ## + + wifi_action_tx_req_t* {.importc: "wifi_action_tx_req_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Action Frame Tx Request + ## + ifx* {.importc: "ifx".}: wifi_interface_t ## < Wi-Fi interface to send request to + dest_mac* {.importc: "dest_mac".}: array[6, uint8] ## + ## < Destination MAC address + `type`* {.importc: "type".}: wifi_action_tx_t ## < ACTION TX operation type + channel* {.importc: "channel".}: uint8 ## < Channel on which to perform ACTION TX Operation + wait_time_ms* {.importc: "wait_time_ms".}: uint32 ## + ## < Duration to wait for on target channel + no_ack* {.importc: "no_ack".}: bool ## < Indicates no ack required + rx_cb* {.importc: "rx_cb".}: wifi_action_rx_cb_t ## + ## < Rx Callback to receive action frames + op_id* {.importc: "op_id".}: uint8 ## < Unique Identifier for operation provided by wifi driver + data_len* {.importc: "data_len".}: uint32 ## < Length of the appended Data + data* {.importc: "data".}: UncheckedArray[uint8] + ## < Appended Data payload + + + wifi_roc_done_status_t* {.size: sizeof(cint).} = enum ## + ## Status codes for WIFI_EVENT_ROC_DONE evt + WIFI_ROC_DONE = 0, ## < ROC operation was completed successfully + WIFI_ROC_FAIL ## < ROC operation was cancelled + + +type + + wifi_action_roc_done_cb_t* = proc (context: uint32; op_id: uint8; + status: wifi_roc_done_status_t) {.cdecl.} ## + ## + ## @brief The callback function executed when ROC operation has ended + ## + ## @param context rxcb registered for the corresponding ROC operation + ## @param op_id ID of the corresponding ROC operation + ## @param status status code of the ROC operation denoted + ## + ## + + wifi_roc_req_t* {.importc: "wifi_roc_req_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Remain on Channel request + ## + ## + ## + ifx* {.importc: "ifx".}: wifi_interface_t ## < WiFi interface to send request to + `type`* {.importc: "type".}: wifi_roc_t ## < ROC operation type + channel* {.importc: "channel".}: uint8 ## < Channel on which to perform ROC Operation + sec_channel* {.importc: "sec_channel".}: wifi_second_chan_t ## + ## < Secondary channel + wait_time_ms* {.importc: "wait_time_ms".}: uint32 ## + ## < Duration to wait for on target channel + rx_cb* {.importc: "rx_cb".}: wifi_action_rx_cb_t ## + ## < Rx Callback to receive any response + op_id* {.importc: "op_id".}: uint8 ## < ID of this specific ROC operation provided by wifi driver + done_cb* {.importc: "done_cb".}: wifi_action_roc_done_cb_t + ## < Callback to function that will be called upon ROC done. If assigned, WIFI_EVENT_ROC_DONE event will not be posted + + + wifi_ftm_initiator_cfg_t* {.importc: "wifi_ftm_initiator_cfg_t", + header: hdr, bycopy.} = object ## + ## + ## @brief FTM Initiator configuration + ## + ## + resp_mac* {.importc: "resp_mac".}: array[6, uint8] ## + ## < MAC address of the FTM Responder + channel* {.importc: "channel".}: uint8 ## < Primary channel of the FTM Responder + frm_count* {.importc: "frm_count".}: uint8 ## < No. of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0(No pref), 16, 24, 32, 64) + burst_period* {.importc: "burst_period".}: uint16 ## + ## < Requested period between FTM bursts in 100's of milliseconds (allowed values 0(No pref) - 100) + use_get_report_api* {.importc: "use_get_report_api".}: bool + ## < True - Using esp_wifi_ftm_get_report to get FTM report, False - Using ftm_report_data from + ## WIFI_EVENT_FTM_REPORT to get FTM report + + +const + ESP_WIFI_NAN_MAX_SVC_SUPPORTED* = 2 + ESP_WIFI_NAN_DATAPATH_MAX_PEERS* = 2 + ESP_WIFI_NDP_ROLE_INITIATOR* = 1 + ESP_WIFI_NDP_ROLE_RESPONDER* = 2 + ESP_WIFI_MAX_SVC_NAME_LEN* = 256 + ESP_WIFI_MAX_FILTER_LEN* = 256 + ESP_WIFI_MAX_SVC_INFO_LEN* = 64 + ESP_WIFI_MAX_FUP_SSI_LEN* = 2048 + ESP_WIFI_MAX_SVC_SSI_LEN* = 512 + ESP_WIFI_MAX_NEIGHBOR_REP_LEN* = 64 + WIFI_OUI_LEN* = 3 + +type + + wifi_nan_svc_proto_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Protocol types in NAN service specific info attribute + ## + ## + WIFI_SVC_PROTO_RESERVED = 0, ## < Value 0 Reserved + WIFI_SVC_PROTO_BONJOUR = 1, ## < Bonjour Protocol + WIFI_SVC_PROTO_GENERIC = 2, ## < Generic Service Protocol + WIFI_SVC_PROTO_CSA_MATTER = 3, ## < CSA Matter specific protocol + WIFI_SVC_PROTO_MAX ## < Values 4-255 Reserved + + +type + + wifi_nan_wfa_ssi_t* {.importc: "wifi_nan_wfa_ssi_t", + header: hdr, bycopy.} = object ## + ## + ## @brief WFA defined Protocol types in NAN service specific info attribute + ## + ## + wfa_oui* {.importc: "wfa_oui".}: array[WIFI_OUI_LEN, uint8] ## + ## < WFA OUI - 0x50, 0x6F, 0x9A + proto* {.importc: "proto".}: wifi_nan_svc_proto_t ## + ## < WFA defined protocol types + payload* {.importc: "payload".}: UncheckedArray[uint8] + ## < Service Info payload + + + wifi_nan_service_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief NAN Services types + ## + ## + NAN_PUBLISH_SOLICITED, ## < Send unicast Publish frame to Subscribers that match the requirement + NAN_PUBLISH_UNSOLICITED, ## < Send broadcast Publish frames in every Discovery Window(DW) + NAN_SUBSCRIBE_ACTIVE, ## < Send broadcast Subscribe frames in every DW + NAN_SUBSCRIBE_PASSIVE ## < Passively listens to Publish frames + + +type + + wifi_nan_publish_cfg_t* {.importc: "wifi_nan_publish_cfg_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Publish service configuration parameters + ## + ## + service_name* {.importc: "service_name".}: array[ESP_WIFI_MAX_SVC_NAME_LEN, + char] ## < Service name identifier + `type`* {.importc: "type".}: wifi_nan_service_type_t ## + ## < Service type + matching_filter* {.importc: "matching_filter".}: array[ + ESP_WIFI_MAX_FILTER_LEN, char] ## < Comma separated filters for filtering services + svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, char] ## + ## < To be deprecated in next major release, use ssi instead + single_replied_event* {.importc: "single_replied_event", bitsize: 1.}: uint8 ## + ## < Give single Replied event or every time + datapath_reqd* {.importc: "datapath_reqd", bitsize: 1.}: uint8 ## + ## < NAN Datapath required for the service + fsd_reqd* {.importc: "fsd_reqd", bitsize: 1.}: uint8 ## + ## < Further Service Discovery(FSD) required + fsd_gas* {.importc: "fsd_gas", bitsize: 1.}: uint8 ## + ## < 0 - Follow-up used for FSD, 1 - GAS used for FSD + reserved* {.importc: "reserved", bitsize: 4.}: uint8 ## + ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info, maximum allowed length - ESP_WIFI_MAX_SVC_SSI_LEN + ssi* {.importc: "ssi".}: ptr uint8 + ## < Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications + + + wifi_nan_subscribe_cfg_t* {.importc: "wifi_nan_subscribe_cfg_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Subscribe service configuration parameters + ## + ## + service_name* {.importc: "service_name".}: array[ESP_WIFI_MAX_SVC_NAME_LEN, + char] ## < Service name identifier + `type`* {.importc: "type".}: wifi_nan_service_type_t ## + ## < Service type + matching_filter* {.importc: "matching_filter".}: array[ + ESP_WIFI_MAX_FILTER_LEN, char] ## < Comma separated filters for filtering services + svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, char] ## + ## < To be deprecated in next major release, use ssi instead + single_match_event* {.importc: "single_match_event", bitsize: 1.}: uint8 ## + ## < Give single Match event(per SSI update) or every time + datapath_reqd* {.importc: "datapath_reqd", bitsize: 1.}: uint8 ## + ## < NAN Datapath required for the service + fsd_reqd* {.importc: "fsd_reqd", bitsize: 1.}: uint8 ## + ## < Further Service Discovery(FSD) required + fsd_gas* {.importc: "fsd_gas", bitsize: 1.}: uint8 ## + ## < 0 - Follow-up used for FSD, 1 - GAS used for FSD + reserved* {.importc: "reserved", bitsize: 4.}: uint8 ## + ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info, maximum allowed length - ESP_WIFI_MAX_SVC_SSI_LEN + ssi* {.importc: "ssi".}: ptr uint8 + ## < Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications + + + wifi_nan_followup_params_t* {.importc: "wifi_nan_followup_params_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Follow-up parameters + ## + ## + inst_id* {.importc: "inst_id".}: uint8 ## < Own service instance id + peer_inst_id* {.importc: "peer_inst_id".}: uint8 ## + ## < Peer's service instance id + peer_mac* {.importc: "peer_mac".}: array[6, uint8] ## + ## < Peer's MAC address + svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, char] ## + ## < To be deprecated in next major release, use ssi instead + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info, maximum allowed length - ESP_WIFI_MAX_FUP_SSI_LEN + ssi* {.importc: "ssi".}: ptr uint8 + ## < Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications + + + wifi_nan_datapath_req_t* {.importc: "wifi_nan_datapath_req_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Datapath Request parameters + ## + ## + pub_id* {.importc: "pub_id".}: uint8 ## < Publisher's service instance id + peer_mac* {.importc: "peer_mac".}: array[6, uint8] ## + ## < Peer's MAC address + confirm_required* {.importc: "confirm_required".}: bool + ## < NDP Confirm frame required + + + wifi_nan_datapath_resp_t* {.importc: "wifi_nan_datapath_resp_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Datapath Response parameters + ## + ## + accept* {.importc: "accept".}: bool ## < True - Accept incoming NDP, False - Reject it + ndp_id* {.importc: "ndp_id".}: uint8 ## < NAN Datapath Identifier + peer_mac* {.importc: "peer_mac".}: array[6, uint8] + ## < Peer's MAC address + + + wifi_nan_datapath_end_req_t* {.importc: "wifi_nan_datapath_end_req_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Datapath End parameters + ## + ## + ndp_id* {.importc: "ndp_id".}: uint8 ## < NAN Datapath Identifier + peer_mac* {.importc: "peer_mac".}: array[6, uint8] + ## < Peer's MAC address + + + wifi_phy_rate_t* {.importc: "wifi_phy_rate_t", header: hdr.} = cint ##\ + ## @brief Wi-Fi PHY rate encodings + ## + ## @note Rate Table: MCS Rate and Guard Interval Information + ## | MCS RATE | HT20 | HT40 | HE20 | VHT20 | + ## + ## |-----------------------------|-------------------------|-------------------------|-------------------------|-------------------------| + ## | WIFI_PHY_RATE_MCS0_LGI | 6.5 Mbps (800 ns) | 13.5 Mbps (800 ns) | 8.1 Mbps (1600 ns) | 6.5 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS1_LGI | 13 Mbps (800 ns) | 27 Mbps (800 ns) | 16.3 Mbps (1600 ns) | 13 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS2_LGI | 19.5 Mbps (800 ns) | 40.5 Mbps (800 ns) | 24.4 Mbps (1600 ns) | 19.5 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS3_LGI | 26 Mbps (800 ns) | 54 Mbps (800 ns) | 32.5 Mbps (1600 ns) | 26 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS4_LGI | 39 Mbps (800 ns) | 81 Mbps (800 ns) | 48.8 Mbps (1600 ns) | 39 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS5_LGI | 52 Mbps (800 ns) | 108 Mbps (800 ns) | 65 Mbps (1600 ns) | 52 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS6_LGI | 58.5 Mbps (800 ns) | 121.5 Mbps (800 ns) | 73.1 Mbps (1600 ns) | 58.5 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS7_LGI | 65 Mbps (800 ns) | 135 Mbps (800 ns) | 81.3 Mbps (1600 ns) | 65 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS8_LGI | | | 97.5 Mbps (1600 ns) | | + ## | WIFI_PHY_RATE_MCS9_LGI | | | 108.3 Mbps (1600 ns) | | + ## + ## @note + ## | MCS RATE | HT20 | HT40 | HE20 | VHT20 | + ## + ## |-----------------------------|-------------------------|-------------------------|-------------------------|-------------------------| + ## | WIFI_PHY_RATE_MCS0_SGI | 7.2 Mbps (400 ns) | 15 Mbps (400 ns) | 8.6 Mbps (800 ns) | 7.2 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS1_SGI | 14.4 Mbps (400 ns) | 30 Mbps (400 ns) | 17.2 Mbps (800 ns) | 14.4 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS2_SGI | 21.7 Mbps (400 ns) | 45 Mbps (400 ns) | 25.8 Mbps (800 ns) | 21.7 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS3_SGI | 28.9 Mbps (400 ns) | 60 Mbps (400 ns) | 34.4 Mbps (800 ns) | 28.9 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS4_SGI | 43.3 Mbps (400 ns) | 90 Mbps (400 ns) | 51.6 Mbps (800 ns) | 43.3 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS5_SGI | 57.8 Mbps (400 ns) | 120 Mbps (400 ns) | 68.8 Mbps (800 ns) | 57.8 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS6_SGI | 65 Mbps (400 ns) | 135 Mbps (400 ns) | 77.4 Mbps (800 ns) | 65 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS7_SGI | 72.2 Mbps (400 ns) | 150 Mbps (400 ns) | 86 Mbps (800 ns) | 72.2 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS8_SGI | | | 103.2 Mbps (800 ns) | | + ## | WIFI_PHY_RATE_MCS9_SGI | | | 114.7 Mbps (800 ns) | | + ## + ## + +let + WIFI_PHY_RATE_1M_L {.importc: "WIFI_PHY_RATE_1M_L", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_2M_L {.importc: "WIFI_PHY_RATE_2M_L", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_5M_L {.importc: "WIFI_PHY_RATE_5M_L", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_11M_L {.importc: "WIFI_PHY_RATE_11M_L", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_2M_S {.importc: "WIFI_PHY_RATE_2M_S", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_5M_S {.importc: "WIFI_PHY_RATE_5M_S", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_11M_S {.importc: "WIFI_PHY_RATE_11M_S", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_48M {.importc: "WIFI_PHY_RATE_48M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_24M {.importc: "WIFI_PHY_RATE_24M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_12M {.importc: "WIFI_PHY_RATE_12M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_6M {.importc: "WIFI_PHY_RATE_6M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_54M {.importc: "WIFI_PHY_RATE_54M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_36M {.importc: "WIFI_PHY_RATE_36M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_18M {.importc: "WIFI_PHY_RATE_18M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_9M {.importc: "WIFI_PHY_RATE_9M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS0_LGI {.importc: "WIFI_PHY_RATE_MCS0_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS1_LGI {.importc: "WIFI_PHY_RATE_MCS1_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS2_LGI {.importc: "WIFI_PHY_RATE_MCS2_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS3_LGI {.importc: "WIFI_PHY_RATE_MCS3_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS4_LGI {.importc: "WIFI_PHY_RATE_MCS4_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS5_LGI {.importc: "WIFI_PHY_RATE_MCS5_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS6_LGI {.importc: "WIFI_PHY_RATE_MCS6_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS7_LGI {.importc: "WIFI_PHY_RATE_MCS7_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS8_LGI {.importc: "WIFI_PHY_RATE_MCS8_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS9_LGI {.importc: "WIFI_PHY_RATE_MCS9_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS0_SGI {.importc: "WIFI_PHY_RATE_MCS0_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS1_SGI {.importc: "WIFI_PHY_RATE_MCS1_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS2_SGI {.importc: "WIFI_PHY_RATE_MCS2_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS3_SGI {.importc: "WIFI_PHY_RATE_MCS3_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS4_SGI {.importc: "WIFI_PHY_RATE_MCS4_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS5_SGI {.importc: "WIFI_PHY_RATE_MCS5_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS6_SGI {.importc: "WIFI_PHY_RATE_MCS6_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS7_SGI {.importc: "WIFI_PHY_RATE_MCS7_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS8_SGI {.importc: "WIFI_PHY_RATE_MCS8_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS9_SGI {.importc: "WIFI_PHY_RATE_MCS9_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_LORA_250K {.importc: "WIFI_PHY_RATE_LORA_250K", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_LORA_500K {.importc: "WIFI_PHY_RATE_LORA_500K", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MAX {.importc: "WIFI_PHY_RATE_MAX", header: hdr.}: wifi_phy_rate_t + + +type + + wifi_event_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi event declarations + ## + WIFI_EVENT_WIFI_READY = 0, ## < Wi-Fi ready + WIFI_EVENT_SCAN_DONE, ## < Finished scanning AP + WIFI_EVENT_STA_START, ## < Station start + WIFI_EVENT_STA_STOP, ## < Station stop + WIFI_EVENT_STA_CONNECTED, ## < Station connected to AP + WIFI_EVENT_STA_DISCONNECTED, ## < Station disconnected from AP + WIFI_EVENT_STA_AUTHMODE_CHANGE, ## < The auth mode of AP connected by device's station changed + WIFI_EVENT_STA_WPS_ER_SUCCESS, ## < Station WPS succeeds in enrollee mode + WIFI_EVENT_STA_WPS_ER_FAILED, ## < Station WPS fails in enrollee mode + WIFI_EVENT_STA_WPS_ER_TIMEOUT, ## < Station WPS timeout in enrollee mode + WIFI_EVENT_STA_WPS_ER_PIN, ## < Station WPS pin code in enrollee mode + WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, ## < Station WPS overlap in enrollee mode + WIFI_EVENT_AP_START, ## < Soft-AP start + WIFI_EVENT_AP_STOP, ## < Soft-AP stop + WIFI_EVENT_AP_STACONNECTED, ## < A station connected to Soft-AP + WIFI_EVENT_AP_STADISCONNECTED, ## < A station disconnected from Soft-AP + WIFI_EVENT_AP_PROBEREQRECVED, ## < Receive probe request packet in soft-AP interface + WIFI_EVENT_FTM_REPORT, ## < Receive report of FTM procedure + ## Add next events after this only + WIFI_EVENT_STA_BSS_RSSI_LOW, ## < AP's RSSI crossed configured threshold + WIFI_EVENT_ACTION_TX_STATUS, ## < Status indication of Action Tx operation + WIFI_EVENT_ROC_DONE, ## < Remain-on-Channel operation complete + WIFI_EVENT_STA_BEACON_TIMEOUT, ## < Station beacon timeout + WIFI_EVENT_CONNECTIONLESS_MODULE_WAKE_INTERVAL_START, ## + ## < Connectionless module wake interval start + ## Add next events after this only + WIFI_EVENT_AP_WPS_RG_SUCCESS, ## < Soft-AP wps succeeds in registrar mode + WIFI_EVENT_AP_WPS_RG_FAILED, ## < Soft-AP wps fails in registrar mode + WIFI_EVENT_AP_WPS_RG_TIMEOUT, ## < Soft-AP wps timeout in registrar mode + WIFI_EVENT_AP_WPS_RG_PIN, ## < Soft-AP wps pin code in registrar mode + WIFI_EVENT_AP_WPS_RG_PBC_OVERLAP, ## < Soft-AP wps overlap in registrar mode + WIFI_EVENT_ITWT_SETUP, ## < iTWT setup + WIFI_EVENT_ITWT_TEARDOWN, ## < iTWT teardown + WIFI_EVENT_ITWT_PROBE, ## < iTWT probe + WIFI_EVENT_ITWT_SUSPEND, ## < iTWT suspend + WIFI_EVENT_TWT_WAKEUP, ## < TWT wakeup + WIFI_EVENT_BTWT_SETUP, ## < bTWT setup + WIFI_EVENT_BTWT_TEARDOWN, ## < bTWT teardown + WIFI_EVENT_NAN_STARTED, ## < NAN Discovery has started + WIFI_EVENT_NAN_STOPPED, ## < NAN Discovery has stopped + WIFI_EVENT_NAN_SVC_MATCH, ## < NAN Service Discovery match found + WIFI_EVENT_NAN_REPLIED, ## < Replied to a NAN peer with Service Discovery match + WIFI_EVENT_NAN_RECEIVE, ## < Received a Follow-up message + WIFI_EVENT_NDP_INDICATION, ## < Received NDP Request from a NAN Peer + WIFI_EVENT_NDP_CONFIRM, ## < NDP Confirm Indication + WIFI_EVENT_NDP_TERMINATED, ## < NAN Datapath terminated indication + WIFI_EVENT_HOME_CHANNEL_CHANGE, ## < Wi-Fi home channel change,doesn't occur when scanning + WIFI_EVENT_STA_NEIGHBOR_REP, ## < Received Neighbor Report response + WIFI_EVENT_AP_WRONG_PASSWORD, ## < a station tried to connect with wrong password + WIFI_EVENT_STA_BEACON_OFFSET_UNSTABLE, ## < Station sampled beacon offset unstable + WIFI_EVENT_DPP_URI_READY, ## < DPP URI is ready through Bootstrapping + WIFI_EVENT_DPP_CFG_RECVD, ## < Config received via DPP Authentication + WIFI_EVENT_DPP_FAILED, ## < DPP failed + WIFI_EVENT_MAX ## < Invalid Wi-Fi event ID + + +## @cond * +## @brief Wi-Fi event base declaration + +# ESP_EVENT_DECLARE_BASE(WIFI_EVENT) +let WIFI_EVENT* {.importc: "WIFI_EVENT", header: "esp_wifi_types.h".}: esp_event_base_t + +type + + wifi_event_sta_scan_done_t* {.importc: "wifi_event_sta_scan_done_t", + header: hdr, bycopy.} = object ## + ## @endcond * + ## + ## @brief Argument structure for WIFI_EVENT_SCAN_DONE event + ## + status* {.importc: "status".}: uint32 ## < Status of scanning APs: 0 — success, 1 - failure + number* {.importc: "number".}: uint8 ## < Number of scan results + scan_id* {.importc: "scan_id".}: uint8 + ## < Scan sequence number, used for block scan + + + wifi_event_sta_connected_t* {.importc: "wifi_event_sta_connected_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_CONNECTED event + ## + ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of connected AP + ssid_len* {.importc: "ssid_len".}: uint8 ## < SSID length of connected AP + bssid* {.importc: "bssid".}: array[6, uint8] ## < BSSID of connected AP + channel* {.importc: "channel".}: uint8 ## < Channel of connected AP + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## + ## < Authentication mode used by the connection + aid* {.importc: "aid".}: uint16 + ## < Authentication id assigned by the connected AP + + + wifi_event_sta_disconnected_t* {.importc: "wifi_event_sta_disconnected_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_DISCONNECTED event + ## + ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of disconnected AP + ssid_len* {.importc: "ssid_len".}: uint8 ## < SSID length of disconnected AP + bssid* {.importc: "bssid".}: array[6, uint8] ## < BSSID of disconnected AP + reason* {.importc: "reason".}: uint8 ## < Disconnection reason + rssi* {.importc: "rssi".}: int8 + ## < Disconnection RSSI + + + wifi_event_sta_authmode_change_t* {.importc: "wifi_event_sta_authmode_change_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_AUTHMODE_CHANGE event + ## + old_mode* {.importc: "old_mode".}: wifi_auth_mode_t ## + ## < Old auth mode of AP + new_mode* {.importc: "new_mode".}: wifi_auth_mode_t + ## < New auth mode of AP + + + wifi_event_sta_wps_er_pin_t* {.importc: "wifi_event_sta_wps_er_pin_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_WPS_ER_PIN event + ## + pin_code* {.importc: "pin_code".}: array[8, uint8] + ## < PIN code of station in enrollee mode + + + wifi_event_sta_wps_fail_reason_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_WPS_ER_FAILED event + ## + WPS_FAIL_REASON_NORMAL = 0, ## < WPS normal fail reason + WPS_FAIL_REASON_RECV_M2D, ## < WPS receive M2D frame + WPS_FAIL_REASON_RECV_DEAUTH, ## < Recv deauth from AP while wps handshake + WPS_FAIL_REASON_MAX ## < Max WPS fail reason + +const + MAX_SSID_LEN* = 32 + MAX_PASSPHRASE_LEN* = 64 + MAX_WPS_AP_CRED* = 3 + +type + + INNER_C_STRUCT_esp_wifi_types_generic_1* {. + importc: "wifi_event_sta_wps_er_success_t::no_name", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_WPS_ER_SUCCESS event + ## + ssid* {.importc: "ssid".}: array[MAX_SSID_LEN, uint8] ## + ## < SSID of AP + passphrase* {.importc: "passphrase".}: array[MAX_PASSPHRASE_LEN, uint8] + ## < Passphrase for the AP + + + wifi_event_sta_wps_er_success_t* {.importc: "wifi_event_sta_wps_er_success_t", + header: hdr, bycopy.} = object + ap_cred_cnt* {.importc: "ap_cred_cnt".}: uint8 ## + ## < Number of AP credentials received + ap_cred* {.importc: "ap_cred".}: array[MAX_WPS_AP_CRED, + INNER_C_STRUCT_esp_wifi_types_generic_1] + ## < All AP credentials received from WPS handshake + + + wifi_event_ap_staconnected_t* {.importc: "wifi_event_ap_staconnected_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_STACONNECTED event + ## + mac* {.importc: "mac".}: array[6, uint8] ## < MAC address of the station connected to Soft-AP + aid* {.importc: "aid".}: uint8 ## < AID assigned by the Soft-AP to the connected station + is_mesh_child* {.importc: "is_mesh_child".}: bool + ## < Flag indicating whether the connected station is a mesh child + + + wifi_event_ap_stadisconnected_t* {.importc: "wifi_event_ap_stadisconnected_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_STADISCONNECTED event + ## + mac* {.importc: "mac".}: array[6, uint8] ## < MAC address of the station disconnects from the soft-AP + aid* {.importc: "aid".}: uint8 ## < AID that the Soft-AP assigned to the disconnected station + is_mesh_child* {.importc: "is_mesh_child".}: bool ## + ## < Flag indicating whether the disconnected station is a mesh child + reason* {.importc: "reason".}: uint16 + ## < Disconnection reason + + + wifi_event_ap_probe_req_rx_t* {.importc: "wifi_event_ap_probe_req_rx_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_PROBEREQRECVED event + ## + rssi* {.importc: "rssi".}: cint ## < Received probe request signal strength + mac* {.importc: "mac".}: array[6, uint8] + ## < MAC address of the station which send probe request + + + wifi_event_bss_rssi_low_t* {.importc: "wifi_event_bss_rssi_low_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_BSS_RSSI_LOW event + ## + rssi* {.importc: "rssi".}: int32 + ## < RSSI value of bss + + + wifi_event_home_channel_change_t* {.importc: "wifi_event_home_channel_change_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_HOME_CHANNEL_CHANGE event + ## + old_chan* {.importc: "old_chan".}: uint8 ## < Old home channel of the device + old_snd* {.importc: "old_snd".}: wifi_second_chan_t ## + ## < Old second channel of the device + new_chan* {.importc: "new_chan".}: uint8 ## < New home channel of the device + new_snd* {.importc: "new_snd".}: wifi_second_chan_t + ## < New second channel of the device + + + wifi_ftm_status_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief FTM operation status types + ## + ## + FTM_STATUS_SUCCESS = 0, ## < FTM exchange is successful + FTM_STATUS_UNSUPPORTED, ## < Peer does not support FTM + FTM_STATUS_CONF_REJECTED, ## < Peer rejected FTM configuration in FTM Request + FTM_STATUS_NO_RESPONSE, ## < Peer did not respond to FTM Requests + FTM_STATUS_FAIL, ## < Unknown error during FTM exchange + FTM_STATUS_NO_VALID_MSMT, ## < FTM session did not result in any valid measurements + FTM_STATUS_USER_TERM ## < User triggered termination + + +type + + wifi_ftm_report_entry_t* {.importc: "wifi_ftm_report_entry_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Structure representing a report entry for Fine Timing Measurement (FTM) in Wi-Fi. + ## + ## This structure holds the information related to the FTM process between a Wi-Fi FTM Initiator + ## and a Wi-Fi FTM Responder. FTM is used for precise distance measurement by timing the exchange + ## of frames between devices. + ## + dlog_token* {.importc: "dlog_token".}: uint8 ## < Dialog Token of the FTM frame + rssi* {.importc: "rssi".}: int8 ## < RSSI of the FTM frame received + rtt* {.importc: "rtt".}: uint32 ## < Round Trip Time in pSec with a peer + t1* {.importc: "t1".}: uint64 ## < Time of departure of FTM frame from FTM Responder in pSec + t2* {.importc: "t2".}: uint64 ## < Time of arrival of FTM frame at FTM Initiator in pSec + t3* {.importc: "t3".}: uint64 ## < Time of departure of ACK from FTM Initiator in pSec + t4* {.importc: "t4".}: uint64 + ## < Time of arrival of ACK at FTM Responder in pSec + + + wifi_event_ftm_report_t* {.importc: "wifi_event_ftm_report_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_FTM_REPORT event + ## + peer_mac* {.importc: "peer_mac".}: array[6, uint8] ## + ## < MAC address of the FTM Peer + status* {.importc: "status".}: wifi_ftm_status_t ## + ## < Status of the FTM operation + rtt_raw* {.importc: "rtt_raw".}: uint32 ## < Raw average Round-Trip-Time with peer in Nano-Seconds + rtt_est* {.importc: "rtt_est".}: uint32 ## < Estimated Round-Trip-Time with peer in Nano-Seconds + dist_est* {.importc: "dist_est".}: uint32 ## < Estimated one-way distance in Centi-Meters + ftm_report_data* {.importc: "ftm_report_data".}: ptr wifi_ftm_report_entry_t ## + ## < Pointer to FTM Report, should be freed after use. Note: Highly recommended + ## to use API esp_wifi_ftm_get_report to get the report instead of using this + ftm_report_num_entries* {.importc: "ftm_report_num_entries".}: uint8 + ## < Number of entries in the FTM Report data + + +const + WIFI_STATIS_BUFFER* = (1 shl 0) ## < Buffer status + WIFI_STATIS_RXTX* = (1 shl 1) ## < RX/TX status + WIFI_STATIS_HW* = (1 shl 2) ## < Hardware status + WIFI_STATIS_DIAG* = (1 shl 3) ## < Diagnostic status + WIFI_STATIS_PS* = (1 shl 4) ## < Power save status + WIFI_STATIS_ALL* = (-1) ## < All status + +type + + wifi_action_tx_status_type_t* {.size: sizeof(cint).} = enum ## + ## Status codes for WIFI_EVENT_ACTION_TX_STATUS evt + ## There will be back to back events in success case TX_DONE and TX_DURATION_COMPLETED + WIFI_ACTION_TX_DONE = 0, ## < ACTION_TX operation was completed successfully + WIFI_ACTION_TX_FAILED, ## < ACTION_TX operation failed during tx + WIFI_ACTION_TX_DURATION_COMPLETED, ## < ACTION_TX operation completed it's wait duration + WIFI_ACTION_TX_OP_CANCELLED ## < ACTION_TX operation was cancelled by application or higher priority operation + + +type + + wifi_event_action_tx_status_t* {.importc: "wifi_event_action_tx_status_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_ACTION_TX_STATUS event + ifx* {.importc: "ifx".}: wifi_interface_t ## < WiFi interface to send request to + context* {.importc: "context".}: uint32 ## < Context to identify the request + status* {.importc: "status".}: wifi_action_tx_status_type_t ## + ## < Status of the operation + op_id* {.importc: "op_id".}: uint8 ## < ID of the corresponding operation that was provided during action tx request + channel* {.importc: "channel".}: uint8 + ## < Channel provided in tx request + + + wifi_event_roc_done_t* {.importc: "wifi_event_roc_done_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_ROC_DONE event + ## + context* {.importc: "context".}: uint32 ## < Context to identify the initiator of the request + status* {.importc: "status".}: wifi_roc_done_status_t ## + ## < ROC status + op_id* {.importc: "op_id".}: uint8 ## < ID of the corresponding ROC operation + channel* {.importc: "channel".}: uint8 + ## < Channel provided in tx request + + + wifi_event_ap_wps_rg_pin_t* {.importc: "wifi_event_ap_wps_rg_pin_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_WPS_RG_PIN event + ## + pin_code* {.importc: "pin_code".}: array[8, uint8] + ## < PIN code of station in enrollee mode + + + wps_fail_reason_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief WPS fail reason + ## + WPS_AP_FAIL_REASON_NORMAL = 0, ## < WPS normal fail reason + WPS_AP_FAIL_REASON_CONFIG, ## < WPS failed due to incorrect config + WPS_AP_FAIL_REASON_AUTH, ## < WPS failed during auth + WPS_AP_FAIL_REASON_MAX ## < Max WPS fail reason + + +type + + wifi_event_ap_wps_rg_fail_reason_t* {.importc: "wifi_event_ap_wps_rg_fail_reason_t", + header: hdr, + bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_WPS_RG_FAILED event + ## + reason* {.importc: "reason".}: wps_fail_reason_t ## + ## < WPS failure reason wps_fail_reason_t + peer_macaddr* {.importc: "peer_macaddr".}: array[6, uint8] + ## < Enrollee mac address + + + wifi_event_ap_wps_rg_success_t* {.importc: "wifi_event_ap_wps_rg_success_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_WPS_RG_SUCCESS event + ## + peer_macaddr* {.importc: "peer_macaddr".}: array[6, uint8] + ## < Enrollee mac address + + + wifi_event_nan_svc_match_t* {.importc: "wifi_event_nan_svc_match_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NAN_SVC_MATCH event + ## + subscribe_id* {.importc: "subscribe_id".}: uint8 ## + ## < Subscribe Service Identifier + publish_id* {.importc: "publish_id".}: uint8 ## < Publish Service Identifier + pub_if_mac* {.importc: "pub_if_mac".}: array[6, uint8] ## + ## < NAN Interface MAC of the Publisher + update_pub_id* {.importc: "update_pub_id".}: bool ## + ## < Indicates whether publisher's service ID needs to be updated + datapath_reqd* {.importc: "datapath_reqd", bitsize: 1.}: uint8 ## + ## < NAN Datapath required for the service + fsd_reqd* {.importc: "fsd_reqd", bitsize: 1.}: uint8 ## + ## < Further Service Discovery(FSD) required + fsd_gas* {.importc: "fsd_gas", bitsize: 1.}: uint8 ## + ## < 0 - Follow-up used for FSD, 1 - GAS used for FSD + reserved* {.importc: "reserved", bitsize: 5.}: uint8 ## + ## < Reserved + reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved + reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved + ssi_version* {.importc: "ssi_version".}: uint8 ## + ## < Indicates version of SSI in Publish instance, 0 if not available + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info + ssi* {.importc: "ssi".}: UncheckedArray[uint8] + ## < Service specific info of Publisher + + + wifi_event_nan_replied_t* {.importc: "wifi_event_nan_replied_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NAN_REPLIED event + ## + publish_id* {.importc: "publish_id".}: uint8 ## < Publish Service Identifier + subscribe_id* {.importc: "subscribe_id".}: uint8 ## + ## < Subscribe Service Identifier + sub_if_mac* {.importc: "sub_if_mac".}: array[6, uint8] ## + ## < NAN Interface MAC of the Subscriber + reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved + reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info + ssi* {.importc: "ssi".}: UncheckedArray[uint8] + ## < Service specific info of Subscriber + + + wifi_event_nan_receive_t* {.importc: "wifi_event_nan_receive_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NAN_RECEIVE event + ## + inst_id* {.importc: "inst_id".}: uint8 ## < Our Service Identifier + peer_inst_id* {.importc: "peer_inst_id".}: uint8 ## + ## < Peer's Service Identifier + peer_if_mac* {.importc: "peer_if_mac".}: array[6, uint8] ## + ## < Peer's NAN Interface MAC + peer_svc_info* {.importc: "peer_svc_info".}: array[ + ESP_WIFI_MAX_SVC_INFO_LEN, uint8] ## < To be deprecated in next major release, use ssi instead + reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved + reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info + ssi* {.importc: "ssi".}: UncheckedArray[uint8] + ## < Service specific info from Follow-up + + + wifi_event_ndp_indication_t* {.importc: "wifi_event_ndp_indication_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NDP_INDICATION event + ## + publish_id* {.importc: "publish_id".}: uint8 ## < Publish Id for NAN Service + ndp_id* {.importc: "ndp_id".}: uint8 ## < NDP instance id + peer_nmi* {.importc: "peer_nmi".}: array[6, uint8] ## + ## < Peer's NAN Management Interface MAC + peer_ndi* {.importc: "peer_ndi".}: array[6, uint8] ## + ## < Peer's NAN Data Interface MAC + svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, uint8] ## + ## < To be deprecated in next major release, use ssi instead + reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved + reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info + ssi* {.importc: "ssi".}: UncheckedArray[uint8] + ## < Service specific info from NDP/NDPE Attribute + + + wifi_event_ndp_confirm_t* {.importc: "wifi_event_ndp_confirm_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NDP_CONFIRM event + ## + status* {.importc: "status".}: uint8 ## < NDP status code + ndp_id* {.importc: "ndp_id".}: uint8 ## < NDP instance id + peer_nmi* {.importc: "peer_nmi".}: array[6, uint8] ## + ## < Peer's NAN Management Interface MAC + peer_ndi* {.importc: "peer_ndi".}: array[6, uint8] ## + ## < Peer's NAN Data Interface MAC + own_ndi* {.importc: "own_ndi".}: array[6, uint8] ## + ## < Own NAN Data Interface MAC + svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, uint8] ## + ## < To be deprecated in next major release, use ssi instead + reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved + reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of Service Specific Info + ssi* {.importc: "ssi".}: UncheckedArray[uint8] + ## < Service specific info from NDP/NDPE Attribute + + + wifi_event_ndp_terminated_t* {.importc: "wifi_event_ndp_terminated_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NDP_TERMINATED event + ## + reason* {.importc: "reason".}: uint8 ## < Termination reason code + ndp_id* {.importc: "ndp_id".}: uint8 ## < NDP instance id + init_ndi* {.importc: "init_ndi".}: array[6, uint8] + ## < Initiator's NAN Data Interface MAC + + + wifi_event_neighbor_report_t* {.importc: "wifi_event_neighbor_report_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_NEIGHBOR_REP event + ## + report* {.importc: "report".}: array[ESP_WIFI_MAX_NEIGHBOR_REP_LEN, uint8] ## + ## < Neighbor Report received from the AP (will be deprecated in next major release, use n_report instead) + report_len* {.importc: "report_len".}: uint16 ## < Length of the report + n_report* {.importc: "n_report".}: UncheckedArray[uint8] + ## < Neighbor Report received from the AP + + + wifi_event_ap_wrong_password_t* {.importc: "wifi_event_ap_wrong_password_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_AP_WRONG_PASSWORD event + mac* {.importc: "mac".}: array[6, uint8] + ## < MAC address of the station trying to connect to Soft-AP + + + wifi_tx_rate_config_t* {.importc: "wifi_tx_rate_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for wifi_tx_rate_config + ## + phymode* {.importc: "phymode".}: wifi_phy_mode_t ## + ## < Phymode of specified interface + rate* {.importc: "rate".}: wifi_phy_rate_t ## < Rate of specified interface + ersu* {.importc: "ersu".}: bool ## < Using ERSU to send frame, ERSU is a transmission mode related to 802.11 ax. + ## ERSU is always used in long distance transmission, and its frame has lower rate compared with SU mode + dcm* {.importc: "dcm".}: bool + ## < Using dcm rate to send frame + + +const + WIFI_MAX_SUPPORT_COUNTRY_NUM* = 176 + +when defined(CONFIG_SOC_WIFI_SUPPORT_5G): + const + WIFI_MAX_REGULATORY_RULE_NUM* = 7 +else: + const + WIFI_MAX_REGULATORY_RULE_NUM* = 2 +type + + wifi_reg_rule_t* {.importc: "wifi_reg_rule_t", + header: hdr, bycopy.} = object ## + ## Argument structure for regulatory rule + start_channel* {.importc: "start_channel".}: uint8 ## + ## < start channel of regulatory rule + end_channel* {.importc: "end_channel".}: uint8 ## + ## < end channel of regulatory rule + max_bandwidth* {.importc: "max_bandwidth", bitsize: 3.}: uint16 ## + ## < max bandwidth(MHz) of regulatory rule, 1:20M, 2:40M, 3:80M, 4:160M + max_eirp* {.importc: "max_eirp", bitsize: 6.}: uint16 ## + ## < indicates the maximum Equivalent Isotropically Radiated Power (EIRP), typically measured in dBm + is_dfs* {.importc: "is_dfs", bitsize: 1.}: uint16 ## + ## < flag to identify dfs channel + reserved* {.importc: "reserved", bitsize: 6.}: uint16 + ## < reserved + + + wifi_regulatory_t* {.importc: "wifi_regulatory_t", + header: hdr, bycopy.} = object ## + ## Argument structure for regdomain + n_reg_rules* {.importc: "n_reg_rules".}: uint8 ## + ## < number of regulatory rules + reg_rules* {.importc: "reg_rules".}: array[WIFI_MAX_REGULATORY_RULE_NUM, + wifi_reg_rule_t] + ## < array of regulatory rules + + + wifi_regdomain_t* {.importc: "wifi_regdomain_t", + header: hdr, bycopy.} = object ## + ## Argument structure for regdomain + cn* {.importc: "cn".}: array[2, char] ## < country code string + regulatory_type* {.importc: "regulatory_type".}: uint8 + ## < regulatory type of country + + + wifi_tx_status_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Status of wifi sending data + ## + WIFI_SEND_SUCCESS = 0, ## < Sending Wi-Fi data successfully + WIFI_SEND_FAIL ## < Sending Wi-Fi data fail + + +type + + wifi_tx_info_t* {.importc: "wifi_tx_info_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Information of wifi sending data + ## + des_addr* {.importc: "des_addr".}: ptr uint8 ## < The address of the receive device + src_addr* {.importc: "src_addr".}: ptr uint8 ## < The address of the sending device + ifidx* {.importc: "ifidx".}: wifi_interface_t ## < Interface of sending 80211 tx data + data* {.importc: "data".}: ptr uint8 ## < The data for 80211 tx, start from the MAC header + data_len* {.importc: "data_len".}: uint8 ## < The frame body length for 80211 tx, excluding the MAC header + rate* {.importc: "rate".}: wifi_phy_rate_t ## < Data rate + tx_status* {.importc: "tx_status".}: wifi_tx_status_t + ## < Status of sending 80211 tx data + + + esp_80211_tx_info_t* = wifi_tx_info_t + + wifi_event_sta_beacon_offset_unstable_t* {. + importc: "wifi_event_sta_beacon_offset_unstable_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_STA_BEACON_OFFSET_UNSTABLE event + beacon_success_rate* {.importc: "beacon_success_rate".}: cfloat + ## < Received beacon success rate + + + wifi_event_dpp_uri_ready_t* {.importc: "wifi_event_dpp_uri_ready_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_DPP_URI_READY event + uri_data_len* {.importc: "uri_data_len".}: uint32 ## + ## < URI data length including null termination + uri* {.importc: "uri".}: UncheckedArray[char] + ## < URI data + + + wifi_event_dpp_config_received_t* {.importc: "wifi_event_dpp_config_received_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_DPP_CFG_RECVD event + wifi_cfg* {.importc: "wifi_cfg".}: wifi_config_t + ## < Received WIFI config in DPP + + + wifi_event_dpp_failed_t* {.importc: "wifi_event_dpp_failed_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_DPP_FAIL event + failure_reason* {.importc: "failure_reason".}: cint + ## < Failure reason + diff --git a/src/nesper/wifi.nim b/src/nesper/wifi.nim index fffb588d..4eeab8cf 100644 --- a/src/nesper/wifi.nim +++ b/src/nesper/wifi.nim @@ -1,6 +1,8 @@ import nesper/esp/net/esp_wifi import nesper/esp/net/esp_wifi_types +import nesper/esp/net/esp_wifi_default export esp_wifi -export esp_wifi_types \ No newline at end of file +export esp_wifi_types +export esp_wifi_default \ No newline at end of file From 0a605a19f9a2420f0dc82be599f4fede1889bfec Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 01:29:38 -0600 Subject: [PATCH 115/142] update wifi example --- src/nesper/esp/net/esp_wifi.nim | 143 +- src/nesper/esp/net/esp_wifi_types.nim | 2202 +++++++++++++---- src/nesper/esp/net/esp_wifi_types_generic.nim | 1899 -------------- src/nesper/esp/net/esp_wifi_types_old.nim | 610 +++++ src/nesper/net_utils.nim | 7 - 5 files changed, 2375 insertions(+), 2486 deletions(-) delete mode 100644 src/nesper/esp/net/esp_wifi_types_generic.nim create mode 100644 src/nesper/esp/net/esp_wifi_types_old.nim diff --git a/src/nesper/esp/net/esp_wifi.nim b/src/nesper/esp/net/esp_wifi.nim index e600c919..eeaf18a7 100644 --- a/src/nesper/esp/net/esp_wifi.nim +++ b/src/nesper/esp/net/esp_wifi.nim @@ -57,13 +57,12 @@ import ../esp_event import ../../net_utils import esp_wifi_types +export esp_wifi_types + type wifi_osi_funcs_t* {.importc: "wifi_osi_funcs_t", header: "esp_wifi.h", bycopy.} = object wpa_crypto_funcs_t* {.importc: "wpa_crypto_funcs_t", header: "esp_wifi.h", bycopy.} = object -# import - # esp_err, esp_wifi_types, esp_event, esp_private/esp_wifi_private - const ESP_ERR_WIFI_NOT_INIT* = (ESP_ERR_WIFI_BASE + 1) ## !< WiFi driver was not installed by esp_wifi_init ESP_ERR_WIFI_NOT_STARTED* = (ESP_ERR_WIFI_BASE + 2) ## !< WiFi driver was not started by esp_wifi_start @@ -132,63 +131,25 @@ type magic* {.importc: "magic".}: cint ## *< WiFi init magic number, it should be the last field -# {.emit: """ -# wifi_init_config_t _wifi_init_config_default() { -# wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); -# return cfg; -# } -# """.} - -# proc wifi_init_config_default*(): wifi_init_config_t {.importc:"_wifi_init_config_default", header: "esp_wifi.h".} - proc WIFI_INIT_CONFIG_DEFAULT*(): wifi_init_config_t = {.emit: """ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); `result` = cfg; """.} -# when defined(CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM): -# const -# WIFI_STATIC_TX_BUFFER_NUM* = CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM -# else: -# const -# WIFI_STATIC_TX_BUFFER_NUM* = 0 -# when defined(CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM): -# const -# WIFI_DYNAMIC_TX_BUFFER_NUM* = CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM -# else: -# const -# WIFI_DYNAMIC_TX_BUFFER_NUM* = 0 -# when CONFIG_ESP32_WIFI_CSI_ENABLED: -# const -# WIFI_CSI_ENABLED* = 1 -# else: -# const -# WIFI_CSI_ENABLED* = 0 -# when CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED: -# const -# WIFI_AMPDU_RX_ENABLED* = 1 -# else: -# const -# WIFI_AMPDU_RX_ENABLED* = 0 -# when CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED: -# const -# WIFI_AMPDU_TX_ENABLED* = 1 -# else: -# const -# WIFI_AMPDU_TX_ENABLED* = 0 -# when CONFIG_ESP32_WIFI_NVS_ENABLED: -# const -# WIFI_NVS_ENABLED* = 1 -# else: -# const -# WIFI_NVS_ENABLED* = 0 -# when CONFIG_NEWLIB_NANO_FORMAT: -# const -# WIFI_NANO_FORMAT_ENABLED* = 1 -# else: -# const -# WIFI_NANO_FORMAT_ENABLED* = 0 + +# let ESP_WIFI_MAX_CONN_NUM* {.importc: "ESP_WIFI_MAX_CONN_NUM", header: hdr.}: cint ## *< station list + +type + wifi_sta_list_t* {.importc: "wifi_sta_list_t", header: "esp_wifi_types.h", bycopy.} = object + sta* {.importc: "sta".}: UncheckedArray[wifi_sta_info_t] ## *< station list + num* {.importc: "num".}: cint ## *< number of stations in the list (other entries are invalid) + + wifi_storage_t* {.size: sizeof(cint).} = enum + WIFI_STORAGE_FLASH, ## *< all configuration will store in both memory and flash + WIFI_STORAGE_RAM ## *< all configuration will only store in the memory + + var g_wifi_default_wpa_crypto_funcs* {.importc: "g_wifi_default_wpa_crypto_funcs", header: "esp_wifi.h".}: wpa_crypto_funcs_t @@ -197,80 +158,6 @@ var g_wifi_feature_caps* {.importc: "g_wifi_feature_caps", header: "esp_wifi.h". const WIFI_INIT_CONFIG_MAGIC* = 0x1F2F3F4F -# when defined(CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED): -# const -# WIFI_DEFAULT_TX_BA_WIN* = CONFIG_ESP32_WIFI_TX_BA_WIN -# else: -# const -# WIFI_DEFAULT_TX_BA_WIN* = 0 -# when defined(CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED): -# const -# WIFI_DEFAULT_RX_BA_WIN* = CONFIG_ESP32_WIFI_RX_BA_WIN -# else: -# const -# WIFI_DEFAULT_RX_BA_WIN* = 0 -# when CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1: -# const -# WIFI_TASK_CORE_ID* = 1 -# else: -# const -# WIFI_TASK_CORE_ID* = 0 -# when defined(CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN): -# const -# WIFI_SOFTAP_BEACON_MAX_LEN* = CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN -# else: -# const -# WIFI_SOFTAP_BEACON_MAX_LEN* = 752 -# when defined(CONFIG_ESP32_WIFI_MGMT_SBUF_NUM): -# const -# WIFI_MGMT_SBUF_NUM* = CONFIG_ESP32_WIFI_MGMT_SBUF_NUM -# else: -# const -# WIFI_MGMT_SBUF_NUM* = 32 -# const -# CONFIG_FEATURE_WPA3_SAE_BIT* = (1 shl 0) - -## #define WIFI_INIT_CONFIG_DEFAULT() { \ -## .event_handler = &esp_event_send, \ -## .osi_funcs = &g_wifi_osi_funcs, \ -## .wpa_crypto_funcs = g_wifi_default_wpa_crypto_funcs, \ -## .static_rx_buf_num = CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM,\ -## .dynamic_rx_buf_num = CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM,\ -## .tx_buf_type = CONFIG_ESP32_WIFI_TX_BUFFER_TYPE,\ -## .static_tx_buf_num = WIFI_STATIC_TX_BUFFER_NUM,\ -## .dynamic_tx_buf_num = WIFI_DYNAMIC_TX_BUFFER_NUM,\ -## .csi_enable = WIFI_CSI_ENABLED,\ -## .ampdu_rx_enable = WIFI_AMPDU_RX_ENABLED,\ -## .ampdu_tx_enable = WIFI_AMPDU_TX_ENABLED,\ -## .nvs_enable = WIFI_NVS_ENABLED,\ -## .nano_enable = WIFI_NANO_FORMAT_ENABLED,\ -## .tx_ba_win = WIFI_DEFAULT_TX_BA_WIN,\ -## .rx_ba_win = WIFI_DEFAULT_RX_BA_WIN,\ -## .wifi_task_core_id = WIFI_TASK_CORE_ID,\ -## .beacon_max_len = WIFI_SOFTAP_BEACON_MAX_LEN, \ -## .mgmt_sbuf_num = WIFI_MGMT_SBUF_NUM, \ -## .feature_caps = g_wifi_feature_caps, \ -## .magic = WIFI_INIT_CONFIG_MAGIC\ -## }; -## * -## @brief Init WiFi -## Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer, -## WiFi NVS structure etc, this WiFi also start WiFi task -## -## @attention 1. This API must be called before all other WiFi API can be called -## @attention 2. Always use WIFI_INIT_CONFIG_DEFAULT macro to init the config to default values, this can -## guarantee all the fields got correct value when more fields are added into wifi_init_config_t -## in future release. If you want to set your owner initial values, overwrite the default values -## which are set by WIFI_INIT_CONFIG_DEFAULT, please be notified that the field 'magic' of -## wifi_init_config_t should always be WIFI_INIT_CONFIG_MAGIC! -## -## @param config pointer to WiFi init configuration structure; can point to a temporary variable. -## -## @return -## - ESP_OK: succeed -## - ESP_ERR_NO_MEM: out of memory -## - others: refer to error code esp_err.h -## proc esp_wifi_init*(config: ptr wifi_init_config_t): esp_err_t {. importc: "esp_wifi_init", header: "esp_wifi.h".} diff --git a/src/nesper/esp/net/esp_wifi_types.nim b/src/nesper/esp/net/esp_wifi_types.nim index 1cad2b36..2dcef267 100644 --- a/src/nesper/esp/net/esp_wifi_types.nim +++ b/src/nesper/esp/net/esp_wifi_types.nim @@ -1,392 +1,892 @@ -## Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## http://www.apache.org/licenses/LICENSE-2.0 -## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. + import ../esp_event +const hdr = "esp_wifi_types.h" + +let + WIFI_AP_DEFAULT_MAX_IDLE_PERIOD* {.importc: "WIFI_AP_DEFAULT_MAX_IDLE_PERIOD", header: hdr.}: cint ## + ## SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + ## + ## SPDX-License-Identifier: Apache-2.0 + ## + type - wifi_country_policy_t* {.size: sizeof(cint).} = enum - WIFI_COUNTRY_POLICY_AUTO, ## *< Country policy is auto, use the country info of AP to which the station is connected - WIFI_COUNTRY_POLICY_MANUAL ## *< Country policy is manual, always use the configured country info + wifi_mode_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi mode type + ## + WIFI_MODE_NULL = 0, ## < Null mode + WIFI_MODE_STA, ## < Wi-Fi station mode + WIFI_MODE_AP, ## < Wi-Fi soft-AP mode + WIFI_MODE_APSTA, ## < Wi-Fi station + soft-AP mode + WIFI_MODE_NAN, ## < Wi-Fi NAN mode + WIFI_MODE_MAX -## * @brief Structure describing WiFi country-based regional restrictions. type - wifi_country_t* {.importc: "wifi_country_t", header: "esp_wifi_types.h", bycopy.} = object - cc* {.importc: "cc".}: array[3, char] ## *< country code string - schan* {.importc: "schan".}: uint8 ## *< start channel - nchan* {.importc: "nchan".}: uint8 ## *< total channel number - max_tx_power* {.importc: "max_tx_power".}: int8 ## *< This field is used for getting WiFi maximum transmitting power, call esp_wifi_set_max_tx_power to set the maximum transmitting power. - policy* {.importc: "policy".}: wifi_country_policy_t ## *< country policy - wifi_auth_mode_t* {.size: sizeof(cint).} = enum - WIFI_AUTH_OPEN = 0, ## *< authenticate mode : open - WIFI_AUTH_WEP, ## *< authenticate mode : WEP - WIFI_AUTH_WPA_PSK, ## *< authenticate mode : WPA_PSK - WIFI_AUTH_WPA2_PSK, ## *< authenticate mode : WPA2_PSK - WIFI_AUTH_WPA_WPA2_PSK, ## *< authenticate mode : WPA_WPA2_PSK - WIFI_AUTH_WPA2_ENTERPRISE, ## *< authenticate mode : WPA2_ENTERPRISE - WIFI_AUTH_WPA3_PSK, ## *< authenticate mode : WPA3_PSK - WIFI_AUTH_WPA2_WPA3_PSK, ## *< authenticate mode : WPA2_WPA3_PSK - WIFI_AUTH_MAX - wifi_err_reason_t* {.size: sizeof(cint).} = enum - WIFI_REASON_UNSPECIFIED = 1, WIFI_REASON_AUTH_EXPIRE = 2, - WIFI_REASON_AUTH_LEAVE = 3, WIFI_REASON_ASSOC_EXPIRE = 4, - WIFI_REASON_ASSOC_TOOMANY = 5, WIFI_REASON_NOT_AUTHED = 6, - WIFI_REASON_NOT_ASSOCED = 7, WIFI_REASON_ASSOC_LEAVE = 8, - WIFI_REASON_ASSOC_NOT_AUTHED = 9, WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, - WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11, WIFI_REASON_IE_INVALID = 13, - WIFI_REASON_MIC_FAILURE = 14, WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, - WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, WIFI_REASON_IE_IN_4WAY_DIFFERS = 17, - WIFI_REASON_GROUP_CIPHER_INVALID = 18, - WIFI_REASON_PAIRWISE_CIPHER_INVALID = 19, WIFI_REASON_AKMP_INVALID = 20, - WIFI_REASON_UNSUPP_RSN_IE_VERSION = 21, WIFI_REASON_INVALID_RSN_IE_CAP = 22, - WIFI_REASON_802_1X_AUTH_FAILED = 23, WIFI_REASON_CIPHER_SUITE_REJECTED = 24, - WIFI_REASON_INVALID_PMKID = 53, WIFI_REASON_BEACON_TIMEOUT = 200, - WIFI_REASON_NO_AP_FOUND = 201, WIFI_REASON_AUTH_FAIL = 202, - WIFI_REASON_ASSOC_FAIL = 203, WIFI_REASON_HANDSHAKE_TIMEOUT = 204, - WIFI_REASON_CONNECTION_FAIL = 205 - wifi_second_chan_t* {.size: sizeof(cint).} = enum - WIFI_SECOND_CHAN_NONE = 0, ## *< the channel width is HT20 - WIFI_SECOND_CHAN_ABOVE, ## *< the channel width is HT40 and the secondary channel is above the primary channel - WIFI_SECOND_CHAN_BELOW ## *< the channel width is HT40 and the secondary channel is below the primary channel - wifi_scan_type_t* {.size: sizeof(cint).} = enum - WIFI_SCAN_TYPE_ACTIVE = 0, ## *< active scan - WIFI_SCAN_TYPE_PASSIVE ## *< passive scan - - - - - -## * @brief Range of active scan times per channel + wifi_interface_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi interface type + ## + WIFI_IF_STA, ## < Station interface + WIFI_IF_AP, ## < Soft-AP interface + WIFI_IF_NAN ## < NAN interface -type - wifi_active_scan_time_t* {.importc: "wifi_active_scan_time_t", - header: "esp_wifi_types.h", bycopy.} = object - min* {.importc: "min".}: uint32 ## *< minimum active scan time per channel, units: millisecond - max* {.importc: "max".}: uint32 ## *< maximum active scan time per channel, units: millisecond, values above 1500ms may - ## cause station to disconnect from AP and are not recommended. + wifi_action_tx_t* {.size: sizeof(cint).} = enum + WIFI_OFFCHAN_TX_CANCEL, ## < Cancel off-channel transmission + WIFI_OFFCHAN_TX_REQ ## < Request off-channel transmission + wifi_roc_t* {.size: sizeof(cint).} = enum + WIFI_ROC_CANCEL, ## < Cancel remain on channel + WIFI_ROC_REQ ## < Request remain on channel -## * @brief Aggregate of active & passive scan time per channel type - wifi_scan_time_t* {.importc: "wifi_scan_time_t", header: "esp_wifi_types.h", bycopy, union.} = object - active* {.importc: "active".}: wifi_active_scan_time_t ## *< active scan time per channel, units: millisecond. - passive* {.importc: "passive".}: uint32 ## *< passive scan time per channel, units: millisecond, values above 1500ms may - ## cause station to disconnect from AP and are not recommended. + wifi_country_policy_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi country policy + ## + WIFI_COUNTRY_POLICY_AUTO, ## < Country policy is auto, use the country info of AP to which the station is connected + WIFI_COUNTRY_POLICY_MANUAL ## < Country policy is manual, always use the configured country info -## * @brief Parameters for an SSID scan. type - wifi_scan_config_t* {.importc: "wifi_scan_config_t", header: "esp_wifi_types.h", - bycopy.} = object - ssid* {.importc: "ssid".}: ptr uint8 ## *< SSID of AP - bssid* {.importc: "bssid".}: ptr uint8 ## *< MAC address of AP - channel* {.importc: "channel".}: uint8 ## *< channel, scan the specific channel - show_hidden* {.importc: "show_hidden".}: bool ## *< enable to scan AP whose SSID is hidden - scan_type* {.importc: "scan_type".}: wifi_scan_type_t ## *< scan type, active or passive - scan_time* {.importc: "scan_time".}: wifi_scan_time_t ## *< scan time per channel - - wifi_cipher_type_t* {.size: sizeof(cint).} = enum - WIFI_CIPHER_TYPE_NONE = 0, ## *< the cipher type is none - WIFI_CIPHER_TYPE_WEP40, ## *< the cipher type is WEP40 - WIFI_CIPHER_TYPE_WEP104, ## *< the cipher type is WEP104 - WIFI_CIPHER_TYPE_TKIP, ## *< the cipher type is TKIP - WIFI_CIPHER_TYPE_CCMP, ## *< the cipher type is CCMP - WIFI_CIPHER_TYPE_TKIP_CCMP, ## *< the cipher type is TKIP and CCMP - WIFI_CIPHER_TYPE_AES_CMAC128, ## *< the cipher type is AES-CMAC-128 - WIFI_CIPHER_TYPE_UNKNOWN ## *< the cipher type is unknown + wifi_country_t* {.importc: "wifi_country_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Structure describing Wi-Fi country-based regional restrictions. + ## + cc* {.importc: "cc".}: array[3, char] ## < Country code string + schan* {.importc: "schan".}: uint8 ## < Start channel of the allowed 2.4GHz Wi-Fi channels + nchan* {.importc: "nchan".}: uint8 ## < Total channel number of the allowed 2.4GHz Wi-Fi channels + max_tx_power* {.importc: "max_tx_power".}: int8 ## + ## < This field is used for getting Wi-Fi maximum transmitting power, call esp_wifi_set_max_tx_power to set the maximum transmitting power. + policy* {.importc: "policy".}: wifi_country_policy_t ## + ## < Country policy + when defined(CONFIG_SOC_WIFI_SUPPORT_5G): + wifi_5g_channel_mask* {.importc: "wifi_5g_channel_mask".}: uint32 + ## < A bitmask representing the allowed 5GHz Wi-Fi channels. + ## Each bit in the mask corresponds to a specific channel as wifi_5g_channel_bit_t shown. + ## Bitmask set to 0 indicates 5GHz channels are allowed according to local regulatory rules. + ## Please note that configured bitmask takes effect only when policy is manual. + + + wifi_auth_mode_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi authmode type + ## Strength of authmodes + ## Personal Networks : OPEN < WEP < WPA_PSK < OWE < WPA2_PSK = WPA_WPA2_PSK < WAPI_PSK < WPA3_PSK = WPA2_WPA3_PSK = DPP + ## Enterprise Networks : WIFI_AUTH_WPA_ENTERPRISE < WIFI_AUTH_WPA2_ENTERPRISE < WIFI_AUTH_WPA3_ENTERPRISE = WIFI_AUTH_WPA2_WPA3_ENTERPRISE < WIFI_AUTH_WPA3_ENT_192 + ## + WIFI_AUTH_OPEN = 0, ## < Authenticate mode : open + WIFI_AUTH_WEP, ## < Authenticate mode : WEP + WIFI_AUTH_WPA_PSK, ## < Authenticate mode : WPA_PSK + WIFI_AUTH_WPA2_PSK, ## < Authenticate mode : WPA2_PSK + WIFI_AUTH_WPA_WPA2_PSK, ## < Authenticate mode : WPA_WPA2_PSK + WIFI_AUTH_ENTERPRISE, ## < Authenticate mode : Wi-Fi EAP security, treated the same as WIFI_AUTH_WPA2_ENTERPRISE + WIFI_AUTH_WPA3_PSK, ## < Authenticate mode : WPA3_PSK + WIFI_AUTH_WPA2_WPA3_PSK, ## < Authenticate mode : WPA2_WPA3_PSK + WIFI_AUTH_WAPI_PSK, ## < Authenticate mode : WAPI_PSK + WIFI_AUTH_OWE, ## < Authenticate mode : OWE + WIFI_AUTH_WPA3_ENT_192, ## < Authenticate mode : WPA3_ENT_SUITE_B_192_BIT + WIFI_AUTH_WPA3_EXT_PSK, ## < This authentication mode will yield same result as WIFI_AUTH_WPA3_PSK and not recommended to be used. It will be deprecated in future, please use WIFI_AUTH_WPA3_PSK instead. + WIFI_AUTH_WPA3_EXT_PSK_MIXED_MODE, ## < This authentication mode will yield same result as WIFI_AUTH_WPA3_PSK and not recommended to be used. It will be deprecated in future, please use WIFI_AUTH_WPA3_PSK instead. + WIFI_AUTH_DPP, ## < Authenticate mode : DPP + WIFI_AUTH_WPA3_ENTERPRISE, ## < Authenticate mode : WPA3-Enterprise Only Mode + WIFI_AUTH_WPA2_WPA3_ENTERPRISE, ## < Authenticate mode : WPA3-Enterprise Transition Mode + WIFI_AUTH_WPA_ENTERPRISE, ## < Authenticate mode : WPA-Enterprise security + WIFI_AUTH_MAX -## * -## @brief WiFi antenna -## -## +const + WIFI_AUTH_WPA2_ENTERPRISE* = WIFI_AUTH_ENTERPRISE type - wifi_ant_t* {.size: sizeof(cint).} = enum - WIFI_ANT_ANT0, ## *< WiFi antenna 0 - WIFI_ANT_ANT1, ## *< WiFi antenna 1 - WIFI_ANT_MAX ## *< Invalid WiFi antenna + wifi_err_reason_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi disconnection reason codes + ## + ## These reason codes are used to indicate the cause of disconnection. + ## + WIFI_REASON_UNSPECIFIED = 1, ## < Unspecified reason + WIFI_REASON_AUTH_EXPIRE = 2, ## < Authentication expired + WIFI_REASON_AUTH_LEAVE = 3, ## < Deauthentication due to leaving + WIFI_REASON_ASSOC_EXPIRE = 4, ## < Deprecated, will be removed in next IDF major release + WIFI_REASON_ASSOC_TOOMANY = 5, ## < Too many associated stations + WIFI_REASON_NOT_AUTHED = 6, ## < Deprecated, will be removed in next IDF major release + WIFI_REASON_NOT_ASSOCED = 7, ## < Deprecated, will be removed in next IDF major release + WIFI_REASON_ASSOC_LEAVE = 8, ## < Deassociated due to leaving + WIFI_REASON_ASSOC_NOT_AUTHED = 9, ## < Association but not authenticated + WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, ## < Disassociated due to poor power capability + WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11, ## < Disassociated due to unsupported channel + WIFI_REASON_BSS_TRANSITION_DISASSOC = 12, ## < Disassociated due to BSS transition + WIFI_REASON_IE_INVALID = 13, ## < Invalid Information Element (IE) + WIFI_REASON_MIC_FAILURE = 14, ## < MIC failure + WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, ## < 4-way handshake timeout + WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, ## < Group key update timeout + WIFI_REASON_IE_IN_4WAY_DIFFERS = 17, ## < IE differs in 4-way handshake + WIFI_REASON_GROUP_CIPHER_INVALID = 18, ## < Invalid group cipher + WIFI_REASON_PAIRWISE_CIPHER_INVALID = 19, ## < Invalid pairwise cipher + WIFI_REASON_AKMP_INVALID = 20, ## < Invalid AKMP + WIFI_REASON_UNSUPP_RSN_IE_VERSION = 21, ## < Unsupported RSN IE version + WIFI_REASON_INVALID_RSN_IE_CAP = 22, ## < Invalid RSN IE capabilities + WIFI_REASON_802_1X_AUTH_FAILED = 23, ## < 802.1X authentication failed + WIFI_REASON_CIPHER_SUITE_REJECTED = 24, ## < Cipher suite rejected + WIFI_REASON_TDLS_PEER_UNREACHABLE = 25, ## < TDLS peer unreachable + WIFI_REASON_TDLS_UNSPECIFIED = 26, ## < TDLS unspecified + WIFI_REASON_SSP_REQUESTED_DISASSOC = 27, ## < SSP requested disassociation + WIFI_REASON_NO_SSP_ROAMING_AGREEMENT = 28, ## < No SSP roaming agreement + WIFI_REASON_BAD_CIPHER_OR_AKM = 29, ## < Bad cipher or AKM + WIFI_REASON_NOT_AUTHORIZED_THIS_LOCATION = 30, ## + ## < Not authorized in this location + WIFI_REASON_SERVICE_CHANGE_PERCLUDES_TS = 31, ## + ## < Service change precludes TS + WIFI_REASON_UNSPECIFIED_QOS = 32, ## < Unspecified QoS reason + WIFI_REASON_NOT_ENOUGH_BANDWIDTH = 33, ## < Not enough bandwidth + WIFI_REASON_MISSING_ACKS = 34, ## < Missing ACKs + WIFI_REASON_EXCEEDED_TXOP = 35, ## < Exceeded TXOP + WIFI_REASON_STA_LEAVING = 36, ## < Station leaving + WIFI_REASON_END_BA = 37, ## < End of Block Ack (BA) + WIFI_REASON_UNKNOWN_BA = 38, ## < Unknown Block Ack (BA) + WIFI_REASON_TIMEOUT = 39, ## < Timeout + WIFI_REASON_PEER_INITIATED = 46, ## < Peer initiated disassociation + WIFI_REASON_AP_INITIATED = 47, ## < AP initiated disassociation + WIFI_REASON_INVALID_FT_ACTION_FRAME_COUNT = 48, ## + ## < Invalid FT action frame count + WIFI_REASON_INVALID_PMKID = 49, ## < Invalid PMKID + WIFI_REASON_INVALID_MDE = 50, ## < Invalid MDE + WIFI_REASON_INVALID_FTE = 51, ## < Invalid FTE + WIFI_REASON_TRANSMISSION_LINK_ESTABLISH_FAILED = 67, ## + ## < Transmission link establishment failed + WIFI_REASON_ALTERATIVE_CHANNEL_OCCUPIED = 68, ## + ## < Alternative channel occupied + WIFI_REASON_BEACON_TIMEOUT = 200, ## < Beacon timeout + WIFI_REASON_NO_AP_FOUND = 201, ## < No AP found + WIFI_REASON_AUTH_FAIL = 202, ## < Authentication failed + WIFI_REASON_ASSOC_FAIL = 203, ## < Association failed + WIFI_REASON_HANDSHAKE_TIMEOUT = 204, ## < Handshake timeout + WIFI_REASON_CONNECTION_FAIL = 205, ## < Connection failed + WIFI_REASON_AP_TSF_RESET = 206, ## < AP TSF reset + WIFI_REASON_ROAMING = 207, ## < Roaming + WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG = 208, ## + ## < Association comeback time too long + WIFI_REASON_SA_QUERY_TIMEOUT = 209, ## < SA query timeout + WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY = 210, ## + ## < No AP found with compatible security + WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD = 211, ## + ## < No AP found in auth mode threshold + WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD = 212 ## + ## < No AP found in RSSI threshold -## * @brief Description of a WiFi AP +const + WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY = WIFI_REASON_ASSOC_EXPIRE + WIFI_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = WIFI_REASON_NOT_AUTHED + WIFI_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = WIFI_REASON_NOT_ASSOCED type - wifi_ap_record_t* {.importc: "wifi_ap_record_t", header: "esp_wifi_types.h", bycopy.} = object - bssid* {.importc: "bssid".}: array[6, uint8] ## *< MAC address of AP - ssid* {.importc: "ssid".}: array[33, uint8] ## *< SSID of AP - primary* {.importc: "primary".}: uint8 ## *< channel of AP - second* {.importc: "second".}: wifi_second_chan_t ## *< secondary channel of AP - rssi* {.importc: "rssi".}: int8 ## *< signal strength of AP - authmode* {.importc: "authmode".}: wifi_auth_mode_t ## *< authmode of AP - pairwise_cipher* {.importc: "pairwise_cipher".}: wifi_cipher_type_t ## *< pairwise cipher of AP - group_cipher* {.importc: "group_cipher".}: wifi_cipher_type_t ## *< group cipher of AP - ant* {.importc: "ant".}: wifi_ant_t ## *< antenna used to receive beacon from AP - phy_11b* {.importc: "phy_11b", bitsize: 1.}: uint32 ## *< bit: 0 flag to identify if 11b mode is enabled or not - phy_11g* {.importc: "phy_11g", bitsize: 1.}: uint32 ## *< bit: 1 flag to identify if 11g mode is enabled or not - phy_11n* {.importc: "phy_11n", bitsize: 1.}: uint32 ## *< bit: 2 flag to identify if 11n mode is enabled or not - phy_lr* {.importc: "phy_lr", bitsize: 1.}: uint32 ## *< bit: 3 flag to identify if low rate is enabled or not - wps* {.importc: "wps", bitsize: 1.}: uint32 ## *< bit: 4 flag to identify if WPS is supported or not - reserved* {.importc: "reserved", bitsize: 27.}: uint32 ## *< bit: 5..31 reserved - country* {.importc: "country".}: wifi_country_t ## *< country information of AP - wifi_scan_method_t* {.size: sizeof(cint).} = enum - WIFI_FAST_SCAN = 0, ## *< Do fast scan, scan will end after find SSID match AP - WIFI_ALL_CHANNEL_SCAN ## *< All channel scan, scan will end after scan all the channel - wifi_sort_method_t* {.size: sizeof(cint).} = enum - WIFI_CONNECT_AP_BY_SIGNAL = 0, ## *< Sort match AP in scan list by RSSI - WIFI_CONNECT_AP_BY_SECURITY ## *< Sort match AP in scan list by security mode + wifi_second_chan_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi second channel type + ## + WIFI_SECOND_CHAN_NONE = 0, ## < The channel width is HT20 + WIFI_SECOND_CHAN_ABOVE, ## < The channel width is HT40 and the secondary channel is above the primary channel + WIFI_SECOND_CHAN_BELOW ## < The channel width is HT40 and the secondary channel is below the primary channel + +let + WIFI_ACTIVE_SCAN_MIN_DEFAULT_TIME* {.importc, header: hdr.}: cint + WIFI_ACTIVE_SCAN_MAX_DEFAULT_TIME* {.importc, header: hdr.}: cint + WIFI_PASSIVE_SCAN_DEFAULT_TIME* {.importc, header: hdr.}: cint + WIFI_SCAN_HOME_CHANNEL_DWELL_DEFAULT_TIME* {.importc, header: hdr.}: cint +type + wifi_scan_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi scan type + ## + WIFI_SCAN_TYPE_ACTIVE = 0, ## < Active scan + WIFI_SCAN_TYPE_PASSIVE ## < Passive scan -## * @brief Structure describing parameters for a WiFi fast scan type - wifi_scan_threshold_t* {.importc: "wifi_scan_threshold_t", - header: "esp_wifi_types.h", bycopy.} = object - rssi* {.importc: "rssi".}: int8 ## *< The minimum rssi to accept in the fast scan mode - authmode* {.importc: "authmode".}: wifi_auth_mode_t ## *< The weakest authmode to accept in the fast scan mode - wifi_ps_type_t* {.size: sizeof(cint).} = enum - WIFI_PS_NONE, ## *< No power save - WIFI_PS_MIN_MODEM, ## *< Minimum modem power saving. In this mode, station wakes up to receive beacon every DTIM period - WIFI_PS_MAX_MODEM ## *< Maximum modem power saving. In this mode, interval to receive beacons is determined by the listen_interval parameter in wifi_sta_config_t + wifi_active_scan_time_t* {.importc: "wifi_active_scan_time_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Range of active scan times per channel + ## + min* {.importc: "min".}: uint32 ## < Minimum active scan time per channel, units: millisecond + max* {.importc: "max".}: uint32 + ## < Maximum active scan time per channel, units: millisecond, values above 1500 ms may + ## cause station to disconnect from AP and are not recommended. + + + wifi_scan_time_t* {.importc: "wifi_scan_time_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Aggregate of active & passive scan time per channel + ## + active* {.importc: "active".}: wifi_active_scan_time_t ## + ## < Active scan time per channel, units: millisecond. + passive* {.importc: "passive".}: uint32 + ## < Passive scan time per channel, units: millisecond, values above 1500 ms may + ## cause station to disconnect from AP and are not recommended. + + + wifi_scan_channel_bitmap_t* {.importc: "wifi_scan_channel_bitmap_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Channel bitmap for setting specific channels to be scanned + ## + ghz_2_channels* {.importc: "ghz_2_channels".}: uint16 ## + ## < Represents 2.4 GHz channels, that bits can be set as wifi_2g_channel_bit_t shown. + ghz_5_channels* {.importc: "ghz_5_channels".}: uint32 + ## < Represents 5 GHz channels, that bits can be set as wifi_5g_channel_bit_t shown. + + + wifi_scan_config_t* {.importc: "wifi_scan_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Parameters for an SSID scan + ## + ssid* {.importc: "ssid".}: ptr uint8 ## < SSID of AP + bssid* {.importc: "bssid".}: ptr uint8 ## < MAC address of AP + channel* {.importc: "channel".}: uint8 ## < Channel, scan the specific channel + show_hidden* {.importc: "show_hidden".}: bool ## < Enable it to scan AP whose SSID is hidden + scan_type* {.importc: "scan_type".}: wifi_scan_type_t ## + ## < Scan type, active or passive + scan_time* {.importc: "scan_time".}: wifi_scan_time_t ## + ## < Scan time per channel + home_chan_dwell_time* {.importc: "home_chan_dwell_time".}: uint8 ## + ## < Time spent at home channel between scanning consecutive channels. + channel_bitmap* {.importc: "channel_bitmap".}: wifi_scan_channel_bitmap_t ## + ## < Channel bitmap for setting specific channels to be scanned. + ## Please note that the 'channel' parameter above needs to be set to 0 to allow scanning by bitmap. + ## Also, note that only allowed channels configured by wifi_country_t can be scanned. + coex_background_scan* {.importc: "coex_background_scan".}: bool + ## < Enable it to scan return home channel under coexist + + + wifi_scan_default_params_t* {.importc: "wifi_scan_default_params_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Parameters default scan configurations + ## + scan_time* {.importc: "scan_time".}: wifi_scan_time_t ## + ## < Scan time per channel + home_chan_dwell_time* {.importc: "home_chan_dwell_time".}: uint8 + ## < Time spent at home channel between scanning consecutive channels. + + + wifi_cipher_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi cipher type + ## + WIFI_CIPHER_TYPE_NONE = 0, ## < The cipher type is none + WIFI_CIPHER_TYPE_WEP40, ## < The cipher type is WEP40 + WIFI_CIPHER_TYPE_WEP104, ## < The cipher type is WEP104 + WIFI_CIPHER_TYPE_TKIP, ## < The cipher type is TKIP + WIFI_CIPHER_TYPE_CCMP, ## < The cipher type is CCMP + WIFI_CIPHER_TYPE_TKIP_CCMP, ## < The cipher type is TKIP and CCMP + WIFI_CIPHER_TYPE_AES_CMAC128, ## < The cipher type is AES-CMAC-128 + WIFI_CIPHER_TYPE_SMS4, ## < The cipher type is SMS4 + WIFI_CIPHER_TYPE_GCMP, ## < The cipher type is GCMP + WIFI_CIPHER_TYPE_GCMP256, ## < The cipher type is GCMP-256 + WIFI_CIPHER_TYPE_AES_GMAC128, ## < The cipher type is AES-GMAC-128 + WIFI_CIPHER_TYPE_AES_GMAC256, ## < The cipher type is AES-GMAC-256 + WIFI_CIPHER_TYPE_UNKNOWN ## < The cipher type is unknown + +type + + wifi_bandwidth_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi bandwidth type + ## + WIFI_BW_HT20 = 1, ## < Bandwidth is HT20 + WIFI_BW_HT40 = 2, ## < Bandwidth is HT40 + WIFI_BW80 = 3, ## < Bandwidth is 80 MHz + WIFI_BW160 = 4, ## < Bandwidth is 160 MHz + WIFI_BW80_BW80 = 5 ## < Bandwidth is 80 + 80 MHz const - WIFI_PROTOCOL_11B* = 1 - WIFI_PROTOCOL_11G* = 2 - WIFI_PROTOCOL_11N* = 4 - WIFI_PROTOCOL_LR* = 8 + WIFI_BW20* = WIFI_BW_HT20 + WIFI_BW40* = WIFI_BW_HT40 type - wifi_bandwidth_t* {.size: sizeof(cint).} = enum - WIFI_BW_HT20 = 1, ## Bandwidth is HT20 - WIFI_BW_HT40 ## Bandwidth is HT40 + wifi_ant_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi antenna + ## + WIFI_ANT_ANT0, ## < Wi-Fi antenna 0 + WIFI_ANT_ANT1, ## < Wi-Fi antenna 1 + WIFI_ANT_MAX ## < Invalid Wi-Fi antenna -## * Configuration structure for Protected Management Frame type - wifi_pmf_config_t* {.importc: "wifi_pmf_config_t", header: "esp_wifi_types.h", - bycopy.} = object - capable* {.importc: "capable".}: bool ## *< Advertizes support for Protected Management Frame. Device will prefer to connect in PMF mode if other device also advertizes PMF capability. - required* {.importc: "required".}: bool ## *< Advertizes that Protected Management Frame is required. Device will not associate to non-PMF capable devices. + wifi_he_ap_info_t* {.importc: "wifi_he_ap_info_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Description of a Wi-Fi AP HE Info + ## + bss_color* {.importc: "bss_color", bitsize: 6.}: uint8 ## + ## < The BSS Color value associated with the AP's corresponding BSS + partial_bss_color* {.importc: "partial_bss_color", bitsize: 1.}: uint8 ## + ## < Indicates whether an AID assignment rule is based on the BSS color + bss_color_disabled* {.importc: "bss_color_disabled", bitsize: 1.}: uint8 ## + ## < Indicates whether the BSS color usage is disabled + bssid_index* {.importc: "bssid_index".}: uint8 + ## < In a M-BSSID set, identifies the non-transmitted BSSID + + + wifi_ap_record_t* {.importc: "wifi_ap_record_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Description of a Wi-Fi AP + ## + bssid* {.importc: "bssid".}: array[6, uint8] ## < MAC address of AP + ssid* {.importc: "ssid".}: array[33, uint8] ## < SSID of AP + primary* {.importc: "primary".}: uint8 ## < Channel of AP + second* {.importc: "second".}: wifi_second_chan_t ## + ## < Secondary channel of AP + rssi* {.importc: "rssi".}: int8 ## < Signal strength of AP. Note that in some rare cases where signal strength is very strong, RSSI values can be slightly positive + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## + ## < Auth mode of AP + pairwise_cipher* {.importc: "pairwise_cipher".}: wifi_cipher_type_t ## + ## < Pairwise cipher of AP + group_cipher* {.importc: "group_cipher".}: wifi_cipher_type_t ## + ## < Group cipher of AP + ant* {.importc: "ant".}: wifi_ant_t ## < Antenna used to receive beacon from AP + phy_11b* {.importc: "phy_11b", bitsize: 1.}: uint32 ## + ## < Bit: 0 flag to identify if 11b mode is enabled or not + phy_11g* {.importc: "phy_11g", bitsize: 1.}: uint32 ## + ## < Bit: 1 flag to identify if 11g mode is enabled or not + phy_11n* {.importc: "phy_11n", bitsize: 1.}: uint32 ## + ## < Bit: 2 flag to identify if 11n mode is enabled or not + phy_lr* {.importc: "phy_lr", bitsize: 1.}: uint32 ## + ## < Bit: 3 flag to identify if low rate is enabled or not + phy_11a* {.importc: "phy_11a", bitsize: 1.}: uint32 ## + ## < Bit: 4 flag to identify if 11ax mode is enabled or not + phy_11ac* {.importc: "phy_11ac", bitsize: 1.}: uint32 ## + ## < Bit: 5 flag to identify if 11ax mode is enabled or not + phy_11ax* {.importc: "phy_11ax", bitsize: 1.}: uint32 ## + ## < Bit: 6 flag to identify if 11ax mode is enabled or not + wps* {.importc: "wps", bitsize: 1.}: uint32 ## < Bit: 7 flag to identify if WPS is supported or not + ftm_responder* {.importc: "ftm_responder", bitsize: 1.}: uint32 ## + ## < Bit: 8 flag to identify if FTM is supported in responder mode + ftm_initiator* {.importc: "ftm_initiator", bitsize: 1.}: uint32 ## + ## < Bit: 9 flag to identify if FTM is supported in initiator mode + reserved* {.importc: "reserved", bitsize: 22.}: uint32 ## + ## < Bit: 10..31 reserved + country* {.importc: "country".}: wifi_country_t ## + ## < Country information of AP + he_ap* {.importc: "he_ap".}: wifi_he_ap_info_t ## + ## < HE AP info + bandwidth* {.importc: "bandwidth".}: wifi_bandwidth_t ## + ## < Bandwidth of AP + vht_ch_freq1* {.importc: "vht_ch_freq1".}: uint8 ## + ## < This fields are used only AP bandwidth is 80 and 160 MHz, to transmit the center channel + ## frequency of the BSS. For AP bandwidth is 80 + 80 MHz, it is the center channel frequency + ## of the lower frequency segment. + vht_ch_freq2* {.importc: "vht_ch_freq2".}: uint8 + ## < this fields are used only AP bandwidth is 80 + 80 MHz, and is used to transmit the center + ## channel frequency of the second segment. + + + wifi_scan_method_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi scan method + ## + WIFI_FAST_SCAN = 0, ## < Do fast scan, scan will end after find SSID match AP + WIFI_ALL_CHANNEL_SCAN ## < All channel scan, scan will end after scan all the channel -## * @brief Soft-AP configuration settings for the ESP32 type - wifi_ap_config_t* {.importc: "wifi_ap_config_t", header: "esp_wifi_types.h", bycopy.} = object - ssid* {.importc: "ssid".}: array[32, uint8] ## *< SSID of ESP32 soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. - password* {.importc: "password".}: array[64, uint8] ## *< Password of ESP32 soft-AP. Null terminated string. - ssid_len* {.importc: "ssid_len".}: uint8 ## *< Optional length of SSID field. - channel* {.importc: "channel".}: uint8 ## *< Channel of ESP32 soft-AP - authmode* {.importc: "authmode".}: wifi_auth_mode_t ## *< Auth mode of ESP32 soft-AP. Do not support AUTH_WEP in soft-AP mode - ssid_hidden* {.importc: "ssid_hidden".}: uint8 ## *< Broadcast SSID or not, default 0, broadcast the SSID - max_connection* {.importc: "max_connection".}: uint8 ## *< Max number of stations allowed to connect in, default 4, max 10 - beacon_interval* {.importc: "beacon_interval".}: uint16 ## *< Beacon interval, 100 ~ 60000 ms, default 100 ms + wifi_sort_method_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Wi-Fi sort AP method + ## + WIFI_CONNECT_AP_BY_SIGNAL = 0, ## < Sort match AP in scan list by RSSI + WIFI_CONNECT_AP_BY_SECURITY ## < Sort match AP in scan list by security mode -## * @brief STA configuration settings for the ESP32 type - wifi_sta_config_t* {.importc: "wifi_sta_config_t", header: "esp_wifi_types.h", - bycopy.} = object - ssid* {.importc: "ssid".}: array[32, uint8] ## *< SSID of target AP. Null terminated string. - password* {.importc: "password".}: array[64, uint8] ## *< Password of target AP. Null terminated string. - scan_method* {.importc: "scan_method".}: wifi_scan_method_t ## *< do all channel scan or fast scan - bssid_set* {.importc: "bssid_set".}: bool ## *< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP. - bssid* {.importc: "bssid".}: array[6, uint8] ## *< MAC address of target AP - channel* {.importc: "channel".}: uint8 ## *< channel of target AP. Set to 1~13 to scan starting from the specified channel before connecting to AP. If the channel of AP is unknown, set it to 0. - listen_interval* {.importc: "listen_interval".}: uint16 ## *< Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. - sort_method* {.importc: "sort_method".}: wifi_sort_method_t ## *< sort the connect AP in the list by rssi or security mode - threshold* {.importc: "threshold".}: wifi_scan_threshold_t ## *< When sort_method is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. - pmf_cfg* {.importc: "pmf_cfg".}: wifi_pmf_config_t ## *< Configuration for Protected Management Frame. Will be advertized in RSN Capabilities in RSN IE. + wifi_scan_threshold_t* {.importc: "wifi_scan_threshold_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Structure describing parameters for a Wi-Fi fast scan + ## + rssi* {.importc: "rssi".}: int8 ## < The minimum rssi to accept in the fast scan mode. Defaults to -127 if set to >= 0 + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## + ## < The weakest auth mode to accept in the fast scan mode + ## Note: In case this value is not set and password is set as per WPA2 standards(password len >= 8), it will be defaulted to WPA2 and device won't connect to deprecated WEP/WPA networks. Please set auth mode threshold as WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK to connect to WEP/WPA networks + rssi_5g_adjustment* {.importc: "rssi_5g_adjustment".}: uint8 + ## < The RSSI value of the 5G AP is within the rssi_5g_adjustment range compared to the 2G AP, the 5G AP will be given priority for connection. + + + wifi_ps_type_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi power save type + ## + WIFI_PS_NONE, ## < No power save + WIFI_PS_MIN_MODEM, ## < Minimum modem power saving. In this mode, station wakes up to receive beacon every DTIM period + WIFI_PS_MAX_MODEM ## < Maximum modem power saving. In this mode, interval to receive beacons is determined by the listen_interval parameter in wifi_sta_config_t -## * @brief Configuration data for ESP32 AP or STA. -## -## The usage of this union (for ap or sta configuration) is determined by the accompanying -## interface argument passed to esp_wifi_set_config() or esp_wifi_get_config() -## -## type - wifi_config_t* {.importc: "wifi_config_t", header: "esp_wifi_types.h", bycopy, union.} = object - ap* {.importc: "ap".}: wifi_ap_config_t ## *< configuration of AP - sta* {.importc: "sta".}: wifi_sta_config_t ## *< configuration of STA + wifi_band_t* {.size: sizeof(cint).} = enum ## + ## @brief Argument structure for Wi-Fi band + ## + WIFI_BAND_2G = 1, ## < Band is 2.4 GHz + WIFI_BAND_5G = 2 ## < Band is 5 GHz -## * @brief Description of STA associated with AP type - wifi_sta_info_t* {.importc: "wifi_sta_info_t", header: "esp_wifi_types.h", bycopy.} = object - mac* {.importc: "mac".}: array[6, uint8] ## *< mac address - rssi* {.importc: "rssi".}: int8 ## *< current average rssi of sta connected - phy_11b* {.importc: "phy_11b", bitsize: 1.}: uint32 ## *< bit: 0 flag to identify if 11b mode is enabled or not - phy_11g* {.importc: "phy_11g", bitsize: 1.}: uint32 ## *< bit: 1 flag to identify if 11g mode is enabled or not - phy_11n* {.importc: "phy_11n", bitsize: 1.}: uint32 ## *< bit: 2 flag to identify if 11n mode is enabled or not - phy_lr* {.importc: "phy_lr", bitsize: 1.}: uint32 ## *< bit: 3 flag to identify if low rate is enabled or not - reserved* {.importc: "reserved", bitsize: 28.}: uint32 ## *< bit: 4..31 reserved + wifi_band_mode_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Argument structure for Wi-Fi band mode + ## + WIFI_BAND_MODE_2G_ONLY = 1, ## < Wi-Fi band mode is 2.4 GHz only + WIFI_BAND_MODE_5G_ONLY = 2, ## < Wi-Fi band mode is 5 GHz only + WIFI_BAND_MODE_AUTO = 3 ## < Wi-Fi band mode is 2.4 GHz + 5 GHz -const - ESP_WIFI_MAX_CONN_NUM* = (10) ## *< max number of stations which can connect to ESP32 soft-AP -## * @brief List of stations associated with the ESP32 Soft-AP +proc BIT(nr: cint): cint = (1.cint shl nr) type - wifi_sta_list_t* {.importc: "wifi_sta_list_t", header: "esp_wifi_types.h", bycopy.} = object - sta* {.importc: "sta".}: array[ESP_WIFI_MAX_CONN_NUM, wifi_sta_info_t] ## *< station list - num* {.importc: "num".}: cint ## *< number of stations in the list (other entries are invalid) - wifi_storage_t* {.size: sizeof(cint).} = enum - WIFI_STORAGE_FLASH, ## *< all configuration will store in both memory and flash - WIFI_STORAGE_RAM ## *< all configuration will only store in the memory + wifi_2g_channel_bit_t* {.size: sizeof(cint).} = enum ## + ## Argument structure for 2.4G channels + WIFI_CHANNEL_1 = BIT(1), ## < Wi-Fi channel 1 + WIFI_CHANNEL_2 = BIT(2), ## < Wi-Fi channel 2 + WIFI_CHANNEL_3 = BIT(3), ## < Wi-Fi channel 3 + WIFI_CHANNEL_4 = BIT(4), ## < Wi-Fi channel 4 + WIFI_CHANNEL_5 = BIT(5), ## < Wi-Fi channel 5 + WIFI_CHANNEL_6 = BIT(6), ## < Wi-Fi channel 6 + WIFI_CHANNEL_7 = BIT(7), ## < Wi-Fi channel 7 + WIFI_CHANNEL_8 = BIT(8), ## < Wi-Fi channel 8 + WIFI_CHANNEL_9 = BIT(9), ## < Wi-Fi channel 9 + WIFI_CHANNEL_10 = BIT(10), ## < Wi-Fi channel 10 + WIFI_CHANNEL_11 = BIT(11), ## < Wi-Fi channel 11 + WIFI_CHANNEL_12 = BIT(12), ## < Wi-Fi channel 12 + WIFI_CHANNEL_13 = BIT(13), ## < Wi-Fi channel 13 + WIFI_CHANNEL_14 = BIT(14) ## < Wi-Fi channel 14 -## * -## @brief Vendor Information Element type -## -## Determines the frame type that the IE will be associated with. -## +type + + wifi_5g_channel_bit_t* {.size: sizeof(cint).} = enum ## + ## Argument structure for 5G channels + WIFI_CHANNEL_36 = BIT(1), ## < Wi-Fi channel 36 + WIFI_CHANNEL_40 = BIT(2), ## < Wi-Fi channel 40 + WIFI_CHANNEL_44 = BIT(3), ## < Wi-Fi channel 44 + WIFI_CHANNEL_48 = BIT(4), ## < Wi-Fi channel 48 + WIFI_CHANNEL_52 = BIT(5), ## < Wi-Fi channel 52 + WIFI_CHANNEL_56 = BIT(6), ## < Wi-Fi channel 56 + WIFI_CHANNEL_60 = BIT(7), ## < Wi-Fi channel 60 + WIFI_CHANNEL_64 = BIT(8), ## < Wi-Fi channel 64 + WIFI_CHANNEL_100 = BIT(9), ## < Wi-Fi channel 100 + WIFI_CHANNEL_104 = BIT(10), ## < Wi-Fi channel 104 + WIFI_CHANNEL_108 = BIT(11), ## < Wi-Fi channel 108 + WIFI_CHANNEL_112 = BIT(12), ## < Wi-Fi channel 112 + WIFI_CHANNEL_116 = BIT(13), ## < Wi-Fi channel 116 + WIFI_CHANNEL_120 = BIT(14), ## < Wi-Fi channel 120 + WIFI_CHANNEL_124 = BIT(15), ## < Wi-Fi channel 124 + WIFI_CHANNEL_128 = BIT(16), ## < Wi-Fi channel 128 + WIFI_CHANNEL_132 = BIT(17), ## < Wi-Fi channel 132 + WIFI_CHANNEL_136 = BIT(18), ## < Wi-Fi channel 136 + WIFI_CHANNEL_140 = BIT(19), ## < Wi-Fi channel 140 + WIFI_CHANNEL_144 = BIT(20), ## < Wi-Fi channel 144 + WIFI_CHANNEL_149 = BIT(21), ## < Wi-Fi channel 149 + WIFI_CHANNEL_153 = BIT(22), ## < Wi-Fi channel 153 + WIFI_CHANNEL_157 = BIT(23), ## < Wi-Fi channel 157 + WIFI_CHANNEL_161 = BIT(24), ## < Wi-Fi channel 161 + WIFI_CHANNEL_165 = BIT(25), ## < Wi-Fi channel 165 + WIFI_CHANNEL_169 = BIT(26), ## < Wi-Fi channel 169 + WIFI_CHANNEL_173 = BIT(27), ## < Wi-Fi channel 173 + WIFI_CHANNEL_177 = BIT(28) ## < Wi-Fi channel 177 + +let + WIFI_PROTOCOL_11B* {.importc, header: hdr.}: uint16 = 0x1 + WIFI_PROTOCOL_11G* {.importc, header: hdr.}: uint16 = 0x2 + WIFI_PROTOCOL_11N* {.importc, header: hdr.}: uint16 = 0x4 + WIFI_PROTOCOL_LR* {.importc, header: hdr.}: uint16 = 0x8 + WIFI_PROTOCOL_11A* {.importc, header: hdr.}: uint16 = 0x10 + WIFI_PROTOCOL_11AC* {.importc, header: hdr.}: uint16 = 0x20 + WIFI_PROTOCOL_11AX* {.importc, header: hdr.}: uint16 = 0x40 type - wifi_vendor_ie_type_t* {.size: sizeof(cint).} = enum - WIFI_VND_IE_TYPE_BEACON, WIFI_VND_IE_TYPE_PROBE_REQ, - WIFI_VND_IE_TYPE_PROBE_RESP, WIFI_VND_IE_TYPE_ASSOC_REQ, - WIFI_VND_IE_TYPE_ASSOC_RESP + wifi_protocols_t* {.importc: "wifi_protocols_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Description of a Wi-Fi protocols + ## + ghz_2g* {.importc: "ghz_2g".}: uint16 ## < Represents 2.4 GHz protocol, support 802.11b or 802.11g or 802.11n or 802.11ax or LR mode + ghz_5g* {.importc: "ghz_5g".}: uint16 + ## < Represents 5 GHz protocol, support 802.11a or 802.11n or 802.11ac or 802.11ax + + + wifi_bandwidths_t* {.importc: "wifi_bandwidths_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Description of a Wi-Fi band bandwidths + ## + ghz_2g* {.importc: "ghz_2g".}: wifi_bandwidth_t ## + ## < Represents 2.4 GHz bandwidth + ghz_5g* {.importc: "ghz_5g".}: wifi_bandwidth_t + ## < Represents 5 GHz bandwidth + + + wifi_pmf_config_t* {.importc: "wifi_pmf_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Configuration structure for Protected Management Frame + ## + capable* {.importc: "capable".}: bool ## < Deprecated variable. Device will always connect in PMF mode if other device also advertises PMF capability. + required* {.importc: "required".}: bool + ## < Advertises that Protected Management Frame is required. Device will not associate to non-PMF capable devices. + + + wifi_sae_pwe_method_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Configuration for SAE PWE derivation + ## + WPA3_SAE_PWE_UNSPECIFIED, WPA3_SAE_PWE_HUNT_AND_PECK, + WPA3_SAE_PWE_HASH_TO_ELEMENT, WPA3_SAE_PWE_BOTH -## * -## @brief Vendor Information Element index -## -## Each IE type can have up to two associated vendor ID elements. -## type - wifi_vendor_ie_id_t* {.size: sizeof(cint).} = enum - WIFI_VND_IE_ID_0, WIFI_VND_IE_ID_1 + + wifi_sae_pk_mode_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Configuration for SAE-PK + ## + WPA3_SAE_PK_MODE_AUTOMATIC = 0, WPA3_SAE_PK_MODE_ONLY = 1, + WPA3_SAE_PK_MODE_DISABLED = 2 + + +type + + wifi_bss_max_idle_config_t* {.importc: "wifi_bss_max_idle_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Configuration structure for BSS max idle + ## + period* {.importc: "period".}: uint16 ## < Sets BSS Max idle period (1 Unit = 1000TUs OR 1.024 Seconds). If there are no frames for this period from a STA, SoftAP will disassociate due to inactivity. Setting it to 0 disables the feature + protected_keep_alive* {.importc: "protected_keep_alive".}: bool + ## < Requires clients to use protected keep alive frames for BSS Max Idle period + + + wifi_ap_config_t* {.importc: "wifi_ap_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Soft-AP configuration settings for the device + ## + ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. + password* {.importc: "password".}: array[64, uint8] ## + ## < Password of soft-AP. + ssid_len* {.importc: "ssid_len".}: uint8 ## < Optional length of SSID field. + channel* {.importc: "channel".}: uint8 ## < Channel of soft-AP + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## + ## < Auth mode of soft-AP. Do not support AUTH_WEP, AUTH_WAPI_PSK and AUTH_OWE in soft-AP mode. When the auth mode is set to WPA2_PSK, WPA2_WPA3_PSK or WPA3_PSK, the pairwise cipher will be overwritten with WIFI_CIPHER_TYPE_CCMP by default, unless explicitly set. + ssid_hidden* {.importc: "ssid_hidden".}: uint8 ## + ## < Broadcast SSID or not, default 0, broadcast the SSID + max_connection* {.importc: "max_connection".}: uint8 ## + ## < Max number of stations allowed to connect in + beacon_interval* {.importc: "beacon_interval".}: uint16 ## + ## < Beacon interval which should be multiples of 100. Unit: TU(time unit, 1 TU = 1024 us). Range: 100 ~ 60000. Default value: 100 + csa_count* {.importc: "csa_count".}: uint8 ## < Channel Switch Announcement Count. Notify the station that the channel will switch after the csa_count beacon intervals. Default value: 3 + dtim_period* {.importc: "dtim_period".}: uint8 ## + ## < Dtim period of soft-AP. Range: 1 ~ 10. Default value: 1 + pairwise_cipher* {.importc: "pairwise_cipher".}: wifi_cipher_type_t ## + ## < Pairwise cipher of SoftAP, group cipher will be derived using this. Cipher values are valid starting from WIFI_CIPHER_TYPE_TKIP, enum values before that will be considered as invalid and default cipher suites(TKIP+CCMP) will be used. Valid cipher suites in softAP mode are WIFI_CIPHER_TYPE_TKIP, WIFI_CIPHER_TYPE_CCMP, WIFI_CIPHER_TYPE_TKIP_CCMP, WIFI_CIPHER_TYPE_GCMP and WIFI_CIPHER_TYPE_GCMP256. + ftm_responder* {.importc: "ftm_responder".}: bool ## + ## < Enable FTM Responder mode + pmf_cfg* {.importc: "pmf_cfg".}: wifi_pmf_config_t ## + ## < Configuration for Protected Management Frame + sae_pwe_h2e* {.importc: "sae_pwe_h2e".}: wifi_sae_pwe_method_t ## + ## < Configuration for SAE PWE derivation method + transition_disable* {.importc: "transition_disable".}: uint8 ## + ## < Whether to enable transition disable feature + sae_ext* {.importc: "sae_ext".}: uint8 ## < Enable SAE EXT feature. SOC_GCMP_SUPPORT is required for this feature. + bss_max_idle_cfg* {.importc: "bss_max_idle_cfg".}: wifi_bss_max_idle_config_t ## + ## < Configuration for bss max idle, effective if CONFIG_WIFI_BSS_MAX_IDLE_SUPPORT is enabled + gtk_rekey_interval* {.importc: "gtk_rekey_interval".}: uint16 + ## < GTK rekeying interval in seconds. If set to 0, GTK rekeying is disabled. Range: 60 ~ 65535 including 0. const - WIFI_VENDOR_IE_ELEMENT_ID* = 0x000000DD + SAE_H2E_IDENTIFIER_LEN* = 32 + +type + + wifi_sta_config_t* {.importc: "wifi_sta_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief STA configuration settings for the device + ## + ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of target AP. + password* {.importc: "password".}: array[64, uint8] ## + ## < Password of target AP. + scan_method* {.importc: "scan_method".}: wifi_scan_method_t ## + ## < Do all channel scan or fast scan + bssid_set* {.importc: "bssid_set".}: bool ## < Whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP. + bssid* {.importc: "bssid".}: array[6, uint8] ## < MAC address of target AP + channel* {.importc: "channel".}: uint8 ## < Channel hint for target AP. For 2.4G AP, set to 1~13 to scan starting from the specified channel before connecting to AP. For 5G AP, set to 36~177 (36, 40, 44 ... 177) to scan starting from the specified channel before connecting to AP. Set to 0 for no preference + listen_interval* {.importc: "listen_interval".}: uint16 ## + ## < Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. + sort_method* {.importc: "sort_method".}: wifi_sort_method_t ## + ## < Sort the connect AP in the list by rssi or security mode + threshold* {.importc: "threshold".}: wifi_scan_threshold_t ## + ## < When scan_threshold is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. + pmf_cfg* {.importc: "pmf_cfg".}: wifi_pmf_config_t ## + ## < Configuration for Protected Management Frame. Will be advertised in RSN Capabilities in RSN IE. + rm_enabled* {.importc: "rm_enabled", bitsize: 1.}: uint32 ## + ## < Whether Radio Measurements are enabled for the connection + btm_enabled* {.importc: "btm_enabled", bitsize: 1.}: uint32 ## + ## < Whether BSS Transition Management is enabled for the connection. Note that when btm is enabled, the application itself should not set specific bssid (i.e using bssid_set and bssid in this config)or channel to connect to. This defeats the purpose of a BTM supported network, and hence if btm is supported and a specific bssid or channel is set in this config, it will be cleared from the config at the first disconnection or connection so that the device can roam to other BSS. It is recommended not to set BSSID when BTM is enabled. + mbo_enabled* {.importc: "mbo_enabled", bitsize: 1.}: uint32 ## + ## < Whether MBO is enabled for the connection. Note that when mbo is enabled, the application itself should not set specific bssid (i.e using bssid_set and bssid in this config)or channel to connect to. This defeats the purpose of a MBO supported network, and hence if btm is supported and a specific bssid or channel is set in this config, it will be cleared from the config at the first disconnection or connection so that the device can roam to other BSS. It is recommended not to set BSSID when MBO is enabled. Enabling mbo here, automatically enables btm and rm above. + ft_enabled* {.importc: "ft_enabled", bitsize: 1.}: uint32 ## + ## < Whether FT is enabled for the connection + owe_enabled* {.importc: "owe_enabled", bitsize: 1.}: uint32 ## + ## < Whether OWE is enabled for the connection + transition_disable* {.importc: "transition_disable", bitsize: 1.}: uint32 ## + ## < Whether to enable transition disable feature + reserved1* {.importc: "reserved1", bitsize: 26.}: uint32 ## + ## < Reserved for future feature set + sae_pwe_h2e* {.importc: "sae_pwe_h2e".}: wifi_sae_pwe_method_t ## + ## < Configuration for SAE PWE derivation method + sae_pk_mode* {.importc: "sae_pk_mode".}: wifi_sae_pk_mode_t ## + ## < Configuration for SAE-PK (Public Key) Authentication method + failure_retry_cnt* {.importc: "failure_retry_cnt".}: uint8 ## + ## < Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config. + ## Note: Enabling this may cause connection time to increase in case best AP doesn't behave properly. + he_dcm_set* {.importc: "he_dcm_set", bitsize: 1.}: uint32 ## + ## < Whether DCM max.constellation for transmission and reception is set. + he_dcm_max_constellation_tx* {.importc: "he_dcm_max_constellation_tx", + bitsize: 2.}: uint32 ## + ## < Indicate the max.constellation for DCM in TB PPDU the STA supported. 0: not supported. 1: BPSK, 2: QPSK, 3: 16-QAM. The default value is 3. + he_dcm_max_constellation_rx* {.importc: "he_dcm_max_constellation_rx", + bitsize: 2.}: uint32 ## + ## < Indicate the max.constellation for DCM in both Data field and HE-SIG-B field the STA supported. 0: not supported. 1: BPSK, 2: QPSK, 3: 16-QAM. The default value is 3. + he_mcs9_enabled* {.importc: "he_mcs9_enabled", bitsize: 1.}: uint32 ## + ## < Whether to support HE-MCS8 and HE-MCS9. The default value is 0. + he_su_beamformee_disabled* {.importc: "he_su_beamformee_disabled", + bitsize: 1.}: uint32 ## + ## < Whether to disable support for operation as an SU beamformee. + he_trig_su_bmforming_feedback_disabled* + {.importc: "he_trig_su_bmforming_feedback_disabled", bitsize: 1.}: uint32 ## + ## < Whether to disable support the transmission of SU feedback in an HE TB sounding sequence. + he_trig_mu_bmforming_partial_feedback_disabled* {. + importc: "he_trig_mu_bmforming_partial_feedback_disabled", bitsize: 1.}: uint32 ## + ## < Whether to disable support the transmission of partial-bandwidth MU feedback in an HE TB sounding sequence. + he_trig_cqi_feedback_disabled* {.importc: "he_trig_cqi_feedback_disabled", + bitsize: 1.}: uint32 ## + ## < Whether to disable support the transmission of CQI feedback in an HE TB sounding sequence. + vht_su_beamformee_disabled* {.importc: "vht_su_beamformee_disabled", + bitsize: 1.}: uint32 ## + ## < Whether to disable support for operation as an VHT SU beamformee. + vht_mu_beamformee_disabled* {.importc: "vht_mu_beamformee_disabled", + bitsize: 1.}: uint32 ## + ## < Whether to disable support for operation as an VHT MU beamformee. + vht_mcs8_enabled* {.importc: "vht_mcs8_enabled", bitsize: 1.}: uint32 ## + ## < Whether to support VHT-MCS8. The default value is 0. + reserved2* {.importc: "reserved2", bitsize: 19.}: uint32 ## + ## < Reserved for future feature set + sae_h2e_identifier* {.importc: "sae_h2e_identifier".}: array[ + SAE_H2E_IDENTIFIER_LEN, uint8] + ## < Password identifier for H2E. this needs to be null terminated string + + + wifi_nan_config_t* {.importc: "wifi_nan_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Discovery start configuration + ## + op_channel* {.importc: "op_channel".}: uint8 ## < NAN Discovery operating channel + master_pref* {.importc: "master_pref".}: uint8 ## + ## < Device's preference value to serve as NAN Master + scan_time* {.importc: "scan_time".}: uint8 ## < Scan time in seconds while searching for a NAN cluster + warm_up_sec* {.importc: "warm_up_sec".}: uint16 + ## < Warm up time before assuming NAN Anchor Master role + + + wifi_config_t* {.importc: "wifi_config_t", header: hdr, + bycopy, union.} = object ## + ## @brief Configuration data for device's AP or STA or NAN. + ## + ## The usage of this union (for ap, sta or nan configuration) is determined by the accompanying + ## interface argument passed to esp_wifi_set_config() or esp_wifi_get_config() + ## + ## + ap* {.importc: "ap".}: wifi_ap_config_t ## < Configuration of AP + sta* {.importc: "sta".}: wifi_sta_config_t ## < Configuration of STA + nan* {.importc: "nan".}: wifi_nan_config_t + ## < Configuration of NAN + + + wifi_sta_info_t* {.importc: "wifi_sta_info_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Description of STA associated with AP + ## + mac* {.importc: "mac".}: array[6, uint8] ## < MAC address + rssi* {.importc: "rssi".}: int8 ## < Current average rssi of sta connected + phy_11b* {.importc: "phy_11b", bitsize: 1.}: uint32 ## + ## < Bit: 0 flag to identify if 11b mode is enabled or not + phy_11g* {.importc: "phy_11g", bitsize: 1.}: uint32 ## + ## < Bit: 1 flag to identify if 11g mode is enabled or not + phy_11n* {.importc: "phy_11n", bitsize: 1.}: uint32 ## + ## < Bit: 2 flag to identify if 11n mode is enabled or not + phy_lr* {.importc: "phy_lr", bitsize: 1.}: uint32 ## + ## < Bit: 3 flag to identify if low rate is enabled or not + phy_11a* {.importc: "phy_11a", bitsize: 1.}: uint32 ## + ## < Bit: 4 flag to identify if 11ax mode is enabled or not + phy_11ac* {.importc: "phy_11ac", bitsize: 1.}: uint32 ## + ## < Bit: 5 flag to identify if 11ax mode is enabled or not + phy_11ax* {.importc: "phy_11ax", bitsize: 1.}: uint32 ## + ## < Bit: 6 flag to identify if 11ax mode is enabled or not + is_mesh_child* {.importc: "is_mesh_child", bitsize: 1.}: uint32 ## + ## < Bit: 7 flag to identify mesh child + reserved* {.importc: "reserved", bitsize: 24.}: uint32 + ## < Bit: 8..31 reserved + + + wifi_storage_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi storage type + ## + WIFI_STORAGE_FLASH, ## < All configuration will store in both memory and flash + WIFI_STORAGE_RAM ## < All configuration will only store in the memory -## * -## @brief Vendor Information Element header -## -## The first bytes of the Information Element will match this header. Payload follows. -## type - vendor_ie_data_t* {.importc: "vendor_ie_data_t", header: "esp_wifi_types.h", bycopy.} = object - element_id* {.importc: "element_id".}: uint8 ## *< Should be set to WIFI_VENDOR_IE_ELEMENT_ID (0xDD) - length* {.importc: "length".}: uint8 ## *< Length of all bytes in the element data following this field. Minimum 4. - vendor_oui* {.importc: "vendor_oui".}: array[3, uint8] ## *< Vendor identifier (OUI). - vendor_oui_type* {.importc: "vendor_oui_type".}: uint8 ## *< Vendor-specific OUI type. - payload* {.importc: "payload".}: UncheckedArray[uint8] ## *< Payload. Length is equal to value in 'length' field, minus 4. - - wifi_pkt_rx_ctrl_t* {.importc: "wifi_pkt_rx_ctrl_t", header: "esp_wifi_types.h", - bycopy.} = object - rssi* {.importc: "rssi", bitsize: 8.}: cint ## *< Received Signal Strength Indicator(RSSI) of packet. unit: dBm - rate* {.importc: "rate", bitsize: 5.}: cuint ## *< PHY rate encoding of the packet. Only valid for non HT(11bg) packet - r1* {.importc: "r1", bitsize: 1.}: cuint ## *< reserve - sig_mode* {.importc: "sig_mode", bitsize: 2.}: cuint ## *< 0: non HT(11bg) packet; 1: HT(11n) packet; 3: VHT(11ac) packet - r2* {.importc: "r2", bitsize: 16.}: cuint ## *< reserve - mcs* {.importc: "mcs", bitsize: 7.}: cuint ## *< Modulation Coding Scheme. If is HT(11n) packet, shows the modulation, range from 0 to 76(MSC0 ~ MCS76) - cwb* {.importc: "cwb", bitsize: 1.}: cuint ## *< Channel Bandwidth of the packet. 0: 20MHz; 1: 40MHz - r3* {.importc: "r3", bitsize: 16.}: cuint ## *< reserve - smoothing* {.importc: "smoothing", bitsize: 1.}: cuint ## *< reserve - not_sounding* {.importc: "not_sounding", bitsize: 1.}: cuint ## *< reserve - r4* {.importc: "r4", bitsize: 1.}: cuint ## *< reserve - aggregation* {.importc: "aggregation", bitsize: 1.}: cuint ## *< Aggregation. 0: MPDU packet; 1: AMPDU packet - stbc* {.importc: "stbc", bitsize: 2.}: cuint ## *< Space Time Block Code(STBC). 0: non STBC packet; 1: STBC packet - fec_coding* {.importc: "fec_coding", bitsize: 1.}: cuint ## *< Flag is set for 11n packets which are LDPC - sgi* {.importc: "sgi", bitsize: 1.}: cuint ## *< Short Guide Interval(SGI). 0: Long GI; 1: Short GI - noise_floor* {.importc: "noise_floor", bitsize: 8.}: cint ## *< noise floor of Radio Frequency Module(RF). unit: 0.25dBm - ampdu_cnt* {.importc: "ampdu_cnt", bitsize: 8.}: cuint ## *< ampdu cnt - channel* {.importc: "channel", bitsize: 4.}: cuint ## *< primary channel on which this packet is received - secondary_channel* {.importc: "secondary_channel", bitsize: 4.}: cuint ## *< secondary channel on which this packet is received. 0: none; 1: above; 2: below - r5* {.importc: "r5", bitsize: 8.}: cuint ## *< reserve - timestamp* {.importc: "timestamp", bitsize: 32.}: cuint ## *< timestamp. The local time when this packet is received. It is precise only if modem sleep or light sleep is not enabled. unit: microsecond - r6* {.importc: "r6", bitsize: 32.}: cuint ## *< reserve - r7* {.importc: "r7", bitsize: 31.}: cuint ## *< reserve - ant* {.importc: "ant", bitsize: 1.}: cuint ## *< antenna number from which this packet is received. 0: WiFi antenna 0; 1: WiFi antenna 1 - sig_len* {.importc: "sig_len", bitsize: 12.}: cuint ## *< length of packet including Frame Check Sequence(FCS) - r8* {.importc: "r8", bitsize: 12.}: cuint ## *< reserve - rx_state* {.importc: "rx_state", bitsize: 8.}: cuint ## *< state of the packet. 0: no error; others: error numbers which are not public - - wifi_promiscuous_pkt_type_t* {.size: sizeof(cint).} = enum - WIFI_PKT_MGMT, ## *< Management frame, indicates 'buf' argument is wifi_promiscuous_pkt_t - WIFI_PKT_CTRL, ## *< Control frame, indicates 'buf' argument is wifi_promiscuous_pkt_t - WIFI_PKT_DATA, ## *< Data frame, indiciates 'buf' argument is wifi_promiscuous_pkt_t - WIFI_PKT_MISC ## *< Other type, such as MIMO etc. 'buf' argument is wifi_promiscuous_pkt_t but the payload is zero length. + wifi_vendor_ie_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Vendor Information Element type + ## + ## Determines the frame type that the IE will be associated with. + ## + WIFI_VND_IE_TYPE_BEACON, ## < Beacon frame + WIFI_VND_IE_TYPE_PROBE_REQ, ## < Probe request frame + WIFI_VND_IE_TYPE_PROBE_RESP, ## < Probe response frame + WIFI_VND_IE_TYPE_ASSOC_REQ, ## < Association request frame + WIFI_VND_IE_TYPE_ASSOC_RESP ## < Association response frame -const - WIFI_PROMIS_FILTER_MASK_ALL* = (0xFFFFFFFF) ## *< filter all packets - WIFI_PROMIS_FILTER_MASK_MGMT* = (1) ## *< filter the packets with type of WIFI_PKT_MGMT - WIFI_PROMIS_FILTER_MASK_CTRL* = (1 shl 1) ## *< filter the packets with type of WIFI_PKT_CTRL - WIFI_PROMIS_FILTER_MASK_DATA* = (1 shl 2) ## *< filter the packets with type of WIFI_PKT_DATA - WIFI_PROMIS_FILTER_MASK_MISC* = (1 shl 3) ## *< filter the packets with type of WIFI_PKT_MISC - WIFI_PROMIS_FILTER_MASK_DATA_MPDU* = (1 shl 4) ## *< filter the MPDU which is a kind of WIFI_PKT_DATA - WIFI_PROMIS_FILTER_MASK_DATA_AMPDU* = (1 shl 5) ## *< filter the AMPDU which is a kind of WIFI_PKT_DATA - WIFI_PROMIS_CTRL_FILTER_MASK_ALL* = (0xFF800000) ## *< filter all control packets - WIFI_PROMIS_CTRL_FILTER_MASK_WRAPPER* = (1 shl 23) ## *< filter the control packets with subtype of Control Wrapper - WIFI_PROMIS_CTRL_FILTER_MASK_BAR* = (1 shl 24) ## *< filter the control packets with subtype of Block Ack Request - WIFI_PROMIS_CTRL_FILTER_MASK_BA* = (1 shl 25) ## *< filter the control packets with subtype of Block Ack - WIFI_PROMIS_CTRL_FILTER_MASK_PSPOLL* = (1 shl 26) ## *< filter the control packets with subtype of PS-Poll - WIFI_PROMIS_CTRL_FILTER_MASK_RTS* = (1 shl 27) ## *< filter the control packets with subtype of RTS - WIFI_PROMIS_CTRL_FILTER_MASK_CTS* = (1 shl 28) ## *< filter the control packets with subtype of CTS - WIFI_PROMIS_CTRL_FILTER_MASK_ACK* = (1 shl 29) ## *< filter the control packets with subtype of ACK - WIFI_PROMIS_CTRL_FILTER_MASK_CFEND* = (1 shl 30) ## *< filter the control packets with subtype of CF-END - WIFI_PROMIS_CTRL_FILTER_MASK_CFENDACK* = (1 shl 31) ## *< filter the control packets with subtype of CF-END+CF-ACK - -## * @brief Mask for filtering different packet types in promiscuous mode. type - wifi_promiscuous_filter_t* {.importc: "wifi_promiscuous_filter_t", - header: "esp_wifi_types.h", bycopy.} = object - filter_mask* {.importc: "filter_mask".}: uint32 ## *< OR of one or more filter values WIFI_PROMIS_FILTER_* + wifi_vendor_ie_id_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Vendor Information Element index + ## + ## Each IE type can have up to two associated vendor ID elements. + ## + WIFI_VND_IE_ID_0, ## < Vendor ID element 0 + WIFI_VND_IE_ID_1 ## < Vendor ID element 1 -const - WIFI_EVENT_MASK_ALL* = (0xFFFFFFFF) ## *< mask all WiFi events - WIFI_EVENT_MASK_NONE* = (0) ## *< mask none of the WiFi events - WIFI_EVENT_MASK_AP_PROBEREQRECVED* = (BIT(0)) ## *< mask SYSTEM_EVENT_AP_PROBEREQRECVED event +let + WIFI_VENDOR_IE_ELEMENT_ID* {.importc, header: hdr.}: uint8 -## * -## @brief Channel state information(CSI) configuration type -## -## +type + + wifi_phy_mode_t* {.size: sizeof(cint).} = enum ## + ## @brief Operation PHY mode + ## + WIFI_PHY_MODE_LR, ## < PHY mode for Low Rate + WIFI_PHY_MODE_11B, ## < PHY mode for 11b + WIFI_PHY_MODE_11G, ## < PHY mode for 11g + WIFI_PHY_MODE_11A, ## < PHY mode for 11a + WIFI_PHY_MODE_HT20, ## < PHY mode for Bandwidth HT20 + WIFI_PHY_MODE_HT40, ## < PHY mode for Bandwidth HT40 + WIFI_PHY_MODE_HE20, ## < PHY mode for Bandwidth HE20 + WIFI_PHY_MODE_VHT20 ## < PHY mode for Bandwidth VHT20 + + +type + + vendor_ie_data_t* {.importc: "vendor_ie_data_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Vendor Information Element header + ## + ## The first bytes of the Information Element will match this header. Payload follows. + ## + element_id* {.importc: "element_id".}: uint8 ## < Should be set to WIFI_VENDOR_IE_ELEMENT_ID (0xDD) + length* {.importc: "length".}: uint8 ## < Length of all bytes in the element data following this field. Minimum 4. + vendor_oui* {.importc: "vendor_oui".}: array[3, uint8] ## + ## < Vendor identifier (OUI). + vendor_oui_type* {.importc: "vendor_oui_type".}: uint8 ## + ## < Vendor-specific OUI type. + payload* {.importc: "payload".}: UncheckedArray[uint8] + ## < Payload. Length is equal to value in 'length' field, minus 4. + + + wifi_promiscuous_pkt_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Promiscuous frame type + ## + ## Passed to promiscuous mode RX callback to indicate the type of parameter in the buffer. + ## + ## + WIFI_PKT_MGMT, ## < Management frame, indicates 'buf' argument is wifi_promiscuous_pkt_t + WIFI_PKT_CTRL, ## < Control frame, indicates 'buf' argument is wifi_promiscuous_pkt_t + WIFI_PKT_DATA, ## < Data frame, indicates 'buf' argument is wifi_promiscuous_pkt_t + WIFI_PKT_MISC ## < Other type, such as MIMO etc. 'buf' argument is wifi_promiscuous_pkt_t but the payload is zero length. + +const + WIFI_PROMIS_FILTER_MASK_ALL* = (0xFFFFFFFF) ## < Filter all packets + WIFI_PROMIS_FILTER_MASK_MGMT* = (1) ## < Filter the packets with type of WIFI_PKT_MGMT + WIFI_PROMIS_FILTER_MASK_CTRL* = (1 shl 1) ## < Filter the packets with type of WIFI_PKT_CTRL + WIFI_PROMIS_FILTER_MASK_DATA* = (1 shl 2) ## < Filter the packets with type of WIFI_PKT_DATA + WIFI_PROMIS_FILTER_MASK_MISC* = (1 shl 3) ## < Filter the packets with type of WIFI_PKT_MISC + WIFI_PROMIS_FILTER_MASK_DATA_MPDU* = (1 shl 4) ## < Filter the MPDU which is a kind of WIFI_PKT_DATA + WIFI_PROMIS_FILTER_MASK_DATA_AMPDU* = (1 shl 5) ## < Filter the AMPDU which is a kind of WIFI_PKT_DATA + WIFI_PROMIS_FILTER_MASK_FCSFAIL* = (1 shl 6) ## < Filter the FCS failed packets, do not open it in general + WIFI_PROMIS_CTRL_FILTER_MASK_ALL* = (0xFF800000) ## + ## < Filter all control packets + WIFI_PROMIS_CTRL_FILTER_MASK_WRAPPER* = (1 shl 23) ## + ## < Filter the control packets with subtype of Control Wrapper + WIFI_PROMIS_CTRL_FILTER_MASK_BAR* = (1 shl 24) ## < Filter the control packets with subtype of Block Ack Request + WIFI_PROMIS_CTRL_FILTER_MASK_BA* = (1 shl 25) ## < Filter the control packets with subtype of Block Ack + WIFI_PROMIS_CTRL_FILTER_MASK_PSPOLL* = (1 shl 26) ## + ## < Filter the control packets with subtype of PS-Poll + WIFI_PROMIS_CTRL_FILTER_MASK_RTS* = (1 shl 27) ## < Filter the control packets with subtype of RTS + WIFI_PROMIS_CTRL_FILTER_MASK_CTS* = (1 shl 28) ## < Filter the control packets with subtype of CTS + WIFI_PROMIS_CTRL_FILTER_MASK_ACK* = (1 shl 29) ## < Filter the control packets with subtype of ACK + WIFI_PROMIS_CTRL_FILTER_MASK_CFEND* = (1 shl 30) ## + ## < Filter the control packets with subtype of CF-END + WIFI_PROMIS_CTRL_FILTER_MASK_CFENDACK* = (1 shl 31) ## + ## < Filter the control packets with subtype of CF-END+CF-ACK type - wifi_csi_config_t* {.importc: "wifi_csi_config_t", header: "esp_wifi_types.h", - bycopy.} = object - lltf_en* {.importc: "lltf_en".}: bool ## *< enable to receive legacy long training field(lltf) data. Default enabled - htltf_en* {.importc: "htltf_en".}: bool ## *< enable to receive HT long training field(htltf) data. Default enabled - stbc_htltf2_en* {.importc: "stbc_htltf2_en".}: bool ## *< enable to receive space time block code HT long training field(stbc-htltf2) data. Default enabled - ltf_merge_en* {.importc: "ltf_merge_en".}: bool ## *< enable to generate htlft data by averaging lltf and ht_ltf data when receiving HT packet. Otherwise, use ht_ltf data directly. Default enabled - channel_filter_en* {.importc: "channel_filter_en".}: bool ## *< enable to turn on channel filter to smooth adjacent sub-carrier. Disable it to keep independence of adjacent sub-carrier. Default enabled - manu_scale* {.importc: "manu_scale".}: bool ## *< manually scale the CSI data by left shifting or automatically scale the CSI data. If set true, please set the shift bits. false: automatically. true: manually. Default false - shift* {.importc: "shift".}: uint8 ## *< manually left shift bits of the scale of the CSI data. The range of the left shift bits is 0~15 + wifi_promiscuous_filter_t* {.importc: "wifi_promiscuous_filter_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Mask for filtering different packet types in promiscuous mode + ## + filter_mask* {.importc: "filter_mask".}: uint32 + ## < OR of one or more filter values WIFI_PROMIS_FILTER_* + + +const + WIFI_EVENT_MASK_ALL* = (0xFFFFFFFF) ## < Mask all Wi-Fi events + WIFI_EVENT_MASK_NONE* = (0) ## < Mask none of the Wi-Fi events + WIFI_EVENT_MASK_AP_PROBEREQRECVED* = (BIT(0)) ## < Mask SYSTEM_EVENT_AP_PROBEREQRECVED event -## * +## ## @brief CSI data type ## ## @@ -400,211 +900,1009 @@ type len* {.importc: "len".}: uint16 ## *< length of CSI data -## * -## @brief WiFi GPIO configuration for antenna selection -## -## +type + + wifi_ant_gpio_t* {.importc: "wifi_ant_gpio_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Wi-Fi GPIO configuration for antenna selection + ## + ## + gpio_select* {.importc: "gpio_select", bitsize: 1.}: uint8 ## + ## < Whether this GPIO is connected to external antenna switch + gpio_num* {.importc: "gpio_num", bitsize: 7.}: uint8 + ## < The GPIO number that connects to external antenna switch + + + wifi_ant_gpio_config_t* {.importc: "wifi_ant_gpio_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Wi-Fi GPIOs configuration for antenna selection + ## + ## + gpio_cfg* {.importc: "gpio_cfg".}: array[4, wifi_ant_gpio_t] + ## < The configurations of GPIOs that connect to external antenna switch + + + wifi_ant_mode_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi antenna mode + ## + ## + WIFI_ANT_MODE_ANT0, ## < Enable Wi-Fi antenna 0 only + WIFI_ANT_MODE_ANT1, ## < Enable Wi-Fi antenna 1 only + WIFI_ANT_MODE_AUTO, ## < Enable Wi-Fi antenna 0 and 1, automatically select an antenna + WIFI_ANT_MODE_MAX ## < Invalid Wi-Fi enabled antenna + type - wifi_ant_gpio_t* {.importc: "wifi_ant_gpio_t", header: "esp_wifi_types.h", bycopy.} = object - gpio_select* {.importc: "gpio_select", bitsize: 1.}: uint8 ## *< Whether this GPIO is connected to external antenna switch - gpio_num* {.importc: "gpio_num", bitsize: 7.}: uint8 ## *< The GPIO number that connects to external antenna switch + wifi_ant_config_t* {.importc: "wifi_ant_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Wi-Fi antenna configuration + ## + ## + rx_ant_mode* {.importc: "rx_ant_mode".}: wifi_ant_mode_t ## + ## < Wi-Fi antenna mode for receiving + rx_ant_default* {.importc: "rx_ant_default".}: wifi_ant_t ## + ## < Default antenna mode for receiving, it's ignored if rx_ant_mode is not WIFI_ANT_MODE_AUTO + tx_ant_mode* {.importc: "tx_ant_mode".}: wifi_ant_mode_t ## + ## < Wi-Fi antenna mode for transmission, it can be set to WIFI_ANT_MODE_AUTO only if rx_ant_mode is set to WIFI_ANT_MODE_AUTO + enabled_ant0* {.importc: "enabled_ant0", bitsize: 4.}: uint8 ## + ## < Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT0 + enabled_ant1* {.importc: "enabled_ant1", bitsize: 4.}: uint8 + ## < Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT1 + + + wifi_action_rx_cb_t* = proc (hdr: ptr uint8; payload: ptr uint8; len: csize_t; + channel: uint8): cint {.cdecl.} ## + ## + ## @brief The Rx callback function of Action Tx operations + ## + ## @param hdr Pointer to the IEEE 802.11 Header structure + ## @param payload Pointer to the Payload following 802.11 Header + ## @param len Length of the Payload + ## @param channel Channel number the frame is received on + ## + ## + + wifi_action_tx_req_t* {.importc: "wifi_action_tx_req_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Action Frame Tx Request + ## + ifx* {.importc: "ifx".}: wifi_interface_t ## < Wi-Fi interface to send request to + dest_mac* {.importc: "dest_mac".}: array[6, uint8] ## + ## < Destination MAC address + `type`* {.importc: "type".}: wifi_action_tx_t ## < ACTION TX operation type + channel* {.importc: "channel".}: uint8 ## < Channel on which to perform ACTION TX Operation + wait_time_ms* {.importc: "wait_time_ms".}: uint32 ## + ## < Duration to wait for on target channel + no_ack* {.importc: "no_ack".}: bool ## < Indicates no ack required + rx_cb* {.importc: "rx_cb".}: wifi_action_rx_cb_t ## + ## < Rx Callback to receive action frames + op_id* {.importc: "op_id".}: uint8 ## < Unique Identifier for operation provided by wifi driver + data_len* {.importc: "data_len".}: uint32 ## < Length of the appended Data + data* {.importc: "data".}: UncheckedArray[uint8] + ## < Appended Data payload + + + wifi_roc_done_status_t* {.size: sizeof(cint).} = enum ## + ## Status codes for WIFI_EVENT_ROC_DONE evt + WIFI_ROC_DONE = 0, ## < ROC operation was completed successfully + WIFI_ROC_FAIL ## < ROC operation was cancelled -## * -## @brief WiFi GPIOs configuration for antenna selection -## -## type - wifi_ant_gpio_config_t* {.importc: "wifi_ant_gpio_config_t", - header: "esp_wifi_types.h", bycopy.} = object - gpio_cfg* {.importc: "gpio_cfg".}: array[4, wifi_ant_gpio_t] ## *< The configurations of GPIOs that connect to external antenna switch + wifi_action_roc_done_cb_t* = proc (context: uint32; op_id: uint8; + status: wifi_roc_done_status_t) {.cdecl.} ## + ## + ## @brief The callback function executed when ROC operation has ended + ## + ## @param context rxcb registered for the corresponding ROC operation + ## @param op_id ID of the corresponding ROC operation + ## @param status status code of the ROC operation denoted + ## + ## + + wifi_roc_req_t* {.importc: "wifi_roc_req_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Remain on Channel request + ## + ## + ## + ifx* {.importc: "ifx".}: wifi_interface_t ## < WiFi interface to send request to + `type`* {.importc: "type".}: wifi_roc_t ## < ROC operation type + channel* {.importc: "channel".}: uint8 ## < Channel on which to perform ROC Operation + sec_channel* {.importc: "sec_channel".}: wifi_second_chan_t ## + ## < Secondary channel + wait_time_ms* {.importc: "wait_time_ms".}: uint32 ## + ## < Duration to wait for on target channel + rx_cb* {.importc: "rx_cb".}: wifi_action_rx_cb_t ## + ## < Rx Callback to receive any response + op_id* {.importc: "op_id".}: uint8 ## < ID of this specific ROC operation provided by wifi driver + done_cb* {.importc: "done_cb".}: wifi_action_roc_done_cb_t + ## < Callback to function that will be called upon ROC done. If assigned, WIFI_EVENT_ROC_DONE event will not be posted + + + wifi_ftm_initiator_cfg_t* {.importc: "wifi_ftm_initiator_cfg_t", + header: hdr, bycopy.} = object ## + ## + ## @brief FTM Initiator configuration + ## + ## + resp_mac* {.importc: "resp_mac".}: array[6, uint8] ## + ## < MAC address of the FTM Responder + channel* {.importc: "channel".}: uint8 ## < Primary channel of the FTM Responder + frm_count* {.importc: "frm_count".}: uint8 ## < No. of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0(No pref), 16, 24, 32, 64) + burst_period* {.importc: "burst_period".}: uint16 ## + ## < Requested period between FTM bursts in 100's of milliseconds (allowed values 0(No pref) - 100) + use_get_report_api* {.importc: "use_get_report_api".}: bool + ## < True - Using esp_wifi_ftm_get_report to get FTM report, False - Using ftm_report_data from + ## WIFI_EVENT_FTM_REPORT to get FTM report -## * -## @brief WiFi antenna mode -## -## + +const + ESP_WIFI_NAN_MAX_SVC_SUPPORTED* = 2 + ESP_WIFI_NAN_DATAPATH_MAX_PEERS* = 2 + ESP_WIFI_NDP_ROLE_INITIATOR* = 1 + ESP_WIFI_NDP_ROLE_RESPONDER* = 2 + ESP_WIFI_MAX_SVC_NAME_LEN* = 256 + ESP_WIFI_MAX_FILTER_LEN* = 256 + ESP_WIFI_MAX_SVC_INFO_LEN* = 64 + ESP_WIFI_MAX_FUP_SSI_LEN* = 2048 + ESP_WIFI_MAX_SVC_SSI_LEN* = 512 + ESP_WIFI_MAX_NEIGHBOR_REP_LEN* = 64 + WIFI_OUI_LEN* = 3 type - wifi_ant_mode_t* {.size: sizeof(cint).} = enum - WIFI_ANT_MODE_ANT0, ## *< Enable WiFi antenna 0 only - WIFI_ANT_MODE_ANT1, ## *< Enable WiFi antenna 1 only - WIFI_ANT_MODE_AUTO, ## *< Enable WiFi antenna 0 and 1, automatically select an antenna - WIFI_ANT_MODE_MAX ## *< Invalid WiFi enabled antenna + wifi_nan_svc_proto_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Protocol types in NAN service specific info attribute + ## + ## + WIFI_SVC_PROTO_RESERVED = 0, ## < Value 0 Reserved + WIFI_SVC_PROTO_BONJOUR = 1, ## < Bonjour Protocol + WIFI_SVC_PROTO_GENERIC = 2, ## < Generic Service Protocol + WIFI_SVC_PROTO_CSA_MATTER = 3, ## < CSA Matter specific protocol + WIFI_SVC_PROTO_MAX ## < Values 4-255 Reserved -## * -## @brief WiFi antenna configuration -## -## type - wifi_ant_config_t* {.importc: "wifi_ant_config_t", header: "esp_wifi_types.h", - bycopy.} = object - rx_ant_mode* {.importc: "rx_ant_mode".}: wifi_ant_mode_t ## *< WiFi antenna mode for receiving - rx_ant_default* {.importc: "rx_ant_default".}: wifi_ant_t ## *< Default antenna mode for receiving, it's ignored if rx_ant_mode is not WIFI_ANT_MODE_AUTO - tx_ant_mode* {.importc: "tx_ant_mode".}: wifi_ant_mode_t ## *< WiFi antenna mode for transmission, it can be set to WIFI_ANT_MODE_AUTO only if rx_ant_mode is set to WIFI_ANT_MODE_AUTO - enabled_ant0* {.importc: "enabled_ant0", bitsize: 4.}: uint8 ## *< Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT0 - enabled_ant1* {.importc: "enabled_ant1", bitsize: 4.}: uint8 ## *< Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT1 + wifi_nan_wfa_ssi_t* {.importc: "wifi_nan_wfa_ssi_t", + header: hdr, bycopy.} = object ## + ## + ## @brief WFA defined Protocol types in NAN service specific info attribute + ## + ## + wfa_oui* {.importc: "wfa_oui".}: array[WIFI_OUI_LEN, uint8] ## + ## < WFA OUI - 0x50, 0x6F, 0x9A + proto* {.importc: "proto".}: wifi_nan_svc_proto_t ## + ## < WFA defined protocol types + payload* {.importc: "payload".}: UncheckedArray[uint8] + ## < Service Info payload + + + wifi_nan_service_type_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief NAN Services types + ## + ## + NAN_PUBLISH_SOLICITED, ## < Send unicast Publish frame to Subscribers that match the requirement + NAN_PUBLISH_UNSOLICITED, ## < Send broadcast Publish frames in every Discovery Window(DW) + NAN_SUBSCRIBE_ACTIVE, ## < Send broadcast Subscribe frames in every DW + NAN_SUBSCRIBE_PASSIVE ## < Passively listens to Publish frames -## * -## @brief WiFi PHY rate encodings -## -## type - wifi_phy_rate_t* {.size: sizeof(cint).} = enum - WIFI_PHY_RATE_1M_L = 0x00000000, ## *< 1 Mbps with long preamble - WIFI_PHY_RATE_2M_L = 0x00000001, ## *< 2 Mbps with long preamble - WIFI_PHY_RATE_5M_L = 0x00000002, ## *< 5.5 Mbps with long preamble - WIFI_PHY_RATE_11M_L = 0x00000003, ## *< 11 Mbps with long preamble - WIFI_PHY_RATE_2M_S = 0x00000005, ## *< 2 Mbps with short preamble - WIFI_PHY_RATE_5M_S = 0x00000006, ## *< 5.5 Mbps with short preamble - WIFI_PHY_RATE_11M_S = 0x00000007, ## *< 11 Mbps with short preamble - WIFI_PHY_RATE_48M = 0x00000008, ## *< 48 Mbps - WIFI_PHY_RATE_24M = 0x00000009, ## *< 24 Mbps - WIFI_PHY_RATE_12M = 0x0000000A, ## *< 12 Mbps - WIFI_PHY_RATE_6M = 0x0000000B, ## *< 6 Mbps - WIFI_PHY_RATE_54M = 0x0000000C, ## *< 54 Mbps - WIFI_PHY_RATE_36M = 0x0000000D, ## *< 36 Mbps - WIFI_PHY_RATE_18M = 0x0000000E, ## *< 18 Mbps - WIFI_PHY_RATE_9M = 0x0000000F, ## *< 9 Mbps - WIFI_PHY_RATE_MCS0_LGI = 0x00000010, ## *< MCS0 with long GI, 6.5 Mbps for 20MHz, 13.5 Mbps for 40MHz - WIFI_PHY_RATE_MCS1_LGI = 0x00000011, ## *< MCS1 with long GI, 13 Mbps for 20MHz, 27 Mbps for 40MHz - WIFI_PHY_RATE_MCS2_LGI = 0x00000012, ## *< MCS2 with long GI, 19.5 Mbps for 20MHz, 40.5 Mbps for 40MHz - WIFI_PHY_RATE_MCS3_LGI = 0x00000013, ## *< MCS3 with long GI, 26 Mbps for 20MHz, 54 Mbps for 40MHz - WIFI_PHY_RATE_MCS4_LGI = 0x00000014, ## *< MCS4 with long GI, 39 Mbps for 20MHz, 81 Mbps for 40MHz - WIFI_PHY_RATE_MCS5_LGI = 0x00000015, ## *< MCS5 with long GI, 52 Mbps for 20MHz, 108 Mbps for 40MHz - WIFI_PHY_RATE_MCS6_LGI = 0x00000016, ## *< MCS6 with long GI, 58.5 Mbps for 20MHz, 121.5 Mbps for 40MHz - WIFI_PHY_RATE_MCS7_LGI = 0x00000017, ## *< MCS7 with long GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz - WIFI_PHY_RATE_MCS0_SGI = 0x00000018, ## *< MCS0 with short GI, 7.2 Mbps for 20MHz, 15 Mbps for 40MHz - WIFI_PHY_RATE_MCS1_SGI = 0x00000019, ## *< MCS1 with short GI, 14.4 Mbps for 20MHz, 30 Mbps for 40MHz - WIFI_PHY_RATE_MCS2_SGI = 0x0000001A, ## *< MCS2 with short GI, 21.7 Mbps for 20MHz, 45 Mbps for 40MHz - WIFI_PHY_RATE_MCS3_SGI = 0x0000001B, ## *< MCS3 with short GI, 28.9 Mbps for 20MHz, 60 Mbps for 40MHz - WIFI_PHY_RATE_MCS4_SGI = 0x0000001C, ## *< MCS4 with short GI, 43.3 Mbps for 20MHz, 90 Mbps for 40MHz - WIFI_PHY_RATE_MCS5_SGI = 0x0000001D, ## *< MCS5 with short GI, 57.8 Mbps for 20MHz, 120 Mbps for 40MHz - WIFI_PHY_RATE_MCS6_SGI = 0x0000001E, ## *< MCS6 with short GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz - WIFI_PHY_RATE_MCS7_SGI = 0x0000001F, ## *< MCS7 with short GI, 72.2 Mbps for 20MHz, 150 Mbps for 40MHz - WIFI_PHY_RATE_LORA_250K = 0x00000029, ## *< 250 Kbps - WIFI_PHY_RATE_LORA_500K = 0x0000002A, ## *< 500 Kbps - WIFI_PHY_RATE_MAX - - -## * WiFi event declarations - -type - wifi_event_t* {.size: sizeof(cint).} = enum - WIFI_EVENT_WIFI_READY = 0, ## *< ESP32 WiFi ready - WIFI_EVENT_SCAN_DONE, ## *< ESP32 finish scanning AP - WIFI_EVENT_STA_START, ## *< ESP32 station start - WIFI_EVENT_STA_STOP, ## *< ESP32 station stop - WIFI_EVENT_STA_CONNECTED, ## *< ESP32 station connected to AP - WIFI_EVENT_STA_DISCONNECTED, ## *< ESP32 station disconnected from AP - WIFI_EVENT_STA_AUTHMODE_CHANGE, ## *< the auth mode of AP connected by ESP32 station changed - WIFI_EVENT_STA_WPS_ER_SUCCESS, ## *< ESP32 station wps succeeds in enrollee mode - WIFI_EVENT_STA_WPS_ER_FAILED, ## *< ESP32 station wps fails in enrollee mode - WIFI_EVENT_STA_WPS_ER_TIMEOUT, ## *< ESP32 station wps timeout in enrollee mode - WIFI_EVENT_STA_WPS_ER_PIN, ## *< ESP32 station wps pin code in enrollee mode - WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, ## *< ESP32 station wps overlap in enrollee mode - WIFI_EVENT_AP_START, ## *< ESP32 soft-AP start - WIFI_EVENT_AP_STOP, ## *< ESP32 soft-AP stop - WIFI_EVENT_AP_STACONNECTED, ## *< a station connected to ESP32 soft-AP - WIFI_EVENT_AP_STADISCONNECTED, ## *< a station disconnected from ESP32 soft-AP - WIFI_EVENT_AP_PROBEREQRECVED ## *< Receive probe request packet in soft-AP interface - - -## * @cond * -## * @brief WiFi event base declaration -# ESP_EVENT_DECLARE_BASE(WIFI_EVENT) -var WIFI_EVENT* {.importc: "WIFI_EVENT", header: "esp_wifi_types.h".}: esp_event_base_t + wifi_nan_publish_cfg_t* {.importc: "wifi_nan_publish_cfg_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Publish service configuration parameters + ## + ## + service_name* {.importc: "service_name".}: array[ESP_WIFI_MAX_SVC_NAME_LEN, + char] ## < Service name identifier + `type`* {.importc: "type".}: wifi_nan_service_type_t ## + ## < Service type + matching_filter* {.importc: "matching_filter".}: array[ + ESP_WIFI_MAX_FILTER_LEN, char] ## < Comma separated filters for filtering services + svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, char] ## + ## < To be deprecated in next major release, use ssi instead + single_replied_event* {.importc: "single_replied_event", bitsize: 1.}: uint8 ## + ## < Give single Replied event or every time + datapath_reqd* {.importc: "datapath_reqd", bitsize: 1.}: uint8 ## + ## < NAN Datapath required for the service + fsd_reqd* {.importc: "fsd_reqd", bitsize: 1.}: uint8 ## + ## < Further Service Discovery(FSD) required + fsd_gas* {.importc: "fsd_gas", bitsize: 1.}: uint8 ## + ## < 0 - Follow-up used for FSD, 1 - GAS used for FSD + reserved* {.importc: "reserved", bitsize: 4.}: uint8 ## + ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info, maximum allowed length - ESP_WIFI_MAX_SVC_SSI_LEN + ssi* {.importc: "ssi".}: ptr uint8 + ## < Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications + + + wifi_nan_subscribe_cfg_t* {.importc: "wifi_nan_subscribe_cfg_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Subscribe service configuration parameters + ## + ## + service_name* {.importc: "service_name".}: array[ESP_WIFI_MAX_SVC_NAME_LEN, + char] ## < Service name identifier + `type`* {.importc: "type".}: wifi_nan_service_type_t ## + ## < Service type + matching_filter* {.importc: "matching_filter".}: array[ + ESP_WIFI_MAX_FILTER_LEN, char] ## < Comma separated filters for filtering services + svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, char] ## + ## < To be deprecated in next major release, use ssi instead + single_match_event* {.importc: "single_match_event", bitsize: 1.}: uint8 ## + ## < Give single Match event(per SSI update) or every time + datapath_reqd* {.importc: "datapath_reqd", bitsize: 1.}: uint8 ## + ## < NAN Datapath required for the service + fsd_reqd* {.importc: "fsd_reqd", bitsize: 1.}: uint8 ## + ## < Further Service Discovery(FSD) required + fsd_gas* {.importc: "fsd_gas", bitsize: 1.}: uint8 ## + ## < 0 - Follow-up used for FSD, 1 - GAS used for FSD + reserved* {.importc: "reserved", bitsize: 4.}: uint8 ## + ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info, maximum allowed length - ESP_WIFI_MAX_SVC_SSI_LEN + ssi* {.importc: "ssi".}: ptr uint8 + ## < Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications + + + wifi_nan_followup_params_t* {.importc: "wifi_nan_followup_params_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Follow-up parameters + ## + ## + inst_id* {.importc: "inst_id".}: uint8 ## < Own service instance id + peer_inst_id* {.importc: "peer_inst_id".}: uint8 ## + ## < Peer's service instance id + peer_mac* {.importc: "peer_mac".}: array[6, uint8] ## + ## < Peer's MAC address + svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, char] ## + ## < To be deprecated in next major release, use ssi instead + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info, maximum allowed length - ESP_WIFI_MAX_FUP_SSI_LEN + ssi* {.importc: "ssi".}: ptr uint8 + ## < Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications + + + wifi_nan_datapath_req_t* {.importc: "wifi_nan_datapath_req_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Datapath Request parameters + ## + ## + pub_id* {.importc: "pub_id".}: uint8 ## < Publisher's service instance id + peer_mac* {.importc: "peer_mac".}: array[6, uint8] ## + ## < Peer's MAC address + confirm_required* {.importc: "confirm_required".}: bool + ## < NDP Confirm frame required + + + wifi_nan_datapath_resp_t* {.importc: "wifi_nan_datapath_resp_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Datapath Response parameters + ## + ## + accept* {.importc: "accept".}: bool ## < True - Accept incoming NDP, False - Reject it + ndp_id* {.importc: "ndp_id".}: uint8 ## < NAN Datapath Identifier + peer_mac* {.importc: "peer_mac".}: array[6, uint8] + ## < Peer's MAC address + + + wifi_nan_datapath_end_req_t* {.importc: "wifi_nan_datapath_end_req_t", + header: hdr, bycopy.} = object ## + ## + ## @brief NAN Datapath End parameters + ## + ## + ndp_id* {.importc: "ndp_id".}: uint8 ## < NAN Datapath Identifier + peer_mac* {.importc: "peer_mac".}: array[6, uint8] + ## < Peer's MAC address + + + wifi_phy_rate_t* {.importc: "wifi_phy_rate_t", header: hdr.} = cint ##\ + ## @brief Wi-Fi PHY rate encodings + ## + ## @note Rate Table: MCS Rate and Guard Interval Information + ## | MCS RATE | HT20 | HT40 | HE20 | VHT20 | + ## + ## |-----------------------------|-------------------------|-------------------------|-------------------------|-------------------------| + ## | WIFI_PHY_RATE_MCS0_LGI | 6.5 Mbps (800 ns) | 13.5 Mbps (800 ns) | 8.1 Mbps (1600 ns) | 6.5 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS1_LGI | 13 Mbps (800 ns) | 27 Mbps (800 ns) | 16.3 Mbps (1600 ns) | 13 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS2_LGI | 19.5 Mbps (800 ns) | 40.5 Mbps (800 ns) | 24.4 Mbps (1600 ns) | 19.5 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS3_LGI | 26 Mbps (800 ns) | 54 Mbps (800 ns) | 32.5 Mbps (1600 ns) | 26 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS4_LGI | 39 Mbps (800 ns) | 81 Mbps (800 ns) | 48.8 Mbps (1600 ns) | 39 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS5_LGI | 52 Mbps (800 ns) | 108 Mbps (800 ns) | 65 Mbps (1600 ns) | 52 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS6_LGI | 58.5 Mbps (800 ns) | 121.5 Mbps (800 ns) | 73.1 Mbps (1600 ns) | 58.5 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS7_LGI | 65 Mbps (800 ns) | 135 Mbps (800 ns) | 81.3 Mbps (1600 ns) | 65 Mbps (800 ns) | + ## | WIFI_PHY_RATE_MCS8_LGI | | | 97.5 Mbps (1600 ns) | | + ## | WIFI_PHY_RATE_MCS9_LGI | | | 108.3 Mbps (1600 ns) | | + ## + ## @note + ## | MCS RATE | HT20 | HT40 | HE20 | VHT20 | + ## + ## |-----------------------------|-------------------------|-------------------------|-------------------------|-------------------------| + ## | WIFI_PHY_RATE_MCS0_SGI | 7.2 Mbps (400 ns) | 15 Mbps (400 ns) | 8.6 Mbps (800 ns) | 7.2 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS1_SGI | 14.4 Mbps (400 ns) | 30 Mbps (400 ns) | 17.2 Mbps (800 ns) | 14.4 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS2_SGI | 21.7 Mbps (400 ns) | 45 Mbps (400 ns) | 25.8 Mbps (800 ns) | 21.7 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS3_SGI | 28.9 Mbps (400 ns) | 60 Mbps (400 ns) | 34.4 Mbps (800 ns) | 28.9 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS4_SGI | 43.3 Mbps (400 ns) | 90 Mbps (400 ns) | 51.6 Mbps (800 ns) | 43.3 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS5_SGI | 57.8 Mbps (400 ns) | 120 Mbps (400 ns) | 68.8 Mbps (800 ns) | 57.8 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS6_SGI | 65 Mbps (400 ns) | 135 Mbps (400 ns) | 77.4 Mbps (800 ns) | 65 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS7_SGI | 72.2 Mbps (400 ns) | 150 Mbps (400 ns) | 86 Mbps (800 ns) | 72.2 Mbps (400 ns) | + ## | WIFI_PHY_RATE_MCS8_SGI | | | 103.2 Mbps (800 ns) | | + ## | WIFI_PHY_RATE_MCS9_SGI | | | 114.7 Mbps (800 ns) | | + ## + ## + +let + WIFI_PHY_RATE_1M_L {.importc: "WIFI_PHY_RATE_1M_L", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_2M_L {.importc: "WIFI_PHY_RATE_2M_L", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_5M_L {.importc: "WIFI_PHY_RATE_5M_L", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_11M_L {.importc: "WIFI_PHY_RATE_11M_L", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_2M_S {.importc: "WIFI_PHY_RATE_2M_S", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_5M_S {.importc: "WIFI_PHY_RATE_5M_S", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_11M_S {.importc: "WIFI_PHY_RATE_11M_S", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_48M {.importc: "WIFI_PHY_RATE_48M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_24M {.importc: "WIFI_PHY_RATE_24M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_12M {.importc: "WIFI_PHY_RATE_12M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_6M {.importc: "WIFI_PHY_RATE_6M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_54M {.importc: "WIFI_PHY_RATE_54M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_36M {.importc: "WIFI_PHY_RATE_36M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_18M {.importc: "WIFI_PHY_RATE_18M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_9M {.importc: "WIFI_PHY_RATE_9M", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS0_LGI {.importc: "WIFI_PHY_RATE_MCS0_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS1_LGI {.importc: "WIFI_PHY_RATE_MCS1_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS2_LGI {.importc: "WIFI_PHY_RATE_MCS2_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS3_LGI {.importc: "WIFI_PHY_RATE_MCS3_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS4_LGI {.importc: "WIFI_PHY_RATE_MCS4_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS5_LGI {.importc: "WIFI_PHY_RATE_MCS5_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS6_LGI {.importc: "WIFI_PHY_RATE_MCS6_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS7_LGI {.importc: "WIFI_PHY_RATE_MCS7_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS8_LGI {.importc: "WIFI_PHY_RATE_MCS8_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS9_LGI {.importc: "WIFI_PHY_RATE_MCS9_LGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS0_SGI {.importc: "WIFI_PHY_RATE_MCS0_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS1_SGI {.importc: "WIFI_PHY_RATE_MCS1_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS2_SGI {.importc: "WIFI_PHY_RATE_MCS2_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS3_SGI {.importc: "WIFI_PHY_RATE_MCS3_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS4_SGI {.importc: "WIFI_PHY_RATE_MCS4_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS5_SGI {.importc: "WIFI_PHY_RATE_MCS5_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS6_SGI {.importc: "WIFI_PHY_RATE_MCS6_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS7_SGI {.importc: "WIFI_PHY_RATE_MCS7_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS8_SGI {.importc: "WIFI_PHY_RATE_MCS8_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MCS9_SGI {.importc: "WIFI_PHY_RATE_MCS9_SGI", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_LORA_250K {.importc: "WIFI_PHY_RATE_LORA_250K", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_LORA_500K {.importc: "WIFI_PHY_RATE_LORA_500K", header: hdr.}: wifi_phy_rate_t + WIFI_PHY_RATE_MAX {.importc: "WIFI_PHY_RATE_MAX", header: hdr.}: wifi_phy_rate_t -## * @endcond * -## * Argument structure for WIFI_EVENT_SCAN_DONE event type - wifi_event_sta_scan_done_t* {.importc: "wifi_event_sta_scan_done_t", - header: "esp_wifi_types.h", bycopy.} = object - status* {.importc: "status".}: uint32 ## *< status of scanning APs: 0 — success, 1 - failure - number* {.importc: "number".}: uint8 ## *< number of scan results - scan_id* {.importc: "scan_id".}: uint8 ## *< scan sequence number, used for block scan + wifi_event_t* {.size: sizeof(cint).} = enum ## + ## @brief Wi-Fi event declarations + ## + WIFI_EVENT_WIFI_READY = 0, ## < Wi-Fi ready + WIFI_EVENT_SCAN_DONE, ## < Finished scanning AP + WIFI_EVENT_STA_START, ## < Station start + WIFI_EVENT_STA_STOP, ## < Station stop + WIFI_EVENT_STA_CONNECTED, ## < Station connected to AP + WIFI_EVENT_STA_DISCONNECTED, ## < Station disconnected from AP + WIFI_EVENT_STA_AUTHMODE_CHANGE, ## < The auth mode of AP connected by device's station changed + WIFI_EVENT_STA_WPS_ER_SUCCESS, ## < Station WPS succeeds in enrollee mode + WIFI_EVENT_STA_WPS_ER_FAILED, ## < Station WPS fails in enrollee mode + WIFI_EVENT_STA_WPS_ER_TIMEOUT, ## < Station WPS timeout in enrollee mode + WIFI_EVENT_STA_WPS_ER_PIN, ## < Station WPS pin code in enrollee mode + WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, ## < Station WPS overlap in enrollee mode + WIFI_EVENT_AP_START, ## < Soft-AP start + WIFI_EVENT_AP_STOP, ## < Soft-AP stop + WIFI_EVENT_AP_STACONNECTED, ## < A station connected to Soft-AP + WIFI_EVENT_AP_STADISCONNECTED, ## < A station disconnected from Soft-AP + WIFI_EVENT_AP_PROBEREQRECVED, ## < Receive probe request packet in soft-AP interface + WIFI_EVENT_FTM_REPORT, ## < Receive report of FTM procedure + ## Add next events after this only + WIFI_EVENT_STA_BSS_RSSI_LOW, ## < AP's RSSI crossed configured threshold + WIFI_EVENT_ACTION_TX_STATUS, ## < Status indication of Action Tx operation + WIFI_EVENT_ROC_DONE, ## < Remain-on-Channel operation complete + WIFI_EVENT_STA_BEACON_TIMEOUT, ## < Station beacon timeout + WIFI_EVENT_CONNECTIONLESS_MODULE_WAKE_INTERVAL_START, ## + ## < Connectionless module wake interval start + ## Add next events after this only + WIFI_EVENT_AP_WPS_RG_SUCCESS, ## < Soft-AP wps succeeds in registrar mode + WIFI_EVENT_AP_WPS_RG_FAILED, ## < Soft-AP wps fails in registrar mode + WIFI_EVENT_AP_WPS_RG_TIMEOUT, ## < Soft-AP wps timeout in registrar mode + WIFI_EVENT_AP_WPS_RG_PIN, ## < Soft-AP wps pin code in registrar mode + WIFI_EVENT_AP_WPS_RG_PBC_OVERLAP, ## < Soft-AP wps overlap in registrar mode + WIFI_EVENT_ITWT_SETUP, ## < iTWT setup + WIFI_EVENT_ITWT_TEARDOWN, ## < iTWT teardown + WIFI_EVENT_ITWT_PROBE, ## < iTWT probe + WIFI_EVENT_ITWT_SUSPEND, ## < iTWT suspend + WIFI_EVENT_TWT_WAKEUP, ## < TWT wakeup + WIFI_EVENT_BTWT_SETUP, ## < bTWT setup + WIFI_EVENT_BTWT_TEARDOWN, ## < bTWT teardown + WIFI_EVENT_NAN_STARTED, ## < NAN Discovery has started + WIFI_EVENT_NAN_STOPPED, ## < NAN Discovery has stopped + WIFI_EVENT_NAN_SVC_MATCH, ## < NAN Service Discovery match found + WIFI_EVENT_NAN_REPLIED, ## < Replied to a NAN peer with Service Discovery match + WIFI_EVENT_NAN_RECEIVE, ## < Received a Follow-up message + WIFI_EVENT_NDP_INDICATION, ## < Received NDP Request from a NAN Peer + WIFI_EVENT_NDP_CONFIRM, ## < NDP Confirm Indication + WIFI_EVENT_NDP_TERMINATED, ## < NAN Datapath terminated indication + WIFI_EVENT_HOME_CHANNEL_CHANGE, ## < Wi-Fi home channel change,doesn't occur when scanning + WIFI_EVENT_STA_NEIGHBOR_REP, ## < Received Neighbor Report response + WIFI_EVENT_AP_WRONG_PASSWORD, ## < a station tried to connect with wrong password + WIFI_EVENT_STA_BEACON_OFFSET_UNSTABLE, ## < Station sampled beacon offset unstable + WIFI_EVENT_DPP_URI_READY, ## < DPP URI is ready through Bootstrapping + WIFI_EVENT_DPP_CFG_RECVD, ## < Config received via DPP Authentication + WIFI_EVENT_DPP_FAILED, ## < DPP failed + WIFI_EVENT_MAX ## < Invalid Wi-Fi event ID + + +## @cond * +## @brief Wi-Fi event base declaration -## * Argument structure for WIFI_EVENT_STA_CONNECTED event +# ESP_EVENT_DECLARE_BASE(WIFI_EVENT) +let WIFI_EVENT* {.importc: "WIFI_EVENT", header: "esp_wifi_types.h".}: esp_event_base_t type + + wifi_event_sta_scan_done_t* {.importc: "wifi_event_sta_scan_done_t", + header: hdr, bycopy.} = object ## + ## @endcond * + ## + ## @brief Argument structure for WIFI_EVENT_SCAN_DONE event + ## + status* {.importc: "status".}: uint32 ## < Status of scanning APs: 0 — success, 1 - failure + number* {.importc: "number".}: uint8 ## < Number of scan results + scan_id* {.importc: "scan_id".}: uint8 + ## < Scan sequence number, used for block scan + + wifi_event_sta_connected_t* {.importc: "wifi_event_sta_connected_t", - header: "esp_wifi_types.h", bycopy.} = object - ssid* {.importc: "ssid".}: array[32, uint8] ## *< SSID of connected AP - ssid_len* {.importc: "ssid_len".}: uint8 ## *< SSID length of connected AP - bssid* {.importc: "bssid".}: array[6, uint8] ## *< BSSID of connected AP - channel* {.importc: "channel".}: uint8 ## *< channel of connected AP - authmode* {.importc: "authmode".}: wifi_auth_mode_t ## *< authentication mode used by AP + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_CONNECTED event + ## + ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of connected AP + ssid_len* {.importc: "ssid_len".}: uint8 ## < SSID length of connected AP + bssid* {.importc: "bssid".}: array[6, uint8] ## < BSSID of connected AP + channel* {.importc: "channel".}: uint8 ## < Channel of connected AP + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## + ## < Authentication mode used by the connection + aid* {.importc: "aid".}: uint16 + ## < Authentication id assigned by the connected AP -## * Argument structure for WIFI_EVENT_STA_DISCONNECTED event + wifi_event_sta_disconnected_t* {.importc: "wifi_event_sta_disconnected_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_DISCONNECTED event + ## + ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of disconnected AP + ssid_len* {.importc: "ssid_len".}: uint8 ## < SSID length of disconnected AP + bssid* {.importc: "bssid".}: array[6, uint8] ## < BSSID of disconnected AP + reason* {.importc: "reason".}: uint8 ## < Disconnection reason + rssi* {.importc: "rssi".}: int8 + ## < Disconnection RSSI + + + wifi_event_sta_authmode_change_t* {.importc: "wifi_event_sta_authmode_change_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_AUTHMODE_CHANGE event + ## + old_mode* {.importc: "old_mode".}: wifi_auth_mode_t ## + ## < Old auth mode of AP + new_mode* {.importc: "new_mode".}: wifi_auth_mode_t + ## < New auth mode of AP + + + wifi_event_sta_wps_er_pin_t* {.importc: "wifi_event_sta_wps_er_pin_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_WPS_ER_PIN event + ## + pin_code* {.importc: "pin_code".}: array[8, uint8] + ## < PIN code of station in enrollee mode + + + wifi_event_sta_wps_fail_reason_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_WPS_ER_FAILED event + ## + WPS_FAIL_REASON_NORMAL = 0, ## < WPS normal fail reason + WPS_FAIL_REASON_RECV_M2D, ## < WPS receive M2D frame + WPS_FAIL_REASON_RECV_DEAUTH, ## < Recv deauth from AP while wps handshake + WPS_FAIL_REASON_MAX ## < Max WPS fail reason + +const + MAX_SSID_LEN* = 32 + MAX_PASSPHRASE_LEN* = 64 + MAX_WPS_AP_CRED* = 3 type - wifi_event_sta_disconnected_t* {.importc: "wifi_event_sta_disconnected_t", - header: "esp_wifi_types.h", bycopy.} = object - ssid* {.importc: "ssid".}: array[32, uint8] ## *< SSID of disconnected AP - ssid_len* {.importc: "ssid_len".}: uint8 ## *< SSID length of disconnected AP - bssid* {.importc: "bssid".}: array[6, uint8] ## *< BSSID of disconnected AP - reason* {.importc: "reason".}: uint8 ## *< reason of disconnection + + INNER_C_STRUCT_esp_wifi_types_generic_1* {. + importc: "wifi_event_sta_wps_er_success_t::no_name", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_WPS_ER_SUCCESS event + ## + ssid* {.importc: "ssid".}: array[MAX_SSID_LEN, uint8] ## + ## < SSID of AP + passphrase* {.importc: "passphrase".}: array[MAX_PASSPHRASE_LEN, uint8] + ## < Passphrase for the AP -## * Argument structure for WIFI_EVENT_STA_AUTHMODE_CHANGE event + wifi_event_sta_wps_er_success_t* {.importc: "wifi_event_sta_wps_er_success_t", + header: hdr, bycopy.} = object + ap_cred_cnt* {.importc: "ap_cred_cnt".}: uint8 ## + ## < Number of AP credentials received + ap_cred* {.importc: "ap_cred".}: array[MAX_WPS_AP_CRED, + INNER_C_STRUCT_esp_wifi_types_generic_1] + ## < All AP credentials received from WPS handshake + + + wifi_event_ap_staconnected_t* {.importc: "wifi_event_ap_staconnected_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_STACONNECTED event + ## + mac* {.importc: "mac".}: array[6, uint8] ## < MAC address of the station connected to Soft-AP + aid* {.importc: "aid".}: uint8 ## < AID assigned by the Soft-AP to the connected station + is_mesh_child* {.importc: "is_mesh_child".}: bool + ## < Flag indicating whether the connected station is a mesh child + + + wifi_event_ap_stadisconnected_t* {.importc: "wifi_event_ap_stadisconnected_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_STADISCONNECTED event + ## + mac* {.importc: "mac".}: array[6, uint8] ## < MAC address of the station disconnects from the soft-AP + aid* {.importc: "aid".}: uint8 ## < AID that the Soft-AP assigned to the disconnected station + is_mesh_child* {.importc: "is_mesh_child".}: bool ## + ## < Flag indicating whether the disconnected station is a mesh child + reason* {.importc: "reason".}: uint16 + ## < Disconnection reason + + + wifi_event_ap_probe_req_rx_t* {.importc: "wifi_event_ap_probe_req_rx_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_PROBEREQRECVED event + ## + rssi* {.importc: "rssi".}: cint ## < Received probe request signal strength + mac* {.importc: "mac".}: array[6, uint8] + ## < MAC address of the station which send probe request + + + wifi_event_bss_rssi_low_t* {.importc: "wifi_event_bss_rssi_low_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_BSS_RSSI_LOW event + ## + rssi* {.importc: "rssi".}: int32 + ## < RSSI value of bss + + + wifi_event_home_channel_change_t* {.importc: "wifi_event_home_channel_change_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_HOME_CHANNEL_CHANGE event + ## + old_chan* {.importc: "old_chan".}: uint8 ## < Old home channel of the device + old_snd* {.importc: "old_snd".}: wifi_second_chan_t ## + ## < Old second channel of the device + new_chan* {.importc: "new_chan".}: uint8 ## < New home channel of the device + new_snd* {.importc: "new_snd".}: wifi_second_chan_t + ## < New second channel of the device + + + wifi_ftm_status_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief FTM operation status types + ## + ## + FTM_STATUS_SUCCESS = 0, ## < FTM exchange is successful + FTM_STATUS_UNSUPPORTED, ## < Peer does not support FTM + FTM_STATUS_CONF_REJECTED, ## < Peer rejected FTM configuration in FTM Request + FTM_STATUS_NO_RESPONSE, ## < Peer did not respond to FTM Requests + FTM_STATUS_FAIL, ## < Unknown error during FTM exchange + FTM_STATUS_NO_VALID_MSMT, ## < FTM session did not result in any valid measurements + FTM_STATUS_USER_TERM ## < User triggered termination + type - wifi_event_sta_authmode_change_t* {.importc: "wifi_event_sta_authmode_change_t", - header: "esp_wifi_types.h", bycopy.} = object - old_mode* {.importc: "old_mode".}: wifi_auth_mode_t ## *< the old auth mode of AP - new_mode* {.importc: "new_mode".}: wifi_auth_mode_t ## *< the new auth mode of AP + + wifi_ftm_report_entry_t* {.importc: "wifi_ftm_report_entry_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Structure representing a report entry for Fine Timing Measurement (FTM) in Wi-Fi. + ## + ## This structure holds the information related to the FTM process between a Wi-Fi FTM Initiator + ## and a Wi-Fi FTM Responder. FTM is used for precise distance measurement by timing the exchange + ## of frames between devices. + ## + dlog_token* {.importc: "dlog_token".}: uint8 ## < Dialog Token of the FTM frame + rssi* {.importc: "rssi".}: int8 ## < RSSI of the FTM frame received + rtt* {.importc: "rtt".}: uint32 ## < Round Trip Time in pSec with a peer + t1* {.importc: "t1".}: uint64 ## < Time of departure of FTM frame from FTM Responder in pSec + t2* {.importc: "t2".}: uint64 ## < Time of arrival of FTM frame at FTM Initiator in pSec + t3* {.importc: "t3".}: uint64 ## < Time of departure of ACK from FTM Initiator in pSec + t4* {.importc: "t4".}: uint64 + ## < Time of arrival of ACK at FTM Responder in pSec + + + wifi_event_ftm_report_t* {.importc: "wifi_event_ftm_report_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_FTM_REPORT event + ## + peer_mac* {.importc: "peer_mac".}: array[6, uint8] ## + ## < MAC address of the FTM Peer + status* {.importc: "status".}: wifi_ftm_status_t ## + ## < Status of the FTM operation + rtt_raw* {.importc: "rtt_raw".}: uint32 ## < Raw average Round-Trip-Time with peer in Nano-Seconds + rtt_est* {.importc: "rtt_est".}: uint32 ## < Estimated Round-Trip-Time with peer in Nano-Seconds + dist_est* {.importc: "dist_est".}: uint32 ## < Estimated one-way distance in Centi-Meters + ftm_report_data* {.importc: "ftm_report_data".}: ptr wifi_ftm_report_entry_t ## + ## < Pointer to FTM Report, should be freed after use. Note: Highly recommended + ## to use API esp_wifi_ftm_get_report to get the report instead of using this + ftm_report_num_entries* {.importc: "ftm_report_num_entries".}: uint8 + ## < Number of entries in the FTM Report data -## * Argument structure for WIFI_EVENT_STA_WPS_ER_PIN event +const + WIFI_STATIS_BUFFER* = (1 shl 0) ## < Buffer status + WIFI_STATIS_RXTX* = (1 shl 1) ## < RX/TX status + WIFI_STATIS_HW* = (1 shl 2) ## < Hardware status + WIFI_STATIS_DIAG* = (1 shl 3) ## < Diagnostic status + WIFI_STATIS_PS* = (1 shl 4) ## < Power save status + WIFI_STATIS_ALL* = (-1) ## < All status type - wifi_event_sta_wps_er_pin_t* {.importc: "wifi_event_sta_wps_er_pin_t", - header: "esp_wifi_types.h", bycopy.} = object - pin_code* {.importc: "pin_code".}: array[8, uint8] ## *< PIN code of station in enrollee mode + wifi_action_tx_status_type_t* {.size: sizeof(cint).} = enum ## + ## Status codes for WIFI_EVENT_ACTION_TX_STATUS evt + ## There will be back to back events in success case TX_DONE and TX_DURATION_COMPLETED + WIFI_ACTION_TX_DONE = 0, ## < ACTION_TX operation was completed successfully + WIFI_ACTION_TX_FAILED, ## < ACTION_TX operation failed during tx + WIFI_ACTION_TX_DURATION_COMPLETED, ## < ACTION_TX operation completed it's wait duration + WIFI_ACTION_TX_OP_CANCELLED ## < ACTION_TX operation was cancelled by application or higher priority operation -## * Argument structure for WIFI_EVENT_STA_WPS_ER_FAILED event type - wifi_event_sta_wps_fail_reason_t* {.size: sizeof(cint).} = enum - WPS_FAIL_REASON_NORMAL = 0, ## *< ESP32 WPS normal fail reason - WPS_FAIL_REASON_RECV_M2D, ## *< ESP32 WPS receive M2D frame - WPS_FAIL_REASON_MAX + wifi_event_action_tx_status_t* {.importc: "wifi_event_action_tx_status_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_ACTION_TX_STATUS event + ifx* {.importc: "ifx".}: wifi_interface_t ## < WiFi interface to send request to + context* {.importc: "context".}: uint32 ## < Context to identify the request + status* {.importc: "status".}: wifi_action_tx_status_type_t ## + ## < Status of the operation + op_id* {.importc: "op_id".}: uint8 ## < ID of the corresponding operation that was provided during action tx request + channel* {.importc: "channel".}: uint8 + ## < Channel provided in tx request + + + wifi_event_roc_done_t* {.importc: "wifi_event_roc_done_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_ROC_DONE event + ## + context* {.importc: "context".}: uint32 ## < Context to identify the initiator of the request + status* {.importc: "status".}: wifi_roc_done_status_t ## + ## < ROC status + op_id* {.importc: "op_id".}: uint8 ## < ID of the corresponding ROC operation + channel* {.importc: "channel".}: uint8 + ## < Channel provided in tx request + + + wifi_event_ap_wps_rg_pin_t* {.importc: "wifi_event_ap_wps_rg_pin_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_WPS_RG_PIN event + ## + pin_code* {.importc: "pin_code".}: array[8, uint8] + ## < PIN code of station in enrollee mode + + + wps_fail_reason_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief WPS fail reason + ## + WPS_AP_FAIL_REASON_NORMAL = 0, ## < WPS normal fail reason + WPS_AP_FAIL_REASON_CONFIG, ## < WPS failed due to incorrect config + WPS_AP_FAIL_REASON_AUTH, ## < WPS failed during auth + WPS_AP_FAIL_REASON_MAX ## < Max WPS fail reason -## * Argument structure for WIFI_EVENT_AP_STACONNECTED event type - wifi_event_ap_staconnected_t* {.importc: "wifi_event_ap_staconnected_t", - header: "esp_wifi_types.h", bycopy.} = object - mac* {.importc: "mac".}: array[6, uint8] ## *< MAC address of the station connected to ESP32 soft-AP - aid* {.importc: "aid".}: uint8 ## *< the aid that ESP32 soft-AP gives to the station connected to + wifi_event_ap_wps_rg_fail_reason_t* {.importc: "wifi_event_ap_wps_rg_fail_reason_t", + header: hdr, + bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_WPS_RG_FAILED event + ## + reason* {.importc: "reason".}: wps_fail_reason_t ## + ## < WPS failure reason wps_fail_reason_t + peer_macaddr* {.importc: "peer_macaddr".}: array[6, uint8] + ## < Enrollee mac address + + + wifi_event_ap_wps_rg_success_t* {.importc: "wifi_event_ap_wps_rg_success_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_AP_WPS_RG_SUCCESS event + ## + peer_macaddr* {.importc: "peer_macaddr".}: array[6, uint8] + ## < Enrollee mac address + + + wifi_event_nan_svc_match_t* {.importc: "wifi_event_nan_svc_match_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NAN_SVC_MATCH event + ## + subscribe_id* {.importc: "subscribe_id".}: uint8 ## + ## < Subscribe Service Identifier + publish_id* {.importc: "publish_id".}: uint8 ## < Publish Service Identifier + pub_if_mac* {.importc: "pub_if_mac".}: array[6, uint8] ## + ## < NAN Interface MAC of the Publisher + update_pub_id* {.importc: "update_pub_id".}: bool ## + ## < Indicates whether publisher's service ID needs to be updated + datapath_reqd* {.importc: "datapath_reqd", bitsize: 1.}: uint8 ## + ## < NAN Datapath required for the service + fsd_reqd* {.importc: "fsd_reqd", bitsize: 1.}: uint8 ## + ## < Further Service Discovery(FSD) required + fsd_gas* {.importc: "fsd_gas", bitsize: 1.}: uint8 ## + ## < 0 - Follow-up used for FSD, 1 - GAS used for FSD + reserved* {.importc: "reserved", bitsize: 5.}: uint8 ## + ## < Reserved + reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved + reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved + ssi_version* {.importc: "ssi_version".}: uint8 ## + ## < Indicates version of SSI in Publish instance, 0 if not available + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info + ssi* {.importc: "ssi".}: UncheckedArray[uint8] + ## < Service specific info of Publisher + + + wifi_event_nan_replied_t* {.importc: "wifi_event_nan_replied_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NAN_REPLIED event + ## + publish_id* {.importc: "publish_id".}: uint8 ## < Publish Service Identifier + subscribe_id* {.importc: "subscribe_id".}: uint8 ## + ## < Subscribe Service Identifier + sub_if_mac* {.importc: "sub_if_mac".}: array[6, uint8] ## + ## < NAN Interface MAC of the Subscriber + reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved + reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info + ssi* {.importc: "ssi".}: UncheckedArray[uint8] + ## < Service specific info of Subscriber + + + wifi_event_nan_receive_t* {.importc: "wifi_event_nan_receive_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NAN_RECEIVE event + ## + inst_id* {.importc: "inst_id".}: uint8 ## < Our Service Identifier + peer_inst_id* {.importc: "peer_inst_id".}: uint8 ## + ## < Peer's Service Identifier + peer_if_mac* {.importc: "peer_if_mac".}: array[6, uint8] ## + ## < Peer's NAN Interface MAC + peer_svc_info* {.importc: "peer_svc_info".}: array[ + ESP_WIFI_MAX_SVC_INFO_LEN, uint8] ## < To be deprecated in next major release, use ssi instead + reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved + reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info + ssi* {.importc: "ssi".}: UncheckedArray[uint8] + ## < Service specific info from Follow-up + + + wifi_event_ndp_indication_t* {.importc: "wifi_event_ndp_indication_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NDP_INDICATION event + ## + publish_id* {.importc: "publish_id".}: uint8 ## < Publish Id for NAN Service + ndp_id* {.importc: "ndp_id".}: uint8 ## < NDP instance id + peer_nmi* {.importc: "peer_nmi".}: array[6, uint8] ## + ## < Peer's NAN Management Interface MAC + peer_ndi* {.importc: "peer_ndi".}: array[6, uint8] ## + ## < Peer's NAN Data Interface MAC + svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, uint8] ## + ## < To be deprecated in next major release, use ssi instead + reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved + reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info + ssi* {.importc: "ssi".}: UncheckedArray[uint8] + ## < Service specific info from NDP/NDPE Attribute + + + wifi_event_ndp_confirm_t* {.importc: "wifi_event_ndp_confirm_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NDP_CONFIRM event + ## + status* {.importc: "status".}: uint8 ## < NDP status code + ndp_id* {.importc: "ndp_id".}: uint8 ## < NDP instance id + peer_nmi* {.importc: "peer_nmi".}: array[6, uint8] ## + ## < Peer's NAN Management Interface MAC + peer_ndi* {.importc: "peer_ndi".}: array[6, uint8] ## + ## < Peer's NAN Data Interface MAC + own_ndi* {.importc: "own_ndi".}: array[6, uint8] ## + ## < Own NAN Data Interface MAC + svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, uint8] ## + ## < To be deprecated in next major release, use ssi instead + reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved + reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved + ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of Service Specific Info + ssi* {.importc: "ssi".}: UncheckedArray[uint8] + ## < Service specific info from NDP/NDPE Attribute + + + wifi_event_ndp_terminated_t* {.importc: "wifi_event_ndp_terminated_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_NDP_TERMINATED event + ## + reason* {.importc: "reason".}: uint8 ## < Termination reason code + ndp_id* {.importc: "ndp_id".}: uint8 ## < NDP instance id + init_ndi* {.importc: "init_ndi".}: array[6, uint8] + ## < Initiator's NAN Data Interface MAC + + + wifi_event_neighbor_report_t* {.importc: "wifi_event_neighbor_report_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for WIFI_EVENT_STA_NEIGHBOR_REP event + ## + report* {.importc: "report".}: array[ESP_WIFI_MAX_NEIGHBOR_REP_LEN, uint8] ## + ## < Neighbor Report received from the AP (will be deprecated in next major release, use n_report instead) + report_len* {.importc: "report_len".}: uint16 ## < Length of the report + n_report* {.importc: "n_report".}: UncheckedArray[uint8] + ## < Neighbor Report received from the AP + + + wifi_event_ap_wrong_password_t* {.importc: "wifi_event_ap_wrong_password_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_AP_WRONG_PASSWORD event + mac* {.importc: "mac".}: array[6, uint8] + ## < MAC address of the station trying to connect to Soft-AP + + + wifi_tx_rate_config_t* {.importc: "wifi_tx_rate_config_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Argument structure for wifi_tx_rate_config + ## + phymode* {.importc: "phymode".}: wifi_phy_mode_t ## + ## < Phymode of specified interface + rate* {.importc: "rate".}: wifi_phy_rate_t ## < Rate of specified interface + ersu* {.importc: "ersu".}: bool ## < Using ERSU to send frame, ERSU is a transmission mode related to 802.11 ax. + ## ERSU is always used in long distance transmission, and its frame has lower rate compared with SU mode + dcm* {.importc: "dcm".}: bool + ## < Using dcm rate to send frame -## * Argument structure for WIFI_EVENT_AP_STADISCONNECTED event +const + WIFI_MAX_SUPPORT_COUNTRY_NUM* = 176 + +when defined(CONFIG_SOC_WIFI_SUPPORT_5G): + const + WIFI_MAX_REGULATORY_RULE_NUM* = 7 +else: + const + WIFI_MAX_REGULATORY_RULE_NUM* = 2 type - wifi_event_ap_stadisconnected_t* {.importc: "wifi_event_ap_stadisconnected_t", - header: "esp_wifi_types.h", bycopy.} = object - mac* {.importc: "mac".}: array[6, uint8] ## *< MAC address of the station disconnects to ESP32 soft-AP - aid* {.importc: "aid".}: uint8 ## *< the aid that ESP32 soft-AP gave to the station disconnects to + wifi_reg_rule_t* {.importc: "wifi_reg_rule_t", + header: hdr, bycopy.} = object ## + ## Argument structure for regulatory rule + start_channel* {.importc: "start_channel".}: uint8 ## + ## < start channel of regulatory rule + end_channel* {.importc: "end_channel".}: uint8 ## + ## < end channel of regulatory rule + max_bandwidth* {.importc: "max_bandwidth", bitsize: 3.}: uint16 ## + ## < max bandwidth(MHz) of regulatory rule, 1:20M, 2:40M, 3:80M, 4:160M + max_eirp* {.importc: "max_eirp", bitsize: 6.}: uint16 ## + ## < indicates the maximum Equivalent Isotropically Radiated Power (EIRP), typically measured in dBm + is_dfs* {.importc: "is_dfs", bitsize: 1.}: uint16 ## + ## < flag to identify dfs channel + reserved* {.importc: "reserved", bitsize: 6.}: uint16 + ## < reserved + + + wifi_regulatory_t* {.importc: "wifi_regulatory_t", + header: hdr, bycopy.} = object ## + ## Argument structure for regdomain + n_reg_rules* {.importc: "n_reg_rules".}: uint8 ## + ## < number of regulatory rules + reg_rules* {.importc: "reg_rules".}: array[WIFI_MAX_REGULATORY_RULE_NUM, + wifi_reg_rule_t] + ## < array of regulatory rules + + + wifi_regdomain_t* {.importc: "wifi_regdomain_t", + header: hdr, bycopy.} = object ## + ## Argument structure for regdomain + cn* {.importc: "cn".}: array[2, char] ## < country code string + regulatory_type* {.importc: "regulatory_type".}: uint8 + ## < regulatory type of country + + + wifi_tx_status_t* {.size: sizeof(cint).} = enum ## + ## + ## @brief Status of wifi sending data + ## + WIFI_SEND_SUCCESS = 0, ## < Sending Wi-Fi data successfully + WIFI_SEND_FAIL ## < Sending Wi-Fi data fail -## * Argument structure for WIFI_EVENT_AP_PROBEREQRECVED event type - wifi_event_ap_probe_req_rx_t* {.importc: "wifi_event_ap_probe_req_rx_t", - header: "esp_wifi_types.h", bycopy.} = object - rssi* {.importc: "rssi".}: cint ## *< Received probe request signal strength - mac* {.importc: "mac".}: array[6, uint8] ## *< MAC address of the station which send probe request + + wifi_tx_info_t* {.importc: "wifi_tx_info_t", + header: hdr, bycopy.} = object ## + ## + ## @brief Information of wifi sending data + ## + des_addr* {.importc: "des_addr".}: ptr uint8 ## < The address of the receive device + src_addr* {.importc: "src_addr".}: ptr uint8 ## < The address of the sending device + ifidx* {.importc: "ifidx".}: wifi_interface_t ## < Interface of sending 80211 tx data + data* {.importc: "data".}: ptr uint8 ## < The data for 80211 tx, start from the MAC header + data_len* {.importc: "data_len".}: uint8 ## < The frame body length for 80211 tx, excluding the MAC header + rate* {.importc: "rate".}: wifi_phy_rate_t ## < Data rate + tx_status* {.importc: "tx_status".}: wifi_tx_status_t + ## < Status of sending 80211 tx data + + + esp_80211_tx_info_t* = wifi_tx_info_t + + wifi_event_sta_beacon_offset_unstable_t* {. + importc: "wifi_event_sta_beacon_offset_unstable_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_STA_BEACON_OFFSET_UNSTABLE event + beacon_success_rate* {.importc: "beacon_success_rate".}: cfloat + ## < Received beacon success rate + + + wifi_event_dpp_uri_ready_t* {.importc: "wifi_event_dpp_uri_ready_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_DPP_URI_READY event + uri_data_len* {.importc: "uri_data_len".}: uint32 ## + ## < URI data length including null termination + uri* {.importc: "uri".}: UncheckedArray[char] + ## < URI data + + + wifi_event_dpp_config_received_t* {.importc: "wifi_event_dpp_config_received_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_DPP_CFG_RECVD event + wifi_cfg* {.importc: "wifi_cfg".}: wifi_config_t + ## < Received WIFI config in DPP + + + wifi_event_dpp_failed_t* {.importc: "wifi_event_dpp_failed_t", + header: hdr, bycopy.} = object ## + ## Argument structure for WIFI_EVENT_DPP_FAIL event + failure_reason* {.importc: "failure_reason".}: cint + ## < Failure reason diff --git a/src/nesper/esp/net/esp_wifi_types_generic.nim b/src/nesper/esp/net/esp_wifi_types_generic.nim deleted file mode 100644 index b07a0c71..00000000 --- a/src/nesper/esp/net/esp_wifi_types_generic.nim +++ /dev/null @@ -1,1899 +0,0 @@ - - -import ../esp_event - -const hdr = "esp_wifi_types_generic.h" - -let - WIFI_AP_DEFAULT_MAX_IDLE_PERIOD* {.importc: "WIFI_AP_DEFAULT_MAX_IDLE_PERIOD", header: hdr.}: cint ## - ## SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD - ## - ## SPDX-License-Identifier: Apache-2.0 - ## - -type - - wifi_mode_t* {.size: sizeof(cint).} = enum ## - ## @brief Wi-Fi mode type - ## - WIFI_MODE_NULL = 0, ## < Null mode - WIFI_MODE_STA, ## < Wi-Fi station mode - WIFI_MODE_AP, ## < Wi-Fi soft-AP mode - WIFI_MODE_APSTA, ## < Wi-Fi station + soft-AP mode - WIFI_MODE_NAN, ## < Wi-Fi NAN mode - WIFI_MODE_MAX - - -type - - wifi_interface_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Wi-Fi interface type - ## - WIFI_IF_STA, ## < Station interface - WIFI_IF_AP, ## < Soft-AP interface - WIFI_IF_NAN ## < NAN interface - - wifi_action_tx_t* {.size: sizeof(cint).} = enum - WIFI_OFFCHAN_TX_CANCEL, ## < Cancel off-channel transmission - WIFI_OFFCHAN_TX_REQ ## < Request off-channel transmission - - wifi_roc_t* {.size: sizeof(cint).} = enum - WIFI_ROC_CANCEL, ## < Cancel remain on channel - WIFI_ROC_REQ ## < Request remain on channel - - -type - - wifi_country_policy_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Wi-Fi country policy - ## - WIFI_COUNTRY_POLICY_AUTO, ## < Country policy is auto, use the country info of AP to which the station is connected - WIFI_COUNTRY_POLICY_MANUAL ## < Country policy is manual, always use the configured country info - - -type - - wifi_country_t* {.importc: "wifi_country_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Structure describing Wi-Fi country-based regional restrictions. - ## - cc* {.importc: "cc".}: array[3, char] ## < Country code string - schan* {.importc: "schan".}: uint8 ## < Start channel of the allowed 2.4GHz Wi-Fi channels - nchan* {.importc: "nchan".}: uint8 ## < Total channel number of the allowed 2.4GHz Wi-Fi channels - max_tx_power* {.importc: "max_tx_power".}: int8 ## - ## < This field is used for getting Wi-Fi maximum transmitting power, call esp_wifi_set_max_tx_power to set the maximum transmitting power. - policy* {.importc: "policy".}: wifi_country_policy_t ## - ## < Country policy - when defined(CONFIG_SOC_WIFI_SUPPORT_5G): - wifi_5g_channel_mask* {.importc: "wifi_5g_channel_mask".}: uint32 - ## < A bitmask representing the allowed 5GHz Wi-Fi channels. - ## Each bit in the mask corresponds to a specific channel as wifi_5g_channel_bit_t shown. - ## Bitmask set to 0 indicates 5GHz channels are allowed according to local regulatory rules. - ## Please note that configured bitmask takes effect only when policy is manual. - - - wifi_auth_mode_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Wi-Fi authmode type - ## Strength of authmodes - ## Personal Networks : OPEN < WEP < WPA_PSK < OWE < WPA2_PSK = WPA_WPA2_PSK < WAPI_PSK < WPA3_PSK = WPA2_WPA3_PSK = DPP - ## Enterprise Networks : WIFI_AUTH_WPA_ENTERPRISE < WIFI_AUTH_WPA2_ENTERPRISE < WIFI_AUTH_WPA3_ENTERPRISE = WIFI_AUTH_WPA2_WPA3_ENTERPRISE < WIFI_AUTH_WPA3_ENT_192 - ## - WIFI_AUTH_OPEN = 0, ## < Authenticate mode : open - WIFI_AUTH_WEP, ## < Authenticate mode : WEP - WIFI_AUTH_WPA_PSK, ## < Authenticate mode : WPA_PSK - WIFI_AUTH_WPA2_PSK, ## < Authenticate mode : WPA2_PSK - WIFI_AUTH_WPA_WPA2_PSK, ## < Authenticate mode : WPA_WPA2_PSK - WIFI_AUTH_ENTERPRISE, ## < Authenticate mode : Wi-Fi EAP security, treated the same as WIFI_AUTH_WPA2_ENTERPRISE - WIFI_AUTH_WPA3_PSK, ## < Authenticate mode : WPA3_PSK - WIFI_AUTH_WPA2_WPA3_PSK, ## < Authenticate mode : WPA2_WPA3_PSK - WIFI_AUTH_WAPI_PSK, ## < Authenticate mode : WAPI_PSK - WIFI_AUTH_OWE, ## < Authenticate mode : OWE - WIFI_AUTH_WPA3_ENT_192, ## < Authenticate mode : WPA3_ENT_SUITE_B_192_BIT - WIFI_AUTH_WPA3_EXT_PSK, ## < This authentication mode will yield same result as WIFI_AUTH_WPA3_PSK and not recommended to be used. It will be deprecated in future, please use WIFI_AUTH_WPA3_PSK instead. - WIFI_AUTH_WPA3_EXT_PSK_MIXED_MODE, ## < This authentication mode will yield same result as WIFI_AUTH_WPA3_PSK and not recommended to be used. It will be deprecated in future, please use WIFI_AUTH_WPA3_PSK instead. - WIFI_AUTH_DPP, ## < Authenticate mode : DPP - WIFI_AUTH_WPA3_ENTERPRISE, ## < Authenticate mode : WPA3-Enterprise Only Mode - WIFI_AUTH_WPA2_WPA3_ENTERPRISE, ## < Authenticate mode : WPA3-Enterprise Transition Mode - WIFI_AUTH_WPA_ENTERPRISE, ## < Authenticate mode : WPA-Enterprise security - WIFI_AUTH_MAX - -const - WIFI_AUTH_WPA2_ENTERPRISE* = WIFI_AUTH_ENTERPRISE - -type - - wifi_err_reason_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Wi-Fi disconnection reason codes - ## - ## These reason codes are used to indicate the cause of disconnection. - ## - WIFI_REASON_UNSPECIFIED = 1, ## < Unspecified reason - WIFI_REASON_AUTH_EXPIRE = 2, ## < Authentication expired - WIFI_REASON_AUTH_LEAVE = 3, ## < Deauthentication due to leaving - WIFI_REASON_ASSOC_EXPIRE = 4, ## < Deprecated, will be removed in next IDF major release - WIFI_REASON_ASSOC_TOOMANY = 5, ## < Too many associated stations - WIFI_REASON_NOT_AUTHED = 6, ## < Deprecated, will be removed in next IDF major release - WIFI_REASON_NOT_ASSOCED = 7, ## < Deprecated, will be removed in next IDF major release - WIFI_REASON_ASSOC_LEAVE = 8, ## < Deassociated due to leaving - WIFI_REASON_ASSOC_NOT_AUTHED = 9, ## < Association but not authenticated - WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, ## < Disassociated due to poor power capability - WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11, ## < Disassociated due to unsupported channel - WIFI_REASON_BSS_TRANSITION_DISASSOC = 12, ## < Disassociated due to BSS transition - WIFI_REASON_IE_INVALID = 13, ## < Invalid Information Element (IE) - WIFI_REASON_MIC_FAILURE = 14, ## < MIC failure - WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, ## < 4-way handshake timeout - WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, ## < Group key update timeout - WIFI_REASON_IE_IN_4WAY_DIFFERS = 17, ## < IE differs in 4-way handshake - WIFI_REASON_GROUP_CIPHER_INVALID = 18, ## < Invalid group cipher - WIFI_REASON_PAIRWISE_CIPHER_INVALID = 19, ## < Invalid pairwise cipher - WIFI_REASON_AKMP_INVALID = 20, ## < Invalid AKMP - WIFI_REASON_UNSUPP_RSN_IE_VERSION = 21, ## < Unsupported RSN IE version - WIFI_REASON_INVALID_RSN_IE_CAP = 22, ## < Invalid RSN IE capabilities - WIFI_REASON_802_1X_AUTH_FAILED = 23, ## < 802.1X authentication failed - WIFI_REASON_CIPHER_SUITE_REJECTED = 24, ## < Cipher suite rejected - WIFI_REASON_TDLS_PEER_UNREACHABLE = 25, ## < TDLS peer unreachable - WIFI_REASON_TDLS_UNSPECIFIED = 26, ## < TDLS unspecified - WIFI_REASON_SSP_REQUESTED_DISASSOC = 27, ## < SSP requested disassociation - WIFI_REASON_NO_SSP_ROAMING_AGREEMENT = 28, ## < No SSP roaming agreement - WIFI_REASON_BAD_CIPHER_OR_AKM = 29, ## < Bad cipher or AKM - WIFI_REASON_NOT_AUTHORIZED_THIS_LOCATION = 30, ## - ## < Not authorized in this location - WIFI_REASON_SERVICE_CHANGE_PERCLUDES_TS = 31, ## - ## < Service change precludes TS - WIFI_REASON_UNSPECIFIED_QOS = 32, ## < Unspecified QoS reason - WIFI_REASON_NOT_ENOUGH_BANDWIDTH = 33, ## < Not enough bandwidth - WIFI_REASON_MISSING_ACKS = 34, ## < Missing ACKs - WIFI_REASON_EXCEEDED_TXOP = 35, ## < Exceeded TXOP - WIFI_REASON_STA_LEAVING = 36, ## < Station leaving - WIFI_REASON_END_BA = 37, ## < End of Block Ack (BA) - WIFI_REASON_UNKNOWN_BA = 38, ## < Unknown Block Ack (BA) - WIFI_REASON_TIMEOUT = 39, ## < Timeout - WIFI_REASON_PEER_INITIATED = 46, ## < Peer initiated disassociation - WIFI_REASON_AP_INITIATED = 47, ## < AP initiated disassociation - WIFI_REASON_INVALID_FT_ACTION_FRAME_COUNT = 48, ## - ## < Invalid FT action frame count - WIFI_REASON_INVALID_PMKID = 49, ## < Invalid PMKID - WIFI_REASON_INVALID_MDE = 50, ## < Invalid MDE - WIFI_REASON_INVALID_FTE = 51, ## < Invalid FTE - WIFI_REASON_TRANSMISSION_LINK_ESTABLISH_FAILED = 67, ## - ## < Transmission link establishment failed - WIFI_REASON_ALTERATIVE_CHANNEL_OCCUPIED = 68, ## - ## < Alternative channel occupied - WIFI_REASON_BEACON_TIMEOUT = 200, ## < Beacon timeout - WIFI_REASON_NO_AP_FOUND = 201, ## < No AP found - WIFI_REASON_AUTH_FAIL = 202, ## < Authentication failed - WIFI_REASON_ASSOC_FAIL = 203, ## < Association failed - WIFI_REASON_HANDSHAKE_TIMEOUT = 204, ## < Handshake timeout - WIFI_REASON_CONNECTION_FAIL = 205, ## < Connection failed - WIFI_REASON_AP_TSF_RESET = 206, ## < AP TSF reset - WIFI_REASON_ROAMING = 207, ## < Roaming - WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG = 208, ## - ## < Association comeback time too long - WIFI_REASON_SA_QUERY_TIMEOUT = 209, ## < SA query timeout - WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY = 210, ## - ## < No AP found with compatible security - WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD = 211, ## - ## < No AP found in auth mode threshold - WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD = 212 ## - ## < No AP found in RSSI threshold - -const - WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY = WIFI_REASON_ASSOC_EXPIRE - WIFI_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = WIFI_REASON_NOT_AUTHED - WIFI_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = WIFI_REASON_NOT_ASSOCED - -type - - wifi_second_chan_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Wi-Fi second channel type - ## - WIFI_SECOND_CHAN_NONE = 0, ## < The channel width is HT20 - WIFI_SECOND_CHAN_ABOVE, ## < The channel width is HT40 and the secondary channel is above the primary channel - WIFI_SECOND_CHAN_BELOW ## < The channel width is HT40 and the secondary channel is below the primary channel - -let - WIFI_ACTIVE_SCAN_MIN_DEFAULT_TIME* {.importc, header: hdr.}: cint - WIFI_ACTIVE_SCAN_MAX_DEFAULT_TIME* {.importc, header: hdr.}: cint - WIFI_PASSIVE_SCAN_DEFAULT_TIME* {.importc, header: hdr.}: cint - WIFI_SCAN_HOME_CHANNEL_DWELL_DEFAULT_TIME* {.importc, header: hdr.}: cint - -type - - wifi_scan_type_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Wi-Fi scan type - ## - WIFI_SCAN_TYPE_ACTIVE = 0, ## < Active scan - WIFI_SCAN_TYPE_PASSIVE ## < Passive scan - - -type - - wifi_active_scan_time_t* {.importc: "wifi_active_scan_time_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Range of active scan times per channel - ## - min* {.importc: "min".}: uint32 ## < Minimum active scan time per channel, units: millisecond - max* {.importc: "max".}: uint32 - ## < Maximum active scan time per channel, units: millisecond, values above 1500 ms may - ## cause station to disconnect from AP and are not recommended. - - - wifi_scan_time_t* {.importc: "wifi_scan_time_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Aggregate of active & passive scan time per channel - ## - active* {.importc: "active".}: wifi_active_scan_time_t ## - ## < Active scan time per channel, units: millisecond. - passive* {.importc: "passive".}: uint32 - ## < Passive scan time per channel, units: millisecond, values above 1500 ms may - ## cause station to disconnect from AP and are not recommended. - - - wifi_scan_channel_bitmap_t* {.importc: "wifi_scan_channel_bitmap_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Channel bitmap for setting specific channels to be scanned - ## - ghz_2_channels* {.importc: "ghz_2_channels".}: uint16 ## - ## < Represents 2.4 GHz channels, that bits can be set as wifi_2g_channel_bit_t shown. - ghz_5_channels* {.importc: "ghz_5_channels".}: uint32 - ## < Represents 5 GHz channels, that bits can be set as wifi_5g_channel_bit_t shown. - - - wifi_scan_config_t* {.importc: "wifi_scan_config_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Parameters for an SSID scan - ## - ssid* {.importc: "ssid".}: ptr uint8 ## < SSID of AP - bssid* {.importc: "bssid".}: ptr uint8 ## < MAC address of AP - channel* {.importc: "channel".}: uint8 ## < Channel, scan the specific channel - show_hidden* {.importc: "show_hidden".}: bool ## < Enable it to scan AP whose SSID is hidden - scan_type* {.importc: "scan_type".}: wifi_scan_type_t ## - ## < Scan type, active or passive - scan_time* {.importc: "scan_time".}: wifi_scan_time_t ## - ## < Scan time per channel - home_chan_dwell_time* {.importc: "home_chan_dwell_time".}: uint8 ## - ## < Time spent at home channel between scanning consecutive channels. - channel_bitmap* {.importc: "channel_bitmap".}: wifi_scan_channel_bitmap_t ## - ## < Channel bitmap for setting specific channels to be scanned. - ## Please note that the 'channel' parameter above needs to be set to 0 to allow scanning by bitmap. - ## Also, note that only allowed channels configured by wifi_country_t can be scanned. - coex_background_scan* {.importc: "coex_background_scan".}: bool - ## < Enable it to scan return home channel under coexist - - - wifi_scan_default_params_t* {.importc: "wifi_scan_default_params_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Parameters default scan configurations - ## - scan_time* {.importc: "scan_time".}: wifi_scan_time_t ## - ## < Scan time per channel - home_chan_dwell_time* {.importc: "home_chan_dwell_time".}: uint8 - ## < Time spent at home channel between scanning consecutive channels. - - - wifi_cipher_type_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Wi-Fi cipher type - ## - WIFI_CIPHER_TYPE_NONE = 0, ## < The cipher type is none - WIFI_CIPHER_TYPE_WEP40, ## < The cipher type is WEP40 - WIFI_CIPHER_TYPE_WEP104, ## < The cipher type is WEP104 - WIFI_CIPHER_TYPE_TKIP, ## < The cipher type is TKIP - WIFI_CIPHER_TYPE_CCMP, ## < The cipher type is CCMP - WIFI_CIPHER_TYPE_TKIP_CCMP, ## < The cipher type is TKIP and CCMP - WIFI_CIPHER_TYPE_AES_CMAC128, ## < The cipher type is AES-CMAC-128 - WIFI_CIPHER_TYPE_SMS4, ## < The cipher type is SMS4 - WIFI_CIPHER_TYPE_GCMP, ## < The cipher type is GCMP - WIFI_CIPHER_TYPE_GCMP256, ## < The cipher type is GCMP-256 - WIFI_CIPHER_TYPE_AES_GMAC128, ## < The cipher type is AES-GMAC-128 - WIFI_CIPHER_TYPE_AES_GMAC256, ## < The cipher type is AES-GMAC-256 - WIFI_CIPHER_TYPE_UNKNOWN ## < The cipher type is unknown - - -type - - wifi_bandwidth_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Wi-Fi bandwidth type - ## - WIFI_BW_HT20 = 1, ## < Bandwidth is HT20 - WIFI_BW_HT40 = 2, ## < Bandwidth is HT40 - WIFI_BW80 = 3, ## < Bandwidth is 80 MHz - WIFI_BW160 = 4, ## < Bandwidth is 160 MHz - WIFI_BW80_BW80 = 5 ## < Bandwidth is 80 + 80 MHz - -const - WIFI_BW20* = WIFI_BW_HT20 - WIFI_BW40* = WIFI_BW_HT40 - -type - - wifi_ant_t* {.size: sizeof(cint).} = enum ## - ## @brief Wi-Fi antenna - ## - WIFI_ANT_ANT0, ## < Wi-Fi antenna 0 - WIFI_ANT_ANT1, ## < Wi-Fi antenna 1 - WIFI_ANT_MAX ## < Invalid Wi-Fi antenna - - -type - - wifi_he_ap_info_t* {.importc: "wifi_he_ap_info_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Description of a Wi-Fi AP HE Info - ## - bss_color* {.importc: "bss_color", bitsize: 6.}: uint8 ## - ## < The BSS Color value associated with the AP's corresponding BSS - partial_bss_color* {.importc: "partial_bss_color", bitsize: 1.}: uint8 ## - ## < Indicates whether an AID assignment rule is based on the BSS color - bss_color_disabled* {.importc: "bss_color_disabled", bitsize: 1.}: uint8 ## - ## < Indicates whether the BSS color usage is disabled - bssid_index* {.importc: "bssid_index".}: uint8 - ## < In a M-BSSID set, identifies the non-transmitted BSSID - - - wifi_ap_record_t* {.importc: "wifi_ap_record_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Description of a Wi-Fi AP - ## - bssid* {.importc: "bssid".}: array[6, uint8] ## < MAC address of AP - ssid* {.importc: "ssid".}: array[33, uint8] ## < SSID of AP - primary* {.importc: "primary".}: uint8 ## < Channel of AP - second* {.importc: "second".}: wifi_second_chan_t ## - ## < Secondary channel of AP - rssi* {.importc: "rssi".}: int8 ## < Signal strength of AP. Note that in some rare cases where signal strength is very strong, RSSI values can be slightly positive - authmode* {.importc: "authmode".}: wifi_auth_mode_t ## - ## < Auth mode of AP - pairwise_cipher* {.importc: "pairwise_cipher".}: wifi_cipher_type_t ## - ## < Pairwise cipher of AP - group_cipher* {.importc: "group_cipher".}: wifi_cipher_type_t ## - ## < Group cipher of AP - ant* {.importc: "ant".}: wifi_ant_t ## < Antenna used to receive beacon from AP - phy_11b* {.importc: "phy_11b", bitsize: 1.}: uint32 ## - ## < Bit: 0 flag to identify if 11b mode is enabled or not - phy_11g* {.importc: "phy_11g", bitsize: 1.}: uint32 ## - ## < Bit: 1 flag to identify if 11g mode is enabled or not - phy_11n* {.importc: "phy_11n", bitsize: 1.}: uint32 ## - ## < Bit: 2 flag to identify if 11n mode is enabled or not - phy_lr* {.importc: "phy_lr", bitsize: 1.}: uint32 ## - ## < Bit: 3 flag to identify if low rate is enabled or not - phy_11a* {.importc: "phy_11a", bitsize: 1.}: uint32 ## - ## < Bit: 4 flag to identify if 11ax mode is enabled or not - phy_11ac* {.importc: "phy_11ac", bitsize: 1.}: uint32 ## - ## < Bit: 5 flag to identify if 11ax mode is enabled or not - phy_11ax* {.importc: "phy_11ax", bitsize: 1.}: uint32 ## - ## < Bit: 6 flag to identify if 11ax mode is enabled or not - wps* {.importc: "wps", bitsize: 1.}: uint32 ## < Bit: 7 flag to identify if WPS is supported or not - ftm_responder* {.importc: "ftm_responder", bitsize: 1.}: uint32 ## - ## < Bit: 8 flag to identify if FTM is supported in responder mode - ftm_initiator* {.importc: "ftm_initiator", bitsize: 1.}: uint32 ## - ## < Bit: 9 flag to identify if FTM is supported in initiator mode - reserved* {.importc: "reserved", bitsize: 22.}: uint32 ## - ## < Bit: 10..31 reserved - country* {.importc: "country".}: wifi_country_t ## - ## < Country information of AP - he_ap* {.importc: "he_ap".}: wifi_he_ap_info_t ## - ## < HE AP info - bandwidth* {.importc: "bandwidth".}: wifi_bandwidth_t ## - ## < Bandwidth of AP - vht_ch_freq1* {.importc: "vht_ch_freq1".}: uint8 ## - ## < This fields are used only AP bandwidth is 80 and 160 MHz, to transmit the center channel - ## frequency of the BSS. For AP bandwidth is 80 + 80 MHz, it is the center channel frequency - ## of the lower frequency segment. - vht_ch_freq2* {.importc: "vht_ch_freq2".}: uint8 - ## < this fields are used only AP bandwidth is 80 + 80 MHz, and is used to transmit the center - ## channel frequency of the second segment. - - - wifi_scan_method_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Wi-Fi scan method - ## - WIFI_FAST_SCAN = 0, ## < Do fast scan, scan will end after find SSID match AP - WIFI_ALL_CHANNEL_SCAN ## < All channel scan, scan will end after scan all the channel - - -type - - wifi_sort_method_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Wi-Fi sort AP method - ## - WIFI_CONNECT_AP_BY_SIGNAL = 0, ## < Sort match AP in scan list by RSSI - WIFI_CONNECT_AP_BY_SECURITY ## < Sort match AP in scan list by security mode - - -type - - wifi_scan_threshold_t* {.importc: "wifi_scan_threshold_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Structure describing parameters for a Wi-Fi fast scan - ## - rssi* {.importc: "rssi".}: int8 ## < The minimum rssi to accept in the fast scan mode. Defaults to -127 if set to >= 0 - authmode* {.importc: "authmode".}: wifi_auth_mode_t ## - ## < The weakest auth mode to accept in the fast scan mode - ## Note: In case this value is not set and password is set as per WPA2 standards(password len >= 8), it will be defaulted to WPA2 and device won't connect to deprecated WEP/WPA networks. Please set auth mode threshold as WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK to connect to WEP/WPA networks - rssi_5g_adjustment* {.importc: "rssi_5g_adjustment".}: uint8 - ## < The RSSI value of the 5G AP is within the rssi_5g_adjustment range compared to the 2G AP, the 5G AP will be given priority for connection. - - - wifi_ps_type_t* {.size: sizeof(cint).} = enum ## - ## @brief Wi-Fi power save type - ## - WIFI_PS_NONE, ## < No power save - WIFI_PS_MIN_MODEM, ## < Minimum modem power saving. In this mode, station wakes up to receive beacon every DTIM period - WIFI_PS_MAX_MODEM ## < Maximum modem power saving. In this mode, interval to receive beacons is determined by the listen_interval parameter in wifi_sta_config_t - - -type - - wifi_band_t* {.size: sizeof(cint).} = enum ## - ## @brief Argument structure for Wi-Fi band - ## - WIFI_BAND_2G = 1, ## < Band is 2.4 GHz - WIFI_BAND_5G = 2 ## < Band is 5 GHz - - -type - - wifi_band_mode_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Argument structure for Wi-Fi band mode - ## - WIFI_BAND_MODE_2G_ONLY = 1, ## < Wi-Fi band mode is 2.4 GHz only - WIFI_BAND_MODE_5G_ONLY = 2, ## < Wi-Fi band mode is 5 GHz only - WIFI_BAND_MODE_AUTO = 3 ## < Wi-Fi band mode is 2.4 GHz + 5 GHz - - -proc BIT(nr: cint): cint = (1.cint shl nr) - -type - - wifi_2g_channel_bit_t* {.size: sizeof(cint).} = enum ## - ## Argument structure for 2.4G channels - WIFI_CHANNEL_1 = BIT(1), ## < Wi-Fi channel 1 - WIFI_CHANNEL_2 = BIT(2), ## < Wi-Fi channel 2 - WIFI_CHANNEL_3 = BIT(3), ## < Wi-Fi channel 3 - WIFI_CHANNEL_4 = BIT(4), ## < Wi-Fi channel 4 - WIFI_CHANNEL_5 = BIT(5), ## < Wi-Fi channel 5 - WIFI_CHANNEL_6 = BIT(6), ## < Wi-Fi channel 6 - WIFI_CHANNEL_7 = BIT(7), ## < Wi-Fi channel 7 - WIFI_CHANNEL_8 = BIT(8), ## < Wi-Fi channel 8 - WIFI_CHANNEL_9 = BIT(9), ## < Wi-Fi channel 9 - WIFI_CHANNEL_10 = BIT(10), ## < Wi-Fi channel 10 - WIFI_CHANNEL_11 = BIT(11), ## < Wi-Fi channel 11 - WIFI_CHANNEL_12 = BIT(12), ## < Wi-Fi channel 12 - WIFI_CHANNEL_13 = BIT(13), ## < Wi-Fi channel 13 - WIFI_CHANNEL_14 = BIT(14) ## < Wi-Fi channel 14 - - -type - - wifi_5g_channel_bit_t* {.size: sizeof(cint).} = enum ## - ## Argument structure for 5G channels - WIFI_CHANNEL_36 = BIT(1), ## < Wi-Fi channel 36 - WIFI_CHANNEL_40 = BIT(2), ## < Wi-Fi channel 40 - WIFI_CHANNEL_44 = BIT(3), ## < Wi-Fi channel 44 - WIFI_CHANNEL_48 = BIT(4), ## < Wi-Fi channel 48 - WIFI_CHANNEL_52 = BIT(5), ## < Wi-Fi channel 52 - WIFI_CHANNEL_56 = BIT(6), ## < Wi-Fi channel 56 - WIFI_CHANNEL_60 = BIT(7), ## < Wi-Fi channel 60 - WIFI_CHANNEL_64 = BIT(8), ## < Wi-Fi channel 64 - WIFI_CHANNEL_100 = BIT(9), ## < Wi-Fi channel 100 - WIFI_CHANNEL_104 = BIT(10), ## < Wi-Fi channel 104 - WIFI_CHANNEL_108 = BIT(11), ## < Wi-Fi channel 108 - WIFI_CHANNEL_112 = BIT(12), ## < Wi-Fi channel 112 - WIFI_CHANNEL_116 = BIT(13), ## < Wi-Fi channel 116 - WIFI_CHANNEL_120 = BIT(14), ## < Wi-Fi channel 120 - WIFI_CHANNEL_124 = BIT(15), ## < Wi-Fi channel 124 - WIFI_CHANNEL_128 = BIT(16), ## < Wi-Fi channel 128 - WIFI_CHANNEL_132 = BIT(17), ## < Wi-Fi channel 132 - WIFI_CHANNEL_136 = BIT(18), ## < Wi-Fi channel 136 - WIFI_CHANNEL_140 = BIT(19), ## < Wi-Fi channel 140 - WIFI_CHANNEL_144 = BIT(20), ## < Wi-Fi channel 144 - WIFI_CHANNEL_149 = BIT(21), ## < Wi-Fi channel 149 - WIFI_CHANNEL_153 = BIT(22), ## < Wi-Fi channel 153 - WIFI_CHANNEL_157 = BIT(23), ## < Wi-Fi channel 157 - WIFI_CHANNEL_161 = BIT(24), ## < Wi-Fi channel 161 - WIFI_CHANNEL_165 = BIT(25), ## < Wi-Fi channel 165 - WIFI_CHANNEL_169 = BIT(26), ## < Wi-Fi channel 169 - WIFI_CHANNEL_173 = BIT(27), ## < Wi-Fi channel 173 - WIFI_CHANNEL_177 = BIT(28) ## < Wi-Fi channel 177 - -let - WIFI_PROTOCOL_11B* {.importc, header: hdr.}: uint16 = 0x1 - WIFI_PROTOCOL_11G* {.importc, header: hdr.}: uint16 = 0x2 - WIFI_PROTOCOL_11N* {.importc, header: hdr.}: uint16 = 0x4 - WIFI_PROTOCOL_LR* {.importc, header: hdr.}: uint16 = 0x8 - WIFI_PROTOCOL_11A* {.importc, header: hdr.}: uint16 = 0x10 - WIFI_PROTOCOL_11AC* {.importc, header: hdr.}: uint16 = 0x20 - WIFI_PROTOCOL_11AX* {.importc, header: hdr.}: uint16 = 0x40 - -type - - wifi_protocols_t* {.importc: "wifi_protocols_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Description of a Wi-Fi protocols - ## - ghz_2g* {.importc: "ghz_2g".}: uint16 ## < Represents 2.4 GHz protocol, support 802.11b or 802.11g or 802.11n or 802.11ax or LR mode - ghz_5g* {.importc: "ghz_5g".}: uint16 - ## < Represents 5 GHz protocol, support 802.11a or 802.11n or 802.11ac or 802.11ax - - - wifi_bandwidths_t* {.importc: "wifi_bandwidths_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Description of a Wi-Fi band bandwidths - ## - ghz_2g* {.importc: "ghz_2g".}: wifi_bandwidth_t ## - ## < Represents 2.4 GHz bandwidth - ghz_5g* {.importc: "ghz_5g".}: wifi_bandwidth_t - ## < Represents 5 GHz bandwidth - - - wifi_pmf_config_t* {.importc: "wifi_pmf_config_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Configuration structure for Protected Management Frame - ## - capable* {.importc: "capable".}: bool ## < Deprecated variable. Device will always connect in PMF mode if other device also advertises PMF capability. - required* {.importc: "required".}: bool - ## < Advertises that Protected Management Frame is required. Device will not associate to non-PMF capable devices. - - - wifi_sae_pwe_method_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Configuration for SAE PWE derivation - ## - WPA3_SAE_PWE_UNSPECIFIED, WPA3_SAE_PWE_HUNT_AND_PECK, - WPA3_SAE_PWE_HASH_TO_ELEMENT, WPA3_SAE_PWE_BOTH - - -type - - wifi_sae_pk_mode_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Configuration for SAE-PK - ## - WPA3_SAE_PK_MODE_AUTOMATIC = 0, WPA3_SAE_PK_MODE_ONLY = 1, - WPA3_SAE_PK_MODE_DISABLED = 2 - - -type - - wifi_bss_max_idle_config_t* {.importc: "wifi_bss_max_idle_config_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Configuration structure for BSS max idle - ## - period* {.importc: "period".}: uint16 ## < Sets BSS Max idle period (1 Unit = 1000TUs OR 1.024 Seconds). If there are no frames for this period from a STA, SoftAP will disassociate due to inactivity. Setting it to 0 disables the feature - protected_keep_alive* {.importc: "protected_keep_alive".}: bool - ## < Requires clients to use protected keep alive frames for BSS Max Idle period - - - wifi_ap_config_t* {.importc: "wifi_ap_config_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Soft-AP configuration settings for the device - ## - ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. - password* {.importc: "password".}: array[64, uint8] ## - ## < Password of soft-AP. - ssid_len* {.importc: "ssid_len".}: uint8 ## < Optional length of SSID field. - channel* {.importc: "channel".}: uint8 ## < Channel of soft-AP - authmode* {.importc: "authmode".}: wifi_auth_mode_t ## - ## < Auth mode of soft-AP. Do not support AUTH_WEP, AUTH_WAPI_PSK and AUTH_OWE in soft-AP mode. When the auth mode is set to WPA2_PSK, WPA2_WPA3_PSK or WPA3_PSK, the pairwise cipher will be overwritten with WIFI_CIPHER_TYPE_CCMP by default, unless explicitly set. - ssid_hidden* {.importc: "ssid_hidden".}: uint8 ## - ## < Broadcast SSID or not, default 0, broadcast the SSID - max_connection* {.importc: "max_connection".}: uint8 ## - ## < Max number of stations allowed to connect in - beacon_interval* {.importc: "beacon_interval".}: uint16 ## - ## < Beacon interval which should be multiples of 100. Unit: TU(time unit, 1 TU = 1024 us). Range: 100 ~ 60000. Default value: 100 - csa_count* {.importc: "csa_count".}: uint8 ## < Channel Switch Announcement Count. Notify the station that the channel will switch after the csa_count beacon intervals. Default value: 3 - dtim_period* {.importc: "dtim_period".}: uint8 ## - ## < Dtim period of soft-AP. Range: 1 ~ 10. Default value: 1 - pairwise_cipher* {.importc: "pairwise_cipher".}: wifi_cipher_type_t ## - ## < Pairwise cipher of SoftAP, group cipher will be derived using this. Cipher values are valid starting from WIFI_CIPHER_TYPE_TKIP, enum values before that will be considered as invalid and default cipher suites(TKIP+CCMP) will be used. Valid cipher suites in softAP mode are WIFI_CIPHER_TYPE_TKIP, WIFI_CIPHER_TYPE_CCMP, WIFI_CIPHER_TYPE_TKIP_CCMP, WIFI_CIPHER_TYPE_GCMP and WIFI_CIPHER_TYPE_GCMP256. - ftm_responder* {.importc: "ftm_responder".}: bool ## - ## < Enable FTM Responder mode - pmf_cfg* {.importc: "pmf_cfg".}: wifi_pmf_config_t ## - ## < Configuration for Protected Management Frame - sae_pwe_h2e* {.importc: "sae_pwe_h2e".}: wifi_sae_pwe_method_t ## - ## < Configuration for SAE PWE derivation method - transition_disable* {.importc: "transition_disable".}: uint8 ## - ## < Whether to enable transition disable feature - sae_ext* {.importc: "sae_ext".}: uint8 ## < Enable SAE EXT feature. SOC_GCMP_SUPPORT is required for this feature. - bss_max_idle_cfg* {.importc: "bss_max_idle_cfg".}: wifi_bss_max_idle_config_t ## - ## < Configuration for bss max idle, effective if CONFIG_WIFI_BSS_MAX_IDLE_SUPPORT is enabled - gtk_rekey_interval* {.importc: "gtk_rekey_interval".}: uint16 - ## < GTK rekeying interval in seconds. If set to 0, GTK rekeying is disabled. Range: 60 ~ 65535 including 0. - - -const - SAE_H2E_IDENTIFIER_LEN* = 32 - -type - - wifi_sta_config_t* {.importc: "wifi_sta_config_t", - header: hdr, bycopy.} = object ## - ## - ## @brief STA configuration settings for the device - ## - ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of target AP. - password* {.importc: "password".}: array[64, uint8] ## - ## < Password of target AP. - scan_method* {.importc: "scan_method".}: wifi_scan_method_t ## - ## < Do all channel scan or fast scan - bssid_set* {.importc: "bssid_set".}: bool ## < Whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP. - bssid* {.importc: "bssid".}: array[6, uint8] ## < MAC address of target AP - channel* {.importc: "channel".}: uint8 ## < Channel hint for target AP. For 2.4G AP, set to 1~13 to scan starting from the specified channel before connecting to AP. For 5G AP, set to 36~177 (36, 40, 44 ... 177) to scan starting from the specified channel before connecting to AP. Set to 0 for no preference - listen_interval* {.importc: "listen_interval".}: uint16 ## - ## < Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. - sort_method* {.importc: "sort_method".}: wifi_sort_method_t ## - ## < Sort the connect AP in the list by rssi or security mode - threshold* {.importc: "threshold".}: wifi_scan_threshold_t ## - ## < When scan_threshold is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. - pmf_cfg* {.importc: "pmf_cfg".}: wifi_pmf_config_t ## - ## < Configuration for Protected Management Frame. Will be advertised in RSN Capabilities in RSN IE. - rm_enabled* {.importc: "rm_enabled", bitsize: 1.}: uint32 ## - ## < Whether Radio Measurements are enabled for the connection - btm_enabled* {.importc: "btm_enabled", bitsize: 1.}: uint32 ## - ## < Whether BSS Transition Management is enabled for the connection. Note that when btm is enabled, the application itself should not set specific bssid (i.e using bssid_set and bssid in this config)or channel to connect to. This defeats the purpose of a BTM supported network, and hence if btm is supported and a specific bssid or channel is set in this config, it will be cleared from the config at the first disconnection or connection so that the device can roam to other BSS. It is recommended not to set BSSID when BTM is enabled. - mbo_enabled* {.importc: "mbo_enabled", bitsize: 1.}: uint32 ## - ## < Whether MBO is enabled for the connection. Note that when mbo is enabled, the application itself should not set specific bssid (i.e using bssid_set and bssid in this config)or channel to connect to. This defeats the purpose of a MBO supported network, and hence if btm is supported and a specific bssid or channel is set in this config, it will be cleared from the config at the first disconnection or connection so that the device can roam to other BSS. It is recommended not to set BSSID when MBO is enabled. Enabling mbo here, automatically enables btm and rm above. - ft_enabled* {.importc: "ft_enabled", bitsize: 1.}: uint32 ## - ## < Whether FT is enabled for the connection - owe_enabled* {.importc: "owe_enabled", bitsize: 1.}: uint32 ## - ## < Whether OWE is enabled for the connection - transition_disable* {.importc: "transition_disable", bitsize: 1.}: uint32 ## - ## < Whether to enable transition disable feature - reserved1* {.importc: "reserved1", bitsize: 26.}: uint32 ## - ## < Reserved for future feature set - sae_pwe_h2e* {.importc: "sae_pwe_h2e".}: wifi_sae_pwe_method_t ## - ## < Configuration for SAE PWE derivation method - sae_pk_mode* {.importc: "sae_pk_mode".}: wifi_sae_pk_mode_t ## - ## < Configuration for SAE-PK (Public Key) Authentication method - failure_retry_cnt* {.importc: "failure_retry_cnt".}: uint8 ## - ## < Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config. - ## Note: Enabling this may cause connection time to increase in case best AP doesn't behave properly. - he_dcm_set* {.importc: "he_dcm_set", bitsize: 1.}: uint32 ## - ## < Whether DCM max.constellation for transmission and reception is set. - he_dcm_max_constellation_tx* {.importc: "he_dcm_max_constellation_tx", - bitsize: 2.}: uint32 ## - ## < Indicate the max.constellation for DCM in TB PPDU the STA supported. 0: not supported. 1: BPSK, 2: QPSK, 3: 16-QAM. The default value is 3. - he_dcm_max_constellation_rx* {.importc: "he_dcm_max_constellation_rx", - bitsize: 2.}: uint32 ## - ## < Indicate the max.constellation for DCM in both Data field and HE-SIG-B field the STA supported. 0: not supported. 1: BPSK, 2: QPSK, 3: 16-QAM. The default value is 3. - he_mcs9_enabled* {.importc: "he_mcs9_enabled", bitsize: 1.}: uint32 ## - ## < Whether to support HE-MCS8 and HE-MCS9. The default value is 0. - he_su_beamformee_disabled* {.importc: "he_su_beamformee_disabled", - bitsize: 1.}: uint32 ## - ## < Whether to disable support for operation as an SU beamformee. - he_trig_su_bmforming_feedback_disabled* - {.importc: "he_trig_su_bmforming_feedback_disabled", bitsize: 1.}: uint32 ## - ## < Whether to disable support the transmission of SU feedback in an HE TB sounding sequence. - he_trig_mu_bmforming_partial_feedback_disabled* {. - importc: "he_trig_mu_bmforming_partial_feedback_disabled", bitsize: 1.}: uint32 ## - ## < Whether to disable support the transmission of partial-bandwidth MU feedback in an HE TB sounding sequence. - he_trig_cqi_feedback_disabled* {.importc: "he_trig_cqi_feedback_disabled", - bitsize: 1.}: uint32 ## - ## < Whether to disable support the transmission of CQI feedback in an HE TB sounding sequence. - vht_su_beamformee_disabled* {.importc: "vht_su_beamformee_disabled", - bitsize: 1.}: uint32 ## - ## < Whether to disable support for operation as an VHT SU beamformee. - vht_mu_beamformee_disabled* {.importc: "vht_mu_beamformee_disabled", - bitsize: 1.}: uint32 ## - ## < Whether to disable support for operation as an VHT MU beamformee. - vht_mcs8_enabled* {.importc: "vht_mcs8_enabled", bitsize: 1.}: uint32 ## - ## < Whether to support VHT-MCS8. The default value is 0. - reserved2* {.importc: "reserved2", bitsize: 19.}: uint32 ## - ## < Reserved for future feature set - sae_h2e_identifier* {.importc: "sae_h2e_identifier".}: array[ - SAE_H2E_IDENTIFIER_LEN, uint8] - ## < Password identifier for H2E. this needs to be null terminated string - - - wifi_nan_config_t* {.importc: "wifi_nan_config_t", - header: hdr, bycopy.} = object ## - ## - ## @brief NAN Discovery start configuration - ## - op_channel* {.importc: "op_channel".}: uint8 ## < NAN Discovery operating channel - master_pref* {.importc: "master_pref".}: uint8 ## - ## < Device's preference value to serve as NAN Master - scan_time* {.importc: "scan_time".}: uint8 ## < Scan time in seconds while searching for a NAN cluster - warm_up_sec* {.importc: "warm_up_sec".}: uint16 - ## < Warm up time before assuming NAN Anchor Master role - - - wifi_config_t* {.importc: "wifi_config_t", header: hdr, - bycopy, union.} = object ## - ## @brief Configuration data for device's AP or STA or NAN. - ## - ## The usage of this union (for ap, sta or nan configuration) is determined by the accompanying - ## interface argument passed to esp_wifi_set_config() or esp_wifi_get_config() - ## - ## - ap* {.importc: "ap".}: wifi_ap_config_t ## < Configuration of AP - sta* {.importc: "sta".}: wifi_sta_config_t ## < Configuration of STA - nan* {.importc: "nan".}: wifi_nan_config_t - ## < Configuration of NAN - - - wifi_sta_info_t* {.importc: "wifi_sta_info_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Description of STA associated with AP - ## - mac* {.importc: "mac".}: array[6, uint8] ## < MAC address - rssi* {.importc: "rssi".}: int8 ## < Current average rssi of sta connected - phy_11b* {.importc: "phy_11b", bitsize: 1.}: uint32 ## - ## < Bit: 0 flag to identify if 11b mode is enabled or not - phy_11g* {.importc: "phy_11g", bitsize: 1.}: uint32 ## - ## < Bit: 1 flag to identify if 11g mode is enabled or not - phy_11n* {.importc: "phy_11n", bitsize: 1.}: uint32 ## - ## < Bit: 2 flag to identify if 11n mode is enabled or not - phy_lr* {.importc: "phy_lr", bitsize: 1.}: uint32 ## - ## < Bit: 3 flag to identify if low rate is enabled or not - phy_11a* {.importc: "phy_11a", bitsize: 1.}: uint32 ## - ## < Bit: 4 flag to identify if 11ax mode is enabled or not - phy_11ac* {.importc: "phy_11ac", bitsize: 1.}: uint32 ## - ## < Bit: 5 flag to identify if 11ax mode is enabled or not - phy_11ax* {.importc: "phy_11ax", bitsize: 1.}: uint32 ## - ## < Bit: 6 flag to identify if 11ax mode is enabled or not - is_mesh_child* {.importc: "is_mesh_child", bitsize: 1.}: uint32 ## - ## < Bit: 7 flag to identify mesh child - reserved* {.importc: "reserved", bitsize: 24.}: uint32 - ## < Bit: 8..31 reserved - - - wifi_storage_t* {.size: sizeof(cint).} = enum ## - ## @brief Wi-Fi storage type - ## - WIFI_STORAGE_FLASH, ## < All configuration will store in both memory and flash - WIFI_STORAGE_RAM ## < All configuration will only store in the memory - - -type - - wifi_vendor_ie_type_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Vendor Information Element type - ## - ## Determines the frame type that the IE will be associated with. - ## - WIFI_VND_IE_TYPE_BEACON, ## < Beacon frame - WIFI_VND_IE_TYPE_PROBE_REQ, ## < Probe request frame - WIFI_VND_IE_TYPE_PROBE_RESP, ## < Probe response frame - WIFI_VND_IE_TYPE_ASSOC_REQ, ## < Association request frame - WIFI_VND_IE_TYPE_ASSOC_RESP ## < Association response frame - - -type - - wifi_vendor_ie_id_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Vendor Information Element index - ## - ## Each IE type can have up to two associated vendor ID elements. - ## - WIFI_VND_IE_ID_0, ## < Vendor ID element 0 - WIFI_VND_IE_ID_1 ## < Vendor ID element 1 - -let - WIFI_VENDOR_IE_ELEMENT_ID* {.importc, header: hdr.}: uint8 - -type - - wifi_phy_mode_t* {.size: sizeof(cint).} = enum ## - ## @brief Operation PHY mode - ## - WIFI_PHY_MODE_LR, ## < PHY mode for Low Rate - WIFI_PHY_MODE_11B, ## < PHY mode for 11b - WIFI_PHY_MODE_11G, ## < PHY mode for 11g - WIFI_PHY_MODE_11A, ## < PHY mode for 11a - WIFI_PHY_MODE_HT20, ## < PHY mode for Bandwidth HT20 - WIFI_PHY_MODE_HT40, ## < PHY mode for Bandwidth HT40 - WIFI_PHY_MODE_HE20, ## < PHY mode for Bandwidth HE20 - WIFI_PHY_MODE_VHT20 ## < PHY mode for Bandwidth VHT20 - - -type - - vendor_ie_data_t* {.importc: "vendor_ie_data_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Vendor Information Element header - ## - ## The first bytes of the Information Element will match this header. Payload follows. - ## - element_id* {.importc: "element_id".}: uint8 ## < Should be set to WIFI_VENDOR_IE_ELEMENT_ID (0xDD) - length* {.importc: "length".}: uint8 ## < Length of all bytes in the element data following this field. Minimum 4. - vendor_oui* {.importc: "vendor_oui".}: array[3, uint8] ## - ## < Vendor identifier (OUI). - vendor_oui_type* {.importc: "vendor_oui_type".}: uint8 ## - ## < Vendor-specific OUI type. - payload* {.importc: "payload".}: UncheckedArray[uint8] - ## < Payload. Length is equal to value in 'length' field, minus 4. - - - wifi_promiscuous_pkt_type_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Promiscuous frame type - ## - ## Passed to promiscuous mode RX callback to indicate the type of parameter in the buffer. - ## - ## - WIFI_PKT_MGMT, ## < Management frame, indicates 'buf' argument is wifi_promiscuous_pkt_t - WIFI_PKT_CTRL, ## < Control frame, indicates 'buf' argument is wifi_promiscuous_pkt_t - WIFI_PKT_DATA, ## < Data frame, indicates 'buf' argument is wifi_promiscuous_pkt_t - WIFI_PKT_MISC ## < Other type, such as MIMO etc. 'buf' argument is wifi_promiscuous_pkt_t but the payload is zero length. - -const - WIFI_PROMIS_FILTER_MASK_ALL* = (0xFFFFFFFF) ## < Filter all packets - WIFI_PROMIS_FILTER_MASK_MGMT* = (1) ## < Filter the packets with type of WIFI_PKT_MGMT - WIFI_PROMIS_FILTER_MASK_CTRL* = (1 shl 1) ## < Filter the packets with type of WIFI_PKT_CTRL - WIFI_PROMIS_FILTER_MASK_DATA* = (1 shl 2) ## < Filter the packets with type of WIFI_PKT_DATA - WIFI_PROMIS_FILTER_MASK_MISC* = (1 shl 3) ## < Filter the packets with type of WIFI_PKT_MISC - WIFI_PROMIS_FILTER_MASK_DATA_MPDU* = (1 shl 4) ## < Filter the MPDU which is a kind of WIFI_PKT_DATA - WIFI_PROMIS_FILTER_MASK_DATA_AMPDU* = (1 shl 5) ## < Filter the AMPDU which is a kind of WIFI_PKT_DATA - WIFI_PROMIS_FILTER_MASK_FCSFAIL* = (1 shl 6) ## < Filter the FCS failed packets, do not open it in general - WIFI_PROMIS_CTRL_FILTER_MASK_ALL* = (0xFF800000) ## - ## < Filter all control packets - WIFI_PROMIS_CTRL_FILTER_MASK_WRAPPER* = (1 shl 23) ## - ## < Filter the control packets with subtype of Control Wrapper - WIFI_PROMIS_CTRL_FILTER_MASK_BAR* = (1 shl 24) ## < Filter the control packets with subtype of Block Ack Request - WIFI_PROMIS_CTRL_FILTER_MASK_BA* = (1 shl 25) ## < Filter the control packets with subtype of Block Ack - WIFI_PROMIS_CTRL_FILTER_MASK_PSPOLL* = (1 shl 26) ## - ## < Filter the control packets with subtype of PS-Poll - WIFI_PROMIS_CTRL_FILTER_MASK_RTS* = (1 shl 27) ## < Filter the control packets with subtype of RTS - WIFI_PROMIS_CTRL_FILTER_MASK_CTS* = (1 shl 28) ## < Filter the control packets with subtype of CTS - WIFI_PROMIS_CTRL_FILTER_MASK_ACK* = (1 shl 29) ## < Filter the control packets with subtype of ACK - WIFI_PROMIS_CTRL_FILTER_MASK_CFEND* = (1 shl 30) ## - ## < Filter the control packets with subtype of CF-END - WIFI_PROMIS_CTRL_FILTER_MASK_CFENDACK* = (1 shl 31) ## - ## < Filter the control packets with subtype of CF-END+CF-ACK - -type - - wifi_promiscuous_filter_t* {.importc: "wifi_promiscuous_filter_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Mask for filtering different packet types in promiscuous mode - ## - filter_mask* {.importc: "filter_mask".}: uint32 - ## < OR of one or more filter values WIFI_PROMIS_FILTER_* - - -const - WIFI_EVENT_MASK_ALL* = (0xFFFFFFFF) ## < Mask all Wi-Fi events - WIFI_EVENT_MASK_NONE* = (0) ## < Mask none of the Wi-Fi events - WIFI_EVENT_MASK_AP_PROBEREQRECVED* = (BIT(0)) ## < Mask SYSTEM_EVENT_AP_PROBEREQRECVED event - -## -## @brief CSI data type -## -## - -type - - wifi_ant_gpio_t* {.importc: "wifi_ant_gpio_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Wi-Fi GPIO configuration for antenna selection - ## - ## - gpio_select* {.importc: "gpio_select", bitsize: 1.}: uint8 ## - ## < Whether this GPIO is connected to external antenna switch - gpio_num* {.importc: "gpio_num", bitsize: 7.}: uint8 - ## < The GPIO number that connects to external antenna switch - - - wifi_ant_gpio_config_t* {.importc: "wifi_ant_gpio_config_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Wi-Fi GPIOs configuration for antenna selection - ## - ## - gpio_cfg* {.importc: "gpio_cfg".}: array[4, wifi_ant_gpio_t] - ## < The configurations of GPIOs that connect to external antenna switch - - - wifi_ant_mode_t* {.size: sizeof(cint).} = enum ## - ## @brief Wi-Fi antenna mode - ## - ## - WIFI_ANT_MODE_ANT0, ## < Enable Wi-Fi antenna 0 only - WIFI_ANT_MODE_ANT1, ## < Enable Wi-Fi antenna 1 only - WIFI_ANT_MODE_AUTO, ## < Enable Wi-Fi antenna 0 and 1, automatically select an antenna - WIFI_ANT_MODE_MAX ## < Invalid Wi-Fi enabled antenna - - -type - - wifi_ant_config_t* {.importc: "wifi_ant_config_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Wi-Fi antenna configuration - ## - ## - rx_ant_mode* {.importc: "rx_ant_mode".}: wifi_ant_mode_t ## - ## < Wi-Fi antenna mode for receiving - rx_ant_default* {.importc: "rx_ant_default".}: wifi_ant_t ## - ## < Default antenna mode for receiving, it's ignored if rx_ant_mode is not WIFI_ANT_MODE_AUTO - tx_ant_mode* {.importc: "tx_ant_mode".}: wifi_ant_mode_t ## - ## < Wi-Fi antenna mode for transmission, it can be set to WIFI_ANT_MODE_AUTO only if rx_ant_mode is set to WIFI_ANT_MODE_AUTO - enabled_ant0* {.importc: "enabled_ant0", bitsize: 4.}: uint8 ## - ## < Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT0 - enabled_ant1* {.importc: "enabled_ant1", bitsize: 4.}: uint8 - ## < Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT1 - - - wifi_action_rx_cb_t* = proc (hdr: ptr uint8; payload: ptr uint8; len: csize_t; - channel: uint8): cint {.cdecl.} ## - ## - ## @brief The Rx callback function of Action Tx operations - ## - ## @param hdr Pointer to the IEEE 802.11 Header structure - ## @param payload Pointer to the Payload following 802.11 Header - ## @param len Length of the Payload - ## @param channel Channel number the frame is received on - ## - ## - - wifi_action_tx_req_t* {.importc: "wifi_action_tx_req_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Action Frame Tx Request - ## - ifx* {.importc: "ifx".}: wifi_interface_t ## < Wi-Fi interface to send request to - dest_mac* {.importc: "dest_mac".}: array[6, uint8] ## - ## < Destination MAC address - `type`* {.importc: "type".}: wifi_action_tx_t ## < ACTION TX operation type - channel* {.importc: "channel".}: uint8 ## < Channel on which to perform ACTION TX Operation - wait_time_ms* {.importc: "wait_time_ms".}: uint32 ## - ## < Duration to wait for on target channel - no_ack* {.importc: "no_ack".}: bool ## < Indicates no ack required - rx_cb* {.importc: "rx_cb".}: wifi_action_rx_cb_t ## - ## < Rx Callback to receive action frames - op_id* {.importc: "op_id".}: uint8 ## < Unique Identifier for operation provided by wifi driver - data_len* {.importc: "data_len".}: uint32 ## < Length of the appended Data - data* {.importc: "data".}: UncheckedArray[uint8] - ## < Appended Data payload - - - wifi_roc_done_status_t* {.size: sizeof(cint).} = enum ## - ## Status codes for WIFI_EVENT_ROC_DONE evt - WIFI_ROC_DONE = 0, ## < ROC operation was completed successfully - WIFI_ROC_FAIL ## < ROC operation was cancelled - - -type - - wifi_action_roc_done_cb_t* = proc (context: uint32; op_id: uint8; - status: wifi_roc_done_status_t) {.cdecl.} ## - ## - ## @brief The callback function executed when ROC operation has ended - ## - ## @param context rxcb registered for the corresponding ROC operation - ## @param op_id ID of the corresponding ROC operation - ## @param status status code of the ROC operation denoted - ## - ## - - wifi_roc_req_t* {.importc: "wifi_roc_req_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Remain on Channel request - ## - ## - ## - ifx* {.importc: "ifx".}: wifi_interface_t ## < WiFi interface to send request to - `type`* {.importc: "type".}: wifi_roc_t ## < ROC operation type - channel* {.importc: "channel".}: uint8 ## < Channel on which to perform ROC Operation - sec_channel* {.importc: "sec_channel".}: wifi_second_chan_t ## - ## < Secondary channel - wait_time_ms* {.importc: "wait_time_ms".}: uint32 ## - ## < Duration to wait for on target channel - rx_cb* {.importc: "rx_cb".}: wifi_action_rx_cb_t ## - ## < Rx Callback to receive any response - op_id* {.importc: "op_id".}: uint8 ## < ID of this specific ROC operation provided by wifi driver - done_cb* {.importc: "done_cb".}: wifi_action_roc_done_cb_t - ## < Callback to function that will be called upon ROC done. If assigned, WIFI_EVENT_ROC_DONE event will not be posted - - - wifi_ftm_initiator_cfg_t* {.importc: "wifi_ftm_initiator_cfg_t", - header: hdr, bycopy.} = object ## - ## - ## @brief FTM Initiator configuration - ## - ## - resp_mac* {.importc: "resp_mac".}: array[6, uint8] ## - ## < MAC address of the FTM Responder - channel* {.importc: "channel".}: uint8 ## < Primary channel of the FTM Responder - frm_count* {.importc: "frm_count".}: uint8 ## < No. of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0(No pref), 16, 24, 32, 64) - burst_period* {.importc: "burst_period".}: uint16 ## - ## < Requested period between FTM bursts in 100's of milliseconds (allowed values 0(No pref) - 100) - use_get_report_api* {.importc: "use_get_report_api".}: bool - ## < True - Using esp_wifi_ftm_get_report to get FTM report, False - Using ftm_report_data from - ## WIFI_EVENT_FTM_REPORT to get FTM report - - -const - ESP_WIFI_NAN_MAX_SVC_SUPPORTED* = 2 - ESP_WIFI_NAN_DATAPATH_MAX_PEERS* = 2 - ESP_WIFI_NDP_ROLE_INITIATOR* = 1 - ESP_WIFI_NDP_ROLE_RESPONDER* = 2 - ESP_WIFI_MAX_SVC_NAME_LEN* = 256 - ESP_WIFI_MAX_FILTER_LEN* = 256 - ESP_WIFI_MAX_SVC_INFO_LEN* = 64 - ESP_WIFI_MAX_FUP_SSI_LEN* = 2048 - ESP_WIFI_MAX_SVC_SSI_LEN* = 512 - ESP_WIFI_MAX_NEIGHBOR_REP_LEN* = 64 - WIFI_OUI_LEN* = 3 - -type - - wifi_nan_svc_proto_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Protocol types in NAN service specific info attribute - ## - ## - WIFI_SVC_PROTO_RESERVED = 0, ## < Value 0 Reserved - WIFI_SVC_PROTO_BONJOUR = 1, ## < Bonjour Protocol - WIFI_SVC_PROTO_GENERIC = 2, ## < Generic Service Protocol - WIFI_SVC_PROTO_CSA_MATTER = 3, ## < CSA Matter specific protocol - WIFI_SVC_PROTO_MAX ## < Values 4-255 Reserved - - -type - - wifi_nan_wfa_ssi_t* {.importc: "wifi_nan_wfa_ssi_t", - header: hdr, bycopy.} = object ## - ## - ## @brief WFA defined Protocol types in NAN service specific info attribute - ## - ## - wfa_oui* {.importc: "wfa_oui".}: array[WIFI_OUI_LEN, uint8] ## - ## < WFA OUI - 0x50, 0x6F, 0x9A - proto* {.importc: "proto".}: wifi_nan_svc_proto_t ## - ## < WFA defined protocol types - payload* {.importc: "payload".}: UncheckedArray[uint8] - ## < Service Info payload - - - wifi_nan_service_type_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief NAN Services types - ## - ## - NAN_PUBLISH_SOLICITED, ## < Send unicast Publish frame to Subscribers that match the requirement - NAN_PUBLISH_UNSOLICITED, ## < Send broadcast Publish frames in every Discovery Window(DW) - NAN_SUBSCRIBE_ACTIVE, ## < Send broadcast Subscribe frames in every DW - NAN_SUBSCRIBE_PASSIVE ## < Passively listens to Publish frames - - -type - - wifi_nan_publish_cfg_t* {.importc: "wifi_nan_publish_cfg_t", - header: hdr, bycopy.} = object ## - ## - ## @brief NAN Publish service configuration parameters - ## - ## - service_name* {.importc: "service_name".}: array[ESP_WIFI_MAX_SVC_NAME_LEN, - char] ## < Service name identifier - `type`* {.importc: "type".}: wifi_nan_service_type_t ## - ## < Service type - matching_filter* {.importc: "matching_filter".}: array[ - ESP_WIFI_MAX_FILTER_LEN, char] ## < Comma separated filters for filtering services - svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, char] ## - ## < To be deprecated in next major release, use ssi instead - single_replied_event* {.importc: "single_replied_event", bitsize: 1.}: uint8 ## - ## < Give single Replied event or every time - datapath_reqd* {.importc: "datapath_reqd", bitsize: 1.}: uint8 ## - ## < NAN Datapath required for the service - fsd_reqd* {.importc: "fsd_reqd", bitsize: 1.}: uint8 ## - ## < Further Service Discovery(FSD) required - fsd_gas* {.importc: "fsd_gas", bitsize: 1.}: uint8 ## - ## < 0 - Follow-up used for FSD, 1 - GAS used for FSD - reserved* {.importc: "reserved", bitsize: 4.}: uint8 ## - ## < Reserved - ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info, maximum allowed length - ESP_WIFI_MAX_SVC_SSI_LEN - ssi* {.importc: "ssi".}: ptr uint8 - ## < Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications - - - wifi_nan_subscribe_cfg_t* {.importc: "wifi_nan_subscribe_cfg_t", - header: hdr, bycopy.} = object ## - ## - ## @brief NAN Subscribe service configuration parameters - ## - ## - service_name* {.importc: "service_name".}: array[ESP_WIFI_MAX_SVC_NAME_LEN, - char] ## < Service name identifier - `type`* {.importc: "type".}: wifi_nan_service_type_t ## - ## < Service type - matching_filter* {.importc: "matching_filter".}: array[ - ESP_WIFI_MAX_FILTER_LEN, char] ## < Comma separated filters for filtering services - svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, char] ## - ## < To be deprecated in next major release, use ssi instead - single_match_event* {.importc: "single_match_event", bitsize: 1.}: uint8 ## - ## < Give single Match event(per SSI update) or every time - datapath_reqd* {.importc: "datapath_reqd", bitsize: 1.}: uint8 ## - ## < NAN Datapath required for the service - fsd_reqd* {.importc: "fsd_reqd", bitsize: 1.}: uint8 ## - ## < Further Service Discovery(FSD) required - fsd_gas* {.importc: "fsd_gas", bitsize: 1.}: uint8 ## - ## < 0 - Follow-up used for FSD, 1 - GAS used for FSD - reserved* {.importc: "reserved", bitsize: 4.}: uint8 ## - ## < Reserved - ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info, maximum allowed length - ESP_WIFI_MAX_SVC_SSI_LEN - ssi* {.importc: "ssi".}: ptr uint8 - ## < Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications - - - wifi_nan_followup_params_t* {.importc: "wifi_nan_followup_params_t", - header: hdr, bycopy.} = object ## - ## - ## @brief NAN Follow-up parameters - ## - ## - inst_id* {.importc: "inst_id".}: uint8 ## < Own service instance id - peer_inst_id* {.importc: "peer_inst_id".}: uint8 ## - ## < Peer's service instance id - peer_mac* {.importc: "peer_mac".}: array[6, uint8] ## - ## < Peer's MAC address - svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, char] ## - ## < To be deprecated in next major release, use ssi instead - ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info, maximum allowed length - ESP_WIFI_MAX_FUP_SSI_LEN - ssi* {.importc: "ssi".}: ptr uint8 - ## < Service Specific Info of type wifi_nan_wfa_ssi_t for WFA defined protocols, otherwise proprietary and defined by Applications - - - wifi_nan_datapath_req_t* {.importc: "wifi_nan_datapath_req_t", - header: hdr, bycopy.} = object ## - ## - ## @brief NAN Datapath Request parameters - ## - ## - pub_id* {.importc: "pub_id".}: uint8 ## < Publisher's service instance id - peer_mac* {.importc: "peer_mac".}: array[6, uint8] ## - ## < Peer's MAC address - confirm_required* {.importc: "confirm_required".}: bool - ## < NDP Confirm frame required - - - wifi_nan_datapath_resp_t* {.importc: "wifi_nan_datapath_resp_t", - header: hdr, bycopy.} = object ## - ## - ## @brief NAN Datapath Response parameters - ## - ## - accept* {.importc: "accept".}: bool ## < True - Accept incoming NDP, False - Reject it - ndp_id* {.importc: "ndp_id".}: uint8 ## < NAN Datapath Identifier - peer_mac* {.importc: "peer_mac".}: array[6, uint8] - ## < Peer's MAC address - - - wifi_nan_datapath_end_req_t* {.importc: "wifi_nan_datapath_end_req_t", - header: hdr, bycopy.} = object ## - ## - ## @brief NAN Datapath End parameters - ## - ## - ndp_id* {.importc: "ndp_id".}: uint8 ## < NAN Datapath Identifier - peer_mac* {.importc: "peer_mac".}: array[6, uint8] - ## < Peer's MAC address - - - wifi_phy_rate_t* {.importc: "wifi_phy_rate_t", header: hdr.} = cint ##\ - ## @brief Wi-Fi PHY rate encodings - ## - ## @note Rate Table: MCS Rate and Guard Interval Information - ## | MCS RATE | HT20 | HT40 | HE20 | VHT20 | - ## - ## |-----------------------------|-------------------------|-------------------------|-------------------------|-------------------------| - ## | WIFI_PHY_RATE_MCS0_LGI | 6.5 Mbps (800 ns) | 13.5 Mbps (800 ns) | 8.1 Mbps (1600 ns) | 6.5 Mbps (800 ns) | - ## | WIFI_PHY_RATE_MCS1_LGI | 13 Mbps (800 ns) | 27 Mbps (800 ns) | 16.3 Mbps (1600 ns) | 13 Mbps (800 ns) | - ## | WIFI_PHY_RATE_MCS2_LGI | 19.5 Mbps (800 ns) | 40.5 Mbps (800 ns) | 24.4 Mbps (1600 ns) | 19.5 Mbps (800 ns) | - ## | WIFI_PHY_RATE_MCS3_LGI | 26 Mbps (800 ns) | 54 Mbps (800 ns) | 32.5 Mbps (1600 ns) | 26 Mbps (800 ns) | - ## | WIFI_PHY_RATE_MCS4_LGI | 39 Mbps (800 ns) | 81 Mbps (800 ns) | 48.8 Mbps (1600 ns) | 39 Mbps (800 ns) | - ## | WIFI_PHY_RATE_MCS5_LGI | 52 Mbps (800 ns) | 108 Mbps (800 ns) | 65 Mbps (1600 ns) | 52 Mbps (800 ns) | - ## | WIFI_PHY_RATE_MCS6_LGI | 58.5 Mbps (800 ns) | 121.5 Mbps (800 ns) | 73.1 Mbps (1600 ns) | 58.5 Mbps (800 ns) | - ## | WIFI_PHY_RATE_MCS7_LGI | 65 Mbps (800 ns) | 135 Mbps (800 ns) | 81.3 Mbps (1600 ns) | 65 Mbps (800 ns) | - ## | WIFI_PHY_RATE_MCS8_LGI | | | 97.5 Mbps (1600 ns) | | - ## | WIFI_PHY_RATE_MCS9_LGI | | | 108.3 Mbps (1600 ns) | | - ## - ## @note - ## | MCS RATE | HT20 | HT40 | HE20 | VHT20 | - ## - ## |-----------------------------|-------------------------|-------------------------|-------------------------|-------------------------| - ## | WIFI_PHY_RATE_MCS0_SGI | 7.2 Mbps (400 ns) | 15 Mbps (400 ns) | 8.6 Mbps (800 ns) | 7.2 Mbps (400 ns) | - ## | WIFI_PHY_RATE_MCS1_SGI | 14.4 Mbps (400 ns) | 30 Mbps (400 ns) | 17.2 Mbps (800 ns) | 14.4 Mbps (400 ns) | - ## | WIFI_PHY_RATE_MCS2_SGI | 21.7 Mbps (400 ns) | 45 Mbps (400 ns) | 25.8 Mbps (800 ns) | 21.7 Mbps (400 ns) | - ## | WIFI_PHY_RATE_MCS3_SGI | 28.9 Mbps (400 ns) | 60 Mbps (400 ns) | 34.4 Mbps (800 ns) | 28.9 Mbps (400 ns) | - ## | WIFI_PHY_RATE_MCS4_SGI | 43.3 Mbps (400 ns) | 90 Mbps (400 ns) | 51.6 Mbps (800 ns) | 43.3 Mbps (400 ns) | - ## | WIFI_PHY_RATE_MCS5_SGI | 57.8 Mbps (400 ns) | 120 Mbps (400 ns) | 68.8 Mbps (800 ns) | 57.8 Mbps (400 ns) | - ## | WIFI_PHY_RATE_MCS6_SGI | 65 Mbps (400 ns) | 135 Mbps (400 ns) | 77.4 Mbps (800 ns) | 65 Mbps (400 ns) | - ## | WIFI_PHY_RATE_MCS7_SGI | 72.2 Mbps (400 ns) | 150 Mbps (400 ns) | 86 Mbps (800 ns) | 72.2 Mbps (400 ns) | - ## | WIFI_PHY_RATE_MCS8_SGI | | | 103.2 Mbps (800 ns) | | - ## | WIFI_PHY_RATE_MCS9_SGI | | | 114.7 Mbps (800 ns) | | - ## - ## - -let - WIFI_PHY_RATE_1M_L {.importc: "WIFI_PHY_RATE_1M_L", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_2M_L {.importc: "WIFI_PHY_RATE_2M_L", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_5M_L {.importc: "WIFI_PHY_RATE_5M_L", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_11M_L {.importc: "WIFI_PHY_RATE_11M_L", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_2M_S {.importc: "WIFI_PHY_RATE_2M_S", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_5M_S {.importc: "WIFI_PHY_RATE_5M_S", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_11M_S {.importc: "WIFI_PHY_RATE_11M_S", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_48M {.importc: "WIFI_PHY_RATE_48M", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_24M {.importc: "WIFI_PHY_RATE_24M", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_12M {.importc: "WIFI_PHY_RATE_12M", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_6M {.importc: "WIFI_PHY_RATE_6M", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_54M {.importc: "WIFI_PHY_RATE_54M", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_36M {.importc: "WIFI_PHY_RATE_36M", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_18M {.importc: "WIFI_PHY_RATE_18M", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_9M {.importc: "WIFI_PHY_RATE_9M", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS0_LGI {.importc: "WIFI_PHY_RATE_MCS0_LGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS1_LGI {.importc: "WIFI_PHY_RATE_MCS1_LGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS2_LGI {.importc: "WIFI_PHY_RATE_MCS2_LGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS3_LGI {.importc: "WIFI_PHY_RATE_MCS3_LGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS4_LGI {.importc: "WIFI_PHY_RATE_MCS4_LGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS5_LGI {.importc: "WIFI_PHY_RATE_MCS5_LGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS6_LGI {.importc: "WIFI_PHY_RATE_MCS6_LGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS7_LGI {.importc: "WIFI_PHY_RATE_MCS7_LGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS8_LGI {.importc: "WIFI_PHY_RATE_MCS8_LGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS9_LGI {.importc: "WIFI_PHY_RATE_MCS9_LGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS0_SGI {.importc: "WIFI_PHY_RATE_MCS0_SGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS1_SGI {.importc: "WIFI_PHY_RATE_MCS1_SGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS2_SGI {.importc: "WIFI_PHY_RATE_MCS2_SGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS3_SGI {.importc: "WIFI_PHY_RATE_MCS3_SGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS4_SGI {.importc: "WIFI_PHY_RATE_MCS4_SGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS5_SGI {.importc: "WIFI_PHY_RATE_MCS5_SGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS6_SGI {.importc: "WIFI_PHY_RATE_MCS6_SGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS7_SGI {.importc: "WIFI_PHY_RATE_MCS7_SGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS8_SGI {.importc: "WIFI_PHY_RATE_MCS8_SGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MCS9_SGI {.importc: "WIFI_PHY_RATE_MCS9_SGI", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_LORA_250K {.importc: "WIFI_PHY_RATE_LORA_250K", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_LORA_500K {.importc: "WIFI_PHY_RATE_LORA_500K", header: hdr.}: wifi_phy_rate_t - WIFI_PHY_RATE_MAX {.importc: "WIFI_PHY_RATE_MAX", header: hdr.}: wifi_phy_rate_t - - -type - - wifi_event_t* {.size: sizeof(cint).} = enum ## - ## @brief Wi-Fi event declarations - ## - WIFI_EVENT_WIFI_READY = 0, ## < Wi-Fi ready - WIFI_EVENT_SCAN_DONE, ## < Finished scanning AP - WIFI_EVENT_STA_START, ## < Station start - WIFI_EVENT_STA_STOP, ## < Station stop - WIFI_EVENT_STA_CONNECTED, ## < Station connected to AP - WIFI_EVENT_STA_DISCONNECTED, ## < Station disconnected from AP - WIFI_EVENT_STA_AUTHMODE_CHANGE, ## < The auth mode of AP connected by device's station changed - WIFI_EVENT_STA_WPS_ER_SUCCESS, ## < Station WPS succeeds in enrollee mode - WIFI_EVENT_STA_WPS_ER_FAILED, ## < Station WPS fails in enrollee mode - WIFI_EVENT_STA_WPS_ER_TIMEOUT, ## < Station WPS timeout in enrollee mode - WIFI_EVENT_STA_WPS_ER_PIN, ## < Station WPS pin code in enrollee mode - WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, ## < Station WPS overlap in enrollee mode - WIFI_EVENT_AP_START, ## < Soft-AP start - WIFI_EVENT_AP_STOP, ## < Soft-AP stop - WIFI_EVENT_AP_STACONNECTED, ## < A station connected to Soft-AP - WIFI_EVENT_AP_STADISCONNECTED, ## < A station disconnected from Soft-AP - WIFI_EVENT_AP_PROBEREQRECVED, ## < Receive probe request packet in soft-AP interface - WIFI_EVENT_FTM_REPORT, ## < Receive report of FTM procedure - ## Add next events after this only - WIFI_EVENT_STA_BSS_RSSI_LOW, ## < AP's RSSI crossed configured threshold - WIFI_EVENT_ACTION_TX_STATUS, ## < Status indication of Action Tx operation - WIFI_EVENT_ROC_DONE, ## < Remain-on-Channel operation complete - WIFI_EVENT_STA_BEACON_TIMEOUT, ## < Station beacon timeout - WIFI_EVENT_CONNECTIONLESS_MODULE_WAKE_INTERVAL_START, ## - ## < Connectionless module wake interval start - ## Add next events after this only - WIFI_EVENT_AP_WPS_RG_SUCCESS, ## < Soft-AP wps succeeds in registrar mode - WIFI_EVENT_AP_WPS_RG_FAILED, ## < Soft-AP wps fails in registrar mode - WIFI_EVENT_AP_WPS_RG_TIMEOUT, ## < Soft-AP wps timeout in registrar mode - WIFI_EVENT_AP_WPS_RG_PIN, ## < Soft-AP wps pin code in registrar mode - WIFI_EVENT_AP_WPS_RG_PBC_OVERLAP, ## < Soft-AP wps overlap in registrar mode - WIFI_EVENT_ITWT_SETUP, ## < iTWT setup - WIFI_EVENT_ITWT_TEARDOWN, ## < iTWT teardown - WIFI_EVENT_ITWT_PROBE, ## < iTWT probe - WIFI_EVENT_ITWT_SUSPEND, ## < iTWT suspend - WIFI_EVENT_TWT_WAKEUP, ## < TWT wakeup - WIFI_EVENT_BTWT_SETUP, ## < bTWT setup - WIFI_EVENT_BTWT_TEARDOWN, ## < bTWT teardown - WIFI_EVENT_NAN_STARTED, ## < NAN Discovery has started - WIFI_EVENT_NAN_STOPPED, ## < NAN Discovery has stopped - WIFI_EVENT_NAN_SVC_MATCH, ## < NAN Service Discovery match found - WIFI_EVENT_NAN_REPLIED, ## < Replied to a NAN peer with Service Discovery match - WIFI_EVENT_NAN_RECEIVE, ## < Received a Follow-up message - WIFI_EVENT_NDP_INDICATION, ## < Received NDP Request from a NAN Peer - WIFI_EVENT_NDP_CONFIRM, ## < NDP Confirm Indication - WIFI_EVENT_NDP_TERMINATED, ## < NAN Datapath terminated indication - WIFI_EVENT_HOME_CHANNEL_CHANGE, ## < Wi-Fi home channel change,doesn't occur when scanning - WIFI_EVENT_STA_NEIGHBOR_REP, ## < Received Neighbor Report response - WIFI_EVENT_AP_WRONG_PASSWORD, ## < a station tried to connect with wrong password - WIFI_EVENT_STA_BEACON_OFFSET_UNSTABLE, ## < Station sampled beacon offset unstable - WIFI_EVENT_DPP_URI_READY, ## < DPP URI is ready through Bootstrapping - WIFI_EVENT_DPP_CFG_RECVD, ## < Config received via DPP Authentication - WIFI_EVENT_DPP_FAILED, ## < DPP failed - WIFI_EVENT_MAX ## < Invalid Wi-Fi event ID - - -## @cond * -## @brief Wi-Fi event base declaration - -# ESP_EVENT_DECLARE_BASE(WIFI_EVENT) -let WIFI_EVENT* {.importc: "WIFI_EVENT", header: "esp_wifi_types.h".}: esp_event_base_t - -type - - wifi_event_sta_scan_done_t* {.importc: "wifi_event_sta_scan_done_t", - header: hdr, bycopy.} = object ## - ## @endcond * - ## - ## @brief Argument structure for WIFI_EVENT_SCAN_DONE event - ## - status* {.importc: "status".}: uint32 ## < Status of scanning APs: 0 — success, 1 - failure - number* {.importc: "number".}: uint8 ## < Number of scan results - scan_id* {.importc: "scan_id".}: uint8 - ## < Scan sequence number, used for block scan - - - wifi_event_sta_connected_t* {.importc: "wifi_event_sta_connected_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_STA_CONNECTED event - ## - ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of connected AP - ssid_len* {.importc: "ssid_len".}: uint8 ## < SSID length of connected AP - bssid* {.importc: "bssid".}: array[6, uint8] ## < BSSID of connected AP - channel* {.importc: "channel".}: uint8 ## < Channel of connected AP - authmode* {.importc: "authmode".}: wifi_auth_mode_t ## - ## < Authentication mode used by the connection - aid* {.importc: "aid".}: uint16 - ## < Authentication id assigned by the connected AP - - - wifi_event_sta_disconnected_t* {.importc: "wifi_event_sta_disconnected_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_STA_DISCONNECTED event - ## - ssid* {.importc: "ssid".}: array[32, uint8] ## < SSID of disconnected AP - ssid_len* {.importc: "ssid_len".}: uint8 ## < SSID length of disconnected AP - bssid* {.importc: "bssid".}: array[6, uint8] ## < BSSID of disconnected AP - reason* {.importc: "reason".}: uint8 ## < Disconnection reason - rssi* {.importc: "rssi".}: int8 - ## < Disconnection RSSI - - - wifi_event_sta_authmode_change_t* {.importc: "wifi_event_sta_authmode_change_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_STA_AUTHMODE_CHANGE event - ## - old_mode* {.importc: "old_mode".}: wifi_auth_mode_t ## - ## < Old auth mode of AP - new_mode* {.importc: "new_mode".}: wifi_auth_mode_t - ## < New auth mode of AP - - - wifi_event_sta_wps_er_pin_t* {.importc: "wifi_event_sta_wps_er_pin_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_STA_WPS_ER_PIN event - ## - pin_code* {.importc: "pin_code".}: array[8, uint8] - ## < PIN code of station in enrollee mode - - - wifi_event_sta_wps_fail_reason_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Argument structure for WIFI_EVENT_STA_WPS_ER_FAILED event - ## - WPS_FAIL_REASON_NORMAL = 0, ## < WPS normal fail reason - WPS_FAIL_REASON_RECV_M2D, ## < WPS receive M2D frame - WPS_FAIL_REASON_RECV_DEAUTH, ## < Recv deauth from AP while wps handshake - WPS_FAIL_REASON_MAX ## < Max WPS fail reason - -const - MAX_SSID_LEN* = 32 - MAX_PASSPHRASE_LEN* = 64 - MAX_WPS_AP_CRED* = 3 - -type - - INNER_C_STRUCT_esp_wifi_types_generic_1* {. - importc: "wifi_event_sta_wps_er_success_t::no_name", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_STA_WPS_ER_SUCCESS event - ## - ssid* {.importc: "ssid".}: array[MAX_SSID_LEN, uint8] ## - ## < SSID of AP - passphrase* {.importc: "passphrase".}: array[MAX_PASSPHRASE_LEN, uint8] - ## < Passphrase for the AP - - - wifi_event_sta_wps_er_success_t* {.importc: "wifi_event_sta_wps_er_success_t", - header: hdr, bycopy.} = object - ap_cred_cnt* {.importc: "ap_cred_cnt".}: uint8 ## - ## < Number of AP credentials received - ap_cred* {.importc: "ap_cred".}: array[MAX_WPS_AP_CRED, - INNER_C_STRUCT_esp_wifi_types_generic_1] - ## < All AP credentials received from WPS handshake - - - wifi_event_ap_staconnected_t* {.importc: "wifi_event_ap_staconnected_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_AP_STACONNECTED event - ## - mac* {.importc: "mac".}: array[6, uint8] ## < MAC address of the station connected to Soft-AP - aid* {.importc: "aid".}: uint8 ## < AID assigned by the Soft-AP to the connected station - is_mesh_child* {.importc: "is_mesh_child".}: bool - ## < Flag indicating whether the connected station is a mesh child - - - wifi_event_ap_stadisconnected_t* {.importc: "wifi_event_ap_stadisconnected_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_AP_STADISCONNECTED event - ## - mac* {.importc: "mac".}: array[6, uint8] ## < MAC address of the station disconnects from the soft-AP - aid* {.importc: "aid".}: uint8 ## < AID that the Soft-AP assigned to the disconnected station - is_mesh_child* {.importc: "is_mesh_child".}: bool ## - ## < Flag indicating whether the disconnected station is a mesh child - reason* {.importc: "reason".}: uint16 - ## < Disconnection reason - - - wifi_event_ap_probe_req_rx_t* {.importc: "wifi_event_ap_probe_req_rx_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_AP_PROBEREQRECVED event - ## - rssi* {.importc: "rssi".}: cint ## < Received probe request signal strength - mac* {.importc: "mac".}: array[6, uint8] - ## < MAC address of the station which send probe request - - - wifi_event_bss_rssi_low_t* {.importc: "wifi_event_bss_rssi_low_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_STA_BSS_RSSI_LOW event - ## - rssi* {.importc: "rssi".}: int32 - ## < RSSI value of bss - - - wifi_event_home_channel_change_t* {.importc: "wifi_event_home_channel_change_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_HOME_CHANNEL_CHANGE event - ## - old_chan* {.importc: "old_chan".}: uint8 ## < Old home channel of the device - old_snd* {.importc: "old_snd".}: wifi_second_chan_t ## - ## < Old second channel of the device - new_chan* {.importc: "new_chan".}: uint8 ## < New home channel of the device - new_snd* {.importc: "new_snd".}: wifi_second_chan_t - ## < New second channel of the device - - - wifi_ftm_status_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief FTM operation status types - ## - ## - FTM_STATUS_SUCCESS = 0, ## < FTM exchange is successful - FTM_STATUS_UNSUPPORTED, ## < Peer does not support FTM - FTM_STATUS_CONF_REJECTED, ## < Peer rejected FTM configuration in FTM Request - FTM_STATUS_NO_RESPONSE, ## < Peer did not respond to FTM Requests - FTM_STATUS_FAIL, ## < Unknown error during FTM exchange - FTM_STATUS_NO_VALID_MSMT, ## < FTM session did not result in any valid measurements - FTM_STATUS_USER_TERM ## < User triggered termination - - -type - - wifi_ftm_report_entry_t* {.importc: "wifi_ftm_report_entry_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Structure representing a report entry for Fine Timing Measurement (FTM) in Wi-Fi. - ## - ## This structure holds the information related to the FTM process between a Wi-Fi FTM Initiator - ## and a Wi-Fi FTM Responder. FTM is used for precise distance measurement by timing the exchange - ## of frames between devices. - ## - dlog_token* {.importc: "dlog_token".}: uint8 ## < Dialog Token of the FTM frame - rssi* {.importc: "rssi".}: int8 ## < RSSI of the FTM frame received - rtt* {.importc: "rtt".}: uint32 ## < Round Trip Time in pSec with a peer - t1* {.importc: "t1".}: uint64 ## < Time of departure of FTM frame from FTM Responder in pSec - t2* {.importc: "t2".}: uint64 ## < Time of arrival of FTM frame at FTM Initiator in pSec - t3* {.importc: "t3".}: uint64 ## < Time of departure of ACK from FTM Initiator in pSec - t4* {.importc: "t4".}: uint64 - ## < Time of arrival of ACK at FTM Responder in pSec - - - wifi_event_ftm_report_t* {.importc: "wifi_event_ftm_report_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_FTM_REPORT event - ## - peer_mac* {.importc: "peer_mac".}: array[6, uint8] ## - ## < MAC address of the FTM Peer - status* {.importc: "status".}: wifi_ftm_status_t ## - ## < Status of the FTM operation - rtt_raw* {.importc: "rtt_raw".}: uint32 ## < Raw average Round-Trip-Time with peer in Nano-Seconds - rtt_est* {.importc: "rtt_est".}: uint32 ## < Estimated Round-Trip-Time with peer in Nano-Seconds - dist_est* {.importc: "dist_est".}: uint32 ## < Estimated one-way distance in Centi-Meters - ftm_report_data* {.importc: "ftm_report_data".}: ptr wifi_ftm_report_entry_t ## - ## < Pointer to FTM Report, should be freed after use. Note: Highly recommended - ## to use API esp_wifi_ftm_get_report to get the report instead of using this - ftm_report_num_entries* {.importc: "ftm_report_num_entries".}: uint8 - ## < Number of entries in the FTM Report data - - -const - WIFI_STATIS_BUFFER* = (1 shl 0) ## < Buffer status - WIFI_STATIS_RXTX* = (1 shl 1) ## < RX/TX status - WIFI_STATIS_HW* = (1 shl 2) ## < Hardware status - WIFI_STATIS_DIAG* = (1 shl 3) ## < Diagnostic status - WIFI_STATIS_PS* = (1 shl 4) ## < Power save status - WIFI_STATIS_ALL* = (-1) ## < All status - -type - - wifi_action_tx_status_type_t* {.size: sizeof(cint).} = enum ## - ## Status codes for WIFI_EVENT_ACTION_TX_STATUS evt - ## There will be back to back events in success case TX_DONE and TX_DURATION_COMPLETED - WIFI_ACTION_TX_DONE = 0, ## < ACTION_TX operation was completed successfully - WIFI_ACTION_TX_FAILED, ## < ACTION_TX operation failed during tx - WIFI_ACTION_TX_DURATION_COMPLETED, ## < ACTION_TX operation completed it's wait duration - WIFI_ACTION_TX_OP_CANCELLED ## < ACTION_TX operation was cancelled by application or higher priority operation - - -type - - wifi_event_action_tx_status_t* {.importc: "wifi_event_action_tx_status_t", - header: hdr, bycopy.} = object ## - ## Argument structure for WIFI_EVENT_ACTION_TX_STATUS event - ifx* {.importc: "ifx".}: wifi_interface_t ## < WiFi interface to send request to - context* {.importc: "context".}: uint32 ## < Context to identify the request - status* {.importc: "status".}: wifi_action_tx_status_type_t ## - ## < Status of the operation - op_id* {.importc: "op_id".}: uint8 ## < ID of the corresponding operation that was provided during action tx request - channel* {.importc: "channel".}: uint8 - ## < Channel provided in tx request - - - wifi_event_roc_done_t* {.importc: "wifi_event_roc_done_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_ROC_DONE event - ## - context* {.importc: "context".}: uint32 ## < Context to identify the initiator of the request - status* {.importc: "status".}: wifi_roc_done_status_t ## - ## < ROC status - op_id* {.importc: "op_id".}: uint8 ## < ID of the corresponding ROC operation - channel* {.importc: "channel".}: uint8 - ## < Channel provided in tx request - - - wifi_event_ap_wps_rg_pin_t* {.importc: "wifi_event_ap_wps_rg_pin_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_AP_WPS_RG_PIN event - ## - pin_code* {.importc: "pin_code".}: array[8, uint8] - ## < PIN code of station in enrollee mode - - - wps_fail_reason_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief WPS fail reason - ## - WPS_AP_FAIL_REASON_NORMAL = 0, ## < WPS normal fail reason - WPS_AP_FAIL_REASON_CONFIG, ## < WPS failed due to incorrect config - WPS_AP_FAIL_REASON_AUTH, ## < WPS failed during auth - WPS_AP_FAIL_REASON_MAX ## < Max WPS fail reason - - -type - - wifi_event_ap_wps_rg_fail_reason_t* {.importc: "wifi_event_ap_wps_rg_fail_reason_t", - header: hdr, - bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_AP_WPS_RG_FAILED event - ## - reason* {.importc: "reason".}: wps_fail_reason_t ## - ## < WPS failure reason wps_fail_reason_t - peer_macaddr* {.importc: "peer_macaddr".}: array[6, uint8] - ## < Enrollee mac address - - - wifi_event_ap_wps_rg_success_t* {.importc: "wifi_event_ap_wps_rg_success_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_AP_WPS_RG_SUCCESS event - ## - peer_macaddr* {.importc: "peer_macaddr".}: array[6, uint8] - ## < Enrollee mac address - - - wifi_event_nan_svc_match_t* {.importc: "wifi_event_nan_svc_match_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_NAN_SVC_MATCH event - ## - subscribe_id* {.importc: "subscribe_id".}: uint8 ## - ## < Subscribe Service Identifier - publish_id* {.importc: "publish_id".}: uint8 ## < Publish Service Identifier - pub_if_mac* {.importc: "pub_if_mac".}: array[6, uint8] ## - ## < NAN Interface MAC of the Publisher - update_pub_id* {.importc: "update_pub_id".}: bool ## - ## < Indicates whether publisher's service ID needs to be updated - datapath_reqd* {.importc: "datapath_reqd", bitsize: 1.}: uint8 ## - ## < NAN Datapath required for the service - fsd_reqd* {.importc: "fsd_reqd", bitsize: 1.}: uint8 ## - ## < Further Service Discovery(FSD) required - fsd_gas* {.importc: "fsd_gas", bitsize: 1.}: uint8 ## - ## < 0 - Follow-up used for FSD, 1 - GAS used for FSD - reserved* {.importc: "reserved", bitsize: 5.}: uint8 ## - ## < Reserved - reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved - reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved - ssi_version* {.importc: "ssi_version".}: uint8 ## - ## < Indicates version of SSI in Publish instance, 0 if not available - ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info - ssi* {.importc: "ssi".}: UncheckedArray[uint8] - ## < Service specific info of Publisher - - - wifi_event_nan_replied_t* {.importc: "wifi_event_nan_replied_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_NAN_REPLIED event - ## - publish_id* {.importc: "publish_id".}: uint8 ## < Publish Service Identifier - subscribe_id* {.importc: "subscribe_id".}: uint8 ## - ## < Subscribe Service Identifier - sub_if_mac* {.importc: "sub_if_mac".}: array[6, uint8] ## - ## < NAN Interface MAC of the Subscriber - reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved - reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved - ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info - ssi* {.importc: "ssi".}: UncheckedArray[uint8] - ## < Service specific info of Subscriber - - - wifi_event_nan_receive_t* {.importc: "wifi_event_nan_receive_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_NAN_RECEIVE event - ## - inst_id* {.importc: "inst_id".}: uint8 ## < Our Service Identifier - peer_inst_id* {.importc: "peer_inst_id".}: uint8 ## - ## < Peer's Service Identifier - peer_if_mac* {.importc: "peer_if_mac".}: array[6, uint8] ## - ## < Peer's NAN Interface MAC - peer_svc_info* {.importc: "peer_svc_info".}: array[ - ESP_WIFI_MAX_SVC_INFO_LEN, uint8] ## < To be deprecated in next major release, use ssi instead - reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved - reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved - ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info - ssi* {.importc: "ssi".}: UncheckedArray[uint8] - ## < Service specific info from Follow-up - - - wifi_event_ndp_indication_t* {.importc: "wifi_event_ndp_indication_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_NDP_INDICATION event - ## - publish_id* {.importc: "publish_id".}: uint8 ## < Publish Id for NAN Service - ndp_id* {.importc: "ndp_id".}: uint8 ## < NDP instance id - peer_nmi* {.importc: "peer_nmi".}: array[6, uint8] ## - ## < Peer's NAN Management Interface MAC - peer_ndi* {.importc: "peer_ndi".}: array[6, uint8] ## - ## < Peer's NAN Data Interface MAC - svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, uint8] ## - ## < To be deprecated in next major release, use ssi instead - reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved - reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved - ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of service specific info - ssi* {.importc: "ssi".}: UncheckedArray[uint8] - ## < Service specific info from NDP/NDPE Attribute - - - wifi_event_ndp_confirm_t* {.importc: "wifi_event_ndp_confirm_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_NDP_CONFIRM event - ## - status* {.importc: "status".}: uint8 ## < NDP status code - ndp_id* {.importc: "ndp_id".}: uint8 ## < NDP instance id - peer_nmi* {.importc: "peer_nmi".}: array[6, uint8] ## - ## < Peer's NAN Management Interface MAC - peer_ndi* {.importc: "peer_ndi".}: array[6, uint8] ## - ## < Peer's NAN Data Interface MAC - own_ndi* {.importc: "own_ndi".}: array[6, uint8] ## - ## < Own NAN Data Interface MAC - svc_info* {.importc: "svc_info".}: array[ESP_WIFI_MAX_SVC_INFO_LEN, uint8] ## - ## < To be deprecated in next major release, use ssi instead - reserved_1* {.importc: "reserved_1".}: uint32 ## < Reserved - reserved_2* {.importc: "reserved_2".}: uint32 ## < Reserved - ssi_len* {.importc: "ssi_len".}: uint16 ## < Length of Service Specific Info - ssi* {.importc: "ssi".}: UncheckedArray[uint8] - ## < Service specific info from NDP/NDPE Attribute - - - wifi_event_ndp_terminated_t* {.importc: "wifi_event_ndp_terminated_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_NDP_TERMINATED event - ## - reason* {.importc: "reason".}: uint8 ## < Termination reason code - ndp_id* {.importc: "ndp_id".}: uint8 ## < NDP instance id - init_ndi* {.importc: "init_ndi".}: array[6, uint8] - ## < Initiator's NAN Data Interface MAC - - - wifi_event_neighbor_report_t* {.importc: "wifi_event_neighbor_report_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for WIFI_EVENT_STA_NEIGHBOR_REP event - ## - report* {.importc: "report".}: array[ESP_WIFI_MAX_NEIGHBOR_REP_LEN, uint8] ## - ## < Neighbor Report received from the AP (will be deprecated in next major release, use n_report instead) - report_len* {.importc: "report_len".}: uint16 ## < Length of the report - n_report* {.importc: "n_report".}: UncheckedArray[uint8] - ## < Neighbor Report received from the AP - - - wifi_event_ap_wrong_password_t* {.importc: "wifi_event_ap_wrong_password_t", - header: hdr, bycopy.} = object ## - ## Argument structure for WIFI_EVENT_AP_WRONG_PASSWORD event - mac* {.importc: "mac".}: array[6, uint8] - ## < MAC address of the station trying to connect to Soft-AP - - - wifi_tx_rate_config_t* {.importc: "wifi_tx_rate_config_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Argument structure for wifi_tx_rate_config - ## - phymode* {.importc: "phymode".}: wifi_phy_mode_t ## - ## < Phymode of specified interface - rate* {.importc: "rate".}: wifi_phy_rate_t ## < Rate of specified interface - ersu* {.importc: "ersu".}: bool ## < Using ERSU to send frame, ERSU is a transmission mode related to 802.11 ax. - ## ERSU is always used in long distance transmission, and its frame has lower rate compared with SU mode - dcm* {.importc: "dcm".}: bool - ## < Using dcm rate to send frame - - -const - WIFI_MAX_SUPPORT_COUNTRY_NUM* = 176 - -when defined(CONFIG_SOC_WIFI_SUPPORT_5G): - const - WIFI_MAX_REGULATORY_RULE_NUM* = 7 -else: - const - WIFI_MAX_REGULATORY_RULE_NUM* = 2 -type - - wifi_reg_rule_t* {.importc: "wifi_reg_rule_t", - header: hdr, bycopy.} = object ## - ## Argument structure for regulatory rule - start_channel* {.importc: "start_channel".}: uint8 ## - ## < start channel of regulatory rule - end_channel* {.importc: "end_channel".}: uint8 ## - ## < end channel of regulatory rule - max_bandwidth* {.importc: "max_bandwidth", bitsize: 3.}: uint16 ## - ## < max bandwidth(MHz) of regulatory rule, 1:20M, 2:40M, 3:80M, 4:160M - max_eirp* {.importc: "max_eirp", bitsize: 6.}: uint16 ## - ## < indicates the maximum Equivalent Isotropically Radiated Power (EIRP), typically measured in dBm - is_dfs* {.importc: "is_dfs", bitsize: 1.}: uint16 ## - ## < flag to identify dfs channel - reserved* {.importc: "reserved", bitsize: 6.}: uint16 - ## < reserved - - - wifi_regulatory_t* {.importc: "wifi_regulatory_t", - header: hdr, bycopy.} = object ## - ## Argument structure for regdomain - n_reg_rules* {.importc: "n_reg_rules".}: uint8 ## - ## < number of regulatory rules - reg_rules* {.importc: "reg_rules".}: array[WIFI_MAX_REGULATORY_RULE_NUM, - wifi_reg_rule_t] - ## < array of regulatory rules - - - wifi_regdomain_t* {.importc: "wifi_regdomain_t", - header: hdr, bycopy.} = object ## - ## Argument structure for regdomain - cn* {.importc: "cn".}: array[2, char] ## < country code string - regulatory_type* {.importc: "regulatory_type".}: uint8 - ## < regulatory type of country - - - wifi_tx_status_t* {.size: sizeof(cint).} = enum ## - ## - ## @brief Status of wifi sending data - ## - WIFI_SEND_SUCCESS = 0, ## < Sending Wi-Fi data successfully - WIFI_SEND_FAIL ## < Sending Wi-Fi data fail - - -type - - wifi_tx_info_t* {.importc: "wifi_tx_info_t", - header: hdr, bycopy.} = object ## - ## - ## @brief Information of wifi sending data - ## - des_addr* {.importc: "des_addr".}: ptr uint8 ## < The address of the receive device - src_addr* {.importc: "src_addr".}: ptr uint8 ## < The address of the sending device - ifidx* {.importc: "ifidx".}: wifi_interface_t ## < Interface of sending 80211 tx data - data* {.importc: "data".}: ptr uint8 ## < The data for 80211 tx, start from the MAC header - data_len* {.importc: "data_len".}: uint8 ## < The frame body length for 80211 tx, excluding the MAC header - rate* {.importc: "rate".}: wifi_phy_rate_t ## < Data rate - tx_status* {.importc: "tx_status".}: wifi_tx_status_t - ## < Status of sending 80211 tx data - - - esp_80211_tx_info_t* = wifi_tx_info_t - - wifi_event_sta_beacon_offset_unstable_t* {. - importc: "wifi_event_sta_beacon_offset_unstable_t", - header: hdr, bycopy.} = object ## - ## Argument structure for WIFI_EVENT_STA_BEACON_OFFSET_UNSTABLE event - beacon_success_rate* {.importc: "beacon_success_rate".}: cfloat - ## < Received beacon success rate - - - wifi_event_dpp_uri_ready_t* {.importc: "wifi_event_dpp_uri_ready_t", - header: hdr, bycopy.} = object ## - ## Argument structure for WIFI_EVENT_DPP_URI_READY event - uri_data_len* {.importc: "uri_data_len".}: uint32 ## - ## < URI data length including null termination - uri* {.importc: "uri".}: UncheckedArray[char] - ## < URI data - - - wifi_event_dpp_config_received_t* {.importc: "wifi_event_dpp_config_received_t", - header: hdr, bycopy.} = object ## - ## Argument structure for WIFI_EVENT_DPP_CFG_RECVD event - wifi_cfg* {.importc: "wifi_cfg".}: wifi_config_t - ## < Received WIFI config in DPP - - - wifi_event_dpp_failed_t* {.importc: "wifi_event_dpp_failed_t", - header: hdr, bycopy.} = object ## - ## Argument structure for WIFI_EVENT_DPP_FAIL event - failure_reason* {.importc: "failure_reason".}: cint - ## < Failure reason - diff --git a/src/nesper/esp/net/esp_wifi_types_old.nim b/src/nesper/esp/net/esp_wifi_types_old.nim new file mode 100644 index 00000000..1cad2b36 --- /dev/null +++ b/src/nesper/esp/net/esp_wifi_types_old.nim @@ -0,0 +1,610 @@ +## Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. + +import ../esp_event + +type + wifi_country_policy_t* {.size: sizeof(cint).} = enum + WIFI_COUNTRY_POLICY_AUTO, ## *< Country policy is auto, use the country info of AP to which the station is connected + WIFI_COUNTRY_POLICY_MANUAL ## *< Country policy is manual, always use the configured country info + + +## * @brief Structure describing WiFi country-based regional restrictions. + +type + wifi_country_t* {.importc: "wifi_country_t", header: "esp_wifi_types.h", bycopy.} = object + cc* {.importc: "cc".}: array[3, char] ## *< country code string + schan* {.importc: "schan".}: uint8 ## *< start channel + nchan* {.importc: "nchan".}: uint8 ## *< total channel number + max_tx_power* {.importc: "max_tx_power".}: int8 ## *< This field is used for getting WiFi maximum transmitting power, call esp_wifi_set_max_tx_power to set the maximum transmitting power. + policy* {.importc: "policy".}: wifi_country_policy_t ## *< country policy + + wifi_auth_mode_t* {.size: sizeof(cint).} = enum + WIFI_AUTH_OPEN = 0, ## *< authenticate mode : open + WIFI_AUTH_WEP, ## *< authenticate mode : WEP + WIFI_AUTH_WPA_PSK, ## *< authenticate mode : WPA_PSK + WIFI_AUTH_WPA2_PSK, ## *< authenticate mode : WPA2_PSK + WIFI_AUTH_WPA_WPA2_PSK, ## *< authenticate mode : WPA_WPA2_PSK + WIFI_AUTH_WPA2_ENTERPRISE, ## *< authenticate mode : WPA2_ENTERPRISE + WIFI_AUTH_WPA3_PSK, ## *< authenticate mode : WPA3_PSK + WIFI_AUTH_WPA2_WPA3_PSK, ## *< authenticate mode : WPA2_WPA3_PSK + WIFI_AUTH_MAX + wifi_err_reason_t* {.size: sizeof(cint).} = enum + WIFI_REASON_UNSPECIFIED = 1, WIFI_REASON_AUTH_EXPIRE = 2, + WIFI_REASON_AUTH_LEAVE = 3, WIFI_REASON_ASSOC_EXPIRE = 4, + WIFI_REASON_ASSOC_TOOMANY = 5, WIFI_REASON_NOT_AUTHED = 6, + WIFI_REASON_NOT_ASSOCED = 7, WIFI_REASON_ASSOC_LEAVE = 8, + WIFI_REASON_ASSOC_NOT_AUTHED = 9, WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, + WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11, WIFI_REASON_IE_INVALID = 13, + WIFI_REASON_MIC_FAILURE = 14, WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, + WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, WIFI_REASON_IE_IN_4WAY_DIFFERS = 17, + WIFI_REASON_GROUP_CIPHER_INVALID = 18, + WIFI_REASON_PAIRWISE_CIPHER_INVALID = 19, WIFI_REASON_AKMP_INVALID = 20, + WIFI_REASON_UNSUPP_RSN_IE_VERSION = 21, WIFI_REASON_INVALID_RSN_IE_CAP = 22, + WIFI_REASON_802_1X_AUTH_FAILED = 23, WIFI_REASON_CIPHER_SUITE_REJECTED = 24, + WIFI_REASON_INVALID_PMKID = 53, WIFI_REASON_BEACON_TIMEOUT = 200, + WIFI_REASON_NO_AP_FOUND = 201, WIFI_REASON_AUTH_FAIL = 202, + WIFI_REASON_ASSOC_FAIL = 203, WIFI_REASON_HANDSHAKE_TIMEOUT = 204, + WIFI_REASON_CONNECTION_FAIL = 205 + wifi_second_chan_t* {.size: sizeof(cint).} = enum + WIFI_SECOND_CHAN_NONE = 0, ## *< the channel width is HT20 + WIFI_SECOND_CHAN_ABOVE, ## *< the channel width is HT40 and the secondary channel is above the primary channel + WIFI_SECOND_CHAN_BELOW ## *< the channel width is HT40 and the secondary channel is below the primary channel + wifi_scan_type_t* {.size: sizeof(cint).} = enum + WIFI_SCAN_TYPE_ACTIVE = 0, ## *< active scan + WIFI_SCAN_TYPE_PASSIVE ## *< passive scan + + + + + +## * @brief Range of active scan times per channel + +type + wifi_active_scan_time_t* {.importc: "wifi_active_scan_time_t", + header: "esp_wifi_types.h", bycopy.} = object + min* {.importc: "min".}: uint32 ## *< minimum active scan time per channel, units: millisecond + max* {.importc: "max".}: uint32 ## *< maximum active scan time per channel, units: millisecond, values above 1500ms may + ## cause station to disconnect from AP and are not recommended. + + +## * @brief Aggregate of active & passive scan time per channel + +type + wifi_scan_time_t* {.importc: "wifi_scan_time_t", header: "esp_wifi_types.h", bycopy, union.} = object + active* {.importc: "active".}: wifi_active_scan_time_t ## *< active scan time per channel, units: millisecond. + passive* {.importc: "passive".}: uint32 ## *< passive scan time per channel, units: millisecond, values above 1500ms may + ## cause station to disconnect from AP and are not recommended. + + +## * @brief Parameters for an SSID scan. + +type + wifi_scan_config_t* {.importc: "wifi_scan_config_t", header: "esp_wifi_types.h", + bycopy.} = object + ssid* {.importc: "ssid".}: ptr uint8 ## *< SSID of AP + bssid* {.importc: "bssid".}: ptr uint8 ## *< MAC address of AP + channel* {.importc: "channel".}: uint8 ## *< channel, scan the specific channel + show_hidden* {.importc: "show_hidden".}: bool ## *< enable to scan AP whose SSID is hidden + scan_type* {.importc: "scan_type".}: wifi_scan_type_t ## *< scan type, active or passive + scan_time* {.importc: "scan_time".}: wifi_scan_time_t ## *< scan time per channel + + wifi_cipher_type_t* {.size: sizeof(cint).} = enum + WIFI_CIPHER_TYPE_NONE = 0, ## *< the cipher type is none + WIFI_CIPHER_TYPE_WEP40, ## *< the cipher type is WEP40 + WIFI_CIPHER_TYPE_WEP104, ## *< the cipher type is WEP104 + WIFI_CIPHER_TYPE_TKIP, ## *< the cipher type is TKIP + WIFI_CIPHER_TYPE_CCMP, ## *< the cipher type is CCMP + WIFI_CIPHER_TYPE_TKIP_CCMP, ## *< the cipher type is TKIP and CCMP + WIFI_CIPHER_TYPE_AES_CMAC128, ## *< the cipher type is AES-CMAC-128 + WIFI_CIPHER_TYPE_UNKNOWN ## *< the cipher type is unknown + + +## * +## @brief WiFi antenna +## +## + +type + wifi_ant_t* {.size: sizeof(cint).} = enum + WIFI_ANT_ANT0, ## *< WiFi antenna 0 + WIFI_ANT_ANT1, ## *< WiFi antenna 1 + WIFI_ANT_MAX ## *< Invalid WiFi antenna + + +## * @brief Description of a WiFi AP + +type + wifi_ap_record_t* {.importc: "wifi_ap_record_t", header: "esp_wifi_types.h", bycopy.} = object + bssid* {.importc: "bssid".}: array[6, uint8] ## *< MAC address of AP + ssid* {.importc: "ssid".}: array[33, uint8] ## *< SSID of AP + primary* {.importc: "primary".}: uint8 ## *< channel of AP + second* {.importc: "second".}: wifi_second_chan_t ## *< secondary channel of AP + rssi* {.importc: "rssi".}: int8 ## *< signal strength of AP + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## *< authmode of AP + pairwise_cipher* {.importc: "pairwise_cipher".}: wifi_cipher_type_t ## *< pairwise cipher of AP + group_cipher* {.importc: "group_cipher".}: wifi_cipher_type_t ## *< group cipher of AP + ant* {.importc: "ant".}: wifi_ant_t ## *< antenna used to receive beacon from AP + phy_11b* {.importc: "phy_11b", bitsize: 1.}: uint32 ## *< bit: 0 flag to identify if 11b mode is enabled or not + phy_11g* {.importc: "phy_11g", bitsize: 1.}: uint32 ## *< bit: 1 flag to identify if 11g mode is enabled or not + phy_11n* {.importc: "phy_11n", bitsize: 1.}: uint32 ## *< bit: 2 flag to identify if 11n mode is enabled or not + phy_lr* {.importc: "phy_lr", bitsize: 1.}: uint32 ## *< bit: 3 flag to identify if low rate is enabled or not + wps* {.importc: "wps", bitsize: 1.}: uint32 ## *< bit: 4 flag to identify if WPS is supported or not + reserved* {.importc: "reserved", bitsize: 27.}: uint32 ## *< bit: 5..31 reserved + country* {.importc: "country".}: wifi_country_t ## *< country information of AP + + wifi_scan_method_t* {.size: sizeof(cint).} = enum + WIFI_FAST_SCAN = 0, ## *< Do fast scan, scan will end after find SSID match AP + WIFI_ALL_CHANNEL_SCAN ## *< All channel scan, scan will end after scan all the channel + wifi_sort_method_t* {.size: sizeof(cint).} = enum + WIFI_CONNECT_AP_BY_SIGNAL = 0, ## *< Sort match AP in scan list by RSSI + WIFI_CONNECT_AP_BY_SECURITY ## *< Sort match AP in scan list by security mode + + + +## * @brief Structure describing parameters for a WiFi fast scan + +type + wifi_scan_threshold_t* {.importc: "wifi_scan_threshold_t", + header: "esp_wifi_types.h", bycopy.} = object + rssi* {.importc: "rssi".}: int8 ## *< The minimum rssi to accept in the fast scan mode + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## *< The weakest authmode to accept in the fast scan mode + + wifi_ps_type_t* {.size: sizeof(cint).} = enum + WIFI_PS_NONE, ## *< No power save + WIFI_PS_MIN_MODEM, ## *< Minimum modem power saving. In this mode, station wakes up to receive beacon every DTIM period + WIFI_PS_MAX_MODEM ## *< Maximum modem power saving. In this mode, interval to receive beacons is determined by the listen_interval parameter in wifi_sta_config_t + + +const + WIFI_PROTOCOL_11B* = 1 + WIFI_PROTOCOL_11G* = 2 + WIFI_PROTOCOL_11N* = 4 + WIFI_PROTOCOL_LR* = 8 + +type + wifi_bandwidth_t* {.size: sizeof(cint).} = enum + WIFI_BW_HT20 = 1, ## Bandwidth is HT20 + WIFI_BW_HT40 ## Bandwidth is HT40 + + +## * Configuration structure for Protected Management Frame + +type + wifi_pmf_config_t* {.importc: "wifi_pmf_config_t", header: "esp_wifi_types.h", + bycopy.} = object + capable* {.importc: "capable".}: bool ## *< Advertizes support for Protected Management Frame. Device will prefer to connect in PMF mode if other device also advertizes PMF capability. + required* {.importc: "required".}: bool ## *< Advertizes that Protected Management Frame is required. Device will not associate to non-PMF capable devices. + + +## * @brief Soft-AP configuration settings for the ESP32 + +type + wifi_ap_config_t* {.importc: "wifi_ap_config_t", header: "esp_wifi_types.h", bycopy.} = object + ssid* {.importc: "ssid".}: array[32, uint8] ## *< SSID of ESP32 soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. + password* {.importc: "password".}: array[64, uint8] ## *< Password of ESP32 soft-AP. Null terminated string. + ssid_len* {.importc: "ssid_len".}: uint8 ## *< Optional length of SSID field. + channel* {.importc: "channel".}: uint8 ## *< Channel of ESP32 soft-AP + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## *< Auth mode of ESP32 soft-AP. Do not support AUTH_WEP in soft-AP mode + ssid_hidden* {.importc: "ssid_hidden".}: uint8 ## *< Broadcast SSID or not, default 0, broadcast the SSID + max_connection* {.importc: "max_connection".}: uint8 ## *< Max number of stations allowed to connect in, default 4, max 10 + beacon_interval* {.importc: "beacon_interval".}: uint16 ## *< Beacon interval, 100 ~ 60000 ms, default 100 ms + + +## * @brief STA configuration settings for the ESP32 + +type + wifi_sta_config_t* {.importc: "wifi_sta_config_t", header: "esp_wifi_types.h", + bycopy.} = object + ssid* {.importc: "ssid".}: array[32, uint8] ## *< SSID of target AP. Null terminated string. + password* {.importc: "password".}: array[64, uint8] ## *< Password of target AP. Null terminated string. + scan_method* {.importc: "scan_method".}: wifi_scan_method_t ## *< do all channel scan or fast scan + bssid_set* {.importc: "bssid_set".}: bool ## *< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP. + bssid* {.importc: "bssid".}: array[6, uint8] ## *< MAC address of target AP + channel* {.importc: "channel".}: uint8 ## *< channel of target AP. Set to 1~13 to scan starting from the specified channel before connecting to AP. If the channel of AP is unknown, set it to 0. + listen_interval* {.importc: "listen_interval".}: uint16 ## *< Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. + sort_method* {.importc: "sort_method".}: wifi_sort_method_t ## *< sort the connect AP in the list by rssi or security mode + threshold* {.importc: "threshold".}: wifi_scan_threshold_t ## *< When sort_method is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. + pmf_cfg* {.importc: "pmf_cfg".}: wifi_pmf_config_t ## *< Configuration for Protected Management Frame. Will be advertized in RSN Capabilities in RSN IE. + + +## * @brief Configuration data for ESP32 AP or STA. +## +## The usage of this union (for ap or sta configuration) is determined by the accompanying +## interface argument passed to esp_wifi_set_config() or esp_wifi_get_config() +## +## + +type + wifi_config_t* {.importc: "wifi_config_t", header: "esp_wifi_types.h", bycopy, union.} = object + ap* {.importc: "ap".}: wifi_ap_config_t ## *< configuration of AP + sta* {.importc: "sta".}: wifi_sta_config_t ## *< configuration of STA + + +## * @brief Description of STA associated with AP + +type + wifi_sta_info_t* {.importc: "wifi_sta_info_t", header: "esp_wifi_types.h", bycopy.} = object + mac* {.importc: "mac".}: array[6, uint8] ## *< mac address + rssi* {.importc: "rssi".}: int8 ## *< current average rssi of sta connected + phy_11b* {.importc: "phy_11b", bitsize: 1.}: uint32 ## *< bit: 0 flag to identify if 11b mode is enabled or not + phy_11g* {.importc: "phy_11g", bitsize: 1.}: uint32 ## *< bit: 1 flag to identify if 11g mode is enabled or not + phy_11n* {.importc: "phy_11n", bitsize: 1.}: uint32 ## *< bit: 2 flag to identify if 11n mode is enabled or not + phy_lr* {.importc: "phy_lr", bitsize: 1.}: uint32 ## *< bit: 3 flag to identify if low rate is enabled or not + reserved* {.importc: "reserved", bitsize: 28.}: uint32 ## *< bit: 4..31 reserved + + +const + ESP_WIFI_MAX_CONN_NUM* = (10) ## *< max number of stations which can connect to ESP32 soft-AP + +## * @brief List of stations associated with the ESP32 Soft-AP + +type + wifi_sta_list_t* {.importc: "wifi_sta_list_t", header: "esp_wifi_types.h", bycopy.} = object + sta* {.importc: "sta".}: array[ESP_WIFI_MAX_CONN_NUM, wifi_sta_info_t] ## *< station list + num* {.importc: "num".}: cint ## *< number of stations in the list (other entries are invalid) + + wifi_storage_t* {.size: sizeof(cint).} = enum + WIFI_STORAGE_FLASH, ## *< all configuration will store in both memory and flash + WIFI_STORAGE_RAM ## *< all configuration will only store in the memory + + +## * +## @brief Vendor Information Element type +## +## Determines the frame type that the IE will be associated with. +## + +type + wifi_vendor_ie_type_t* {.size: sizeof(cint).} = enum + WIFI_VND_IE_TYPE_BEACON, WIFI_VND_IE_TYPE_PROBE_REQ, + WIFI_VND_IE_TYPE_PROBE_RESP, WIFI_VND_IE_TYPE_ASSOC_REQ, + WIFI_VND_IE_TYPE_ASSOC_RESP + + +## * +## @brief Vendor Information Element index +## +## Each IE type can have up to two associated vendor ID elements. +## + +type + wifi_vendor_ie_id_t* {.size: sizeof(cint).} = enum + WIFI_VND_IE_ID_0, WIFI_VND_IE_ID_1 + + +const + WIFI_VENDOR_IE_ELEMENT_ID* = 0x000000DD + +## * +## @brief Vendor Information Element header +## +## The first bytes of the Information Element will match this header. Payload follows. +## + +type + vendor_ie_data_t* {.importc: "vendor_ie_data_t", header: "esp_wifi_types.h", bycopy.} = object + element_id* {.importc: "element_id".}: uint8 ## *< Should be set to WIFI_VENDOR_IE_ELEMENT_ID (0xDD) + length* {.importc: "length".}: uint8 ## *< Length of all bytes in the element data following this field. Minimum 4. + vendor_oui* {.importc: "vendor_oui".}: array[3, uint8] ## *< Vendor identifier (OUI). + vendor_oui_type* {.importc: "vendor_oui_type".}: uint8 ## *< Vendor-specific OUI type. + payload* {.importc: "payload".}: UncheckedArray[uint8] ## *< Payload. Length is equal to value in 'length' field, minus 4. + + wifi_pkt_rx_ctrl_t* {.importc: "wifi_pkt_rx_ctrl_t", header: "esp_wifi_types.h", + bycopy.} = object + rssi* {.importc: "rssi", bitsize: 8.}: cint ## *< Received Signal Strength Indicator(RSSI) of packet. unit: dBm + rate* {.importc: "rate", bitsize: 5.}: cuint ## *< PHY rate encoding of the packet. Only valid for non HT(11bg) packet + r1* {.importc: "r1", bitsize: 1.}: cuint ## *< reserve + sig_mode* {.importc: "sig_mode", bitsize: 2.}: cuint ## *< 0: non HT(11bg) packet; 1: HT(11n) packet; 3: VHT(11ac) packet + r2* {.importc: "r2", bitsize: 16.}: cuint ## *< reserve + mcs* {.importc: "mcs", bitsize: 7.}: cuint ## *< Modulation Coding Scheme. If is HT(11n) packet, shows the modulation, range from 0 to 76(MSC0 ~ MCS76) + cwb* {.importc: "cwb", bitsize: 1.}: cuint ## *< Channel Bandwidth of the packet. 0: 20MHz; 1: 40MHz + r3* {.importc: "r3", bitsize: 16.}: cuint ## *< reserve + smoothing* {.importc: "smoothing", bitsize: 1.}: cuint ## *< reserve + not_sounding* {.importc: "not_sounding", bitsize: 1.}: cuint ## *< reserve + r4* {.importc: "r4", bitsize: 1.}: cuint ## *< reserve + aggregation* {.importc: "aggregation", bitsize: 1.}: cuint ## *< Aggregation. 0: MPDU packet; 1: AMPDU packet + stbc* {.importc: "stbc", bitsize: 2.}: cuint ## *< Space Time Block Code(STBC). 0: non STBC packet; 1: STBC packet + fec_coding* {.importc: "fec_coding", bitsize: 1.}: cuint ## *< Flag is set for 11n packets which are LDPC + sgi* {.importc: "sgi", bitsize: 1.}: cuint ## *< Short Guide Interval(SGI). 0: Long GI; 1: Short GI + noise_floor* {.importc: "noise_floor", bitsize: 8.}: cint ## *< noise floor of Radio Frequency Module(RF). unit: 0.25dBm + ampdu_cnt* {.importc: "ampdu_cnt", bitsize: 8.}: cuint ## *< ampdu cnt + channel* {.importc: "channel", bitsize: 4.}: cuint ## *< primary channel on which this packet is received + secondary_channel* {.importc: "secondary_channel", bitsize: 4.}: cuint ## *< secondary channel on which this packet is received. 0: none; 1: above; 2: below + r5* {.importc: "r5", bitsize: 8.}: cuint ## *< reserve + timestamp* {.importc: "timestamp", bitsize: 32.}: cuint ## *< timestamp. The local time when this packet is received. It is precise only if modem sleep or light sleep is not enabled. unit: microsecond + r6* {.importc: "r6", bitsize: 32.}: cuint ## *< reserve + r7* {.importc: "r7", bitsize: 31.}: cuint ## *< reserve + ant* {.importc: "ant", bitsize: 1.}: cuint ## *< antenna number from which this packet is received. 0: WiFi antenna 0; 1: WiFi antenna 1 + sig_len* {.importc: "sig_len", bitsize: 12.}: cuint ## *< length of packet including Frame Check Sequence(FCS) + r8* {.importc: "r8", bitsize: 12.}: cuint ## *< reserve + rx_state* {.importc: "rx_state", bitsize: 8.}: cuint ## *< state of the packet. 0: no error; others: error numbers which are not public + + wifi_promiscuous_pkt_type_t* {.size: sizeof(cint).} = enum + WIFI_PKT_MGMT, ## *< Management frame, indicates 'buf' argument is wifi_promiscuous_pkt_t + WIFI_PKT_CTRL, ## *< Control frame, indicates 'buf' argument is wifi_promiscuous_pkt_t + WIFI_PKT_DATA, ## *< Data frame, indiciates 'buf' argument is wifi_promiscuous_pkt_t + WIFI_PKT_MISC ## *< Other type, such as MIMO etc. 'buf' argument is wifi_promiscuous_pkt_t but the payload is zero length. + + +const + WIFI_PROMIS_FILTER_MASK_ALL* = (0xFFFFFFFF) ## *< filter all packets + WIFI_PROMIS_FILTER_MASK_MGMT* = (1) ## *< filter the packets with type of WIFI_PKT_MGMT + WIFI_PROMIS_FILTER_MASK_CTRL* = (1 shl 1) ## *< filter the packets with type of WIFI_PKT_CTRL + WIFI_PROMIS_FILTER_MASK_DATA* = (1 shl 2) ## *< filter the packets with type of WIFI_PKT_DATA + WIFI_PROMIS_FILTER_MASK_MISC* = (1 shl 3) ## *< filter the packets with type of WIFI_PKT_MISC + WIFI_PROMIS_FILTER_MASK_DATA_MPDU* = (1 shl 4) ## *< filter the MPDU which is a kind of WIFI_PKT_DATA + WIFI_PROMIS_FILTER_MASK_DATA_AMPDU* = (1 shl 5) ## *< filter the AMPDU which is a kind of WIFI_PKT_DATA + WIFI_PROMIS_CTRL_FILTER_MASK_ALL* = (0xFF800000) ## *< filter all control packets + WIFI_PROMIS_CTRL_FILTER_MASK_WRAPPER* = (1 shl 23) ## *< filter the control packets with subtype of Control Wrapper + WIFI_PROMIS_CTRL_FILTER_MASK_BAR* = (1 shl 24) ## *< filter the control packets with subtype of Block Ack Request + WIFI_PROMIS_CTRL_FILTER_MASK_BA* = (1 shl 25) ## *< filter the control packets with subtype of Block Ack + WIFI_PROMIS_CTRL_FILTER_MASK_PSPOLL* = (1 shl 26) ## *< filter the control packets with subtype of PS-Poll + WIFI_PROMIS_CTRL_FILTER_MASK_RTS* = (1 shl 27) ## *< filter the control packets with subtype of RTS + WIFI_PROMIS_CTRL_FILTER_MASK_CTS* = (1 shl 28) ## *< filter the control packets with subtype of CTS + WIFI_PROMIS_CTRL_FILTER_MASK_ACK* = (1 shl 29) ## *< filter the control packets with subtype of ACK + WIFI_PROMIS_CTRL_FILTER_MASK_CFEND* = (1 shl 30) ## *< filter the control packets with subtype of CF-END + WIFI_PROMIS_CTRL_FILTER_MASK_CFENDACK* = (1 shl 31) ## *< filter the control packets with subtype of CF-END+CF-ACK + +## * @brief Mask for filtering different packet types in promiscuous mode. + +type + wifi_promiscuous_filter_t* {.importc: "wifi_promiscuous_filter_t", + header: "esp_wifi_types.h", bycopy.} = object + filter_mask* {.importc: "filter_mask".}: uint32 ## *< OR of one or more filter values WIFI_PROMIS_FILTER_* + + +const + WIFI_EVENT_MASK_ALL* = (0xFFFFFFFF) ## *< mask all WiFi events + WIFI_EVENT_MASK_NONE* = (0) ## *< mask none of the WiFi events + WIFI_EVENT_MASK_AP_PROBEREQRECVED* = (BIT(0)) ## *< mask SYSTEM_EVENT_AP_PROBEREQRECVED event + +## * +## @brief Channel state information(CSI) configuration type +## +## + +type + wifi_csi_config_t* {.importc: "wifi_csi_config_t", header: "esp_wifi_types.h", + bycopy.} = object + lltf_en* {.importc: "lltf_en".}: bool ## *< enable to receive legacy long training field(lltf) data. Default enabled + htltf_en* {.importc: "htltf_en".}: bool ## *< enable to receive HT long training field(htltf) data. Default enabled + stbc_htltf2_en* {.importc: "stbc_htltf2_en".}: bool ## *< enable to receive space time block code HT long training field(stbc-htltf2) data. Default enabled + ltf_merge_en* {.importc: "ltf_merge_en".}: bool ## *< enable to generate htlft data by averaging lltf and ht_ltf data when receiving HT packet. Otherwise, use ht_ltf data directly. Default enabled + channel_filter_en* {.importc: "channel_filter_en".}: bool ## *< enable to turn on channel filter to smooth adjacent sub-carrier. Disable it to keep independence of adjacent sub-carrier. Default enabled + manu_scale* {.importc: "manu_scale".}: bool ## *< manually scale the CSI data by left shifting or automatically scale the CSI data. If set true, please set the shift bits. false: automatically. true: manually. Default false + shift* {.importc: "shift".}: uint8 ## *< manually left shift bits of the scale of the CSI data. The range of the left shift bits is 0~15 + + +## * +## @brief CSI data type +## +## + +type + wifi_csi_info_t* {.importc: "wifi_csi_info_t", header: "esp_wifi_types.h", bycopy.} = object + rx_ctrl* {.importc: "rx_ctrl".}: wifi_pkt_rx_ctrl_t ## *< received packet radio metadata header of the CSI data + mac* {.importc: "mac".}: array[6, uint8] ## *< source MAC address of the CSI data + first_word_invalid* {.importc: "first_word_invalid".}: bool ## *< first four bytes of the CSI data is invalid or not + buf* {.importc: "buf".}: ptr int8 ## *< buffer of CSI data + len* {.importc: "len".}: uint16 ## *< length of CSI data + + +## * +## @brief WiFi GPIO configuration for antenna selection +## +## + +type + wifi_ant_gpio_t* {.importc: "wifi_ant_gpio_t", header: "esp_wifi_types.h", bycopy.} = object + gpio_select* {.importc: "gpio_select", bitsize: 1.}: uint8 ## *< Whether this GPIO is connected to external antenna switch + gpio_num* {.importc: "gpio_num", bitsize: 7.}: uint8 ## *< The GPIO number that connects to external antenna switch + + +## * +## @brief WiFi GPIOs configuration for antenna selection +## +## + +type + wifi_ant_gpio_config_t* {.importc: "wifi_ant_gpio_config_t", + header: "esp_wifi_types.h", bycopy.} = object + gpio_cfg* {.importc: "gpio_cfg".}: array[4, wifi_ant_gpio_t] ## *< The configurations of GPIOs that connect to external antenna switch + + +## * +## @brief WiFi antenna mode +## +## + +type + wifi_ant_mode_t* {.size: sizeof(cint).} = enum + WIFI_ANT_MODE_ANT0, ## *< Enable WiFi antenna 0 only + WIFI_ANT_MODE_ANT1, ## *< Enable WiFi antenna 1 only + WIFI_ANT_MODE_AUTO, ## *< Enable WiFi antenna 0 and 1, automatically select an antenna + WIFI_ANT_MODE_MAX ## *< Invalid WiFi enabled antenna + + +## * +## @brief WiFi antenna configuration +## +## + +type + wifi_ant_config_t* {.importc: "wifi_ant_config_t", header: "esp_wifi_types.h", + bycopy.} = object + rx_ant_mode* {.importc: "rx_ant_mode".}: wifi_ant_mode_t ## *< WiFi antenna mode for receiving + rx_ant_default* {.importc: "rx_ant_default".}: wifi_ant_t ## *< Default antenna mode for receiving, it's ignored if rx_ant_mode is not WIFI_ANT_MODE_AUTO + tx_ant_mode* {.importc: "tx_ant_mode".}: wifi_ant_mode_t ## *< WiFi antenna mode for transmission, it can be set to WIFI_ANT_MODE_AUTO only if rx_ant_mode is set to WIFI_ANT_MODE_AUTO + enabled_ant0* {.importc: "enabled_ant0", bitsize: 4.}: uint8 ## *< Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT0 + enabled_ant1* {.importc: "enabled_ant1", bitsize: 4.}: uint8 ## *< Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT1 + + +## * +## @brief WiFi PHY rate encodings +## +## + +type + wifi_phy_rate_t* {.size: sizeof(cint).} = enum + WIFI_PHY_RATE_1M_L = 0x00000000, ## *< 1 Mbps with long preamble + WIFI_PHY_RATE_2M_L = 0x00000001, ## *< 2 Mbps with long preamble + WIFI_PHY_RATE_5M_L = 0x00000002, ## *< 5.5 Mbps with long preamble + WIFI_PHY_RATE_11M_L = 0x00000003, ## *< 11 Mbps with long preamble + WIFI_PHY_RATE_2M_S = 0x00000005, ## *< 2 Mbps with short preamble + WIFI_PHY_RATE_5M_S = 0x00000006, ## *< 5.5 Mbps with short preamble + WIFI_PHY_RATE_11M_S = 0x00000007, ## *< 11 Mbps with short preamble + WIFI_PHY_RATE_48M = 0x00000008, ## *< 48 Mbps + WIFI_PHY_RATE_24M = 0x00000009, ## *< 24 Mbps + WIFI_PHY_RATE_12M = 0x0000000A, ## *< 12 Mbps + WIFI_PHY_RATE_6M = 0x0000000B, ## *< 6 Mbps + WIFI_PHY_RATE_54M = 0x0000000C, ## *< 54 Mbps + WIFI_PHY_RATE_36M = 0x0000000D, ## *< 36 Mbps + WIFI_PHY_RATE_18M = 0x0000000E, ## *< 18 Mbps + WIFI_PHY_RATE_9M = 0x0000000F, ## *< 9 Mbps + WIFI_PHY_RATE_MCS0_LGI = 0x00000010, ## *< MCS0 with long GI, 6.5 Mbps for 20MHz, 13.5 Mbps for 40MHz + WIFI_PHY_RATE_MCS1_LGI = 0x00000011, ## *< MCS1 with long GI, 13 Mbps for 20MHz, 27 Mbps for 40MHz + WIFI_PHY_RATE_MCS2_LGI = 0x00000012, ## *< MCS2 with long GI, 19.5 Mbps for 20MHz, 40.5 Mbps for 40MHz + WIFI_PHY_RATE_MCS3_LGI = 0x00000013, ## *< MCS3 with long GI, 26 Mbps for 20MHz, 54 Mbps for 40MHz + WIFI_PHY_RATE_MCS4_LGI = 0x00000014, ## *< MCS4 with long GI, 39 Mbps for 20MHz, 81 Mbps for 40MHz + WIFI_PHY_RATE_MCS5_LGI = 0x00000015, ## *< MCS5 with long GI, 52 Mbps for 20MHz, 108 Mbps for 40MHz + WIFI_PHY_RATE_MCS6_LGI = 0x00000016, ## *< MCS6 with long GI, 58.5 Mbps for 20MHz, 121.5 Mbps for 40MHz + WIFI_PHY_RATE_MCS7_LGI = 0x00000017, ## *< MCS7 with long GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz + WIFI_PHY_RATE_MCS0_SGI = 0x00000018, ## *< MCS0 with short GI, 7.2 Mbps for 20MHz, 15 Mbps for 40MHz + WIFI_PHY_RATE_MCS1_SGI = 0x00000019, ## *< MCS1 with short GI, 14.4 Mbps for 20MHz, 30 Mbps for 40MHz + WIFI_PHY_RATE_MCS2_SGI = 0x0000001A, ## *< MCS2 with short GI, 21.7 Mbps for 20MHz, 45 Mbps for 40MHz + WIFI_PHY_RATE_MCS3_SGI = 0x0000001B, ## *< MCS3 with short GI, 28.9 Mbps for 20MHz, 60 Mbps for 40MHz + WIFI_PHY_RATE_MCS4_SGI = 0x0000001C, ## *< MCS4 with short GI, 43.3 Mbps for 20MHz, 90 Mbps for 40MHz + WIFI_PHY_RATE_MCS5_SGI = 0x0000001D, ## *< MCS5 with short GI, 57.8 Mbps for 20MHz, 120 Mbps for 40MHz + WIFI_PHY_RATE_MCS6_SGI = 0x0000001E, ## *< MCS6 with short GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz + WIFI_PHY_RATE_MCS7_SGI = 0x0000001F, ## *< MCS7 with short GI, 72.2 Mbps for 20MHz, 150 Mbps for 40MHz + WIFI_PHY_RATE_LORA_250K = 0x00000029, ## *< 250 Kbps + WIFI_PHY_RATE_LORA_500K = 0x0000002A, ## *< 500 Kbps + WIFI_PHY_RATE_MAX + + +## * WiFi event declarations + +type + wifi_event_t* {.size: sizeof(cint).} = enum + WIFI_EVENT_WIFI_READY = 0, ## *< ESP32 WiFi ready + WIFI_EVENT_SCAN_DONE, ## *< ESP32 finish scanning AP + WIFI_EVENT_STA_START, ## *< ESP32 station start + WIFI_EVENT_STA_STOP, ## *< ESP32 station stop + WIFI_EVENT_STA_CONNECTED, ## *< ESP32 station connected to AP + WIFI_EVENT_STA_DISCONNECTED, ## *< ESP32 station disconnected from AP + WIFI_EVENT_STA_AUTHMODE_CHANGE, ## *< the auth mode of AP connected by ESP32 station changed + WIFI_EVENT_STA_WPS_ER_SUCCESS, ## *< ESP32 station wps succeeds in enrollee mode + WIFI_EVENT_STA_WPS_ER_FAILED, ## *< ESP32 station wps fails in enrollee mode + WIFI_EVENT_STA_WPS_ER_TIMEOUT, ## *< ESP32 station wps timeout in enrollee mode + WIFI_EVENT_STA_WPS_ER_PIN, ## *< ESP32 station wps pin code in enrollee mode + WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, ## *< ESP32 station wps overlap in enrollee mode + WIFI_EVENT_AP_START, ## *< ESP32 soft-AP start + WIFI_EVENT_AP_STOP, ## *< ESP32 soft-AP stop + WIFI_EVENT_AP_STACONNECTED, ## *< a station connected to ESP32 soft-AP + WIFI_EVENT_AP_STADISCONNECTED, ## *< a station disconnected from ESP32 soft-AP + WIFI_EVENT_AP_PROBEREQRECVED ## *< Receive probe request packet in soft-AP interface + + +## * @cond * +## * @brief WiFi event base declaration + +# ESP_EVENT_DECLARE_BASE(WIFI_EVENT) +var WIFI_EVENT* {.importc: "WIFI_EVENT", header: "esp_wifi_types.h".}: esp_event_base_t + +## * @endcond * +## * Argument structure for WIFI_EVENT_SCAN_DONE event + +type + wifi_event_sta_scan_done_t* {.importc: "wifi_event_sta_scan_done_t", + header: "esp_wifi_types.h", bycopy.} = object + status* {.importc: "status".}: uint32 ## *< status of scanning APs: 0 — success, 1 - failure + number* {.importc: "number".}: uint8 ## *< number of scan results + scan_id* {.importc: "scan_id".}: uint8 ## *< scan sequence number, used for block scan + + +## * Argument structure for WIFI_EVENT_STA_CONNECTED event + +type + wifi_event_sta_connected_t* {.importc: "wifi_event_sta_connected_t", + header: "esp_wifi_types.h", bycopy.} = object + ssid* {.importc: "ssid".}: array[32, uint8] ## *< SSID of connected AP + ssid_len* {.importc: "ssid_len".}: uint8 ## *< SSID length of connected AP + bssid* {.importc: "bssid".}: array[6, uint8] ## *< BSSID of connected AP + channel* {.importc: "channel".}: uint8 ## *< channel of connected AP + authmode* {.importc: "authmode".}: wifi_auth_mode_t ## *< authentication mode used by AP + + +## * Argument structure for WIFI_EVENT_STA_DISCONNECTED event + +type + wifi_event_sta_disconnected_t* {.importc: "wifi_event_sta_disconnected_t", + header: "esp_wifi_types.h", bycopy.} = object + ssid* {.importc: "ssid".}: array[32, uint8] ## *< SSID of disconnected AP + ssid_len* {.importc: "ssid_len".}: uint8 ## *< SSID length of disconnected AP + bssid* {.importc: "bssid".}: array[6, uint8] ## *< BSSID of disconnected AP + reason* {.importc: "reason".}: uint8 ## *< reason of disconnection + + +## * Argument structure for WIFI_EVENT_STA_AUTHMODE_CHANGE event + +type + wifi_event_sta_authmode_change_t* {.importc: "wifi_event_sta_authmode_change_t", + header: "esp_wifi_types.h", bycopy.} = object + old_mode* {.importc: "old_mode".}: wifi_auth_mode_t ## *< the old auth mode of AP + new_mode* {.importc: "new_mode".}: wifi_auth_mode_t ## *< the new auth mode of AP + + +## * Argument structure for WIFI_EVENT_STA_WPS_ER_PIN event + +type + wifi_event_sta_wps_er_pin_t* {.importc: "wifi_event_sta_wps_er_pin_t", + header: "esp_wifi_types.h", bycopy.} = object + pin_code* {.importc: "pin_code".}: array[8, uint8] ## *< PIN code of station in enrollee mode + + +## * Argument structure for WIFI_EVENT_STA_WPS_ER_FAILED event + +type + wifi_event_sta_wps_fail_reason_t* {.size: sizeof(cint).} = enum + WPS_FAIL_REASON_NORMAL = 0, ## *< ESP32 WPS normal fail reason + WPS_FAIL_REASON_RECV_M2D, ## *< ESP32 WPS receive M2D frame + WPS_FAIL_REASON_MAX + + +## * Argument structure for WIFI_EVENT_AP_STACONNECTED event + +type + wifi_event_ap_staconnected_t* {.importc: "wifi_event_ap_staconnected_t", + header: "esp_wifi_types.h", bycopy.} = object + mac* {.importc: "mac".}: array[6, uint8] ## *< MAC address of the station connected to ESP32 soft-AP + aid* {.importc: "aid".}: uint8 ## *< the aid that ESP32 soft-AP gives to the station connected to + + +## * Argument structure for WIFI_EVENT_AP_STADISCONNECTED event + +type + wifi_event_ap_stadisconnected_t* {.importc: "wifi_event_ap_stadisconnected_t", + header: "esp_wifi_types.h", bycopy.} = object + mac* {.importc: "mac".}: array[6, uint8] ## *< MAC address of the station disconnects to ESP32 soft-AP + aid* {.importc: "aid".}: uint8 ## *< the aid that ESP32 soft-AP gave to the station disconnects to + + +## * Argument structure for WIFI_EVENT_AP_PROBEREQRECVED event + +type + wifi_event_ap_probe_req_rx_t* {.importc: "wifi_event_ap_probe_req_rx_t", + header: "esp_wifi_types.h", bycopy.} = object + rssi* {.importc: "rssi".}: cint ## *< Received probe request signal strength + mac* {.importc: "mac".}: array[6, uint8] ## *< MAC address of the station which send probe request + diff --git a/src/nesper/net_utils.nim b/src/nesper/net_utils.nim index 9f986852..263bc7b7 100644 --- a/src/nesper/net_utils.nim +++ b/src/nesper/net_utils.nim @@ -52,13 +52,6 @@ type ESP_IF_WIFI_AP, ## *< ESP32 soft-AP interface ESP_IF_ETH, ## *< ESP32 ethernet interface ESP_IF_MAX - wifi_mode_t* {.size: sizeof(cint).} = enum - WIFI_MODE_NULL = 0, ## *< null mode - WIFI_MODE_STA, ## *< WiFi station mode - WIFI_MODE_AP, ## *< WiFi soft-AP mode - WIFI_MODE_APSTA, ## *< WiFi station + soft-AP mode - WIFI_MODE_MAX - wifi_interface_t* = esp_interface_t const WIFI_IF_STA* = ESP_IF_WIFI_STA From 2b10b7819212db7d831771e0ec078bfcec4bc21e Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 01:31:38 -0600 Subject: [PATCH 116/142] update wifi example --- src/nesper/esp/net/esp_wifi_types.nim | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/nesper/esp/net/esp_wifi_types.nim b/src/nesper/esp/net/esp_wifi_types.nim index 2dcef267..dce38d50 100644 --- a/src/nesper/esp/net/esp_wifi_types.nim +++ b/src/nesper/esp/net/esp_wifi_types.nim @@ -892,6 +892,22 @@ const ## type + wifi_csi_config_t* {.importc: "wifi_csi_config_t", header: "esp_wifi_types.h", + bycopy.} = object + lltf_en* {.importc: "lltf_en".}: bool ## *< enable to receive legacy long training field(lltf) data. Default enabled + htltf_en* {.importc: "htltf_en".}: bool ## *< enable to receive HT long training field(htltf) data. Default enabled + stbc_htltf2_en* {.importc: "stbc_htltf2_en".}: bool ## *< enable to receive space time block code HT long training field(stbc-htltf2) data. Default enabled + ltf_merge_en* {.importc: "ltf_merge_en".}: bool ## *< enable to generate htlft data by averaging lltf and ht_ltf data when receiving HT packet. Otherwise, use ht_ltf data directly. Default enabled + channel_filter_en* {.importc: "channel_filter_en".}: bool ## *< enable to turn on channel filter to smooth adjacent sub-carrier. Disable it to keep independence of adjacent sub-carrier. Default enabled + manu_scale* {.importc: "manu_scale".}: bool ## *< manually scale the CSI data by left shifting or automatically scale the CSI data. If set true, please set the shift bits. false: automatically. true: manually. Default false + shift* {.importc: "shift".}: uint8 ## *< manually left shift bits of the scale of the CSI data. The range of the left shift bits is 0~15 + + wifi_pkt_rx_ctrl_t* {.importc: "wifi_pkt_rx_ctrl_t", header: "esp_wifi_types.h", + bycopy.} = object + rssi* {.importc: "rssi", bitsize: 8.}: cint ## *< Received Signal Strength Indicator(RSSI) of packet. unit: dBm + rate* {.importc: "rate", bitsize: 5.}: cuint ## *< PHY rate encoding of the packet. Only valid for non HT(11bg) packet + + wifi_csi_info_t* {.importc: "wifi_csi_info_t", header: "esp_wifi_types.h", bycopy.} = object rx_ctrl* {.importc: "rx_ctrl".}: wifi_pkt_rx_ctrl_t ## *< received packet radio metadata header of the CSI data mac* {.importc: "mac".}: array[6, uint8] ## *< source MAC address of the CSI data From e603be63a9c07d91917945af044e3eb013602518 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 01:35:00 -0600 Subject: [PATCH 117/142] update wifi example --- esp-idf-examples/simplewifi/main/main.nim | 2 +- src/nesper/esp/net/esp_wifi.nim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/esp-idf-examples/simplewifi/main/main.nim b/esp-idf-examples/simplewifi/main/main.nim index e9ffa614..aae3fae6 100644 --- a/esp-idf-examples/simplewifi/main/main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -73,7 +73,7 @@ proc wifiInitSta() = wifi_config.sta.sae_h2e_identifier.setFromString("") check: esp_wifi_set_mode(WIFI_MODE_STA) - check: esp_wifi_set_config(ESP_IF_WIFI_STA, addr wifi_config) + check: esp_wifi_set_config(WIFI_IF_STA, addr wifi_config) check: esp_wifi_start() logw(TAG, "Wifi Init Sta finished.") diff --git a/src/nesper/esp/net/esp_wifi.nim b/src/nesper/esp/net/esp_wifi.nim index eeaf18a7..b8484321 100644 --- a/src/nesper/esp/net/esp_wifi.nim +++ b/src/nesper/esp/net/esp_wifi.nim @@ -727,7 +727,7 @@ proc esp_wifi_get_promiscuous_ctrl_filter*(filter: ptr wifi_promiscuous_filter_t ## - others: refer to the erro code in esp_err.h ## -proc esp_wifi_set_config*(`interface`: wifi_interface_t; conf: ptr wifi_config_t): esp_err_t {. +proc esp_wifi_set_config*(intf: wifi_interface_t; conf: ptr wifi_config_t): esp_err_t {. importc: "esp_wifi_set_config", header: "esp_wifi.h".} ## * ## @brief Get configuration of specified interface @@ -742,7 +742,7 @@ proc esp_wifi_set_config*(`interface`: wifi_interface_t; conf: ptr wifi_config_t ## - ESP_ERR_WIFI_IF: invalid interface ## -proc esp_wifi_get_config*(`interface`: wifi_interface_t; conf: ptr wifi_config_t): esp_err_t {. +proc esp_wifi_get_config*(intf: wifi_interface_t; conf: ptr wifi_config_t): esp_err_t {. importc: "esp_wifi_get_config", header: "esp_wifi.h".} ## * ## @brief Get STAs associated with soft-AP From 91d2f209c04574586a9a0fb2d417ddc3aaf4af9d Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 01:37:36 -0600 Subject: [PATCH 118/142] update wifi example --- esp-idf-examples/simplewifi/main/main.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp-idf-examples/simplewifi/main/main.nim b/esp-idf-examples/simplewifi/main/main.nim index aae3fae6..cd1dfe86 100644 --- a/esp-idf-examples/simplewifi/main/main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -106,4 +106,4 @@ app_main(): while true: echo "looping..." - delayMillis(1000) + delayMillis(10_000) From 023a787ae468af89bfd1333065b46a38bb339b74 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 01:42:47 -0600 Subject: [PATCH 119/142] update wifi example --- esp-idf-examples/simplewifi/config.nims | 2 + .../simplewifi/main/CMakeLists.txt | 1 - esp-idf-examples/simplewifi/main/main.nim | 39 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/esp-idf-examples/simplewifi/config.nims b/esp-idf-examples/simplewifi/config.nims index bd5706dd..09e67e99 100644 --- a/esp-idf-examples/simplewifi/config.nims +++ b/esp-idf-examples/simplewifi/config.nims @@ -3,6 +3,8 @@ switch("define", "esp32s3") # or other variants switch("define", "nimNetSocketExtras") switch("define", "nimIoselectorEventfd") +switch("define", "FastRpcServer") + switch("define", "McuUtilsLoggingLevel:lvlTrace") patchFile("stdlib", "ioselectors_select", "main/ioselectors_select.nim") diff --git a/esp-idf-examples/simplewifi/main/CMakeLists.txt b/esp-idf-examples/simplewifi/main/CMakeLists.txt index 7676b03b..12f8ce0d 100644 --- a/esp-idf-examples/simplewifi/main/CMakeLists.txt +++ b/esp-idf-examples/simplewifi/main/CMakeLists.txt @@ -1,7 +1,6 @@ idf_component_register(SRC_DIRS "./nimcache" INCLUDE_DIRS "" - PRIV_REQUIRES esp_wifi nvs_flash esp_timer ) # set(C_COMPILE_OPTIONS "${C_COMPILE_OPTIONS} -Wno-error=unused-label") diff --git a/esp-idf-examples/simplewifi/main/main.nim b/esp-idf-examples/simplewifi/main/main.nim index cd1dfe86..889b2104 100644 --- a/esp-idf-examples/simplewifi/main/main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -88,6 +88,42 @@ proc wifiInitSta() = else: loge(TAG, "UNEXPECTED EVENT") +when defined(FastRpcServer): + import fastrpc/server/fastrpcserver + import fastrpc/server/rpcmethods + import nesper/esp/esp_vfs_eventfd + + # Define RPC Server # + DefineRpcs(name=exampleRpcs): + + proc add(a: int, b: int): int {.rpc.} = + echo "adding: ", a, " + ", b + result = 1 + a + b + + proc runFastRpcServer() = + try: + let cfg = ESP_VFS_EVENTD_CONFIG_DEFAULT() + logi(TAG, "cfg: %s", repr(cfg)) + check esp_vfs_eventfd_register(addr cfg) + + logi(TAG, "setting up fast rpc router") + let inetAddrs = [ + newInetAddr("::", 5555, Protocol.IPPROTO_UDP), + ] + logi(TAG, "newing fast rpc router") + var rt: FastRpcRouter = newFastRpcRouter() + logi(TAG, "registering rpcs") + rt.registerRpcs(exampleRpcs) + logi(TAG, "newing fast rpc server") + var frpcServer = newFastRpcServer(rt, prefixMsgSize=true, threaded=false) + logi(TAG, "starting fast rpc server") + startSocketServer(inetAddrs, frpcServer) + logi(TAG, "fast rpc server done") + except CatchableError as e: + loge(TAG, "Error starting FastRpcServer: %s, %s", $e.name, $e.msg) + for ste in getCurrentException().getStackTraceEntries(): + loge(TAG, "Error: %s", $ste) + app_main(): logw(TAG, "Running main app...") @@ -104,6 +140,9 @@ app_main(): else: wifiInitSta() + when defined(FastRpcServer): + runFastRpcServer() + while true: echo "looping..." delayMillis(10_000) From c7a723f5ba1475776a24d1f31a494eaa3c2ec051 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 01:48:29 -0600 Subject: [PATCH 120/142] update wifi example --- esp-idf-examples/simplewifi/main/main.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/esp-idf-examples/simplewifi/main/main.nim b/esp-idf-examples/simplewifi/main/main.nim index 889b2104..3c62a348 100644 --- a/esp-idf-examples/simplewifi/main/main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -108,6 +108,7 @@ when defined(FastRpcServer): logi(TAG, "setting up fast rpc router") let inetAddrs = [ + newInetAddr("0.0.0.0", 5556, Protocol.IPPROTO_UDP), newInetAddr("::", 5555, Protocol.IPPROTO_UDP), ] logi(TAG, "newing fast rpc router") From 01181ba3f88f377fa58a352e9ab9b3a5044700bc Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 02:45:42 -0600 Subject: [PATCH 121/142] update wifi example --- esp-idf-examples/net_pppos_usb/config.nims | 2 +- esp-idf-examples/simplewifi/config.nims | 2 +- .../simplewifi/main/ioselectors_select.nim | 482 ------------------ .../simplewifi/sdkconfig.defaults | 9 + .../networking/ioselectors_select_patch.nim | 18 +- 5 files changed, 22 insertions(+), 491 deletions(-) delete mode 100644 esp-idf-examples/simplewifi/main/ioselectors_select.nim create mode 100644 esp-idf-examples/simplewifi/sdkconfig.defaults rename esp-idf-examples/net_pppos_usb/main/ioselectors_select.nim => src/nesper/networking/ioselectors_select_patch.nim (96%) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index bfa97030..ff4d5f30 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -10,6 +10,6 @@ switch("define", "McuUtilsLoggingLevel:lvlTrace") # switch("define", "RUN_NCM") patchFile("stdlib", "cpuinfo", "main/cpuinfo.nim") -patchFile("stdlib", "ioselectors_select", "main/ioselectors_select.nim") +patchFile("stdlib", "ioselectors_select", "../../src/nesper/networking/ioselectors_select_patch.nim") include nesper/build_utils/builds diff --git a/esp-idf-examples/simplewifi/config.nims b/esp-idf-examples/simplewifi/config.nims index 09e67e99..6e4adda6 100644 --- a/esp-idf-examples/simplewifi/config.nims +++ b/esp-idf-examples/simplewifi/config.nims @@ -7,7 +7,7 @@ switch("define", "FastRpcServer") switch("define", "McuUtilsLoggingLevel:lvlTrace") -patchFile("stdlib", "ioselectors_select", "main/ioselectors_select.nim") +patchFile("stdlib", "ioselectors_select", "../../src/nesper/networking/ioselectors_select_patch.nim") switch("define", "EXAMPLE_ESP_WIFI_SSID=" & getEnv("WIFI_SSID")) switch("define", "EXAMPLE_ESP_WIFI_PASS=" & getEnv("WIFI_PASSWORD")) diff --git a/esp-idf-examples/simplewifi/main/ioselectors_select.nim b/esp-idf-examples/simplewifi/main/ioselectors_select.nim deleted file mode 100644 index 80f62ad7..00000000 --- a/esp-idf-examples/simplewifi/main/ioselectors_select.nim +++ /dev/null @@ -1,482 +0,0 @@ -# -# -# Nim's Runtime Library -# (c) Copyright 2016 Eugene Kabanov -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -# This module implements Posix and Windows select(). - -import std/[times, nativesockets] - -when defined(windows): - import std/winlean - when defined(gcc): - {.passl: "-lws2_32".} - elif defined(vcc): - {.passl: "ws2_32.lib".} - const platformHeaders = """#include - #include """ - const EAGAIN = WSAEWOULDBLOCK -else: - const platformHeaders = """#include - #include - #include - #include """ -type - FdSet {.importc: "fd_set", header: platformHeaders, pure, final.} = object -var - FD_SETSIZE {.importc: "FD_SETSIZE", header: platformHeaders.}: cint - -proc IOFD_SET(fd: SocketHandle, fdset: ptr FdSet) - {.cdecl, importc: "FD_SET", header: platformHeaders, inline.} -proc IOFD_CLR(fd: SocketHandle, fdset: ptr FdSet) - {.cdecl, importc: "FD_CLR", header: platformHeaders, inline.} -proc IOFD_ZERO(fdset: ptr FdSet) - {.cdecl, importc: "FD_ZERO", header: platformHeaders, inline.} - -when defined(windows): - proc IOFD_ISSET(fd: SocketHandle, fdset: ptr FdSet): cint - {.stdcall, importc: "FD_ISSET", header: platformHeaders, inline.} - proc ioselect(nfds: cint, readFds, writeFds, exceptFds: ptr FdSet, - timeout: ptr Timeval): cint - {.stdcall, importc: "select", header: platformHeaders.} -else: - proc IOFD_ISSET(fd: SocketHandle, fdset: ptr FdSet): cint - {.cdecl, importc: "FD_ISSET", header: platformHeaders, inline.} - proc ioselect(nfds: cint, readFds, writeFds, exceptFds: ptr FdSet, - timeout: ptr Timeval): cint - {.cdecl, importc: "select", header: platformHeaders.} - -when hasThreadSupport: - type - SelectorImpl[T] = object - rSet: FdSet - wSet: FdSet - eSet: FdSet - maxFD: int - fds: ptr SharedArray[SelectorKey[T]] - count*: int - lock: Lock - Selector*[T] = ptr SelectorImpl[T] -else: - type - SelectorImpl[T] = object - rSet: FdSet - wSet: FdSet - eSet: FdSet - maxFD: int - fds: seq[SelectorKey[T]] - count*: int - Selector*[T] = ref SelectorImpl[T] - -type - SelectEventImpl = object - rsock: SocketHandle - wsock: SocketHandle - SelectEvent* = ptr SelectEventImpl - -when hasThreadSupport: - template withSelectLock[T](s: Selector[T], body: untyped) = - acquire(s.lock) - {.locks: [s.lock].}: - try: - body - finally: - release(s.lock) -else: - template withSelectLock[T](s: Selector[T], body: untyped) = - body - -proc newSelector*[T](): Selector[T] = - when hasThreadSupport: - result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T]))) - result.fds = allocSharedArray[SelectorKey[T]](FD_SETSIZE) - initLock result.lock - else: - result = Selector[T]() - result.fds = newSeq[SelectorKey[T]](FD_SETSIZE) - - for i in 0 ..< FD_SETSIZE: - result.fds[i].ident = InvalidIdent - - IOFD_ZERO(addr result.rSet) - IOFD_ZERO(addr result.wSet) - IOFD_ZERO(addr result.eSet) - -proc close*[T](s: Selector[T]) = - when hasThreadSupport: - deallocSharedArray(s.fds) - deallocShared(cast[pointer](s)) - deinitLock(s.lock) - -when defined(windows): - proc newSelectEvent*(): SelectEvent = - var ssock = createNativeSocket() - var wsock = createNativeSocket() - var rsock: SocketHandle = INVALID_SOCKET - var saddr = Sockaddr_in() - - saddr.sin_family = winlean.AF_INET - saddr.sin_port = 0 - saddr.sin_addr.s_addr = INADDR_ANY - if bindAddr(ssock, cast[ptr SockAddr](addr(saddr)), - sizeof(saddr).SockLen) < 0'i32: - raiseIOSelectorsError(osLastError()) - - if winlean.listen(ssock, 1) != 0: - raiseIOSelectorsError(osLastError()) - - var namelen = sizeof(saddr).SockLen - if getsockname(ssock, cast[ptr SockAddr](addr(saddr)), - addr(namelen)) != 0'i32: - raiseIOSelectorsError(osLastError()) - - saddr.sin_addr.s_addr = 0x0100007F - if winlean.connect(wsock, cast[ptr SockAddr](addr(saddr)), - sizeof(saddr).SockLen) != 0: - raiseIOSelectorsError(osLastError()) - namelen = sizeof(saddr).SockLen - rsock = winlean.accept(ssock, cast[ptr SockAddr](addr(saddr)), - cast[ptr SockLen](addr(namelen))) - if rsock == SocketHandle(-1): - raiseIOSelectorsError(osLastError()) - - if winlean.closesocket(ssock) != 0: - raiseIOSelectorsError(osLastError()) - - var mode = clong(1) - if ioctlsocket(rsock, FIONBIO, addr(mode)) != 0: - raiseIOSelectorsError(osLastError()) - mode = clong(1) - if ioctlsocket(wsock, FIONBIO, addr(mode)) != 0: - raiseIOSelectorsError(osLastError()) - - result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) - result.rsock = rsock - result.wsock = wsock - - proc trigger*(ev: SelectEvent) = - var data: uint64 = 1 - if winlean.send(ev.wsock, cast[pointer](addr data), - cint(sizeof(uint64)), 0) != sizeof(uint64): - raiseIOSelectorsError(osLastError()) - - proc close*(ev: SelectEvent) = - let res1 = winlean.closesocket(ev.rsock) - let res2 = winlean.closesocket(ev.wsock) - deallocShared(cast[pointer](ev)) - if res1 != 0 or res2 != 0: - raiseIOSelectorsError(osLastError()) - -elif defined(nimIoselectorEventfd): - proc eventfd(fd: cint, flags: cint): cint {.importc: "eventfd", header: platformHeaders, inline.} - - proc newSelectEvent*(): SelectEvent = - when compiles(O_CLOEXEC): - echo "eventfd O_CLOEXEC or O_NONBLOCK" - let fdci = eventfd(0, O_CLOEXEC or O_NONBLOCK) - else: - echo "eventfd O_NONBLOCK" - let fdci = eventfd(0, 0) - echo "eventfd O_NONBLOCK result: ", $fdci - if fdci == -1: - raiseIOSelectorsError(osLastError()) - result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) - result.rsock = SocketHandle(fdci) - result.wsock = SocketHandle(-1) - - proc trigger*(ev: SelectEvent) = - var data: uint64 = 1 - if posix.write(ev.rsock.cint, addr data, sizeof(uint64)) == -1: - raiseIOSelectorsError(osLastError()) - - proc close*(ev: SelectEvent) = - let res = posix.close(ev.rsock.cint) - deallocShared(cast[pointer](ev)) - if res != 0: - raiseIOSelectorsError(osLastError()) - -else: - proc newSelectEvent*(): SelectEvent = - var fds: array[2, cint] - if posix.pipe(fds) != 0: - raiseIOSelectorsError(osLastError()) - setNonBlocking(fds[0]) - setNonBlocking(fds[1]) - result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) - result.rsock = SocketHandle(fds[0]) - result.wsock = SocketHandle(fds[1]) - - proc trigger*(ev: SelectEvent) = - var data: uint64 = 1 - if posix.write(cint(ev.wsock), addr data, sizeof(uint64)) != sizeof(uint64): - raiseIOSelectorsError(osLastError()) - - proc close*(ev: SelectEvent) = - let res1 = posix.close(cint(ev.rsock)) - let res2 = posix.close(cint(ev.wsock)) - deallocShared(cast[pointer](ev)) - if res1 != 0 or res2 != 0: - raiseIOSelectorsError(osLastError()) - -proc setSelectKey[T](s: Selector[T], fd: SocketHandle, events: set[Event], - data: T) = - var i = 0 - let fdi = int(fd) - while i < FD_SETSIZE: - if s.fds[i].ident == InvalidIdent: - var pkey = addr(s.fds[i]) - pkey.ident = fdi - pkey.events = events - pkey.data = data - break - inc(i) - if i >= FD_SETSIZE: - raiseIOSelectorsError("Maximum number of descriptors is exhausted!") - -proc getKey[T](s: Selector[T], fd: SocketHandle): ptr SelectorKey[T] = - var i = 0 - let fdi = int(fd) - while i < FD_SETSIZE: - if s.fds[i].ident == fdi: - result = addr(s.fds[i]) - break - inc(i) - doAssert(i < FD_SETSIZE, - "Descriptor [" & $int(fd) & "] is not registered in the queue!") - -proc delKey[T](s: Selector[T], fd: SocketHandle) = - var empty: T - var i = 0 - while i < FD_SETSIZE: - if s.fds[i].ident == fd.int: - s.fds[i].ident = InvalidIdent - s.fds[i].events = {} - s.fds[i].data = empty - break - inc(i) - doAssert(i < FD_SETSIZE, - "Descriptor [" & $int(fd) & "] is not registered in the queue!") - -proc registerHandle*[T](s: Selector[T], fd: int | SocketHandle, - events: set[Event], data: T) = - when not defined(windows): - let fdi = int(fd) - s.withSelectLock(): - s.setSelectKey(fd, events, data) - when not defined(windows): - if fdi > s.maxFD: s.maxFD = fdi - if Event.Read in events: - IOFD_SET(fd, addr s.rSet) - inc(s.count) - if Event.Write in events: - IOFD_SET(fd, addr s.wSet) - IOFD_SET(fd, addr s.eSet) - inc(s.count) - -proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = - when not defined(windows): - let fdi = int(ev.rsock) - s.withSelectLock(): - s.setSelectKey(ev.rsock, {Event.User}, data) - when not defined(windows): - if fdi > s.maxFD: s.maxFD = fdi - IOFD_SET(ev.rsock, addr s.rSet) - inc(s.count) - -proc updateHandle*[T](s: Selector[T], fd: int | SocketHandle, - events: set[Event]) = - let maskEvents = {Event.Timer, Event.Signal, Event.Process, Event.Vnode, - Event.User, Event.Oneshot, Event.Error} - s.withSelectLock(): - var pkey = s.getKey(fd) - doAssert(pkey.events * maskEvents == {}) - if pkey.events != events: - if (Event.Read in pkey.events) and (Event.Read notin events): - IOFD_CLR(fd, addr s.rSet) - dec(s.count) - if (Event.Write in pkey.events) and (Event.Write notin events): - IOFD_CLR(fd, addr s.wSet) - IOFD_CLR(fd, addr s.eSet) - dec(s.count) - if (Event.Read notin pkey.events) and (Event.Read in events): - IOFD_SET(fd, addr s.rSet) - inc(s.count) - if (Event.Write notin pkey.events) and (Event.Write in events): - IOFD_SET(fd, addr s.wSet) - IOFD_SET(fd, addr s.eSet) - inc(s.count) - pkey.events = events - -proc unregister*[T](s: Selector[T], fd: SocketHandle|int) = - s.withSelectLock(): - let fd = fd.SocketHandle - var pkey = s.getKey(fd) - if Event.Read in pkey.events or Event.User in pkey.events: - IOFD_CLR(fd, addr s.rSet) - dec(s.count) - if Event.Write in pkey.events: - IOFD_CLR(fd, addr s.wSet) - IOFD_CLR(fd, addr s.eSet) - dec(s.count) - s.delKey(fd) - -proc unregister*[T](s: Selector[T], ev: SelectEvent) = - let fd = ev.rsock - s.withSelectLock(): - var pkey = s.getKey(fd) - IOFD_CLR(fd, addr s.rSet) - dec(s.count) - s.delKey(fd) - -proc selectInto*[T](s: Selector[T], timeout: int, - results: var openArray[ReadyKey]): int = - var tv = Timeval() - var ptv = addr tv - var rset, wset, eset: FdSet - - verifySelectParams(timeout) - - if timeout != -1: - when defined(genode) or defined(freertos) or defined(zephyr) or defined(nuttx): - tv.tv_sec = posix.Time(timeout div 1_000) - else: - tv.tv_sec = timeout.int32 div 1_000 - tv.tv_usec = (timeout.int32 %% 1_000) * 1_000 - else: - ptv = nil - - s.withSelectLock(): - rset = s.rSet - wset = s.wSet - eset = s.eSet - - var count = ioselect(cint(s.maxFD) + 1, addr(rset), addr(wset), - addr(eset), ptv) - if count < 0: - result = 0 - when defined(windows): - raiseIOSelectorsError(osLastError()) - else: - let err = osLastError() - if cint(err) != EINTR: - raiseIOSelectorsError(err) - elif count == 0: - result = 0 - else: - var rindex = 0 - var i = 0 - var k = 0 - - while (i < FD_SETSIZE) and (k < count): - if s.fds[i].ident != InvalidIdent: - var flag = false - var pkey = addr(s.fds[i]) - var rkey = ReadyKey(fd: int(pkey.ident), events: {}) - let fd = SocketHandle(pkey.ident) - if IOFD_ISSET(fd, addr rset) != 0: - if Event.User in pkey.events: - var data: uint64 = 0 - if recv(fd, cast[pointer](addr(data)), - sizeof(uint64).cint, 0) != sizeof(uint64): - let err = osLastError() - if cint(err) != EAGAIN: - raiseIOSelectorsError(err) - else: - inc(i) - inc(k) - continue - else: - flag = true - rkey.events = {Event.User} - else: - flag = true - rkey.events = {Event.Read} - if IOFD_ISSET(fd, addr wset) != 0: - rkey.events.incl(Event.Write) - if IOFD_ISSET(fd, addr eset) != 0: - rkey.events.incl(Event.Error) - flag = true - if flag: - results[rindex] = rkey - inc(rindex) - inc(k) - inc(i) - result = rindex - -proc select*[T](s: Selector[T], timeout: int): seq[ReadyKey] = - result = newSeq[ReadyKey](FD_SETSIZE) - var count = selectInto(s, timeout, result) - result.setLen(count) - -proc flush*[T](s: Selector[T]) = discard - -template isEmpty*[T](s: Selector[T]): bool = - (s.count == 0) - -proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} = - s.withSelectLock(): - result = false - - let fdi = int(fd) - for i in 0.. Date: Fri, 5 Sep 2025 02:47:20 -0600 Subject: [PATCH 122/142] update wifi example --- src/nesper/networking/ioselectors_select_patch.nim | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/nesper/networking/ioselectors_select_patch.nim b/src/nesper/networking/ioselectors_select_patch.nim index 2e58f5de..315c858b 100644 --- a/src/nesper/networking/ioselectors_select_patch.nim +++ b/src/nesper/networking/ioselectors_select_patch.nim @@ -351,10 +351,8 @@ proc selectInto*[T](s: Selector[T], timeout: int, wset = s.wSet eset = s.eSet - echo "selectInto s.maxFD: ", $s.maxFD, " rset: ", $rset, " wset: ", $wset, " eset: ", $eset var count = ioselect(cint(s.maxFD) + 1, addr(rset), addr(wset), addr(eset), ptv) - echo "selectInto count: ", $count if count < 0: result = 0 when defined(windows): From 7ca187a5557033ddad6281f472e10559c03dfe98 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 02:50:12 -0600 Subject: [PATCH 123/142] update wifi example --- esp-idf-examples/simplewifi/config.nims | 2 +- esp-idf-examples/simplewifi/main/config.nims | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/esp-idf-examples/simplewifi/config.nims b/esp-idf-examples/simplewifi/config.nims index 6e4adda6..6edc6f79 100644 --- a/esp-idf-examples/simplewifi/config.nims +++ b/esp-idf-examples/simplewifi/config.nims @@ -5,7 +5,7 @@ switch("define", "nimIoselectorEventfd") switch("define", "FastRpcServer") -switch("define", "McuUtilsLoggingLevel:lvlTrace") +switch("define", "McuUtilsLoggingLevel:lvlInfo") patchFile("stdlib", "ioselectors_select", "../../src/nesper/networking/ioselectors_select_patch.nim") diff --git a/esp-idf-examples/simplewifi/main/config.nims b/esp-idf-examples/simplewifi/main/config.nims index 3259fd64..a15d6f72 100644 --- a/esp-idf-examples/simplewifi/main/config.nims +++ b/esp-idf-examples/simplewifi/main/config.nims @@ -1,6 +1,5 @@ --nomain --compileOnly ---define:debug --define:NimAppMain --nimcache:nimcache From 7189f4158935fb1442139e24f1b28c70f2d10cdc Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 03:07:14 -0600 Subject: [PATCH 124/142] update wifi example --- esp-idf-examples/simplewifi/main/config.nims | 1 + esp-idf-examples/simplewifi/main/main.nim | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/esp-idf-examples/simplewifi/main/config.nims b/esp-idf-examples/simplewifi/main/config.nims index a15d6f72..3259fd64 100644 --- a/esp-idf-examples/simplewifi/main/config.nims +++ b/esp-idf-examples/simplewifi/main/config.nims @@ -1,5 +1,6 @@ --nomain --compileOnly +--define:debug --define:NimAppMain --nimcache:nimcache diff --git a/esp-idf-examples/simplewifi/main/main.nim b/esp-idf-examples/simplewifi/main/main.nim index 3c62a348..9ee7ca98 100644 --- a/esp-idf-examples/simplewifi/main/main.nim +++ b/esp-idf-examples/simplewifi/main/main.nim @@ -97,7 +97,7 @@ when defined(FastRpcServer): DefineRpcs(name=exampleRpcs): proc add(a: int, b: int): int {.rpc.} = - echo "adding: ", a, " + ", b + echo "RPC: adding: ", a, " + ", b result = 1 + a + b proc runFastRpcServer() = From 6328a174482cc09235e705b29f556acc8a98c4b2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 03:29:52 -0600 Subject: [PATCH 125/142] update wifi example --- src/nesper/esp/esp_event.nim | 5 - src/nesper/esp/esp_event_legacy.nim | 1 - src/nesper/esp/mdns.nim | 8 +- src/nesper/esp/net/esp_netif.nim | 1 + src/nesper/esp/net/tcpip_adapter.nim | 856 --------------------------- src/nesper/general.nim | 3 - src/nesper/net_utils.nim | 35 -- tests/tgeneral.nim | 2 - 8 files changed, 5 insertions(+), 906 deletions(-) delete mode 100644 src/nesper/esp/net/tcpip_adapter.nim diff --git a/src/nesper/esp/esp_event.nim b/src/nesper/esp/esp_event.nim index c3094d61..071c3dd4 100644 --- a/src/nesper/esp/esp_event.nim +++ b/src/nesper/esp/esp_event.nim @@ -7,11 +7,6 @@ import ../consts export consts -when ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0): - import esp_event_legacy - - export esp_event_legacy - type esp_event_base_t* {.importc: "esp_event_base_t", header: "esp_event.h".} = pointer diff --git a/src/nesper/esp/esp_event_legacy.nim b/src/nesper/esp/esp_event_legacy.nim index 5bb163b4..1537b787 100644 --- a/src/nesper/esp/esp_event_legacy.nim +++ b/src/nesper/esp/esp_event_legacy.nim @@ -16,7 +16,6 @@ ## * System event types enumeration import ../consts import net/esp_wifi_types -import net/tcpip_adapter type system_event_id_t* {.size: sizeof(cint).} = enum diff --git a/src/nesper/esp/mdns.nim b/src/nesper/esp/mdns.nim index b7139bd6..05039bc0 100644 --- a/src/nesper/esp/mdns.nim +++ b/src/nesper/esp/mdns.nim @@ -403,7 +403,7 @@ proc mdns_query_txt*(instance_name: cstring; service_type: cstring; proto: cstri ## - ESP_ERR_INVALID_ARG parameter error ## -proc mdns_query_a*(host_name: cstring; timeout: uint32; `addr`: ptr ip4_addr_t): esp_err_t {. +proc mdns_query_a*(host_name: cstring; timeout: uint32; `addr`: ptr esp_ip4_addr_t): esp_err_t {. importc: "mdns_query_a", header: hdr.} ## * ## @brief Query mDNS for A record @@ -419,7 +419,7 @@ proc mdns_query_a*(host_name: cstring; timeout: uint32; `addr`: ptr ip4_addr_t): ## - ESP_ERR_INVALID_ARG parameter error ## -proc mdns_query_aaaa*(host_name: cstring; timeout: uint32; `addr`: ptr ip6_addr_t): esp_err_t {. +proc mdns_query_aaaa*(host_name: cstring; timeout: uint32; `addr`: ptr esp_ip6_addr_t): esp_err_t {. importc: "mdns_query_aaaa", header: hdr.} ## * ## @brief System event handler @@ -430,5 +430,5 @@ proc mdns_query_aaaa*(host_name: cstring; timeout: uint32; `addr`: ptr ip6_addr_ ## @param event The system event ## -proc mdns_handle_system_event*(ctx: pointer; event: ptr system_event_t): esp_err_t {. - importc: "mdns_handle_system_event", header: hdr.} \ No newline at end of file +# proc mdns_handle_system_event*(ctx: pointer; event: ptr system_event_t): esp_err_t {. +# importc: "mdns_handle_system_event", header: hdr.} \ No newline at end of file diff --git a/src/nesper/esp/net/esp_netif.nim b/src/nesper/esp/net/esp_netif.nim index b576091b..8a42a9ab 100644 --- a/src/nesper/esp/net/esp_netif.nim +++ b/src/nesper/esp/net/esp_netif.nim @@ -20,6 +20,7 @@ import ../../consts ## when defined(ESP_IDF_V4_0): + import esp_netif_ip_addr include tcpip_adapter else: diff --git a/src/nesper/esp/net/tcpip_adapter.nim b/src/nesper/esp/net/tcpip_adapter.nim deleted file mode 100644 index 3e46fa8b..00000000 --- a/src/nesper/esp/net/tcpip_adapter.nim +++ /dev/null @@ -1,856 +0,0 @@ -## Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## http://www.apache.org/licenses/LICENSE-2.0 -## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. - -import ../../consts -import ../../net_utils -import esp_wifi_types - -# import - # sys/queue, esp_wifi_types, sdkconfig - -# import - # lwip/ip_addr, dhcpserver/dhcpserver - -# type - # tcpip_adapter_dhcps_lease_t* = dhcps_lease_t - -# template IP2STR*(ipaddr: untyped): untyped = -# ip4_addr1_16(ipaddr) -# ip4_addr2_16(ipaddr) -# ip4_addr3_16(ipaddr) -# ip4_addr4_16(ipaddr) - -# const -# IPSTR* = "%d.%d.%d.%d" -# template IPV62STR*(ipaddr: untyped): untyped = -# IP6_ADDR_BLOCK1(addr((ipaddr))) -# IP6_ADDR_BLOCK2(addr((ipaddr))) -# IP6_ADDR_BLOCK3(addr((ipaddr))) -# IP6_ADDR_BLOCK4(addr((ipaddr))) -# IP6_ADDR_BLOCK5(addr((ipaddr))) -# IP6_ADDR_BLOCK6(addr((ipaddr))) -# IP6_ADDR_BLOCK7(addr((ipaddr))) -# IP6_ADDR_BLOCK8(addr((ipaddr))) - -# const - # IPV6STR* = "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" -## * @brief IPV4 IP address information -## -type - tcpip_adapter_ip_info_t* {.importc: "tcpip_adapter_ip_info_t", - header: "tcpip_adapter.h", bycopy.} = object - ip* {.importc: "ip".}: ip4_addr_t ## *< Interface IPV4 address - netmask* {.importc: "netmask".}: ip4_addr_t ## *< Interface IPV4 netmask - gw* {.importc: "gw".}: ip4_addr_t ## *< Interface IPV4 gateway address - -## * @brief IPV6 IP address information -## -type - tcpip_adapter_ip6_info_t* {.importc: "tcpip_adapter_ip6_info_t", - header: "tcpip_adapter.h", bycopy.} = object - ip* {.importc: "ip".}: ip6_addr_t ## *< Interface IPV6 address - -## * @brief IP address info of station connected to WLAN AP -## -## @note See also wifi_sta_info_t (MAC layer information only) -## -type - tcpip_adapter_sta_info_t* {.importc: "tcpip_adapter_sta_info_t", - header: "tcpip_adapter.h", bycopy.} = object - mac* {.importc: "mac".}: array[6, uint8] ## *< Station MAC address - ip* {.importc: "ip".}: ip4_addr_t ## *< Station assigned IP address - -## * @brief WLAN AP: Connected stations list -## -## Used to retrieve IP address information about connected stations. -## -type - tcpip_adapter_sta_list_t* {.importc: "tcpip_adapter_sta_list_t", - header: "tcpip_adapter.h", bycopy.} = object - sta* {.importc: "sta".}: array[ESP_WIFI_MAX_CONN_NUM, tcpip_adapter_sta_info_t] ## *< Connected stations - num* {.importc: "num".}: cint ## *< Number of connected stations - -const - ESP_ERR_TCPIP_ADAPTER_BASE* = 0x00005000 - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS* = ESP_ERR_TCPIP_ADAPTER_BASE + 0x00000001 - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY* = ESP_ERR_TCPIP_ADAPTER_BASE + 0x00000002 - ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED* = ESP_ERR_TCPIP_ADAPTER_BASE + - 0x00000003 - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED* = ESP_ERR_TCPIP_ADAPTER_BASE + - 0x00000004 - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED* = ESP_ERR_TCPIP_ADAPTER_BASE + - 0x00000005 - ESP_ERR_TCPIP_ADAPTER_NO_MEM* = ESP_ERR_TCPIP_ADAPTER_BASE + 0x00000006 - ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED* = ESP_ERR_TCPIP_ADAPTER_BASE + - 0x00000007 - -## @brief On-chip network interfaces - -type - tcpip_adapter_if_t* {.size: sizeof(cint).} = enum - TCPIP_ADAPTER_IF_STA = 0, ## *< Wi-Fi STA (station) interface - TCPIP_ADAPTER_IF_AP, ## *< Wi-Fi soft-AP interface - TCPIP_ADAPTER_IF_ETH, ## *< Ethernet interface - TCPIP_ADAPTER_IF_TEST, ## *< tcpip stack test interface - TCPIP_ADAPTER_IF_MAX - - -## * @brief Type of DNS server - -type - tcpip_adapter_dns_type_t* {.size: sizeof(cint).} = enum - TCPIP_ADAPTER_DNS_MAIN = 0, ## *< DNS main server address - TCPIP_ADAPTER_DNS_BACKUP, ## *< DNS backup server address (Wi-Fi STA and Ethernet only) - TCPIP_ADAPTER_DNS_FALLBACK, ## *< DNS fallback server address (Wi-Fi STA and Ethernet only) - TCPIP_ADAPTER_DNS_MAX - - -## * @brief DNS server info - -type - tcpip_adapter_dns_info_t* {.importc: "tcpip_adapter_dns_info_t", - header: "tcpip_adapter.h", bycopy.} = object - ip* {.importc: "ip".}: ip_addr_t ## *< IPV4 address of DNS server - - -## * @brief Status of DHCP client or DHCP server - -type - tcpip_adapter_dhcp_status_t* {.size: sizeof(cint).} = enum - TCPIP_ADAPTER_DHCP_INIT = 0, ## *< DHCP client/server is in initial state (not yet started) - TCPIP_ADAPTER_DHCP_STARTED, ## *< DHCP client/server has been started - TCPIP_ADAPTER_DHCP_STOPPED, ## *< DHCP client/server has been stopped - TCPIP_ADAPTER_DHCP_STATUS_MAX - - -## * @brief Mode for DHCP client or DHCP server option functions - -type - tcpip_adapter_dhcp_option_mode_t* {.size: sizeof(cint).} = enum - TCPIP_ADAPTER_OP_START = 0, TCPIP_ADAPTER_OP_SET, ## *< Set option - TCPIP_ADAPTER_OP_GET, ## *< Get option - TCPIP_ADAPTER_OP_MAX - - -## Deprecated name for tcpip_adapter_dhcp_option_mode_t, to remove after ESP-IDF V4.0 - -type - tcpip_adapter_option_mode_t* = tcpip_adapter_dhcp_option_mode_t - -## * @brief Supported options for DHCP client or DHCP server - -type - tcpip_adapter_dhcp_option_id_t* {.size: sizeof(cint).} = enum - TCPIP_ADAPTER_DOMAIN_NAME_SERVER = 6, ## *< Domain name server - TCPIP_ADAPTER_ROUTER_SOLICITATION_ADDRESS = 32, ## *< Solicitation router address - TCPIP_ADAPTER_REQUESTED_IP_ADDRESS = 50, ## *< Request specific IP address - TCPIP_ADAPTER_IP_ADDRESS_LEASE_TIME = 51, ## *< Request IP address lease time - TCPIP_ADAPTER_IP_REQUEST_RETRY_TIME = 52 ## *< Request IP address retry counter - - -## Deprecated name for tcpip_adapter_dhcp_option_id_t, to remove after ESP-IDF V4.0 - -type - tcpip_adapter_option_id_t* = tcpip_adapter_dhcp_option_id_t - -## * IP event declarations - -type - ip_event_t* {.size: sizeof(cint).} = enum - IP_EVENT_STA_GOT_IP, ## !< ESP32 station got IP from connected AP - IP_EVENT_STA_LOST_IP, ## !< ESP32 station lost IP and the IP is reset to 0 - IP_EVENT_AP_STAIPASSIGNED, ## !< ESP32 soft-AP assign an IP to a connected station - IP_EVENT_GOT_IP6, ## !< ESP32 station or ap or ethernet interface v6IP addr is preferred - IP_EVENT_ETH_GOT_IP ## !< ESP32 ethernet got IP from connected AP - - -## * @brief IP event base declaration - -# ESP_EVENT_DECLARE_BASE(IP_EVENT) -var IP_EVENT* {.importc: "IP_EVENT", header: "tcpip_adapter.h".}: esp_event_base_t -## * Event structure for IP_EVENT_STA_GOT_IP, IP_EVENT_ETH_GOT_IP events - -type - ip_event_got_ip_t* {.importc: "ip_event_got_ip_t", header: "tcpip_adapter.h", - bycopy.} = object - if_index* {.importc: "if_index".}: tcpip_adapter_if_t ## !< Interface for which the event is received - ip_info* {.importc: "ip_info".}: tcpip_adapter_ip_info_t ## !< IP address, netmask, gatway IP address - ip_changed* {.importc: "ip_changed".}: bool ## !< Whether the assigned IP has changed or not - - -## * Event structure for IP_EVENT_GOT_IP6 event - -type - ip_event_got_ip6_t* {.importc: "ip_event_got_ip6_t", header: "tcpip_adapter.h", - bycopy.} = object - if_index* {.importc: "if_index".}: tcpip_adapter_if_t ## !< Interface for which the event is received - ip6_info* {.importc: "ip6_info".}: tcpip_adapter_ip6_info_t ## !< IPv6 address of the interface - - -## * Event structure for IP_EVENT_AP_STAIPASSIGNED event - -type - ip_event_ap_staipassigned_t* {.importc: "ip_event_ap_staipassigned_t", - header: "tcpip_adapter.h", bycopy.} = object - ip* {.importc: "ip".}: ip4_addr_t ## !< IP address which was assigned to the station - - -## * -## @brief Initialize the underlying TCP/IP stack -## -## @note This function should be called exactly once from application code, when the application starts up. -## - -proc tcpip_adapter_init*() {.importc: "tcpip_adapter_init", - header: "tcpip_adapter.h".} -## * -## @brief Cause the TCP/IP stack to start the Ethernet interface with specified MAC and IP -## -## @note This function should be called after the Ethernet MAC hardware is initialized. In the default configuration, application code does not need to call this function - it is called automatically by the default handler for the SYSTEM_EVENT_ETH_START event. -## -## @param[in] mac Set MAC address of this interface -## @param[in] ip_info Set IP address of this interface -## @param[in] args extra args passed to tcpip_adapter -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_NO_MEM -## - -proc tcpip_adapter_eth_start*(mac: ptr uint8; - ip_info: ptr tcpip_adapter_ip_info_t; args: pointer): esp_err_t {. - importc: "tcpip_adapter_eth_start", header: "tcpip_adapter.h".} -## * -## @brief Cause the TCP/IP stack to start the Wi-Fi station interface with specified MAC and IP -## -## -## @note This function should be called after the Wi-Fi Station hardware is initialized. In the default configuration, application code does not need to call this function - it is called automatically by the default handler for the SYSTEM_EVENT_STA_START event. -## -## @param[in] mac Set MAC address of this interface -## @param[in] ip_info Set IP address of this interface -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_NO_MEM -## - -proc tcpip_adapter_sta_start*(mac: ptr uint8; ip_info: ptr tcpip_adapter_ip_info_t): esp_err_t {. - importc: "tcpip_adapter_sta_start", header: "tcpip_adapter.h".} -## * -## @brief Cause the TCP/IP stack to start the Wi-Fi AP interface with specified MAC and IP -## -## @note This function should be called after the Wi-Fi AP hardware is initialized. In the default configuration, application code does not need to call this function - it is called automatically by the default handler for the SYSTEM_EVENT_AP_START event. -## -## DHCP server will be started automatically when this function is called. -## -## @param[in] mac Set MAC address of this interface -## @param[in] ip_info Set IP address of this interface -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_NO_MEM -## - -proc tcpip_adapter_ap_start*(mac: ptr uint8; ip_info: ptr tcpip_adapter_ip_info_t): esp_err_t {. - importc: "tcpip_adapter_ap_start", header: "tcpip_adapter.h".} -## * -## @brief Cause the TCP/IP stack to stop a network interface -## -## Causes TCP/IP stack to clean up this interface. This includes stopping the DHCP server or client, if they are started. -## -## @note This API is called by the default Wi-Fi and Ethernet event handlers if the underlying network driver reports that the -## interface has stopped. -## -## @note To stop an interface from application code, call the network-specific API (esp_wifi_stop() or esp_eth_stop()). -## The driver layer will then send a stop event and the event handler should call this API. -## Otherwise, the driver and MAC layer will remain started. -## -## @param[in] tcpip_if Interface which will be stopped -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY -## - -proc tcpip_adapter_stop*(tcpip_if: tcpip_adapter_if_t): esp_err_t {. - importc: "tcpip_adapter_stop", header: "tcpip_adapter.h".} -## * -## @brief Cause the TCP/IP stack to bring up an interface -## -## @note This function is called automatically by the default event handlers for the Wi-Fi Station and Ethernet interfaces, -## in response to the SYSTEM_EVENT_STA_CONNECTED and SYSTEM_EVENT_ETH_CONNECTED events, respectively. -## -## @note This function is not normally used with Wi-Fi AP interface. If the AP interface is started, it is up. -## -## @param[in] tcpip_if Interface to bring up -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY -## - -proc tcpip_adapter_up*(tcpip_if: tcpip_adapter_if_t): esp_err_t {. - importc: "tcpip_adapter_up", header: "tcpip_adapter.h".} -## * -## @brief Cause the TCP/IP stack to shutdown an interface -## -## @note This function is called automatically by the default event handlers for the Wi-Fi Station and Ethernet interfaces, -## in response to the SYSTEM_EVENT_STA_DISCONNECTED and SYSTEM_EVENT_ETH_DISCONNECTED events, respectively. -## -## @note This function is not normally used with Wi-Fi AP interface. If the AP interface is stopped, it is down. -## -## @param[in] tcpip_if Interface to shutdown -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY -## - -proc tcpip_adapter_down*(tcpip_if: tcpip_adapter_if_t): esp_err_t {. - importc: "tcpip_adapter_down", header: "tcpip_adapter.h".} -## * -## @brief Get interface's IP address information -## -## If the interface is up, IP information is read directly from the TCP/IP stack. -## -## If the interface is down, IP information is read from a copy kept in the TCP/IP adapter -## library itself. -## -## @param[in] tcpip_if Interface to get IP information -## @param[out] ip_info If successful, IP information will be returned in this argument. -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - -proc tcpip_adapter_get_ip_info*(tcpip_if: tcpip_adapter_if_t; - ip_info: ptr tcpip_adapter_ip_info_t): esp_err_t {. - importc: "tcpip_adapter_get_ip_info", header: "tcpip_adapter.h".} -## * -## @brief Set interface's IP address information -## -## This function is mainly used to set a static IP on an interface. -## -## If the interface is up, the new IP information is set directly in the TCP/IP stack. -## -## The copy of IP information kept in the TCP/IP adapter library is also updated (this -## copy is returned if the IP is queried while the interface is still down.) -## -## @note DHCP client/server must be stopped before setting new IP information. -## -## @note Calling this interface for the Wi-Fi STA or Ethernet interfaces may generate a -## SYSTEM_EVENT_STA_GOT_IP or SYSTEM_EVENT_ETH_GOT_IP event. -## -## @param[in] tcpip_if Interface to set IP information -## @param[in] ip_info IP information to set on the specified interface -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED If DHCP server or client is still running -## - -proc tcpip_adapter_set_ip_info*(tcpip_if: tcpip_adapter_if_t; - ip_info: ptr tcpip_adapter_ip_info_t): esp_err_t {. - importc: "tcpip_adapter_set_ip_info", header: "tcpip_adapter.h".} -## * -## @brief Set DNS Server information -## -## This function behaves differently for different interfaces: -## -## - For Wi-Fi Station interface and Ethernet interface, up to three types of DNS server can be set (in order of priority): -## - Main DNS Server (TCPIP_ADAPTER_DNS_MAIN) -## - Backup DNS Server (TCPIP_ADAPTER_DNS_BACKUP) -## - Fallback DNS Server (TCPIP_ADAPTER_DNS_FALLBACK) -## -## If DHCP client is enabled, main and backup DNS servers will be updated automatically from the DHCP lease if the relevant DHCP options are set. Fallback DNS Server is never updated from the DHCP lease and is designed to be set via this API. -## -## If DHCP client is disabled, all DNS server types can be set via this API only. -## -## - For Wi-Fi AP interface, the Main DNS Server setting is used by the DHCP server to provide a DNS Server option to DHCP clients (Wi-Fi stations). -## - The default Main DNS server is the IP of the Wi-Fi AP interface itself. -## - This function can override it by setting server type TCPIP_ADAPTER_DNS_MAIN. -## - Other DNS Server types are not supported for the Wi-Fi AP interface. -## -## @param[in] tcpip_if Interface to set DNS Server information -## @param[in] type Type of DNS Server to set: TCPIP_ADAPTER_DNS_MAIN, TCPIP_ADAPTER_DNS_BACKUP, TCPIP_ADAPTER_DNS_FALLBACK -## @param[in] dns DNS Server address to set -## -## @return -## - ESP_OK on success -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS invalid params -## - -proc tcpip_adapter_set_dns_info*(tcpip_if: tcpip_adapter_if_t; - `type`: tcpip_adapter_dns_type_t; - dns: ptr tcpip_adapter_dns_info_t): esp_err_t {. - importc: "tcpip_adapter_set_dns_info", header: "tcpip_adapter.h".} -## * -## @brief Get DNS Server information -## -## Return the currently configured DNS Server address for the specified interface and Server type. -## -## This may be result of a previous call to tcpip_adapter_set_dns_info(). If the interface's DHCP client is enabled, -## the Main or Backup DNS Server may be set by the current DHCP lease. -## -## @param[in] tcpip_if Interface to get DNS Server information -## @param[in] type Type of DNS Server to get: TCPIP_ADAPTER_DNS_MAIN, TCPIP_ADAPTER_DNS_BACKUP, TCPIP_ADAPTER_DNS_FALLBACK -## @param[out] dns DNS Server result is written here on success -## -## @return -## - ESP_OK on success -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS invalid params -## - -proc tcpip_adapter_get_dns_info*(tcpip_if: tcpip_adapter_if_t; - `type`: tcpip_adapter_dns_type_t; - dns: ptr tcpip_adapter_dns_info_t): esp_err_t {. - importc: "tcpip_adapter_get_dns_info", header: "tcpip_adapter.h".} -## * -## @brief Get interface's old IP information -## -## Returns an "old" IP address previously stored for the interface when the valid IP changed. -## -## If the IP lost timer has expired (meaning the interface was down for longer than the configured interval) -## then the old IP information will be zero. -## -## @param[in] tcpip_if Interface to get old IP information -## @param[out] ip_info If successful, IP information will be returned in this argument. -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - -proc tcpip_adapter_get_old_ip_info*(tcpip_if: tcpip_adapter_if_t; - ip_info: ptr tcpip_adapter_ip_info_t): esp_err_t {. - importc: "tcpip_adapter_get_old_ip_info", header: "tcpip_adapter.h".} -## * -## @brief Set interface old IP information -## -## This function is called from the DHCP client for the Wi-Fi STA and Ethernet interfaces, before a new IP is set. It is also called from the default handlers for the SYSTEM_EVENT_STA_CONNECTED and SYSTEM_EVENT_ETH_CONNECTED events. -## -## Calling this function stores the previously configured IP, which can be used to determine if the IP changes in the future. -## -## If the interface is disconnected or down for too long, the "IP lost timer" will expire (after the configured interval) and set the old IP information to zero. -## -## @param[in] tcpip_if Interface to set old IP information -## @param[in] ip_info Store the old IP information for the specified interface -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - -proc tcpip_adapter_set_old_ip_info*(tcpip_if: tcpip_adapter_if_t; - ip_info: ptr tcpip_adapter_ip_info_t): esp_err_t {. - importc: "tcpip_adapter_set_old_ip_info", header: "tcpip_adapter.h".} -## * -## @brief Create interface link-local IPv6 address -## -## Cause the TCP/IP stack to create a link-local IPv6 address for the specified interface. -## -## This function also registers a callback for the specified interface, so that if the link-local address becomes verified as the preferred address then a SYSTEM_EVENT_GOT_IP6 event will be sent. -## -## @param[in] tcpip_if Interface to create a link-local IPv6 address -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - -proc tcpip_adapter_create_ip6_linklocal*(tcpip_if: tcpip_adapter_if_t): esp_err_t {. - importc: "tcpip_adapter_create_ip6_linklocal", header: "tcpip_adapter.h".} -## * -## @brief Get interface link-local IPv6 address -## -## If the specified interface is up and a preferred link-local IPv6 address -## has been created for the interface, return a copy of it. -## -## @param[in] tcpip_if Interface to get link-local IPv6 address -## @param[out] if_ip6 IPv6 information will be returned in this argument if successful. -## -## @return -## - ESP_OK -## - ESP_FAIL If interface is down, does not have a link-local IPv6 address, or the link-local IPv6 address is not a preferred address. -## - -proc tcpip_adapter_get_ip6_linklocal*(tcpip_if: tcpip_adapter_if_t; - if_ip6: ptr ip6_addr_t): esp_err_t {. - importc: "tcpip_adapter_get_ip6_linklocal", header: "tcpip_adapter.h".} -## * -## @brief Get interface global IPv6 address -## -## If the specified interface is up and a preferred global IPv6 address -## has been created for the interface, return a copy of it. -## -## @param[in] tcpip_if Interface to get global IPv6 address -## @param[out] if_ip6 IPv6 information will be returned in this argument if successful. -## -## @return -## - ESP_OK -## - ESP_FAIL If interface is down, does not have a global IPv6 address, or the global IPv6 address is not a preferred address. -## - -proc tcpip_adapter_get_ip6_global*(tcpip_if: tcpip_adapter_if_t; - if_ip6: ptr ip6_addr_t): esp_err_t {. - importc: "tcpip_adapter_get_ip6_global", header: "tcpip_adapter.h".} -proc tcpip_adapter_get_mac*(tcpip_if: tcpip_adapter_if_t; mac: ptr uint8): esp_err_t {. - importc: "tcpip_adapter_get_mac", header: "tcpip_adapter.h".} -proc tcpip_adapter_set_mac*(tcpip_if: tcpip_adapter_if_t; mac: ptr uint8): esp_err_t {. - importc: "tcpip_adapter_set_mac", header: "tcpip_adapter.h".} - -## * -## @brief Get DHCP Server status -## -## @param[in] tcpip_if Interface to get status of DHCP server. -## @param[out] status If successful, the status of the DHCP server will be returned in this argument. -## -## @return -## - ESP_OK -## - -proc tcpip_adapter_dhcps_get_status*(tcpip_if: tcpip_adapter_if_t; - status: ptr tcpip_adapter_dhcp_status_t): esp_err_t {. - importc: "tcpip_adapter_dhcps_get_status", header: "tcpip_adapter.h".} -## * -## @brief Set or Get DHCP server option -## -## @param[in] opt_op TCPIP_ADAPTER_OP_SET to set an option, TCPIP_ADAPTER_OP_GET to get an option. -## @param[in] opt_id Option index to get or set, must be one of the supported enum values. -## @param[inout] opt_val Pointer to the option parameter. -## @param[in] opt_len Length of the option parameter. -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED -## - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED -## - -proc tcpip_adapter_dhcps_option*(opt_op: tcpip_adapter_dhcp_option_mode_t; - opt_id: tcpip_adapter_dhcp_option_id_t; - opt_val: pointer; opt_len: uint32): esp_err_t {. - importc: "tcpip_adapter_dhcps_option", header: "tcpip_adapter.h".} -## * -## @brief Start DHCP server -## -## @note Currently DHCP server is only supported on the Wi-Fi AP interface. -## -## @param[in] tcpip_if Interface to start DHCP server. Must be TCPIP_ADAPTER_IF_AP. -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED -## - -proc tcpip_adapter_dhcps_start*(tcpip_if: tcpip_adapter_if_t): esp_err_t {. - importc: "tcpip_adapter_dhcps_start", header: "tcpip_adapter.h".} -## * -## @brief Stop DHCP server -## -## @note Currently DHCP server is only supported on the Wi-Fi AP interface. -## -## @param[in] tcpip_if Interface to stop DHCP server. Must be TCPIP_ADAPTER_IF_AP. -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED -## - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY -## - -proc tcpip_adapter_dhcps_stop*(tcpip_if: tcpip_adapter_if_t): esp_err_t {. - importc: "tcpip_adapter_dhcps_stop", header: "tcpip_adapter.h".} -## * -## @brief Get DHCP client status -## -## @param[in] tcpip_if Interface to get status of DHCP client -## @param[out] status If successful, the status of DHCP client will be returned in this argument. -## -## @return -## - ESP_OK -## - -proc tcpip_adapter_dhcpc_get_status*(tcpip_if: tcpip_adapter_if_t; - status: ptr tcpip_adapter_dhcp_status_t): esp_err_t {. - importc: "tcpip_adapter_dhcpc_get_status", header: "tcpip_adapter.h".} -## * -## @brief Set or Get DHCP client's option -## -## @note This function is not yet implemented -## -## @param[in] opt_op TCPIP_ADAPTER_OP_SET to set an option, TCPIP_ADAPTER_OP_GET to get an option. -## @param[in] opt_id Option index to get or set, must be one of the supported enum values. -## @param[inout] opt_val Pointer to the option parameter. -## @param[in] opt_len Length of the option parameter. -## -## @return -## - ESP_ERR_NOT_SUPPORTED (not implemented) -## - -proc tcpip_adapter_dhcpc_option*(opt_op: tcpip_adapter_dhcp_option_mode_t; - opt_id: tcpip_adapter_dhcp_option_id_t; - opt_val: pointer; opt_len: uint32): esp_err_t {. - importc: "tcpip_adapter_dhcpc_option", header: "tcpip_adapter.h".} -## * -## @brief Start DHCP client -## -## @note DHCP Client is only supported for the Wi-Fi station and Ethernet interfaces. -## -## @note The default event handlers for the SYSTEM_EVENT_STA_CONNECTED and SYSTEM_EVENT_ETH_CONNECTED events call this function. -## -## @param[in] tcpip_if Interface to start the DHCP client -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED -## - ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED -## - -proc tcpip_adapter_dhcpc_start*(tcpip_if: tcpip_adapter_if_t): esp_err_t {. - importc: "tcpip_adapter_dhcpc_start", header: "tcpip_adapter.h".} -## * -## @brief Stop DHCP client -## -## @note DHCP Client is only supported for the Wi-Fi station and Ethernet interfaces. -## -## @note Calling tcpip_adapter_stop() or tcpip_adapter_down() will also stop the DHCP Client if it is running. -## -## @param[in] tcpip_if Interface to stop the DHCP client -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED -## - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY -## - -proc tcpip_adapter_dhcpc_stop*(tcpip_if: tcpip_adapter_if_t): esp_err_t {. - importc: "tcpip_adapter_dhcpc_stop", header: "tcpip_adapter.h".} -## * -## @brief Receive an Ethernet frame from the Ethernet interface -## -## This function will automatically be installed by esp_eth_init(). The Ethernet driver layer will then call this function to forward frames to the TCP/IP stack. -## -## @note Application code does not usually need to use this function directly. -## -## @param[in] buffer Received data -## @param[in] len Length of the data frame -## @param[in] eb Pointer to internal Wi-Fi buffer (ignored for Ethernet) -## -## @return -## - ESP_OK -## - -proc tcpip_adapter_eth_input*(buffer: pointer; len: uint16; eb: pointer): esp_err_t {. - importc: "tcpip_adapter_eth_input", header: "tcpip_adapter.h".} -## * -## @brief Receive an 802.11 data frame from the Wi-Fi Station interface -## -## This function should be installed by calling esp_wifi_reg_rxcb(). The Wi-Fi driver layer will then call this function to forward frames to the TCP/IP stack. -## -## @note Installation happens automatically in the default handler for the SYSTEM_EVENT_STA_CONNECTED event. -## -## @note Application code does not usually need to call this function directly. -## -## @param[in] buffer Received data -## @param[in] len Length of the data frame -## @param[in] eb Pointer to internal Wi-Fi buffer -## -## @return -## - ESP_OK -## - -proc tcpip_adapter_sta_input*(buffer: pointer; len: uint16; eb: pointer): esp_err_t {. - importc: "tcpip_adapter_sta_input", header: "tcpip_adapter.h".} -## * -## @brief Receive an 802.11 data frame from the Wi-Fi AP interface -## -## This function should be installed by calling esp_wifi_reg_rxcb(). The Wi-Fi driver layer will then call this function to forward frames to the TCP/IP stack. -## -## @note Installation happens automatically in the default handler for the SYSTEM_EVENT_AP_START event. -## -## @note Application code does not usually need to call this function directly. -## -## @param[in] buffer Received data -## @param[in] len Length of the data frame -## @param[in] eb Pointer to internal Wi-Fi buffer -## -## @return -## - ESP_OK -## - -proc tcpip_adapter_ap_input*(buffer: pointer; len: uint16; eb: pointer): esp_err_t {. - importc: "tcpip_adapter_ap_input", header: "tcpip_adapter.h".} -## * -## @brief Get network interface index -## -## Get network interface from TCP/IP implementation-specific interface pointer. -## -## @param[in] dev Implementation-specific TCP/IP stack interface pointer. -## -## @return -## - ESP_IF_WIFI_STA -## - ESP_IF_WIFI_AP -## - ESP_IF_ETH -## - ESP_IF_MAX - invalid parameter -## - -proc tcpip_adapter_get_esp_if*(dev: pointer): esp_interface_t {. - importc: "tcpip_adapter_get_esp_if", header: "tcpip_adapter.h".} -## * -## @brief Get IP information for stations connected to the Wi-Fi AP interface -## -## @param[in] wifi_sta_list Wi-Fi station info list, returned from esp_wifi_ap_get_sta_list() -## @param[out] tcpip_sta_list IP layer station info list, corresponding to MAC addresses provided in wifi_sta_list -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_NO_MEM -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - -proc tcpip_adapter_get_sta_list*(wifi_sta_list: ptr wifi_sta_list_t; - tcpip_sta_list: ptr tcpip_adapter_sta_list_t): esp_err_t {. - importc: "tcpip_adapter_get_sta_list", header: "tcpip_adapter.h".} -const - TCPIP_HOSTNAME_MAX_SIZE* = 32 - -## * -## @brief Set the hostname of an interface -## -## @param[in] tcpip_if Interface to set the hostname -## @param[in] hostname New hostname for the interface. Maximum length 32 bytes. -## -## @return -## - ESP_OK - success -## - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY - interface status error -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS - parameter error -## - -proc tcpip_adapter_set_hostname*(tcpip_if: tcpip_adapter_if_t; hostname: cstring): esp_err_t {. - importc: "tcpip_adapter_set_hostname", header: "tcpip_adapter.h".} -## * -## @brief Get interface hostname. -## -## @param[in] tcpip_if Interface to get the hostname -## @param[out] hostname Returns a pointer to the hostname. May be NULL if no hostname is set. If set non-NULL, pointer remains valid (and string may change if the hostname changes). -## -## @return -## - ESP_OK - success -## - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY - interface status error -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS - parameter error -## - -proc tcpip_adapter_get_hostname*(tcpip_if: tcpip_adapter_if_t; - hostname: cstringArray): esp_err_t {. - importc: "tcpip_adapter_get_hostname", header: "tcpip_adapter.h".} -## * -## @brief Get the TCP/IP stack-specific interface that is assigned to a given interface -## -## @note For lwIP, this returns a pointer to a netif structure. -## -## @param[in] tcpip_if Interface to get the implementation-specific interface -## @param[out] netif Pointer to the implementation-specific interface -## -## @return -## - ESP_OK - success -## - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY - interface status error -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS - parameter error -## - -proc tcpip_adapter_get_netif*(tcpip_if: tcpip_adapter_if_t; netif: ptr pointer): esp_err_t {. - importc: "tcpip_adapter_get_netif", header: "tcpip_adapter.h".} -## * -## @brief Test if supplied interface is up or down -## -## @param[in] tcpip_if Interface to test up/down status -## -## @return -## - true - Interface is up -## - false - Interface is down -## - -proc tcpip_adapter_is_netif_up*(tcpip_if: tcpip_adapter_if_t): bool {. - importc: "tcpip_adapter_is_netif_up", header: "tcpip_adapter.h".} -## * -## @brief Cause the TCP/IP stack to start the test interface with specified MAC and IP. -## Test interface is used to exercise network stack with injected packets from SW. -## -## @param[in] mac Set MAC address of this interface -## @param[in] ip_info Set IP address of this interface -## -## @return -## - ESP_OK -## - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS -## - ESP_ERR_NO_MEM -## - -proc tcpip_adapter_test_start*(mac: ptr uint8; - ip_info: ptr tcpip_adapter_ip_info_t): esp_err_t {. - importc: "tcpip_adapter_test_start", header: "tcpip_adapter.h".} -## * -## @brief Install default event handlers for Ethernet interface -## @return -## - ESP_OK on success -## - one of the errors from esp_event on failure -## - -proc tcpip_adapter_set_default_eth_handlers*(): esp_err_t {. - importc: "tcpip_adapter_set_default_eth_handlers", header: "tcpip_adapter.h".} -## * -## @brief Uninstall default event handlers for Ethernet interface -## @return -## - ESP_OK on success -## - one of the errors from esp_event on failure -## - -proc tcpip_adapter_clear_default_eth_handlers*(): esp_err_t {. - importc: "tcpip_adapter_clear_default_eth_handlers", header: "tcpip_adapter.h".} -## * -## @brief Install default event handlers for Wi-Fi interfaces (station and AP) -## @return -## - ESP_OK on success -## - one of the errors from esp_event on failure -## - -proc tcpip_adapter_set_default_wifi_handlers*(): esp_err_t {. - importc: "tcpip_adapter_set_default_wifi_handlers", header: "tcpip_adapter.h".} -## * -## @brief Uninstall default event handlers for Wi-Fi interfaces (station and AP) -## @return -## - ESP_OK on success -## - one of the errors from esp_event on failure -## - -proc tcpip_adapter_clear_default_wifi_handlers*(): esp_err_t {. - importc: "tcpip_adapter_clear_default_wifi_handlers", - header: "tcpip_adapter.h".} -## * -## @brief Search nefit index through netif interface -## @param[in] tcpip_if Interface to search for netif index -## @return -## - netif_index on success -## - -1 if an invalid parameter is supplied -## - -proc tcpip_adapter_get_netif_index*(tcpip_if: tcpip_adapter_if_t): cint {. - importc: "tcpip_adapter_get_netif_index", header: "tcpip_adapter.h".} \ No newline at end of file diff --git a/src/nesper/general.nim b/src/nesper/general.nim index 3c6e0cdf..2d05f360 100644 --- a/src/nesper/general.nim +++ b/src/nesper/general.nim @@ -30,9 +30,6 @@ type proc esp_restart*() {.cdecl, importc: "esp_restart".} -proc vTaskDelete*( handle: any ) - {.cdecl, importc: "vTaskDelete", header: "".} - proc esp_err_to_name*(code: esp_err_t): cstring {.cdecl, importc: "esp_err_to_name", header: "freertos/FreeRTOS.h".} proc esp_err_to_name_r*(code: esp_err_t; buf: cstring; buflen: csize_t): cstring {.cdecl, diff --git a/src/nesper/net_utils.nim b/src/nesper/net_utils.nim index 263bc7b7..41c86466 100644 --- a/src/nesper/net_utils.nim +++ b/src/nesper/net_utils.nim @@ -11,41 +11,6 @@ when not defined(ESP_IDF_V4_0): export esp_netif -## * This is the aligned version of ip4_addr_t, -## used as local variable, on the stack, etc. -type - ip4_addr_t* {.importc: "ip4_addr_t", header: "lwip/ip4_addr.h", bycopy.} = object - address* {.importc: "addr".}: uint32 - - ip6_addr_t* {.importc: "ip6_addr_t", header: "lwip/ip6_addr.h", bycopy.} = object - address* {.importc: "addr".}: array[4, uint32] - -type - lwip_ip_addr_type* {.size: sizeof(cint).} = enum ## * IPv4 - IPADDR_TYPE_V4 = 0, ## * IPv6 - IPADDR_TYPE_V6 = 6, ## * IPv4+IPv6 ("dual-stack") - IPADDR_TYPE_ANY = 46 - - -## #if LWIP_IPV4 && LWIP_IPV6 -## * -## @ingroup ipaddr -## A union struct for both IP version's addresses. -## ATTENTION: watch out for its size when adding IPv6 address scope! -## - -type - INNER_C_UNION_ip_addr_71* {.importc: "no_name", header: "lwip/ip_addr.h", bycopy, union.} = object - ip6* {.importc: "ip6".}: ip6_addr_t - ip4* {.importc: "ip4".}: ip4_addr_t - - ip_addr_t* {.importc: "ip_addr_t", header: "lwip/ip_addr.h", bycopy.} = object - u_addr* {.importc: "u_addr".}: INNER_C_UNION_ip_addr_71 ## * @ref lwip_ip_addr_type - `type`* {.importc: "type".}: uint8 - - -var ip_addr_any_type* {.importc: "ip_addr_any_type", header: "lwip/ip_addr.h".}: ip_addr_t - type esp_interface_t* {.size: sizeof(cint).} = enum ESP_IF_WIFI_STA = 0, ## *< ESP32 station interface diff --git a/tests/tgeneral.nim b/tests/tgeneral.nim index 4e576046..69e15a70 100644 --- a/tests/tgeneral.nim +++ b/tests/tgeneral.nim @@ -20,8 +20,6 @@ discard delayMicros(100) delay(Micros(100)) esp_restart() -# vTaskDelete*( handle: any ) - echo "ESP_ERR_FLASH_BASE: " & $esp_err_to_name(ESP_ERR_FLASH_BASE) ESP_ERROR_CHECK(ESP_OK) From 5ed0cb30371aa744a2ec9c7fa54bb74f35cc9937 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 03:31:01 -0600 Subject: [PATCH 126/142] update wifi example --- src/nesper/esp/esp_event_legacy.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/nesper/esp/esp_event_legacy.nim b/src/nesper/esp/esp_event_legacy.nim index 1537b787..e9c9b6aa 100644 --- a/src/nesper/esp/esp_event_legacy.nim +++ b/src/nesper/esp/esp_event_legacy.nim @@ -16,6 +16,7 @@ ## * System event types enumeration import ../consts import net/esp_wifi_types +import net/esp_netif_types type system_event_id_t* {.size: sizeof(cint).} = enum @@ -100,8 +101,8 @@ type ## * Argument structure of event -type - system_event_ap_staipassigned_t* = ip_event_ap_staipassigned_t +# type +# system_event_ap_staipassigned_t* = ip_event_ap_staipassigned_t ## * Argument structure of event @@ -128,7 +129,7 @@ type sta_connected* {.importc: "sta_connected".}: system_event_ap_staconnected_t ## !< a station connected to ESP32 soft-AP sta_disconnected* {.importc: "sta_disconnected".}: system_event_ap_stadisconnected_t ## !< a station disconnected to ESP32 soft-AP ap_probereqrecved* {.importc: "ap_probereqrecved".}: system_event_ap_probe_req_rx_t ## !< ESP32 soft-AP receive probe request packet - ap_staipassigned* {.importc: "ap_staipassigned".}: system_event_ap_staipassigned_t ## *< ESP32 soft-AP assign an IP to the station + # ap_staipassigned* {.importc: "ap_staipassigned".}: system_event_ap_staipassigned_t ## *< ESP32 soft-AP assign an IP to the station got_ip6* {.importc: "got_ip6".}: system_event_got_ip6_t ## !< ESP32 station or ap or ethernet ipv6 addr state change to preferred From 7fd516ffda0901517a1f91f6307261935007a2fd Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 04:43:23 -0600 Subject: [PATCH 127/142] going back to callback style rpc methods --- esp-idf-examples/net_pppos_usb/config.nims | 3 ++- esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index ff4d5f30..c25abad1 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -9,7 +9,8 @@ switch("define", "FastRpcServer") switch("define", "McuUtilsLoggingLevel:lvlTrace") # switch("define", "RUN_NCM") -patchFile("stdlib", "cpuinfo", "main/cpuinfo.nim") patchFile("stdlib", "ioselectors_select", "../../src/nesper/networking/ioselectors_select_patch.nim") +patchFile("stdlib", "cpuinfo", "main/cpuinfo.nim") + include nesper/build_utils/builds diff --git a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp index 3f0e1fd6..6c22b462 100644 --- a/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp +++ b/esp-idf-examples/net_pppos_usb/sdkconfig.defaults.ppp @@ -9,6 +9,12 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_USJ_ENABLE_USB_SERIAL_JTAG=n CONFIG_ESP_CONSOLE_SECONDARY_NONE=y +CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384 +CONFIG_LWIP_MAX_SOCKETS=16 +CONFIG_LWIP_SO_RCVBUF=y +CONFIG_LWIP_IPV6_AUTOCONFIG=y +CONFIG_LWIP_IPV6_DHCP6=y + # LWIP PPP CONFIG_LWIP_PPP_SUPPORT=y CONFIG_LWIP_PPP_PAP_SUPPORT=y From ccaa3523d5a6f16e4f0887e4bce33f4ecc9b91d5 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 04:43:47 -0600 Subject: [PATCH 128/142] going back to callback style rpc methods --- esp-idf-examples/net_pppos_usb/config.nims | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp-idf-examples/net_pppos_usb/config.nims b/esp-idf-examples/net_pppos_usb/config.nims index c25abad1..ad38d83f 100644 --- a/esp-idf-examples/net_pppos_usb/config.nims +++ b/esp-idf-examples/net_pppos_usb/config.nims @@ -6,7 +6,7 @@ switch("define", "nimIoselectorEventfd") # switch("define", "UdpEchoServer") switch("define", "FastRpcServer") -switch("define", "McuUtilsLoggingLevel:lvlTrace") +switch("define", "McuUtilsLoggingLevel:lvlInfo") # switch("define", "RUN_NCM") patchFile("stdlib", "ioselectors_select", "../../src/nesper/networking/ioselectors_select_patch.nim") From fff089539ad49ead0df59998421177582763b982 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 04:56:58 -0600 Subject: [PATCH 129/142] exports --- esp-idf-examples/net_pppos_usb/main/config.nims | 2 +- src/nesper/networking/usb_ppp_dualcdc.nim | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/config.nims b/esp-idf-examples/net_pppos_usb/main/config.nims index 3259fd64..e6233552 100644 --- a/esp-idf-examples/net_pppos_usb/main/config.nims +++ b/esp-idf-examples/net_pppos_usb/main/config.nims @@ -1,6 +1,6 @@ --nomain --compileOnly ---define:debug +# --define:debug --define:NimAppMain --nimcache:nimcache diff --git a/src/nesper/networking/usb_ppp_dualcdc.nim b/src/nesper/networking/usb_ppp_dualcdc.nim index 1650c15b..a420041a 100644 --- a/src/nesper/networking/usb_ppp_dualcdc.nim +++ b/src/nesper/networking/usb_ppp_dualcdc.nim @@ -3,9 +3,14 @@ import nesper/[general, gpios, timers] import nesper/esp/[esp_log, esp_event, event_groups] import nesper/esp/esp_system import nesper/events -import nesper/esp/net/[esp_netif, esp_netif_ppp, esp_netif_types] +import nesper/esp/net/[esp_netif, esp_netif_ppp, esp_netif_types, esp_netif_impl] import nesper/components/esp_tinyusb/[tinyusb, tinyusb_net, tusb_cdc_acm] +export esp_netif +export esp_netif_ppp +export esp_netif_types +export esp_netif_impl + ## Code that is specific to the USB PPP over Dual CDC (CDC0=PPP, CDC1=console) ## Requires TinyUSB and incompatible with USB JTAG or OTG Modes ## CDC0 is used for PPP data, CDC1 is used for console From 0e88923e40e8791894b249b3204e7dcebf16cbeb Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 04:57:18 -0600 Subject: [PATCH 130/142] exports --- esp-idf-examples/net_pppos_usb/main/main.nim | 3 --- 1 file changed, 3 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 0c0901fe..925eeea3 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -4,9 +4,6 @@ import nesper/[consts, general, timers] import nesper/esp/esp_system import nesper/esp/nvs_flash import nesper/esp/esp_event -import nesper/esp/net/esp_netif -import nesper/esp/net/esp_netif_ppp -import nesper/esp/net/esp_netif_impl import nesper/esp/esp_vfs_eventfd import nesper/net_utils From 687e8c9129b2d8d017a1ee06e14fc0fd761063cb Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 05:00:52 -0600 Subject: [PATCH 131/142] exports --- esp-idf-examples/net_pppos_usb/main/main.nim | 5 ----- src/nesper/net_utils.nim | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/esp-idf-examples/net_pppos_usb/main/main.nim b/esp-idf-examples/net_pppos_usb/main/main.nim index 925eeea3..9ac44cbd 100644 --- a/esp-idf-examples/net_pppos_usb/main/main.nim +++ b/esp-idf-examples/net_pppos_usb/main/main.nim @@ -15,11 +15,6 @@ else: const TAG*: cstring = "main" -proc addIpv6ToNetif*(netif: ptr esp_netif_t; ip: IpAddress): esp_err_t = - ## Convert Nim IpAddress to esp_ip6_addr_t and add it to the interface - let espIp6 = toEspIp6Addr(ip) - result = esp_netif_add_ip6_address(netif, espIp6, preferred=true) - when defined(RpcServer): import nesper/servers/rpc/rpcsocket_json proc setupRpc(rt: var RpcRouter) = diff --git a/src/nesper/net_utils.nim b/src/nesper/net_utils.nim index 41c86466..21f5e490 100644 --- a/src/nesper/net_utils.nim +++ b/src/nesper/net_utils.nim @@ -77,3 +77,8 @@ proc generate_sensor_id*(): string = sensor_id.add(mac[i].toHex(2)) return sensor_id.join(":") + +proc addIpv6ToNetif*(netif: ptr esp_netif_t; ip: IpAddress): esp_err_t = + ## Convert Nim IpAddress to esp_ip6_addr_t and add it to the interface + let espIp6 = toEspIp6Addr(ip) + result = esp_netif_add_ip6_address(netif, espIp6, preferred=true) From 6fc687d1e6e6641339cd333b91c11c0243290c3a Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 5 Sep 2025 05:01:18 -0600 Subject: [PATCH 132/142] exports --- src/nesper/net_utils.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nesper/net_utils.nim b/src/nesper/net_utils.nim index 21f5e490..66a08f58 100644 --- a/src/nesper/net_utils.nim +++ b/src/nesper/net_utils.nim @@ -1,5 +1,6 @@ import strutils +import consts import general import esp/esp_system From 91b5da4488e327b5ae0d070d0ee749371205f3ce Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 8 Sep 2025 19:41:58 -0600 Subject: [PATCH 133/142] cleanup --- src/nesper/networking/setup_wifi.nim | 95 ++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/nesper/networking/setup_wifi.nim diff --git a/src/nesper/networking/setup_wifi.nim b/src/nesper/networking/setup_wifi.nim new file mode 100644 index 00000000..3763cc58 --- /dev/null +++ b/src/nesper/networking/setup_wifi.nim @@ -0,0 +1,95 @@ +import ..//general +import ..//timers +import ..//events +import ..//wifi +import ..//net_utils +import ..//esp/nvs +import ..//esp/nvs_flash +import ..//nvs_utils + +# Config (match the C example names) +const EXAMPLE_ESP_WIFI_SSID* {.strdefine.}: string = "" +const EXAMPLE_ESP_WIFI_PASS* {.strdefine.}: string = "" +const EXAMPLE_ESP_MAXIMUM_RETRY* {.intdefine.}: int = 5 + +const TAG: cstring = "Wifi Example" + +const WIFI_CONNECTED = 1 shl 0 +const WIFI_FAIL = 1 shl 1 + +var sWifiEventGroup: EventGroupHandle_t +var sRetryNum = 0 + +proc eventHandler(arg: pointer; event_base: esp_event_base_t; event_id: int32; event_data: pointer) {.cdecl.} = + logi(TAG, "Wifi Event Handler called: base: %s eventid: %s wifiEvent: %s ipEvent: %s", + $event_base, $event_id, $(event_base == WIFI_EVENT), $(event_base == IP_EVENT)) + if event_base == WIFI_EVENT and wifi_event_t(event_id) == WIFI_EVENT_STA_START: + discard esp_wifi_connect() + elif event_base == WIFI_EVENT and wifi_event_t(event_id) == WIFI_EVENT_STA_DISCONNECTED: + if sRetryNum < EXAMPLE_ESP_MAXIMUM_RETRY: + discard esp_wifi_connect() + inc sRetryNum + loge(TAG, "retry to connect to the AP") + else: + discard xEventGroupSetBits(sWifiEventGroup, EventBits_t(WIFI_FAIL)) + loge(TAG, "Connect to the AP failed") + elif event_base == IP_EVENT and ip_event_t(event_id) == IP_EVENT_STA_GOT_IP: + let ev = cast[ptr ip_event_got_ip_t](event_data) + logi(TAG, "Wifi Got IP: %s", $ev.ip_info.ip) + sRetryNum = 0 + discard xEventGroupSetBits(sWifiEventGroup, EventBits_t(WIFI_CONNECTED)) + +proc wifiInitSta( + ssid: string, + pass: string, + maxRetry: int = 5, + authMode: wifi_auth_mode_t = WIFI_AUTH_WPA3_PSK, + saeMode: wifi_sae_mode_t = WPA3_SAE_PWE_HUNT_AND_PECK, + saeIdentifier: string = "", +) = + logw(TAG, "Wifi Init Sta starting...") + sWifiEventGroup = xEventGroupCreate() + + check: esp_netif_init() + + check: esp_event_loop_create_default() + let netif = esp_netif_create_default_wifi_sta() + + let cfg = WIFI_INIT_CONFIG_DEFAULT() + check: esp_wifi_init(unsafeAddr cfg) + + # Register for all WIFI_EVENT IDs and for IP_EVENT_STA_GOT_IP + var instance_any_id: esp_event_handler_instance_t + var instance_got_ip: esp_event_handler_instance_t + + eventRegister(WIFI_EVENT, + ESP_EVENT_ANY_ID.int32, + eventHandler, + nil, addr instance_any_id) + eventRegister(IP_EVENT, + ESP_EVENT_ANY_ID.int32, + eventHandler, + nil, addr instance_got_ip) + + var wifi_config: wifi_config_t + wifi_config.sta.ssid.setFromString(ssid) + wifi_config.sta.password.setFromString(pass) + wifi_config.sta.threshold.authmode = authMode + wifi_config.sta.sae_pwe_h2e = saeMode + wifi_config.sta.sae_h2e_identifier.setFromString(saeIdentifier) + + check: esp_wifi_set_mode(WIFI_MODE_STA) + check: esp_wifi_set_config(WIFI_IF_STA, addr wifi_config) + check: esp_wifi_start() + + logw(TAG, "Wifi Init Sta finished.") + + logw(TAG, "Wifi Init Sta waiting for events...") + let bits = xEventGroupWaitBits(sWifiEventGroup, EventBits_t(WIFI_CONNECTED or WIFI_FAIL), pdFALSE, pdFALSE, portMAX_DELAY) + + if (bits and EventBits_t(WIFI_CONNECTED)) != 0: + logi(TAG, "connected to ap SSID:%s password:%s", ssid, pass) + elif (bits and EventBits_t(WIFI_FAIL)) != 0: + logi(TAG, "Failed to connect to SSID:%s, password:%s", ssid, pass) + else: + loge(TAG, "unexpected WIFI event: %s", $bits) From b943d930e3b733d48c6e48d3354cebde8f9e0aed Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 8 Sep 2025 19:43:12 -0600 Subject: [PATCH 134/142] cleanup --- src/nesper/networking/setup_wifi.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nesper/networking/setup_wifi.nim b/src/nesper/networking/setup_wifi.nim index 3763cc58..e8169e52 100644 --- a/src/nesper/networking/setup_wifi.nim +++ b/src/nesper/networking/setup_wifi.nim @@ -39,7 +39,7 @@ proc eventHandler(arg: pointer; event_base: esp_event_base_t; event_id: int32; e sRetryNum = 0 discard xEventGroupSetBits(sWifiEventGroup, EventBits_t(WIFI_CONNECTED)) -proc wifiInitSta( +proc wifiInitSta*( ssid: string, pass: string, maxRetry: int = 5, @@ -84,6 +84,7 @@ proc wifiInitSta( logw(TAG, "Wifi Init Sta finished.") +proc waitForWifiConnected*() = logw(TAG, "Wifi Init Sta waiting for events...") let bits = xEventGroupWaitBits(sWifiEventGroup, EventBits_t(WIFI_CONNECTED or WIFI_FAIL), pdFALSE, pdFALSE, portMAX_DELAY) From eeb37c51315469d7a7301a139b6ae08edbe7aa9c Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 8 Sep 2025 19:48:22 -0600 Subject: [PATCH 135/142] cleanup --- src/nesper/networking/setup_wifi.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nesper/networking/setup_wifi.nim b/src/nesper/networking/setup_wifi.nim index e8169e52..bc401eb0 100644 --- a/src/nesper/networking/setup_wifi.nim +++ b/src/nesper/networking/setup_wifi.nim @@ -44,7 +44,7 @@ proc wifiInitSta*( pass: string, maxRetry: int = 5, authMode: wifi_auth_mode_t = WIFI_AUTH_WPA3_PSK, - saeMode: wifi_sae_mode_t = WPA3_SAE_PWE_HUNT_AND_PECK, + saeMode: wifi_sae_pwe_method_t = WPA3_SAE_PWE_HUNT_AND_PECK, saeIdentifier: string = "", ) = logw(TAG, "Wifi Init Sta starting...") From 3f1d60e5f8bfc0a81909f2cf6f0b6620303b0da2 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 8 Sep 2025 19:52:27 -0600 Subject: [PATCH 136/142] cleanup --- src/nesper/networking/setup_wifi.nim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nesper/networking/setup_wifi.nim b/src/nesper/networking/setup_wifi.nim index bc401eb0..d2835d60 100644 --- a/src/nesper/networking/setup_wifi.nim +++ b/src/nesper/networking/setup_wifi.nim @@ -12,7 +12,7 @@ const EXAMPLE_ESP_WIFI_SSID* {.strdefine.}: string = "" const EXAMPLE_ESP_WIFI_PASS* {.strdefine.}: string = "" const EXAMPLE_ESP_MAXIMUM_RETRY* {.intdefine.}: int = 5 -const TAG: cstring = "Wifi Example" +const TAG: cstring = "WiFi Setup" const WIFI_CONNECTED = 1 shl 0 const WIFI_FAIL = 1 shl 1 @@ -35,7 +35,7 @@ proc eventHandler(arg: pointer; event_base: esp_event_base_t; event_id: int32; e loge(TAG, "Connect to the AP failed") elif event_base == IP_EVENT and ip_event_t(event_id) == IP_EVENT_STA_GOT_IP: let ev = cast[ptr ip_event_got_ip_t](event_data) - logi(TAG, "Wifi Got IP: %s", $ev.ip_info.ip) + logi(TAG, "Got IP: %s", $ev.ip_info.ip) sRetryNum = 0 discard xEventGroupSetBits(sWifiEventGroup, EventBits_t(WIFI_CONNECTED)) @@ -47,7 +47,7 @@ proc wifiInitSta*( saeMode: wifi_sae_pwe_method_t = WPA3_SAE_PWE_HUNT_AND_PECK, saeIdentifier: string = "", ) = - logw(TAG, "Wifi Init Sta starting...") + logw(TAG, "Init Sta starting...") sWifiEventGroup = xEventGroupCreate() check: esp_netif_init() @@ -82,15 +82,15 @@ proc wifiInitSta*( check: esp_wifi_set_config(WIFI_IF_STA, addr wifi_config) check: esp_wifi_start() - logw(TAG, "Wifi Init Sta finished.") + logi(TAG, "WiFi STA connecting to ap SSID:%s password:%s", ssid, pass) proc waitForWifiConnected*() = - logw(TAG, "Wifi Init Sta waiting for events...") + logw(TAG, "WiFi Init Sta waiting for events...") let bits = xEventGroupWaitBits(sWifiEventGroup, EventBits_t(WIFI_CONNECTED or WIFI_FAIL), pdFALSE, pdFALSE, portMAX_DELAY) if (bits and EventBits_t(WIFI_CONNECTED)) != 0: - logi(TAG, "connected to ap SSID:%s password:%s", ssid, pass) + logi(TAG, "WiFi Connected") elif (bits and EventBits_t(WIFI_FAIL)) != 0: - logi(TAG, "Failed to connect to SSID:%s, password:%s", ssid, pass) + logi(TAG, "WiFi Failed to connect") else: loge(TAG, "unexpected WIFI event: %s", $bits) From b1c093a1d92ad032b57b32822f553fa756c352b4 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Mon, 15 Sep 2025 08:43:24 -0600 Subject: [PATCH 137/142] init ledc module --- src/nesper/ledcs.nim | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/nesper/ledcs.nim b/src/nesper/ledcs.nim index edcddd90..22eb837d 100644 --- a/src/nesper/ledcs.nim +++ b/src/nesper/ledcs.nim @@ -42,6 +42,13 @@ proc repr*(c: ledc_channel_config_t): string = result &= "duty: " & $c.duty & ", " result &= "hpoint: " & $c.hpoint & ")" +var ledcInitialized*: bool = false + +proc initLedc*() = + if not ledcInitialized: + ledcInitialized = true + check: ledc_fade_func_install(0) + # Timer helpers proc newLedcTimer*( mode: ledc_mode_t, @@ -58,6 +65,8 @@ proc newLedcTimer*( result.cfg.clk_cfg = clkCfg result.cfg.deconfigure = false + initLedc() + let ret = ledc_timer_config(addr result.cfg) if ret != ESP_OK: raise newEspError[LedcError]("ledc_timer_config failed (" & $esp_err_to_name(ret) & ")", ret) From cb91d6832962bf70eec27f895f0007869125adb9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 25 Sep 2025 17:17:34 -0600 Subject: [PATCH 138/142] updates --- src/nesper/ota_utils.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nesper/ota_utils.nim b/src/nesper/ota_utils.nim index 0b88e3cc..339b1b09 100644 --- a/src/nesper/ota_utils.nim +++ b/src/nesper/ota_utils.nim @@ -103,7 +103,7 @@ proc begin*(ota: OtaUpdateHandle) = TAG.loge("esp_ota_begin failed (%s)", repr(ota.update)) raise newEspError[OtaError]("Error ota begin: " & $esp_err_to_name(err), err) -proc checkImageHeader*(ota: OtaUpdateHandle, data: var string; version_check = true): +proc checkImageHeader*(ota: OtaUpdateHandle, data: string; version_check = true): tuple[status: OtaUpdateStatus, info: esp_app_desc_t] = var new_app_info: esp_app_desc_t From 1f9b6718194825af3903cf88295ab47cbb201066 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 25 Sep 2025 17:20:43 -0600 Subject: [PATCH 139/142] updates --- src/nesper/ledcs.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nesper/ledcs.nim b/src/nesper/ledcs.nim index 22eb837d..2be21112 100644 --- a/src/nesper/ledcs.nim +++ b/src/nesper/ledcs.nim @@ -65,7 +65,7 @@ proc newLedcTimer*( result.cfg.clk_cfg = clkCfg result.cfg.deconfigure = false - initLedc() + # initLedc() let ret = ledc_timer_config(addr result.cfg) if ret != ESP_OK: From c9a3c3b9f7f1a07b2624b774f279e5d7f49dbeb9 Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 25 Sep 2025 17:25:07 -0600 Subject: [PATCH 140/142] updates --- src/nesper/ota_utils.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nesper/ota_utils.nim b/src/nesper/ota_utils.nim index 339b1b09..58e8277f 100644 --- a/src/nesper/ota_utils.nim +++ b/src/nesper/ota_utils.nim @@ -145,7 +145,7 @@ proc checkImageHeader*(ota: OtaUpdateHandle, data: string; version_check = true) return (status: VersionNewer, info: new_app_info) -proc write*(ota: var OtaUpdateHandle, write_data: var string) = +proc write*(ota: var OtaUpdateHandle, write_data: string) = let err = esp_ota_write(ota.handle, addr write_data[0], write_data.len().csize_t) if err != ESP_OK: raise newEspError[OtaError]("Error ota write: " & $esp_err_to_name(err), err) From 86e42647e226b566e0d1a02969c9773837920c5b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 25 Sep 2025 17:31:52 -0600 Subject: [PATCH 141/142] updates --- src/nesper/ota_utils.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nesper/ota_utils.nim b/src/nesper/ota_utils.nim index 58e8277f..2bdb6c95 100644 --- a/src/nesper/ota_utils.nim +++ b/src/nesper/ota_utils.nim @@ -5,6 +5,9 @@ import options import consts import general import esp/storage/esp_ota_ops +import esp_app_format + +export esp_app_format const TAG = "OTAUTL" From 67501300959e7c62f77a0bd7e56b7c33a178f13f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Thu, 25 Sep 2025 17:32:21 -0600 Subject: [PATCH 142/142] updates --- src/nesper/ota_utils.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nesper/ota_utils.nim b/src/nesper/ota_utils.nim index 2bdb6c95..9b8dde40 100644 --- a/src/nesper/ota_utils.nim +++ b/src/nesper/ota_utils.nim @@ -5,7 +5,7 @@ import options import consts import general import esp/storage/esp_ota_ops -import esp_app_format +import esp/storage/esp_app_format export esp_app_format