esp32c6: add itwt example

pull/10469/head
yuexia 2022-12-20 22:07:54 +08:00 zatwierdzone przez lvshisheng
rodzic 032ebd76cb
commit a10779c557
7 zmienionych plików z 479 dodań i 0 usunięć

Wyświetl plik

@ -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)

Wyświetl plik

@ -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.

Wyświetl plik

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

Wyświetl plik

@ -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

Wyświetl plik

@ -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();
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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