Forráskód Böngészése

esp32c6: add itwt example

yuexia 3 éve
szülő
commit
a10779c557

+ 8 - 0
examples/wifi/itwt/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)
+
+set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/system/console/advanced/components
+                         $ENV{IDF_PATH}/examples/common_components/iperf)
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(itwt)

+ 26 - 0
examples/wifi/itwt/README.md

@@ -0,0 +1,26 @@
+| Supported Targets | ESP32-C6 |
+| ----------------- | -------- |
+
+# Wifi itwt Example
+
+## Introduction
+This example shows how to use itwt of wifi.
+
+Itwt only works in station mode. And AP needs to support the capability of itwt.
+
+This example support command "itwt, itwt_probe, itwt_info" to config itwt.
+
+* itwt: this command is for itwt setup/teardown.
+
+* itwt_probe: this command will send a probe request to update tsf time with ap
+
+* itwt_info: this command will send a TWT Information frame to AP for suspending/resuming extablished iTWT agreements.
+
+### Typical current consumption with Itwt enabled
+
+
+
+### Typical current consumption with Itwt disabled
+
+
+Note that current consumption and average current are higher when disabled.

+ 2 - 0
examples/wifi/itwt/main/CMakeLists.txt

@@ -0,0 +1,2 @@
+idf_component_register(SRCS "itwt.c"
+                    INCLUDE_DIRS ".")

+ 107 - 0
examples/wifi/itwt/main/Kconfig.projbuild

@@ -0,0 +1,107 @@
+menu "Example Configuration"
+
+    config EXAMPLE_WIFI_SSID
+        string "WiFi SSID"
+        default "myssid"
+        help
+            SSID (network name) for the example to connect to.
+
+    config EXAMPLE_WIFI_PASSWORD
+        string "WiFi Password"
+        default "mypassword"
+        help
+            WiFi password (WPA or WPA2) for the example to use.
+
+    menu "iTWT Configuration"
+        config EXAMPLE_ITWT_TRIGGER_ENABLE
+            bool "trigger-enabled"
+            default y
+            help
+                0- a non-trigger-enabled TWT, 1-a trigger-enabled TWT
+        config EXAMPLE_ITWT_ANNOUNCED
+            bool "announced"
+            default y
+            help
+                0- an unannounced TWT, 1-an announced TWT
+        config EXAMPLE_ITWT_MIN_WAKE_DURA
+            int "itwt minimum wake duration"
+            range 1 255
+            default 255
+            help
+                Nominal Minimum Wake Duration, indicates the minimum amount of time, in unit of 256 us, that the TWT
+                requesting STA expects that it needs to be awake. The value range is [1, 255].
+        config EXAMPLE_ITWT_WAKE_INVL_EXPN
+            int "itwt wake interval exponent"
+            range 0 31
+            default 10
+            help
+                TWT Wake Interval Exponent, in microseconds. The value range is [0, 31].
+        config EXAMPLE_ITWT_WAKE_INVL_MANT
+            int "itwt wake interval mantissa"
+            range 1 65535
+            default 512
+            help
+                TWT Wake Interval Mantissa, in microseconds. The value range is [1, 65535].
+    endmenu
+
+    choice EXAMPLE_MAX_CPU_FREQ
+        prompt "Maximum CPU frequency"
+        default EXAMPLE_MAX_CPU_FREQ_80
+        depends on PM_ENABLE
+        help
+            Maximum CPU frequency to use for dynamic frequency scaling.
+
+        config EXAMPLE_MAX_CPU_FREQ_80
+            bool "80 MHz"
+        config EXAMPLE_MAX_CPU_FREQ_120
+            bool "120 MHz"
+            depends on IDF_TARGET_ESP32C2
+        config EXAMPLE_MAX_CPU_FREQ_160
+            bool "160 MHz"
+            depends on !IDF_TARGET_ESP32C2
+        config EXAMPLE_MAX_CPU_FREQ_240
+            bool "240 MHz"
+            depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
+    endchoice
+
+    config EXAMPLE_MAX_CPU_FREQ_MHZ
+        int
+        default 80 if EXAMPLE_MAX_CPU_FREQ_80
+        default 120 if EXAMPLE_MAX_CPU_FREQ_120
+        default 160 if EXAMPLE_MAX_CPU_FREQ_160
+        default 240 if EXAMPLE_MAX_CPU_FREQ_240
+
+    choice EXAMPLE_MIN_CPU_FREQ
+        prompt "Minimum CPU frequency"
+        default EXAMPLE_MIN_CPU_FREQ_10M
+        depends on PM_ENABLE
+        help
+            Minimum CPU frequency to use for dynamic frequency scaling.
+            Should be set to XTAL frequency or XTAL frequency divided by integer.
+
+        config EXAMPLE_MIN_CPU_FREQ_40M
+            bool "40 MHz (use with 40MHz XTAL)"
+            depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
+        config EXAMPLE_MIN_CPU_FREQ_20M
+            bool "20 MHz (use with 40MHz XTAL)"
+            depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
+        config EXAMPLE_MIN_CPU_FREQ_10M
+            bool "10 MHz (use with 40MHz XTAL)"
+            depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
+        config EXAMPLE_MIN_CPU_FREQ_26M
+            bool "26 MHz (use with 26MHz XTAL)"
+            depends on XTAL_FREQ_26 || XTAL_FREQ_AUTO
+        config EXAMPLE_MIN_CPU_FREQ_13M
+            bool "13 MHz (use with 26MHz XTAL)"
+            depends on XTAL_FREQ_26 || XTAL_FREQ_AUTO
+    endchoice
+
+    config EXAMPLE_MIN_CPU_FREQ_MHZ
+        int
+        default 40 if EXAMPLE_MIN_CPU_FREQ_40M
+        default 20 if EXAMPLE_MIN_CPU_FREQ_20M
+        default 10 if EXAMPLE_MIN_CPU_FREQ_10M
+        default 26 if EXAMPLE_MIN_CPU_FREQ_26M
+        default 13 if EXAMPLE_MIN_CPU_FREQ_13M
+
+endmenu

+ 296 - 0
examples/wifi/itwt/main/itwt.c

@@ -0,0 +1,296 @@
+/* itwt 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.
+*/
+
+/*
+   this example shows how to use itwt
+   set a router or a AP using the same SSID&PASSWORD as configuration of this example.
+   start esp32c6 and when it connected to AP it will setup itwt.
+*/
+#include "freertos/FreeRTOS.h"
+#include "freertos/event_groups.h"
+#include "esp_wifi.h"
+#include "esp_log.h"
+#include "esp_event.h"
+#include "nvs_flash.h"
+#include "esp_console.h"
+#include "cmd_system.h"
+#include "wifi_cmd.h"
+#include "esp_wifi_he.h"
+
+/*******************************************************
+ *                Constants
+ *******************************************************/
+static const char *TAG = "itwt";
+
+/*******************************************************
+ *                Structures
+ *******************************************************/
+
+/*******************************************************
+ *                Variable Definitions
+ *******************************************************/
+/*set the ssid and password via "idf.py menuconfig"*/
+#define DEFAULT_SSID CONFIG_EXAMPLE_WIFI_SSID
+#define DEFAULT_PWD CONFIG_EXAMPLE_WIFI_PASSWORD
+
+#if CONFIG_EXAMPLE_ITWT_TRIGGER_ENABLE
+bool trigger_enabled = true;
+#else
+bool trigger_enabled = false;
+#endif
+
+#if CONFIG_EXAMPLE_ITWT_ANNOUNCED
+bool flow_type_announced = true;
+#else
+bool flow_type_announced = false;
+#endif
+
+esp_netif_t *netif_sta = NULL;
+const int CONNECTED_BIT = BIT0;
+const int DISCONNECTED_BIT = BIT1;
+EventGroupHandle_t wifi_event_group;
+
+/*******************************************************
+ *                Function Declarations
+ *******************************************************/
+
+/*******************************************************
+ *                Function Definitions
+ *******************************************************/
+static const char *itwt_probe_status_to_str(wifi_itwt_probe_status_t status)
+{
+    switch (status) {
+    case ITWT_PROBE_FAIL:                 return "itwt probe fail";
+    case ITWT_PROBE_SUCCESS:              return "itwt probe success";
+    case ITWT_PROBE_TIMEOUT:              return "itwt probe timeout";
+    case ITWT_PROBE_STA_DISCONNECTED:     return "Sta disconnected";
+    default:                              return "Unknown status";
+    }
+}
+
+static void got_ip_handler(void *arg, esp_event_base_t event_base,
+                           int32_t event_id, void *event_data)
+{
+    xEventGroupClearBits(wifi_event_group, DISCONNECTED_BIT);
+    xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
+
+    /* setup a trigger-based announce individual TWT agreement. */
+    esp_err_t err = ESP_OK;
+    int flow_id = 0;
+    wifi_config_t sta_cfg = { 0, };
+    esp_wifi_get_config(WIFI_IF_STA, &sta_cfg);
+    if (sta_cfg.sta.phymode == WIFI_PHY_MODE_HE20) {
+        err = esp_wifi_sta_itwt_setup(TWT_REQUEST, trigger_enabled, flow_type_announced ? 0 : 1,
+                                      CONFIG_EXAMPLE_ITWT_MIN_WAKE_DURA, CONFIG_EXAMPLE_ITWT_WAKE_INVL_EXPN,
+                                      CONFIG_EXAMPLE_ITWT_WAKE_INVL_MANT, &flow_id);
+        if (err != ESP_OK) {
+            ESP_LOGE(TAG, "itwt setup failed, err:0x%x", err);
+        }
+
+    } else {
+        ESP_LOGE(TAG, "Must be in 11ax mode to support itwt");
+    }
+}
+
+static void connect_handler(void *arg, esp_event_base_t event_base,
+                            int32_t event_id, void *event_data)
+{
+    ESP_LOGI(TAG, "sta connect to %s", DEFAULT_SSID);
+    esp_wifi_connect();
+}
+
+static void disconnect_handler(void *arg, esp_event_base_t event_base,
+                               int32_t event_id, void *event_data)
+{
+    ESP_LOGI(TAG, "sta disconnect, reconnect...");
+    xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
+    esp_wifi_connect();
+}
+
+static void itwt_setup_handler(void *arg, esp_event_base_t event_base,
+                               int32_t event_id, void *event_data)
+{
+    wifi_event_sta_itwt_setup_t *setup = (wifi_event_sta_itwt_setup_t *) event_data;
+    if (setup->setup_cmd == TWT_ACCEPT) {
+        /* TWT Wake Interval = TWT Wake Interval Mantissa * (2 ^ TWT Wake Interval Exponent) */
+        ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SETUP>flow_id:%d, %s, %s, wake_dura:%d, wake_invl_e:%d, wake_invl_m:%d", setup->flow_id,
+                setup->trigger ? "trigger-enabled" : "non-trigger-enabled", setup->flow_type ? "unannounced" : "announced",
+                setup->min_wake_dura, setup->wake_invl_expn, setup->wake_invl_mant);
+        ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SETUP>wake duration:%d us, service period:%d ms", setup->min_wake_dura << 8, setup->wake_invl_mant << setup->wake_invl_expn);
+    } else {
+        ESP_LOGE(TAG, "<WIFI_EVENT_ITWT_SETUP>unexpected setup command:%d", setup->setup_cmd);
+    }
+}
+
+static void itwt_teardown_handler(void *arg, esp_event_base_t event_base,
+                                  int32_t event_id, void *event_data)
+{
+    wifi_event_sta_itwt_teardown_t *teardown = (wifi_event_sta_itwt_teardown_t *) event_data;
+    ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_TEARDOWN>flow_id %d%s", teardown->flow_id, (teardown->flow_id == 8) ? "(all twt)" : "");
+}
+
+static void itwt_suspend_handler(void *arg, esp_event_base_t event_base,
+                                 int32_t event_id, void *event_data)
+{
+    wifi_event_sta_itwt_suspend_t *suspend = (wifi_event_sta_itwt_suspend_t *) event_data;
+    ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SUSPEND>status:%d, flow_id_bitmap:0x%x, actual_suspend_time_ms:[%lu %lu %lu %lu %lu %lu %lu %lu]",
+             suspend->status, suspend->flow_id_bitmap,
+             suspend->actual_suspend_time_ms[0], suspend->actual_suspend_time_ms[1], suspend->actual_suspend_time_ms[2], suspend->actual_suspend_time_ms[3],
+             suspend->actual_suspend_time_ms[4], suspend->actual_suspend_time_ms[5], suspend->actual_suspend_time_ms[6], suspend->actual_suspend_time_ms[7]);
+}
+
+static void itwt_probe_handler(void *arg, esp_event_base_t event_base,
+                               int32_t event_id, void *event_data)
+{
+    wifi_event_sta_itwt_probe_t *probe = (wifi_event_sta_itwt_probe_t *) event_data;
+    ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_PROBE>status:%s, reason:0x%x", itwt_probe_status_to_str(probe->status), probe->reason);
+}
+
+static void wifi_itwt(void)
+{
+    ESP_ERROR_CHECK(esp_netif_init());
+    wifi_event_group = xEventGroupCreate();
+    ESP_ERROR_CHECK(esp_event_loop_create_default());
+    netif_sta = esp_netif_create_default_wifi_sta();
+    assert(netif_sta);
+
+    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
+
+    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
+                    WIFI_EVENT_STA_START,
+                    &connect_handler,
+                    NULL,
+                    NULL));
+    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
+                    WIFI_EVENT_STA_DISCONNECTED,
+                    &disconnect_handler,
+                    NULL,
+                    NULL));
+    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
+                    IP_EVENT_STA_GOT_IP,
+                    &got_ip_handler,
+                    NULL,
+                    NULL));
+    /* itwt */
+    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
+                    WIFI_EVENT_ITWT_SETUP,
+                    &itwt_setup_handler,
+                    NULL,
+                    NULL));
+    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
+                    WIFI_EVENT_ITWT_TEARDOWN,
+                    &itwt_teardown_handler,
+                    NULL,
+                    NULL));
+    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
+                    WIFI_EVENT_ITWT_SUSPEND,
+                    &itwt_suspend_handler,
+                    NULL,
+                    NULL));
+    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
+                    WIFI_EVENT_ITWT_PROBE,
+                    &itwt_probe_handler,
+                    NULL,
+                    NULL));
+
+    wifi_config_t wifi_config = {
+        .sta = {
+            .ssid = DEFAULT_SSID,
+            .password = DEFAULT_PWD,
+        },
+    };
+    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
+    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
+
+    esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT20);
+    esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_11AX);
+    esp_wifi_set_ps(WIFI_PS_MIN_MODEM);
+
+    ESP_ERROR_CHECK(esp_wifi_start());
+
+#if CONFIG_ENABLE_WIFI_RX_STATS
+#if CONFIG_ENABLE_WIFI_RX_MU_STATS
+    esp_wifi_enable_rx_statistics(true, true);
+#else
+    esp_wifi_enable_rx_statistics(true, false);
+#endif
+#endif
+#if CONFIG_ENABLE_WIFI_TX_STATS
+    esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_VO, true); //VO, mgmt
+    esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); //BE, data
+#endif
+
+}
+
+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();
+    }
+
+    // TODO: WIFI-5150
+#if CONFIG_PM_ENABLE
+    io_toggle_pmu_internal_signal_map_to_io_init();
+    io_toggle_gpio_init();
+
+    sleep_clock_system_retention_init();
+    sleep_clock_modem_retention_init();
+    sleep_peripheral_retention_init();
+    sleep_modem_wifi_modem_state_init();
+
+    // Configure dynamic frequency scaling:
+    // maximum and minimum frequencies are set in sdkconfig,
+    // automatic light sleep is enabled if tickless idle support is enabled.
+    esp_pm_config_esp32c6_t pm_config = {
+        .max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,
+        .min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,
+#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
+        .light_sleep_enable = true
+#endif
+    };
+    ESP_ERROR_CHECK( esp_pm_configure(&pm_config) );
+    ESP_ERROR_CHECK( ret );
+
+#else
+    printf("\n =================================================\n");
+    printf(" |                   Test WiFi 6 itwt             |\n");
+    printf(" =================================================\n\n");
+
+    esp_console_repl_t *repl = NULL;
+    esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
+    repl_config.prompt = "itwt>";
+
+    // init console REPL environment
+#if CONFIG_ESP_CONSOLE_UART
+    esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
+    ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
+#elif CONFIG_ESP_CONSOLE_USB_CDC
+    esp_console_dev_usb_cdc_config_t cdc_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT();
+    ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&cdc_config, &repl_config, &repl));
+#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
+    esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
+    ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl));
+#endif
+
+    // start console REPL
+    ESP_ERROR_CHECK(esp_console_start_repl(repl));
+#endif
+
+    //start wifi
+    wifi_itwt();
+    // register commands
+    register_system();
+    register_wifi_itwt();
+    register_wifi_stats();
+
+}

+ 21 - 0
examples/wifi/itwt/sdkconfig.defaults

@@ -0,0 +1,21 @@
+# Use lower CPU frequency
+CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80=y
+# Enable support for power management
+CONFIG_PM_ENABLE=y
+# Enable tickless idle mode
+CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
+# Put related source code in IRAM
+CONFIG_PM_SLP_IRAM_OPT=y
+CONFIG_PM_RTOS_IDLE_OPT=y
+# Disable all GPIO at light sleep
+CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL=y
+CONFIG_PM_SLP_DISABLE_GPIO=y
+# Enable wifi sleep iram optimization
+CONFIG_ESP_WIFI_SLP_IRAM_OPT=y
+
+CONFIG_ESP_GRATUITOUS_ARP=n
+CONFIG_LWIP_ESP_GRATUITOUS_ARP=n
+
+# CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set
+# CONFIG_ESP_GRATUITOUS_ARP is not set
+

+ 19 - 0
examples/wifi/itwt/sdkconfig.defaults.esp32c6

@@ -0,0 +1,19 @@
+#
+# ESP32C6-Specific
+#
+CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=20
+CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=38
+CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=35
+CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
+CONFIG_ESP32_WIFI_TX_BA_WIN=20
+CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
+CONFIG_ESP32_WIFI_RX_BA_WIN=20
+CONFIG_ESP32_WIFI_NVS_ENABLED=n
+
+CONFIG_LWIP_TCP_SND_BUF_DEFAULT=30000
+CONFIG_LWIP_TCP_WND_DEFAULT=34000
+CONFIG_LWIP_TCP_RECVMBOX_SIZE=64
+CONFIG_LWIP_UDP_RECVMBOX_SIZE=64
+CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64
+
+