Merge branch 'mesh/power_save_function' into 'master'
mesh/ps: add duty control and support only transmit/receive on active duty See merge request espressif/esp-idf!8152
This commit is contained in:
@@ -19,6 +19,78 @@ menu "Example Configuration"
|
||||
help
|
||||
Mesh Network Topology.
|
||||
|
||||
config MESH_ENABLE_PS
|
||||
bool "Enable mesh PS (power save) function"
|
||||
default y
|
||||
help
|
||||
Enable/Disable Power Save function.
|
||||
|
||||
choice
|
||||
bool "Mesh PS device duty cycle type"
|
||||
depends on MESH_ENABLE_PS
|
||||
default MESH_PS_DEV_DUTY_TYPE_REQUEST
|
||||
help
|
||||
Mesh PS device duty cycle type.
|
||||
|
||||
config MESH_PS_DEV_DUTY_TYPE_REQUEST
|
||||
bool "MESH_PS_DEV_DUTY_TYPE_REQUEST"
|
||||
config MESH_PS_DEV_DUTY_TYPE_DEMAND
|
||||
bool "MESH_PS_DEV_DUTY_TYPE_DEMAND"
|
||||
endchoice
|
||||
|
||||
config MESH_PS_DEV_DUTY_TYPE
|
||||
int
|
||||
depends on MESH_ENABLE_PS
|
||||
default 1 if MESH_PS_DEV_DUTY_TYPE_REQUEST
|
||||
default 4 if MESH_PS_DEV_DUTY_TYPE_DEMAND
|
||||
help
|
||||
Mesh PS device duty cycle type.
|
||||
|
||||
config MESH_PS_DEV_DUTY
|
||||
int "Mesh PS device duty cycle"
|
||||
depends on MESH_ENABLE_PS
|
||||
range 1 100
|
||||
default 12
|
||||
help
|
||||
Mesh PS device duty cycle.
|
||||
|
||||
config MESH_PS_NWK_DUTY
|
||||
int "Mesh PS network duty cycle"
|
||||
depends on MESH_ENABLE_PS
|
||||
range 1 100
|
||||
default 12
|
||||
help
|
||||
Mesh PS network duty cycle.
|
||||
|
||||
config MESH_PS_NWK_DUTY_DURATION
|
||||
int "Mesh PS network duty cycle duration (unit: minutes)"
|
||||
depends on MESH_ENABLE_PS
|
||||
range -1 100
|
||||
default -1
|
||||
help
|
||||
Mesh PS network duty cycle duration.
|
||||
|
||||
choice
|
||||
bool "Mesh PS network duty cycle rule"
|
||||
depends on MESH_ENABLE_PS
|
||||
default MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE
|
||||
help
|
||||
Mesh PS network duty cycle rule.
|
||||
|
||||
config MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE
|
||||
bool "MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE"
|
||||
config MESH_PS_NETWORK_DUTY_APPLIED_UPLINK
|
||||
bool "MESH_PS_NETWORK_DUTY_APPLIED_UPLINK"
|
||||
endchoice
|
||||
|
||||
config MESH_PS_NWK_DUTY_RULE
|
||||
int
|
||||
depends on MESH_ENABLE_PS
|
||||
default 0 if MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE
|
||||
default 1 if MESH_PS_NETWORK_DUTY_APPLIED_UPLINK
|
||||
help
|
||||
Mesh PS network duty cycle rule.
|
||||
|
||||
config MESH_MAX_LAYER
|
||||
int "Mesh Max Layer"
|
||||
range 1 25 if MESH_TOPO_TREE
|
||||
|
||||
@@ -45,9 +45,6 @@ esp_err_t mesh_light_init(void)
|
||||
.timer_num = LEDC_TIMER_0,
|
||||
.clk_cfg = LEDC_AUTO_CLK,
|
||||
};
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;
|
||||
#endif
|
||||
ledc_timer_config(&ledc_timer);
|
||||
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
/*******************************************************
|
||||
* Macros
|
||||
*******************************************************/
|
||||
//#define MESH_ENABLE_POWER_SAVE
|
||||
|
||||
/*******************************************************
|
||||
* Constants
|
||||
@@ -102,18 +101,12 @@ void esp_mesh_p2p_tx_main(void *arg)
|
||||
}
|
||||
|
||||
for (i = 0; i < route_table_size; i++) {
|
||||
#ifdef MESH_ENABLE_POWER_SAVE
|
||||
/* PS is enabled, it's better to check if the device is active now. */
|
||||
while (!esp_mesh_is_network_active()) {
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
}
|
||||
#endif
|
||||
err = esp_mesh_send(&route_table[i], &data, MESH_DATA_P2P, NULL, 0);
|
||||
if (err) {
|
||||
ESP_LOGE(MESH_TAG,
|
||||
"[ROOT-2-UNICAST:%d][L:%d]parent:"MACSTR" to "MACSTR", heap:%d[err:0x%x, proto:%d, tos:%d]",
|
||||
send_count, mesh_layer, MAC2STR(mesh_parent_addr.addr),
|
||||
MAC2STR(route_table[i].addr), esp_get_free_heap_size(),
|
||||
MAC2STR(route_table[i].addr), esp_get_minimum_free_heap_size(),
|
||||
err, data.proto, data.tos);
|
||||
} else if (!(send_count % 100)) {
|
||||
ESP_LOGW(MESH_TAG,
|
||||
@@ -121,7 +114,7 @@ void esp_mesh_p2p_tx_main(void *arg)
|
||||
send_count, mesh_layer,
|
||||
esp_mesh_get_routing_table_size(),
|
||||
MAC2STR(mesh_parent_addr.addr),
|
||||
MAC2STR(route_table[i].addr), esp_get_free_heap_size(),
|
||||
MAC2STR(route_table[i].addr), esp_get_minimum_free_heap_size(),
|
||||
err, data.proto, data.tos);
|
||||
}
|
||||
}
|
||||
@@ -165,7 +158,7 @@ void esp_mesh_p2p_rx_main(void *arg)
|
||||
"[#RX:%d/%d][L:%d] parent:"MACSTR", receive from "MACSTR", size:%d, heap:%d, flag:%d[err:0x%x, proto:%d, tos:%d]",
|
||||
recv_count, send_count, mesh_layer,
|
||||
MAC2STR(mesh_parent_addr.addr), MAC2STR(from.addr),
|
||||
data.size, esp_get_free_heap_size(), flag, err, data.proto,
|
||||
data.size, esp_get_minimum_free_heap_size(), flag, err, data.proto,
|
||||
data.tos);
|
||||
}
|
||||
}
|
||||
@@ -187,7 +180,7 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
mesh_addr_t id = {0,};
|
||||
static uint8_t last_layer = 0;
|
||||
static uint16_t last_layer = 0;
|
||||
|
||||
switch (event_id) {
|
||||
case MESH_EVENT_STARTED: {
|
||||
@@ -244,10 +237,10 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base,
|
||||
mesh_layer = connected->self_layer;
|
||||
memcpy(&mesh_parent_addr.addr, connected->connected.bssid, 6);
|
||||
ESP_LOGI(MESH_TAG,
|
||||
"<MESH_EVENT_PARENT_CONNECTED>layer:%d-->%d, parent:"MACSTR"%s, ID:"MACSTR"",
|
||||
"<MESH_EVENT_PARENT_CONNECTED>layer:%d-->%d, parent:"MACSTR"%s, ID:"MACSTR", duty:%d",
|
||||
last_layer, mesh_layer, MAC2STR(mesh_parent_addr.addr),
|
||||
esp_mesh_is_root() ? "<ROOT>" :
|
||||
(mesh_layer == 2) ? "<layer2>" : "", MAC2STR(id.addr));
|
||||
(mesh_layer == 2) ? "<layer2>" : "", MAC2STR(id.addr), connected->duty);
|
||||
last_layer = mesh_layer;
|
||||
mesh_connected_indicator(mesh_layer);
|
||||
is_mesh_connected = true;
|
||||
@@ -365,6 +358,17 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base,
|
||||
router_switch->ssid, router_switch->channel, MAC2STR(router_switch->bssid));
|
||||
}
|
||||
break;
|
||||
case MESH_EVENT_PS_PARENT_DUTY: {
|
||||
mesh_event_ps_duty_t *ps_duty = (mesh_event_ps_duty_t *)event_data;
|
||||
ESP_LOGI(MESH_TAG, "<MESH_EVENT_PS_PARENT_DUTY>duty:%d", ps_duty->duty);
|
||||
}
|
||||
break;
|
||||
case MESH_EVENT_PS_CHILD_DUTY: {
|
||||
mesh_event_ps_duty_t *ps_duty = (mesh_event_ps_duty_t *)event_data;
|
||||
ESP_LOGI(MESH_TAG, "<MESH_EVENT_PS_CHILD_DUTY>cidx:%d, "MACSTR", duty:%d", ps_duty->child_connected.aid-1,
|
||||
MAC2STR(ps_duty->child_connected.mac), ps_duty->duty);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(MESH_TAG, "unknown id:%d", event_id);
|
||||
break;
|
||||
@@ -394,12 +398,6 @@ void app_main(void)
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&config));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_FLASH));
|
||||
#ifdef MESH_ENABLE_POWER_SAVE
|
||||
/* enable the mesh PS function by setting WIFI_PS_MIN_MODEM for all mesh devices before mesh is started */
|
||||
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_MIN_MODEM));
|
||||
#else
|
||||
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
|
||||
#endif
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
/* mesh initialization */
|
||||
ESP_ERROR_CHECK(esp_mesh_init());
|
||||
@@ -409,12 +407,17 @@ void app_main(void)
|
||||
/* set mesh max layer according to the topology */
|
||||
ESP_ERROR_CHECK(esp_mesh_set_max_layer(CONFIG_MESH_MAX_LAYER));
|
||||
ESP_ERROR_CHECK(esp_mesh_set_vote_percentage(1));
|
||||
#ifdef MESH_ENABLE_POWER_SAVE
|
||||
/* PS is enabled, it's better to increase the associate expired time. */
|
||||
ESP_ERROR_CHECK(esp_mesh_set_xon_qsize(128));
|
||||
#ifdef CONFIG_MESH_ENABLE_PS
|
||||
/* Enable mesh PS function */
|
||||
ESP_ERROR_CHECK(esp_mesh_enable_ps());
|
||||
/* better to increase the associate expired time, if a small duty cycle is set. */
|
||||
ESP_ERROR_CHECK(esp_mesh_set_ap_assoc_expire(60));
|
||||
/* PS is enabled, it's better to increase the announce interval. */
|
||||
/* better to increase the announce interval to avoid too much management traffic, if a small duty cycle is set. */
|
||||
ESP_ERROR_CHECK(esp_mesh_set_announce_interval(600, 3300));
|
||||
#else
|
||||
/* Disable mesh PS function */
|
||||
ESP_ERROR_CHECK(esp_mesh_disable_ps());
|
||||
ESP_ERROR_CHECK(esp_mesh_set_ap_assoc_expire(10));
|
||||
#endif
|
||||
mesh_cfg_t cfg = MESH_INIT_CONFIG_DEFAULT();
|
||||
@@ -432,13 +435,15 @@ void app_main(void)
|
||||
memcpy((uint8_t *) &cfg.mesh_ap.password, CONFIG_MESH_AP_PASSWD,
|
||||
strlen(CONFIG_MESH_AP_PASSWD));
|
||||
ESP_ERROR_CHECK(esp_mesh_set_config(&cfg));
|
||||
#ifdef MESH_ENABLE_POWER_SAVE
|
||||
/* PS is enabled, set the device active duty cycle. (default:12) */
|
||||
ESP_ERROR_CHECK(esp_mesh_set_active_duty_cycle(15, MESH_PS_DEVICE_DUTY_REQUEST));
|
||||
#endif
|
||||
/* mesh start */
|
||||
ESP_ERROR_CHECK(esp_mesh_start());
|
||||
ESP_LOGI(MESH_TAG, "mesh starts successfully, heap:%d, %s<%d>%s\n", esp_get_free_heap_size(),
|
||||
#ifdef CONFIG_MESH_ENABLE_PS
|
||||
/* set the device active duty cycle. (default:12, MESH_PS_DEVICE_DUTY_REQUEST) */
|
||||
ESP_ERROR_CHECK(esp_mesh_set_active_duty_cycle(CONFIG_MESH_PS_DEV_DUTY, CONFIG_MESH_PS_DEV_DUTY_TYPE));
|
||||
/* set the network active duty cycle. (default:12, -1, MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE) */
|
||||
ESP_ERROR_CHECK(esp_mesh_set_network_duty_cycle(CONFIG_MESH_PS_NWK_DUTY, CONFIG_MESH_PS_NWK_DUTY_DURATION, CONFIG_MESH_PS_NWK_DUTY_RULE));
|
||||
#endif
|
||||
ESP_LOGI(MESH_TAG, "mesh starts successfully, heap:%d, %s<%d>%s, ps:%d\n", esp_get_minimum_free_heap_size(),
|
||||
esp_mesh_is_root_fixed() ? "root fixed" : "root not fixed",
|
||||
esp_mesh_get_topology(), esp_mesh_get_topology() ? "(chain)":"(tree)");
|
||||
esp_mesh_get_topology(), esp_mesh_get_topology() ? "(chain)":"(tree)", esp_mesh_is_ps_enabled());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user