From 4f537d3b9889752da51bbd7dd7e9de75f79b7f93 Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Thu, 25 May 2023 18:18:03 +0800 Subject: [PATCH 01/11] ieee802154: support light sleep --- .../include/esp_private/esp_regdma.h | 4 +- .../include/esp_private/sleep_retention.h | 3 +- components/esp_hw_support/sleep_clock.c | 6 +- components/esp_hw_support/sleep_retention.c | 1 - components/ieee802154/Kconfig | 8 + .../ieee802154/driver/esp_ieee802154_dev.c | 54 ++++- components/ieee802154/esp_ieee802154.c | 10 + .../ieee802154/include/esp_ieee802154.h | 11 + .../private_include/esp_ieee802154_dev.h | 12 + components/openthread/port/esp_openthread.cpp | 107 +++++++++ .../openthread/port/esp_openthread_sleep.c | 68 ++++++ .../private_include/esp_openthread_sleep.h | 41 ++++ .../src/port/esp_openthread_radio.c | 2 +- examples/openthread/.build-test-rules.yml | 8 + examples/openthread/README.md | 2 + .../openthread/ot_power_save/CMakeLists.txt | 6 + examples/openthread/ot_power_save/README.md | 46 ++++ .../ot_power_save/main/CMakeLists.txt | 2 + .../ot_power_save/main/esp_ot_power_save.c | 206 ++++++++++++++++++ .../main/esp_ot_power_save_config.h | 54 +++++ .../openthread/ot_power_save/partitions.csv | 6 + .../ot_power_save/sdkconfig.defaults | 53 +++++ 22 files changed, 699 insertions(+), 11 deletions(-) create mode 100644 components/openthread/port/esp_openthread.cpp create mode 100644 components/openthread/port/esp_openthread_sleep.c create mode 100644 components/openthread/private_include/esp_openthread_sleep.h create mode 100644 examples/openthread/ot_power_save/CMakeLists.txt create mode 100644 examples/openthread/ot_power_save/README.md create mode 100644 examples/openthread/ot_power_save/main/CMakeLists.txt create mode 100644 examples/openthread/ot_power_save/main/esp_ot_power_save.c create mode 100644 examples/openthread/ot_power_save/main/esp_ot_power_save_config.h create mode 100644 examples/openthread/ot_power_save/partitions.csv create mode 100644 examples/openthread/ot_power_save/sdkconfig.defaults diff --git a/components/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index 846665c5b4..24d4bd24f6 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -40,8 +40,8 @@ extern "C" { #define REGDMA_IOMUX_LINK(_pri) ((0x12 << 8) | _pri) #define REGDMA_SPIMEM_LINK(_pri) ((0x13 << 8) | _pri) #define REGDMA_SYSTIMER_LINK(_pri) ((0x14 << 8) | _pri) -#define REGDMA_BLE_MAC_LINK(_pri) ((0x15 << 8) | _pri) -#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x16 << 8) | _pri) +#define REGDMA_MODEM_BTBB_LINK(_pri) ((0x15 << 8) | _pri) +#define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x16 << 8) | _pri) #define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri) typedef enum { diff --git a/components/esp_hw_support/include/esp_private/sleep_retention.h b/components/esp_hw_support/include/esp_private/sleep_retention.h index 2c1bb7fecf..007f973f42 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -32,9 +32,8 @@ typedef enum sleep_retention_module_bitmap { SLEEP_RETENTION_MODULE_WIFI_MAC = BIT(10), SLEEP_RETENTION_MODULE_WIFI_BB = BIT(11), SLEEP_RETENTION_MODULE_BLE_MAC = BIT(12), - SLEEP_RETENTION_MODULE_BLE_BB = BIT(13), + SLEEP_RETENTION_MODULE_BT_BB = BIT(13), SLEEP_RETENTION_MODULE_802154_MAC = BIT(14), - SLEEP_RETENTION_MODULE_802154_BB = BIT(15), /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ diff --git a/components/esp_hw_support/sleep_clock.c b/components/esp_hw_support/sleep_clock.c index 3617868d0e..86e2b15ff4 100644 --- a/components/esp_hw_support/sleep_clock.c +++ b/components/esp_hw_support/sleep_clock.c @@ -81,21 +81,21 @@ bool IRAM_ATTR clock_domain_pd_allowed(void) const uint32_t modules = sleep_retention_get_modules(); const uint32_t mask = (const uint32_t) ( SLEEP_RETENTION_MODULE_CLOCK_SYSTEM -#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE +#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE | SLEEP_RETENTION_MODULE_CLOCK_MODEM #endif ); return ((modules & mask) == mask); } -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP || CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP || CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, BIT(0), 106) { #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP sleep_clock_system_retention_init(); #endif -#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE +#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE sleep_clock_modem_retention_init(); #endif return ESP_OK; diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index af357efb3b..562fd3158a 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -21,7 +21,6 @@ #include "sdkconfig.h" #include "esp_pmu.h" - static __attribute__((unused)) const char *TAG = "sleep"; /** diff --git a/components/ieee802154/Kconfig b/components/ieee802154/Kconfig index 4ca8ab64c2..6b01de4e72 100644 --- a/components/ieee802154/Kconfig +++ b/components/ieee802154/Kconfig @@ -74,4 +74,12 @@ menu "IEEE 802.15.4" Enabling this option increases throughput by ~5% at the expense of ~2.1k IRAM code size increase. + + config IEEE802154_SLEEP_ENABLE + bool "Enable IEEE802154 light sleep" + depends on PM_ENABLE && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + default n + help + Enabling this option allows the IEEE802.15.4 module to be powered down during automatic light sleep, + which reduces current consumption. endmenu # IEEE 802.15.4 diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index 1552856101..243228829d 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -24,6 +24,13 @@ #include "esp_ieee802154_timer.h" #include "hal/ieee802154_ll.h" #include "esp_attr.h" +#include "esp_phy_init.h" + +#if CONFIG_IEEE802154_SLEEP_ENABLE +#include "esp_pm.h" +#include "esp_private/esp_clk.h" +#include "esp_private/sleep_retention.h" +#endif #define CCA_DETECTION_TIME 8 @@ -38,6 +45,8 @@ static uint8_t s_enh_ack_frame[128]; static uint8_t s_recent_rx_frame_info_index; static portMUX_TYPE s_ieee802154_spinlock = portMUX_INITIALIZER_UNLOCKED; +static esp_err_t ieee802154_sleep_init(void); + static IRAM_ATTR void event_end_process(void) { ieee802154_etm_channel_clear(IEEE802154_ETM_CHANNEL0); @@ -193,7 +202,7 @@ IEEE802154_STATIC bool stop_current_operation(void) break; case IEEE802154_STATE_IDLE: - // do nothing + ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); break; case IEEE802154_STATE_RX: @@ -580,10 +589,12 @@ IEEE802154_STATIC IRAM_ATTR void ieee802154_exit_critical(void) void ieee802154_enable(void) { modem_clock_module_enable(ieee802154_periph.module); + s_ieee802154_state = IEEE802154_STATE_IDLE; } void ieee802154_disable(void) { + modem_clock_module_disable(ieee802154_periph.module); s_ieee802154_state = IEEE802154_STATE_DISABLE; } @@ -616,12 +627,13 @@ esp_err_t ieee802154_mac_init(void) #endif memset(s_rx_frame, 0, sizeof(s_rx_frame)); - s_ieee802154_state = IEEE802154_STATE_IDLE; // TODO: Add flags for IEEE802154 ISR allocating. TZ-102 ret = esp_intr_alloc(ieee802154_periph.irq_id, 0, ieee802154_isr, NULL, NULL); ESP_RETURN_ON_FALSE(ret == ESP_OK, ESP_FAIL, IEEE802154_TAG, "IEEE802154 MAC init failed"); + ret = ieee802154_sleep_init(); + return ret; } @@ -743,6 +755,44 @@ esp_err_t ieee802154_receive_at(uint32_t time) return ESP_OK; } +static esp_err_t ieee802154_sleep_init(void) +{ + esp_err_t err = ESP_OK; +#if CONFIG_IEEE802154_SLEEP_ENABLE + #define N_REGS_IEEE802154() (((IEEE802154_MAC_DATE_REG - IEEE802154_REG_BASE) / 4) + 1) + const static sleep_retention_entries_config_t ieee802154_mac_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_IEEE802154_LINK(0x00), IEEE802154_REG_BASE, IEEE802154_REG_BASE, N_REGS_IEEE802154(), 0, 0), .owner = ENTRY(3) }, + }; + + err = sleep_retention_entries_create(ieee802154_mac_regs_retention, ARRAY_SIZE(ieee802154_mac_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_802154_MAC); + ESP_RETURN_ON_ERROR(err, IEEE802154_TAG, "failed to allocate memory for ieee802154 mac retention"); + ESP_LOGI(IEEE802154_TAG, "ieee802154 mac sleep retention initialization"); +#endif + return err; +} + +IRAM_ATTR void ieee802154_sleep_cb(void) +{ +#if CONFIG_IEEE802154_SLEEP_ENABLE + esp_phy_disable(); +#if SOC_PM_RETENTION_HAS_CLOCK_BUG + sleep_retention_do_extra_retention(true);// backup +#endif + ieee802154_disable(); // IEEE802154 CLOCK Disable +#endif // CONFIG_IEEE802154_SLEEP_ENABLE +} + +IRAM_ATTR void ieee802154_wakeup_cb(void) +{ +#if CONFIG_IEEE802154_SLEEP_ENABLE + ieee802154_enable(); // IEEE802154 CLOCK Enable +#if SOC_PM_RETENTION_HAS_CLOCK_BUG + sleep_retention_do_extra_retention(false);// restore +#endif + esp_phy_enable(); +#endif //CONFIG_IEEE802154_SLEEP_ENABLE +} + esp_err_t ieee802154_sleep(void) { ieee802154_enter_critical(); diff --git a/components/ieee802154/esp_ieee802154.c b/components/ieee802154/esp_ieee802154.c index cadbabaacf..42c0d2065c 100644 --- a/components/ieee802154/esp_ieee802154.c +++ b/components/ieee802154/esp_ieee802154.c @@ -331,6 +331,16 @@ uint8_t esp_ieee802154_get_recent_lqi(void) return ieee802154_get_recent_lqi(); } +void esp_ieee802154_sleep_cb(void) +{ + ieee802154_sleep_cb(); +} + +void esp_ieee802154_wakeup_cb(void) +{ + ieee802154_wakeup_cb(); +} + __attribute__((weak)) void esp_ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info) { diff --git a/components/ieee802154/include/esp_ieee802154.h b/components/ieee802154/include/esp_ieee802154.h index 96de1a0775..63ac0b5178 100644 --- a/components/ieee802154/include/esp_ieee802154.h +++ b/components/ieee802154/include/esp_ieee802154.h @@ -111,6 +111,17 @@ esp_ieee802154_state_t esp_ieee802154_get_state(void); */ esp_err_t esp_ieee802154_sleep(void); +/** + * @brief The IEEE 802.15.4 sleep callback. + */ + +void esp_ieee802154_sleep_cb(void); + +/** + * @brief The IEEE 802.15.4 wakeup callback. + */ +void esp_ieee802154_wakeup_cb(void); + /** * @brief Set the IEEE 802.15.4 Radio to receive state. * diff --git a/components/ieee802154/private_include/esp_ieee802154_dev.h b/components/ieee802154/private_include/esp_ieee802154_dev.h index b22443cad9..ef13f45445 100644 --- a/components/ieee802154/private_include/esp_ieee802154_dev.h +++ b/components/ieee802154/private_include/esp_ieee802154_dev.h @@ -177,6 +177,18 @@ uint8_t ieee802154_get_recent_lqi(void); */ ieee802154_state_t ieee802154_get_state(void); +/** + * @brief The callback of IEEE 802.15.4 sleep. + * + */ +void ieee802154_sleep_cb(void); + +/** + * @brief The callback of IEEE 802.15.4 wakeup. + * + */ +void ieee802154_wakeup_cb(void); + /** The following three functions are only used for internal test. **/ /** * @brief The clear channel assessment done. diff --git a/components/openthread/port/esp_openthread.cpp b/components/openthread/port/esp_openthread.cpp new file mode 100644 index 0000000000..8b1cc2ae2b --- /dev/null +++ b/components/openthread/port/esp_openthread.cpp @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_openthread.h" +#include "esp_check.h" +#include "esp_openthread_border_router.h" +#include "esp_openthread_common_macro.h" +#include "esp_openthread_dns64.h" +#include "esp_openthread_lock.h" +#include "esp_openthread_platform.h" +#include "esp_openthread_task_queue.h" +#include "esp_openthread_types.h" +#include "freertos/FreeRTOS.h" +#include "lwip/dns.h" +#include "openthread/instance.h" +#include "openthread/netdata.h" +#include "openthread/tasklet.h" +#include "esp_openthread_sleep.h" + +esp_err_t esp_openthread_init(const esp_openthread_platform_config_t *config) +{ +#if CONFIG_IEEE802154_SLEEP_ENABLE + ESP_RETURN_ON_ERROR(esp_openthread_sleep_init(), OT_PLAT_LOG_TAG, + "Failed to initialize OpenThread esp pm_lock"); +#endif + ESP_RETURN_ON_ERROR(esp_openthread_platform_init(config), OT_PLAT_LOG_TAG, + "Failed to initialize OpenThread platform driver"); + esp_openthread_lock_acquire(portMAX_DELAY); + ESP_RETURN_ON_FALSE(otInstanceInitSingle() != NULL, ESP_FAIL, OT_PLAT_LOG_TAG, + "Failed to initialize OpenThread instance"); +#if CONFIG_OPENTHREAD_DNS64_CLIENT + ESP_RETURN_ON_ERROR(esp_openthread_dns64_client_init(), OT_PLAT_LOG_TAG, + "Failed to initialize OpenThread dns64 client"); +#endif + esp_openthread_lock_release(); + + return ESP_OK; +} + +esp_err_t esp_openthread_launch_mainloop(void) +{ + esp_openthread_mainloop_context_t mainloop; + otInstance *instance = esp_openthread_get_instance(); + esp_err_t error = ESP_OK; + + while (true) { + FD_ZERO(&mainloop.read_fds); + FD_ZERO(&mainloop.write_fds); + FD_ZERO(&mainloop.error_fds); + + mainloop.max_fd = -1; + mainloop.timeout.tv_sec = 10; + mainloop.timeout.tv_usec = 0; + + esp_openthread_lock_acquire(portMAX_DELAY); + esp_openthread_platform_update(&mainloop); + if (otTaskletsArePending(instance)) { + mainloop.timeout.tv_sec = 0; + mainloop.timeout.tv_usec = 0; + } +#if CONFIG_IEEE802154_SLEEP_ENABLE + esp_openthread_sleep_process(); +#endif + esp_openthread_lock_release(); + + if (select(mainloop.max_fd + 1, &mainloop.read_fds, &mainloop.write_fds, &mainloop.error_fds, + &mainloop.timeout) >= 0) { + esp_openthread_lock_acquire(portMAX_DELAY); +#if CONFIG_IEEE802154_SLEEP_ENABLE + esp_openthread_wakeup_process(); +#endif + error = esp_openthread_platform_process(instance, &mainloop); + while (otTaskletsArePending(instance)) { + otTaskletsProcess(instance); + } + esp_openthread_lock_release(); + if (error != ESP_OK) { + ESP_LOGE(OT_PLAT_LOG_TAG, "esp_openthread_platform_process failed"); + break; + } + } else { + error = ESP_FAIL; + ESP_LOGE(OT_PLAT_LOG_TAG, "OpenThread system polling failed"); + break; + } + } + return error; +} + +esp_err_t esp_openthread_deinit(void) +{ + otInstanceFinalize(esp_openthread_get_instance()); + return esp_openthread_platform_deinit(); +} + +static void stub_task(void *context) +{ + // this is a empty function used for ot-task signal pending +} + +void otTaskletsSignalPending(otInstance *aInstance) +{ + esp_openthread_task_queue_post(stub_task, NULL); +} diff --git a/components/openthread/port/esp_openthread_sleep.c b/components/openthread/port/esp_openthread_sleep.c new file mode 100644 index 0000000000..f8794e13c0 --- /dev/null +++ b/components/openthread/port/esp_openthread_sleep.c @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_log.h" +#include "esp_check.h" +#include "openthread/instance.h" +#include "openthread/thread.h" +#include "esp_openthread.h" +#include "esp_ieee802154.h" + +#if CONFIG_IEEE802154_SLEEP_ENABLE +#include "esp_pm.h" +static esp_pm_lock_handle_t s_pm_lock = NULL; +static const char* TAG = "esp openthread sleep"; +static bool s_ot_sleep = false; + +esp_err_t esp_openthread_sleep_init(void) +{ + esp_err_t err = ESP_OK; + + err = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "ieee802154", &s_pm_lock); + if (err != ESP_OK) { + goto error; + } + esp_pm_lock_acquire(s_pm_lock); + + ESP_LOGI(TAG, "Enable ieee802154 light sleep, the wake up source is ESP timer"); + + return err; + +error: + /*lock should release first and then delete*/ + if (s_pm_lock != NULL) { + esp_pm_lock_release(s_pm_lock); + esp_pm_lock_delete(s_pm_lock); + s_pm_lock = NULL; + } + return err; +} + +void esp_openthread_sleep_process(void) +{ + otInstance *instance = esp_openthread_get_instance(); + otLinkModeConfig linkMode = otThreadGetLinkMode(instance); + bool s_ot_sed_ssed = false; + if (linkMode.mRxOnWhenIdle == false && linkMode.mDeviceType == false && linkMode.mNetworkData == false) { + s_ot_sed_ssed = true; + } + + if (esp_ieee802154_get_state() == ESP_IEEE802154_RADIO_SLEEP && s_ot_sed_ssed) { + esp_ieee802154_sleep_cb(); + esp_pm_lock_release(s_pm_lock); + s_ot_sleep = true; + } +} + +void esp_openthread_wakeup_process(void) +{ + if (s_ot_sleep) { + esp_pm_lock_acquire(s_pm_lock); + esp_ieee802154_wakeup_cb(); + s_ot_sleep = false; + } +} +#endif // CONFIG_IEEE802154_SLEEP_ENABLE diff --git a/components/openthread/private_include/esp_openthread_sleep.h b/components/openthread/private_include/esp_openthread_sleep.h new file mode 100644 index 0000000000..bae2913d4f --- /dev/null +++ b/components/openthread/private_include/esp_openthread_sleep.h @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CONFIG_IEEE802154_SLEEP_ENABLE +/** + * @brief This function initializes the OpenThread sleep. + * + * @return + * - ESP_OK on success + * - ESP_FAIL on failure + * + */ +esp_err_t esp_openthread_sleep_init(void); + +/** + * @brief This function performs the OpenThread sleep process. + * + */ +void esp_openthread_sleep_process(void); + +/** + * @brief This function performs the OpenThread wakeup process. + * + */ +void esp_openthread_wakeup_process(void); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/openthread/src/port/esp_openthread_radio.c b/components/openthread/src/port/esp_openthread_radio.c index fa4dcfbe12..6ad310fd03 100644 --- a/components/openthread/src/port/esp_openthread_radio.c +++ b/components/openthread/src/port/esp_openthread_radio.c @@ -273,7 +273,7 @@ otError otPlatRadioEnable(otInstance *aInstance) otError otPlatRadioDisable(otInstance *aInstance) { - esp_ieee802154_disable(); + // radio will be disabled in esp_openthread_radio_deinit() return OT_ERROR_NONE; } diff --git a/examples/openthread/.build-test-rules.yml b/examples/openthread/.build-test-rules.yml index 75acba2f4d..bab61b6116 100644 --- a/examples/openthread/.build-test-rules.yml +++ b/examples/openthread/.build-test-rules.yml @@ -18,6 +18,14 @@ examples/openthread/ot_cli: temporary: true reason: only test on esp32h2 +examples/openthread/ot_power_save: + enable: + - if: IDF_TARGET == "esp32c6" + disable_test: + - if: IDF_TARGET in ["esp32h2", "esp32c6"] + temporary: true + reason: No support # TO-DO: TZ-134 + examples/openthread/ot_rcp: enable: - if: IDF_TARGET in ["esp32h2", "esp32c6"] diff --git a/examples/openthread/README.md b/examples/openthread/README.md index 1c7728835e..f7de43d3c7 100644 --- a/examples/openthread/README.md +++ b/examples/openthread/README.md @@ -11,3 +11,5 @@ In this folder, it contains following OpenThread examples: * [ot_rcp](ot_rcp) is an [OpenThread RCP](https://openthread.io/platforms/co-processor) example. It runs on an 802.15.4 SoC like ESP32-H2, to extend 802.15.4 radio. * [ot_br](ot_br) is an [OpenThread Border Router](https://openthread.io/guides/border-router) example. It runs on a Wi-Fi SoC such as ESP32, ESP32-C3 and ESP32-S3. It needs an 802.15.4 SoC like ESP32-H2 running [ot_rcp](ot_rcp) example to provide 802.15.4 radio. + +* [ot_power_save](ot_power_save) is an OpenThread Power save example, it supports 802.15.4 radio light sleep. It runs on an 802.15.4 SoC like ESP32-C6. \ No newline at end of file diff --git a/examples/openthread/ot_power_save/CMakeLists.txt b/examples/openthread/ot_power_save/CMakeLists.txt new file mode 100644 index 0000000000..a975ba7e48 --- /dev/null +++ b/examples/openthread/ot_power_save/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(ot_power_save) diff --git a/examples/openthread/ot_power_save/README.md b/examples/openthread/ot_power_save/README.md new file mode 100644 index 0000000000..adafceb053 --- /dev/null +++ b/examples/openthread/ot_power_save/README.md @@ -0,0 +1,46 @@ +| Supported Targets | ESP32-C6 | +| ----------------- | -------- | + +# OpenThread Power Save Example + +The example demonstrates the OpenThread Power Save based on light sleep, which reduces power consumption by turning off RF, PHY, BB, and IEEE802154 MAC during the sleep state. +## How to use example + +### Hardware Required + +* Prepare an ESP32-C6 development board as an OpenThread Sleepy End Device (SED). +* Connect the board using a USB cable for power supply and programming. +* Choose another ESP32-C6 as the OpenThread Leader. + + +## Configure the Openthread Dataset + +* Run [ot_cli](../ot_cli/) on another ESP32-C6 device to create openthread dataset configuration and start an openthread network as the leader. +* Configure the Openthread dataset (`CONFIG_OPENTHREAD_NETWORK_DATASET`) in [ot_power_save](../ot_power_save/main/esp_ot_power_save_config.h), ensuring that the device's dataset matches the dataset of the leader. + +## Erase the ot_storage + +If desired, erase the ot_storage by running `idf.py -p erase-flash` before flashing the board to remove previous examples or other project data. + +### Build and Flash + + Build the project and flash it to the board. Use the following command: `idf.py -p build flash monitor`. + + +### Example Output + +As the example runs, you will see the log output indicating the initialization and operation of OpenThread, including the device joining the OpenThread network as a Sleepy End Device (SED) and periodic polling of the leader. + +``` +I (769) btbb_init: btbb sleep retention initialization +I (769) ieee802154: ieee802154 mac sleep retention initialization +I(769) OPENTHREAD:[I] ChildSupervsn-: Timeout: 0 -> 190 +I (699) main_task: Returned from app_main() +I (799) OPENTHREAD: OpenThread attached to netif +I(799) OPENTHREAD:[N] Mle-----------: Mode 0x0f -> 0x04 [rx-on:no ftd:no full-net:no] +I(809) OPENTHREAD:[N] Mle-----------: Role disabled -> detached +I (819) OPENTHREAD: netif up +I(1519) OPENTHREAD:[N] Mle-----------: Attach attempt 1, AnyPartition reattaching with Active Dataset +I(2479) OPENTHREAD:[N] Mle-----------: RLOC16 fffe -> 5023 +I(2529) OPENTHREAD:[N] Mle-----------: Role detached -> child +``` \ No newline at end of file diff --git a/examples/openthread/ot_power_save/main/CMakeLists.txt b/examples/openthread/ot_power_save/main/CMakeLists.txt new file mode 100644 index 0000000000..832a7f9bed --- /dev/null +++ b/examples/openthread/ot_power_save/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "esp_ot_power_save.c" + INCLUDE_DIRS ".") diff --git a/examples/openthread/ot_power_save/main/esp_ot_power_save.c b/examples/openthread/ot_power_save/main/esp_ot_power_save.c new file mode 100644 index 0000000000..9d6205d83b --- /dev/null +++ b/examples/openthread/ot_power_save/main/esp_ot_power_save.c @@ -0,0 +1,206 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + * + * OpenThread Command Line 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 +#include +#include + +#include "esp_err.h" +#include "esp_event.h" +#include "esp_log.h" +#include "esp_openthread.h" +#include "esp_openthread_netif_glue.h" +#include "esp_ot_power_save_config.h" +#include "esp_vfs_eventfd.h" +#include "driver/uart.h" +#include "nvs_flash.h" +#include "openthread/logging.h" +#include "openthread/thread.h" + +#ifdef CONFIG_PM_ENABLE +#include "esp_pm.h" +#endif + +#if !SOC_IEEE802154_SUPPORTED +#error "Power save is only supported for the SoCs which have IEEE 802.15.4 module" +#endif + +#define TAG "ot_esp_power_save" + +static int hex_digit_to_int(char hex) +{ + if ('A' <= hex && hex <= 'F') { + return 10 + hex - 'A'; + } + if ('a' <= hex && hex <= 'f') { + return 10 + hex - 'a'; + } + if ('0' <= hex && hex <= '9') { + return hex - '0'; + } + return -1; +} + +static size_t hex_string_to_binary(const char *hex_string, uint8_t *buf) +{ + int num_char = strlen(hex_string); + + if (num_char % 2 == true) { + return 0; + } + + for (size_t i = 0; i < num_char; i += 2) { + int digit0 = hex_digit_to_int(hex_string[i]); + int digit1 = hex_digit_to_int(hex_string[i + 1]); + + if (digit0 < 0 || digit1 < 0) { + return 0; + } + buf[i / 2] = (digit0 << 4) + digit1; + } + + return num_char/2; +} + +static void create_config_network(otInstance *instance) +{ + otLinkModeConfig linkMode; + uint16_t dataset_str_len = strlen(CONFIG_OPENTHREAD_NETWORK_DATASET); + otOperationalDatasetTlvs datasetTlvs; + memset(&linkMode, 0, sizeof(otLinkModeConfig)); + + linkMode.mRxOnWhenIdle = false; + linkMode.mDeviceType = false; + linkMode.mNetworkData = false; + + if (otLinkSetPollPeriod(instance, CONFIG_OPENTHREAD_NETWORK_POLLPERIOD_TIME) != OT_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to set OpenThread pollperiod."); + abort(); + } + + if (otThreadSetLinkMode(instance, linkMode) != OT_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to set OpenThread linkmode."); + abort(); + } + + if (dataset_str_len > (OT_OPERATIONAL_DATASET_MAX_LENGTH * 2)) { + ESP_LOGE(TAG, "dataset length error."); + abort(); + } + + datasetTlvs.mLength = hex_string_to_binary(CONFIG_OPENTHREAD_NETWORK_DATASET, datasetTlvs.mTlvs); + + if (!datasetTlvs.mLength) { + ESP_LOGE(TAG, "Failed convert configured dataset"); + abort(); + } + + if (otDatasetSetActiveTlvs(instance, &datasetTlvs) != OT_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to set OpenThread otDatasetSetActiveTlvs."); + abort(); + } + + if(otIp6SetEnabled(instance, true) != OT_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to enable OpenThread IP6 link"); + abort(); + } + + if(otThreadSetEnabled(instance, true) != OT_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to enable OpenThread"); + abort(); + } +} + +static esp_netif_t *init_openthread_netif(const esp_openthread_platform_config_t *config) +{ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD(); + esp_netif_t *netif = esp_netif_new(&cfg); + assert(netif != NULL); + ESP_ERROR_CHECK(esp_netif_attach(netif, esp_openthread_netif_glue_init(config))); + + return netif; +} + +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(), + }; + + // Initialize the OpenThread stack + ESP_ERROR_CHECK(esp_openthread_init(&config)); + +#if CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC + // The OpenThread log level directly matches ESP log level + (void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL); +#endif + esp_netif_t *openthread_netif; + // Initialize the esp_netif bindings + openthread_netif = init_openthread_netif(&config); + esp_netif_set_default_netif(openthread_netif); + + create_config_network(esp_openthread_get_instance()); + + // Run the main loop + esp_openthread_launch_mainloop(); + + // Clean up + esp_netif_destroy(openthread_netif); + esp_openthread_netif_glue_deinit(); + + esp_vfs_eventfd_unregister(); + vTaskDelete(NULL); +} + +static esp_err_t ot_power_save_init(void) +{ + esp_err_t rc = ESP_OK; +#ifdef CONFIG_PM_ENABLE + int cur_cpu_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ; + + esp_pm_config_t pm_config = { + .max_freq_mhz = cur_cpu_freq_mhz, + .min_freq_mhz = cur_cpu_freq_mhz, +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE + .light_sleep_enable = true +#endif + }; + + rc = esp_pm_configure(&pm_config); +#endif + return rc; +} + +void app_main(void) +{ + // Used eventfds: + // * netif + // * ot task queue + // * radio driver + esp_vfs_eventfd_config_t eventfd_config = { + .max_fds = 3, + }; + + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config)); + + ESP_ERROR_CHECK(ot_power_save_init()); + + xTaskCreate(ot_task_worker, "ot_power_save_main", 4096, NULL, 5, NULL); +} diff --git a/examples/openthread/ot_power_save/main/esp_ot_power_save_config.h b/examples/openthread/ot_power_save/main/esp_ot_power_save_config.h new file mode 100644 index 0000000000..217c83370d --- /dev/null +++ b/examples/openthread/ot_power_save/main/esp_ot_power_save_config.h @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + * + * OpenThread Command Line 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. + */ + +#pragma once + +#include "esp_openthread_types.h" + +# define CONFIG_OPENTHREAD_NETWORK_DATASET "0e080000000000010000000300000b35060004001fffe002084c14b4d26855fcd00708fdf7e918eb62e2a905107ca0e75a6ead4b960cfe073386943605030f4f70656e5468726561642d616631360102af1604102b9084b26c9a7d10a1a729bfc2e84ea00c0402a0f7f8" +# define CONFIG_OPENTHREAD_NETWORK_POLLPERIOD_TIME 3000 + +#if SOC_IEEE802154_SUPPORTED +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_NATIVE, \ + } +#endif + +#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, \ + }, \ + } + +#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \ + { \ + .storage_partition_name = "ot_storage", \ + .netif_queue_size = 10, \ + .task_queue_size = 10, \ + } diff --git a/examples/openthread/ot_power_save/partitions.csv b/examples/openthread/ot_power_save/partitions.csv new file mode 100644 index 0000000000..1874ddc89f --- /dev/null +++ b/examples/openthread/ot_power_save/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, 0x120000, +ot_storage, data, 0x3a, , 0x2000, diff --git a/examples/openthread/ot_power_save/sdkconfig.defaults b/examples/openthread/ot_power_save/sdkconfig.defaults new file mode 100644 index 0000000000..5f64593d30 --- /dev/null +++ b/examples/openthread/ot_power_save/sdkconfig.defaults @@ -0,0 +1,53 @@ +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2048 + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +# end of Partition Table + +# +# mbedTLS +# +# ESP32H2-TODO: JIRA TZ-127, enable HW acceleration. +CONFIG_MBEDTLS_HARDWARE_AES=n +CONFIG_MBEDTLS_HARDWARE_MPI=n +CONFIG_MBEDTLS_HARDWARE_SHA=n +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y +CONFIG_MBEDTLS_ECJPAKE_C=y +# end of mbedTLS + +# +# OpenThread +# +CONFIG_OPENTHREAD_ENABLED=y +CONFIG_OPENTHREAD_BORDER_ROUTER=n +CONFIG_OPENTHREAD_DNS64_CLIENT=y +# end of OpenThread + +# +# lwIP +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096 +CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 +CONFIG_LWIP_MULTICAST_PING=y +# end of lwIP + +# +# IEEE 802.15.4 +# +CONFIG_IEEE802154_ENABLED=y +# end of IEEE 802.15.4 + +# +# light sleep +# +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y +CONFIG_IEEE802154_SLEEP_ENABLE=y +# end of light sleep From b4d951fa6a2ad09dfd984efd82a1a98212e64dfa Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Thu, 1 Jun 2023 14:31:03 +0800 Subject: [PATCH 02/11] ieee802154: add sleep state --- .../include/esp_private/esp_regdma.h | 2 +- .../ieee802154/driver/esp_ieee802154_dev.c | 10 +- components/ieee802154/esp_ieee802154.c | 11 +- .../ieee802154/include/esp_ieee802154.h | 8 +- .../ieee802154/include/esp_ieee802154_types.h | 1 + .../private_include/esp_ieee802154_dev.h | 9 +- components/openthread/port/esp_openthread.cpp | 107 ------------------ components/openthread/src/esp_openthread.cpp | 12 ++ .../{ => src}/port/esp_openthread_sleep.c | 39 ++----- examples/openthread/.build-test-rules.yml | 16 +-- examples/openthread/README.md | 2 +- .../ot_power_save/main/CMakeLists.txt | 2 - .../CMakeLists.txt | 2 +- .../README.md | 4 +- .../ot_sleepy_device/main/CMakeLists.txt | 2 + .../main/esp_ot_sleepy_device.c} | 4 +- .../main/esp_ot_sleepy_device_config.h} | 0 .../partitions.csv | 0 .../sdkconfig.defaults | 0 19 files changed, 64 insertions(+), 167 deletions(-) delete mode 100644 components/openthread/port/esp_openthread.cpp rename components/openthread/{ => src}/port/esp_openthread_sleep.c (51%) delete mode 100644 examples/openthread/ot_power_save/main/CMakeLists.txt rename examples/openthread/{ot_power_save => ot_sleepy_device}/CMakeLists.txt (89%) rename examples/openthread/{ot_power_save => ot_sleepy_device}/README.md (87%) create mode 100644 examples/openthread/ot_sleepy_device/main/CMakeLists.txt rename examples/openthread/{ot_power_save/main/esp_ot_power_save.c => ot_sleepy_device/main/esp_ot_sleepy_device.c} (97%) rename examples/openthread/{ot_power_save/main/esp_ot_power_save_config.h => ot_sleepy_device/main/esp_ot_sleepy_device_config.h} (100%) rename examples/openthread/{ot_power_save => ot_sleepy_device}/partitions.csv (100%) rename examples/openthread/{ot_power_save => ot_sleepy_device}/sdkconfig.defaults (100%) diff --git a/components/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index 24d4bd24f6..fbe8c460f4 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -40,7 +40,7 @@ extern "C" { #define REGDMA_IOMUX_LINK(_pri) ((0x12 << 8) | _pri) #define REGDMA_SPIMEM_LINK(_pri) ((0x13 << 8) | _pri) #define REGDMA_SYSTIMER_LINK(_pri) ((0x14 << 8) | _pri) -#define REGDMA_MODEM_BTBB_LINK(_pri) ((0x15 << 8) | _pri) +#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x15 << 8) | _pri) #define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x16 << 8) | _pri) #define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri) diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index 243228829d..a8b6271d8f 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -205,6 +205,10 @@ IEEE802154_STATIC bool stop_current_operation(void) ieee802154_ll_set_cmd(IEEE802154_CMD_STOP); break; + case IEEE802154_STATE_SLEEP: + // Do nothing + break; + case IEEE802154_STATE_RX: stop_rx(); break; @@ -771,7 +775,7 @@ static esp_err_t ieee802154_sleep_init(void) return err; } -IRAM_ATTR void ieee802154_sleep_cb(void) +IRAM_ATTR void ieee802154_enter_sleep(void) { #if CONFIG_IEEE802154_SLEEP_ENABLE esp_phy_disable(); @@ -782,7 +786,7 @@ IRAM_ATTR void ieee802154_sleep_cb(void) #endif // CONFIG_IEEE802154_SLEEP_ENABLE } -IRAM_ATTR void ieee802154_wakeup_cb(void) +IRAM_ATTR void ieee802154_wakeup(void) { #if CONFIG_IEEE802154_SLEEP_ENABLE ieee802154_enable(); // IEEE802154 CLOCK Enable @@ -798,7 +802,7 @@ esp_err_t ieee802154_sleep(void) ieee802154_enter_critical(); stop_current_operation(); - s_ieee802154_state = IEEE802154_STATE_IDLE; + s_ieee802154_state = IEEE802154_STATE_SLEEP; ieee802154_exit_critical(); return ESP_OK; diff --git a/components/ieee802154/esp_ieee802154.c b/components/ieee802154/esp_ieee802154.c index 42c0d2065c..909faff774 100644 --- a/components/ieee802154/esp_ieee802154.c +++ b/components/ieee802154/esp_ieee802154.c @@ -280,6 +280,9 @@ esp_ieee802154_state_t esp_ieee802154_get_state(void) return ESP_IEEE802154_RADIO_DISABLE; case IEEE802154_STATE_IDLE: + return ESP_IEEE802154_RADIO_IDLE; + + case IEEE802154_STATE_SLEEP: return ESP_IEEE802154_RADIO_SLEEP; case IEEE802154_STATE_RX: @@ -331,14 +334,14 @@ uint8_t esp_ieee802154_get_recent_lqi(void) return ieee802154_get_recent_lqi(); } -void esp_ieee802154_sleep_cb(void) +void esp_ieee802154_enter_sleep(void) { - ieee802154_sleep_cb(); + ieee802154_enter_sleep(); } -void esp_ieee802154_wakeup_cb(void) +void esp_ieee802154_wakeup(void) { - ieee802154_wakeup_cb(); + ieee802154_wakeup(); } __attribute__((weak)) void esp_ieee802154_receive_done(uint8_t *data, esp_ieee802154_frame_info_t *frame_info) diff --git a/components/ieee802154/include/esp_ieee802154.h b/components/ieee802154/include/esp_ieee802154.h index 63ac0b5178..a1a7bd03fa 100644 --- a/components/ieee802154/include/esp_ieee802154.h +++ b/components/ieee802154/include/esp_ieee802154.h @@ -112,15 +112,15 @@ esp_ieee802154_state_t esp_ieee802154_get_state(void); esp_err_t esp_ieee802154_sleep(void); /** - * @brief The IEEE 802.15.4 sleep callback. + * @brief The IEEE 802.15.4 enter sleep. */ -void esp_ieee802154_sleep_cb(void); +void esp_ieee802154_enter_sleep(void); /** - * @brief The IEEE 802.15.4 wakeup callback. + * @brief The IEEE 802.15.4 wakeup. */ -void esp_ieee802154_wakeup_cb(void); +void esp_ieee802154_wakeup(void); /** * @brief Set the IEEE 802.15.4 Radio to receive state. diff --git a/components/ieee802154/include/esp_ieee802154_types.h b/components/ieee802154/include/esp_ieee802154_types.h index 2606053b3c..49451ccc4d 100644 --- a/components/ieee802154/include/esp_ieee802154_types.h +++ b/components/ieee802154/include/esp_ieee802154_types.h @@ -18,6 +18,7 @@ extern "C" { */ typedef enum { ESP_IEEE802154_RADIO_DISABLE, /*!< Radio not up */ + ESP_IEEE802154_RADIO_IDLE, /*!< Radio in the idle state */ ESP_IEEE802154_RADIO_SLEEP, /*!< Radio in the sleep state */ ESP_IEEE802154_RADIO_RECEIVE, /*!< Radio in the receive state */ ESP_IEEE802154_RADIO_TRANSMIT, /*!< Radio in the transmit state */ diff --git a/components/ieee802154/private_include/esp_ieee802154_dev.h b/components/ieee802154/private_include/esp_ieee802154_dev.h index ef13f45445..bf80282369 100644 --- a/components/ieee802154/private_include/esp_ieee802154_dev.h +++ b/components/ieee802154/private_include/esp_ieee802154_dev.h @@ -31,6 +31,7 @@ extern "C" { typedef enum { IEEE802154_STATE_DISABLE, /*!< IEEE802154 radio state disable */ IEEE802154_STATE_IDLE, /*!< IEEE802154 radio state idle */ + IEEE802154_STATE_SLEEP, /*!< IEEE802154 radio state sleep */ IEEE802154_STATE_RX, /*!< IEEE802154 radio state rx */ IEEE802154_STATE_TX_ACK, /*!< IEEE802154 radio state tx ack */ IEEE802154_STATE_TX_ENH_ACK, /*!< IEEE802154 radio state tx enh-ack */ @@ -178,16 +179,16 @@ uint8_t ieee802154_get_recent_lqi(void); ieee802154_state_t ieee802154_get_state(void); /** - * @brief The callback of IEEE 802.15.4 sleep. + * @brief The IEEE 802.15.4 enter sleep. * */ -void ieee802154_sleep_cb(void); +void ieee802154_enter_sleep(void); /** - * @brief The callback of IEEE 802.15.4 wakeup. + * @brief The IEEE 802.15.4 wakeup. * */ -void ieee802154_wakeup_cb(void); +void ieee802154_wakeup(void); /** The following three functions are only used for internal test. **/ /** diff --git a/components/openthread/port/esp_openthread.cpp b/components/openthread/port/esp_openthread.cpp deleted file mode 100644 index 8b1cc2ae2b..0000000000 --- a/components/openthread/port/esp_openthread.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "esp_openthread.h" -#include "esp_check.h" -#include "esp_openthread_border_router.h" -#include "esp_openthread_common_macro.h" -#include "esp_openthread_dns64.h" -#include "esp_openthread_lock.h" -#include "esp_openthread_platform.h" -#include "esp_openthread_task_queue.h" -#include "esp_openthread_types.h" -#include "freertos/FreeRTOS.h" -#include "lwip/dns.h" -#include "openthread/instance.h" -#include "openthread/netdata.h" -#include "openthread/tasklet.h" -#include "esp_openthread_sleep.h" - -esp_err_t esp_openthread_init(const esp_openthread_platform_config_t *config) -{ -#if CONFIG_IEEE802154_SLEEP_ENABLE - ESP_RETURN_ON_ERROR(esp_openthread_sleep_init(), OT_PLAT_LOG_TAG, - "Failed to initialize OpenThread esp pm_lock"); -#endif - ESP_RETURN_ON_ERROR(esp_openthread_platform_init(config), OT_PLAT_LOG_TAG, - "Failed to initialize OpenThread platform driver"); - esp_openthread_lock_acquire(portMAX_DELAY); - ESP_RETURN_ON_FALSE(otInstanceInitSingle() != NULL, ESP_FAIL, OT_PLAT_LOG_TAG, - "Failed to initialize OpenThread instance"); -#if CONFIG_OPENTHREAD_DNS64_CLIENT - ESP_RETURN_ON_ERROR(esp_openthread_dns64_client_init(), OT_PLAT_LOG_TAG, - "Failed to initialize OpenThread dns64 client"); -#endif - esp_openthread_lock_release(); - - return ESP_OK; -} - -esp_err_t esp_openthread_launch_mainloop(void) -{ - esp_openthread_mainloop_context_t mainloop; - otInstance *instance = esp_openthread_get_instance(); - esp_err_t error = ESP_OK; - - while (true) { - FD_ZERO(&mainloop.read_fds); - FD_ZERO(&mainloop.write_fds); - FD_ZERO(&mainloop.error_fds); - - mainloop.max_fd = -1; - mainloop.timeout.tv_sec = 10; - mainloop.timeout.tv_usec = 0; - - esp_openthread_lock_acquire(portMAX_DELAY); - esp_openthread_platform_update(&mainloop); - if (otTaskletsArePending(instance)) { - mainloop.timeout.tv_sec = 0; - mainloop.timeout.tv_usec = 0; - } -#if CONFIG_IEEE802154_SLEEP_ENABLE - esp_openthread_sleep_process(); -#endif - esp_openthread_lock_release(); - - if (select(mainloop.max_fd + 1, &mainloop.read_fds, &mainloop.write_fds, &mainloop.error_fds, - &mainloop.timeout) >= 0) { - esp_openthread_lock_acquire(portMAX_DELAY); -#if CONFIG_IEEE802154_SLEEP_ENABLE - esp_openthread_wakeup_process(); -#endif - error = esp_openthread_platform_process(instance, &mainloop); - while (otTaskletsArePending(instance)) { - otTaskletsProcess(instance); - } - esp_openthread_lock_release(); - if (error != ESP_OK) { - ESP_LOGE(OT_PLAT_LOG_TAG, "esp_openthread_platform_process failed"); - break; - } - } else { - error = ESP_FAIL; - ESP_LOGE(OT_PLAT_LOG_TAG, "OpenThread system polling failed"); - break; - } - } - return error; -} - -esp_err_t esp_openthread_deinit(void) -{ - otInstanceFinalize(esp_openthread_get_instance()); - return esp_openthread_platform_deinit(); -} - -static void stub_task(void *context) -{ - // this is a empty function used for ot-task signal pending -} - -void otTaskletsSignalPending(otInstance *aInstance) -{ - esp_openthread_task_queue_post(stub_task, NULL); -} diff --git a/components/openthread/src/esp_openthread.cpp b/components/openthread/src/esp_openthread.cpp index 38f3511528..ded369ae24 100644 --- a/components/openthread/src/esp_openthread.cpp +++ b/components/openthread/src/esp_openthread.cpp @@ -12,6 +12,7 @@ #include "esp_openthread_lock.h" #include "esp_openthread_platform.h" #include "esp_openthread_state.h" +#include "esp_openthread_sleep.h" #include "esp_openthread_task_queue.h" #include "esp_openthread_types.h" #include "freertos/FreeRTOS.h" @@ -21,6 +22,7 @@ #include "openthread/tasklet.h" #include "openthread/thread.h" + static int hex_digit_to_int(char hex) { if ('A' <= hex && hex <= 'F') { @@ -59,6 +61,10 @@ esp_err_t esp_openthread_init(const esp_openthread_platform_config_t *config) { ESP_RETURN_ON_ERROR(esp_openthread_platform_init(config), OT_PLAT_LOG_TAG, "Failed to initialize OpenThread platform driver"); +#if CONFIG_IEEE802154_SLEEP_ENABLE + ESP_RETURN_ON_ERROR(esp_openthread_sleep_init(), OT_PLAT_LOG_TAG, + "Failed to initialize OpenThread esp pm_lock"); +#endif esp_openthread_lock_acquire(portMAX_DELAY); ESP_RETURN_ON_FALSE(otInstanceInitSingle() != NULL, ESP_FAIL, OT_PLAT_LOG_TAG, "Failed to initialize OpenThread instance"); @@ -159,11 +165,17 @@ esp_err_t esp_openthread_launch_mainloop(void) mainloop.timeout.tv_sec = 0; mainloop.timeout.tv_usec = 0; } +#if CONFIG_IEEE802154_SLEEP_ENABLE + esp_openthread_sleep_process(); +#endif esp_openthread_lock_release(); if (select(mainloop.max_fd + 1, &mainloop.read_fds, &mainloop.write_fds, &mainloop.error_fds, &mainloop.timeout) >= 0) { esp_openthread_lock_acquire(portMAX_DELAY); +#if CONFIG_IEEE802154_SLEEP_ENABLE + esp_openthread_wakeup_process(); +#endif error = esp_openthread_platform_process(instance, &mainloop); while (otTaskletsArePending(instance)) { otTaskletsProcess(instance); diff --git a/components/openthread/port/esp_openthread_sleep.c b/components/openthread/src/port/esp_openthread_sleep.c similarity index 51% rename from components/openthread/port/esp_openthread_sleep.c rename to components/openthread/src/port/esp_openthread_sleep.c index f8794e13c0..c4a1361b31 100644 --- a/components/openthread/port/esp_openthread_sleep.c +++ b/components/openthread/src/port/esp_openthread_sleep.c @@ -6,9 +6,6 @@ #include "esp_log.h" #include "esp_check.h" -#include "openthread/instance.h" -#include "openthread/thread.h" -#include "esp_openthread.h" #include "esp_ieee802154.h" #if CONFIG_IEEE802154_SLEEP_ENABLE @@ -22,36 +19,22 @@ esp_err_t esp_openthread_sleep_init(void) esp_err_t err = ESP_OK; err = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "ieee802154", &s_pm_lock); - if (err != ESP_OK) { - goto error; - } - esp_pm_lock_acquire(s_pm_lock); - - ESP_LOGI(TAG, "Enable ieee802154 light sleep, the wake up source is ESP timer"); - - return err; - -error: - /*lock should release first and then delete*/ - if (s_pm_lock != NULL) { - esp_pm_lock_release(s_pm_lock); - esp_pm_lock_delete(s_pm_lock); - s_pm_lock = NULL; + if (err == ESP_OK) { + esp_pm_lock_acquire(s_pm_lock); + ESP_LOGI(TAG, "Enable ieee802154 light sleep, the wake up source is ESP timer"); + } else { + if (s_pm_lock != NULL) { + esp_pm_lock_delete(s_pm_lock); + s_pm_lock = NULL; + } } return err; } void esp_openthread_sleep_process(void) { - otInstance *instance = esp_openthread_get_instance(); - otLinkModeConfig linkMode = otThreadGetLinkMode(instance); - bool s_ot_sed_ssed = false; - if (linkMode.mRxOnWhenIdle == false && linkMode.mDeviceType == false && linkMode.mNetworkData == false) { - s_ot_sed_ssed = true; - } - - if (esp_ieee802154_get_state() == ESP_IEEE802154_RADIO_SLEEP && s_ot_sed_ssed) { - esp_ieee802154_sleep_cb(); + if (esp_ieee802154_get_state() == ESP_IEEE802154_RADIO_SLEEP) { + esp_ieee802154_enter_sleep(); esp_pm_lock_release(s_pm_lock); s_ot_sleep = true; } @@ -61,7 +44,7 @@ void esp_openthread_wakeup_process(void) { if (s_ot_sleep) { esp_pm_lock_acquire(s_pm_lock); - esp_ieee802154_wakeup_cb(); + esp_ieee802154_wakeup(); s_ot_sleep = false; } } diff --git a/examples/openthread/.build-test-rules.yml b/examples/openthread/.build-test-rules.yml index bab61b6116..890ec3fce6 100644 --- a/examples/openthread/.build-test-rules.yml +++ b/examples/openthread/.build-test-rules.yml @@ -18,14 +18,6 @@ examples/openthread/ot_cli: temporary: true reason: only test on esp32h2 -examples/openthread/ot_power_save: - enable: - - if: IDF_TARGET == "esp32c6" - disable_test: - - if: IDF_TARGET in ["esp32h2", "esp32c6"] - temporary: true - reason: No support # TO-DO: TZ-134 - examples/openthread/ot_rcp: enable: - if: IDF_TARGET in ["esp32h2", "esp32c6"] @@ -33,3 +25,11 @@ examples/openthread/ot_rcp: - if: IDF_TARGET == "esp32h2" temporary: true reason: only test on esp32c6 + +examples/openthread/ot_sleepy_device: + enable: + - if: IDF_TARGET == "esp32c6" + disable_test: + - if: IDF_TARGET in ["esp32h2", "esp32c6"] + temporary: true + reason: No support # TO-DO: TZ-134 diff --git a/examples/openthread/README.md b/examples/openthread/README.md index f7de43d3c7..459adf65c2 100644 --- a/examples/openthread/README.md +++ b/examples/openthread/README.md @@ -12,4 +12,4 @@ In this folder, it contains following OpenThread examples: * [ot_br](ot_br) is an [OpenThread Border Router](https://openthread.io/guides/border-router) example. It runs on a Wi-Fi SoC such as ESP32, ESP32-C3 and ESP32-S3. It needs an 802.15.4 SoC like ESP32-H2 running [ot_rcp](ot_rcp) example to provide 802.15.4 radio. -* [ot_power_save](ot_power_save) is an OpenThread Power save example, it supports 802.15.4 radio light sleep. It runs on an 802.15.4 SoC like ESP32-C6. \ No newline at end of file +* [ot_sleepy_device](ot_sleepy_device) is an OpenThread sleepy device example, it supports 802.15.4 radio light sleep. It runs on an 802.15.4 SoC like ESP32-C6. \ No newline at end of file diff --git a/examples/openthread/ot_power_save/main/CMakeLists.txt b/examples/openthread/ot_power_save/main/CMakeLists.txt deleted file mode 100644 index 832a7f9bed..0000000000 --- a/examples/openthread/ot_power_save/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "esp_ot_power_save.c" - INCLUDE_DIRS ".") diff --git a/examples/openthread/ot_power_save/CMakeLists.txt b/examples/openthread/ot_sleepy_device/CMakeLists.txt similarity index 89% rename from examples/openthread/ot_power_save/CMakeLists.txt rename to examples/openthread/ot_sleepy_device/CMakeLists.txt index a975ba7e48..876f5798c5 100644 --- a/examples/openthread/ot_power_save/CMakeLists.txt +++ b/examples/openthread/ot_sleepy_device/CMakeLists.txt @@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(ot_power_save) +project(ot_sleepy_device) diff --git a/examples/openthread/ot_power_save/README.md b/examples/openthread/ot_sleepy_device/README.md similarity index 87% rename from examples/openthread/ot_power_save/README.md rename to examples/openthread/ot_sleepy_device/README.md index adafceb053..ead2e1d059 100644 --- a/examples/openthread/ot_power_save/README.md +++ b/examples/openthread/ot_sleepy_device/README.md @@ -1,9 +1,9 @@ | Supported Targets | ESP32-C6 | | ----------------- | -------- | -# OpenThread Power Save Example +# OpenThread Sleepy Device Example -The example demonstrates the OpenThread Power Save based on light sleep, which reduces power consumption by turning off RF, PHY, BB, and IEEE802154 MAC during the sleep state. +The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Light Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32h2/api-reference/system/sleep_modes.html#sleep-modes) during idle state. ## How to use example ### Hardware Required diff --git a/examples/openthread/ot_sleepy_device/main/CMakeLists.txt b/examples/openthread/ot_sleepy_device/main/CMakeLists.txt new file mode 100644 index 0000000000..a7cde9d16a --- /dev/null +++ b/examples/openthread/ot_sleepy_device/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "esp_ot_sleepy_device.c" + INCLUDE_DIRS ".") diff --git a/examples/openthread/ot_power_save/main/esp_ot_power_save.c b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c similarity index 97% rename from examples/openthread/ot_power_save/main/esp_ot_power_save.c rename to examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c index 9d6205d83b..f05c489b7d 100644 --- a/examples/openthread/ot_power_save/main/esp_ot_power_save.c +++ b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c @@ -22,7 +22,7 @@ #include "esp_log.h" #include "esp_openthread.h" #include "esp_openthread_netif_glue.h" -#include "esp_ot_power_save_config.h" +#include "esp_ot_sleepy_device_config.h" #include "esp_vfs_eventfd.h" #include "driver/uart.h" #include "nvs_flash.h" @@ -34,7 +34,7 @@ #endif #if !SOC_IEEE802154_SUPPORTED -#error "Power save is only supported for the SoCs which have IEEE 802.15.4 module" +#error "Openthread sleepy device is only supported for the SoCs which have IEEE 802.15.4 module" #endif #define TAG "ot_esp_power_save" diff --git a/examples/openthread/ot_power_save/main/esp_ot_power_save_config.h b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h similarity index 100% rename from examples/openthread/ot_power_save/main/esp_ot_power_save_config.h rename to examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h diff --git a/examples/openthread/ot_power_save/partitions.csv b/examples/openthread/ot_sleepy_device/partitions.csv similarity index 100% rename from examples/openthread/ot_power_save/partitions.csv rename to examples/openthread/ot_sleepy_device/partitions.csv diff --git a/examples/openthread/ot_power_save/sdkconfig.defaults b/examples/openthread/ot_sleepy_device/sdkconfig.defaults similarity index 100% rename from examples/openthread/ot_power_save/sdkconfig.defaults rename to examples/openthread/ot_sleepy_device/sdkconfig.defaults From 2ac7558da25094cb7b99d2ab15b59fdf9760b338 Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Tue, 13 Jun 2023 10:50:18 +0800 Subject: [PATCH 03/11] openthread: add openthread autostart for sleep device --- .../include/esp_private/esp_regdma.h | 2 +- .../openthread/ot_sleepy_device/README.md | 2 +- .../main/esp_ot_sleepy_device.c | 65 +------------------ .../main/esp_ot_sleepy_device_config.h | 1 - 4 files changed, 3 insertions(+), 67 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index fbe8c460f4..36952218a3 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -40,7 +40,7 @@ extern "C" { #define REGDMA_IOMUX_LINK(_pri) ((0x12 << 8) | _pri) #define REGDMA_SPIMEM_LINK(_pri) ((0x13 << 8) | _pri) #define REGDMA_SYSTIMER_LINK(_pri) ((0x14 << 8) | _pri) -#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x15 << 8) | _pri) +#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x15 << 8) | _pri) #define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x16 << 8) | _pri) #define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri) diff --git a/examples/openthread/ot_sleepy_device/README.md b/examples/openthread/ot_sleepy_device/README.md index ead2e1d059..0aa2907879 100644 --- a/examples/openthread/ot_sleepy_device/README.md +++ b/examples/openthread/ot_sleepy_device/README.md @@ -16,7 +16,7 @@ The example demonstrates the Thread Sleepy End Device (SED), the device will ent ## Configure the Openthread Dataset * Run [ot_cli](../ot_cli/) on another ESP32-C6 device to create openthread dataset configuration and start an openthread network as the leader. -* Configure the Openthread dataset (`CONFIG_OPENTHREAD_NETWORK_DATASET`) in [ot_power_save](../ot_power_save/main/esp_ot_power_save_config.h), ensuring that the device's dataset matches the dataset of the leader. +* Configure the Openthread dataset using `idf.py menuconfig` in `Component config ---> Openthread ---> Thread Operation Dataset`, ensuring that the openthread sleepy device's dataset matches the dataset of the leader. ## Erase the ot_storage diff --git a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c index f05c489b7d..584208a75f 100644 --- a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c +++ b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c @@ -39,46 +39,9 @@ #define TAG "ot_esp_power_save" -static int hex_digit_to_int(char hex) -{ - if ('A' <= hex && hex <= 'F') { - return 10 + hex - 'A'; - } - if ('a' <= hex && hex <= 'f') { - return 10 + hex - 'a'; - } - if ('0' <= hex && hex <= '9') { - return hex - '0'; - } - return -1; -} - -static size_t hex_string_to_binary(const char *hex_string, uint8_t *buf) -{ - int num_char = strlen(hex_string); - - if (num_char % 2 == true) { - return 0; - } - - for (size_t i = 0; i < num_char; i += 2) { - int digit0 = hex_digit_to_int(hex_string[i]); - int digit1 = hex_digit_to_int(hex_string[i + 1]); - - if (digit0 < 0 || digit1 < 0) { - return 0; - } - buf[i / 2] = (digit0 << 4) + digit1; - } - - return num_char/2; -} - static void create_config_network(otInstance *instance) { otLinkModeConfig linkMode; - uint16_t dataset_str_len = strlen(CONFIG_OPENTHREAD_NETWORK_DATASET); - otOperationalDatasetTlvs datasetTlvs; memset(&linkMode, 0, sizeof(otLinkModeConfig)); linkMode.mRxOnWhenIdle = false; @@ -94,33 +57,7 @@ static void create_config_network(otInstance *instance) ESP_LOGE(TAG, "Failed to set OpenThread linkmode."); abort(); } - - if (dataset_str_len > (OT_OPERATIONAL_DATASET_MAX_LENGTH * 2)) { - ESP_LOGE(TAG, "dataset length error."); - abort(); - } - - datasetTlvs.mLength = hex_string_to_binary(CONFIG_OPENTHREAD_NETWORK_DATASET, datasetTlvs.mTlvs); - - if (!datasetTlvs.mLength) { - ESP_LOGE(TAG, "Failed convert configured dataset"); - abort(); - } - - if (otDatasetSetActiveTlvs(instance, &datasetTlvs) != OT_ERROR_NONE) { - ESP_LOGE(TAG, "Failed to set OpenThread otDatasetSetActiveTlvs."); - abort(); - } - - if(otIp6SetEnabled(instance, true) != OT_ERROR_NONE) { - ESP_LOGE(TAG, "Failed to enable OpenThread IP6 link"); - abort(); - } - - if(otThreadSetEnabled(instance, true) != OT_ERROR_NONE) { - ESP_LOGE(TAG, "Failed to enable OpenThread"); - abort(); - } + ESP_ERROR_CHECK(esp_openthread_auto_start(NULL)); } static esp_netif_t *init_openthread_netif(const esp_openthread_platform_config_t *config) diff --git a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h index 217c83370d..15516a3981 100644 --- a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h +++ b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h @@ -16,7 +16,6 @@ #include "esp_openthread_types.h" -# define CONFIG_OPENTHREAD_NETWORK_DATASET "0e080000000000010000000300000b35060004001fffe002084c14b4d26855fcd00708fdf7e918eb62e2a905107ca0e75a6ead4b960cfe073386943605030f4f70656e5468726561642d616631360102af1604102b9084b26c9a7d10a1a729bfc2e84ea00c0402a0f7f8" # define CONFIG_OPENTHREAD_NETWORK_POLLPERIOD_TIME 3000 #if SOC_IEEE802154_SUPPORTED From aee329de2bb67d8d1ba7e248621a00bf98c68acc Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Mon, 19 Jun 2023 14:29:06 +0800 Subject: [PATCH 04/11] ieee802154: change BLE_BB/ieee802154_BB --- components/esp_hw_support/include/esp_private/esp_regdma.h | 5 +++-- components/esp_hw_support/sleep_modem.c | 4 ++-- components/esp_phy/src/btbb_init.c | 4 ++-- .../ot_sleepy_device/main/esp_ot_sleepy_device_config.h | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index 36952218a3..ebf7ed423c 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -40,8 +40,9 @@ extern "C" { #define REGDMA_IOMUX_LINK(_pri) ((0x12 << 8) | _pri) #define REGDMA_SPIMEM_LINK(_pri) ((0x13 << 8) | _pri) #define REGDMA_SYSTIMER_LINK(_pri) ((0x14 << 8) | _pri) -#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x15 << 8) | _pri) -#define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x16 << 8) | _pri) +#define REGDMA_BLE_MAC_LINK(_pri) ((0x15 << 8) | _pri) +#define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x16 << 8) | _pri) +#define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x17 << 8) | _pri) #define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri) typedef enum { diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index 6b732bcf75..086aed667a 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -279,9 +279,9 @@ bool IRAM_ATTR modem_domain_pd_allowed(void) const uint32_t mask_wifi = (const uint32_t) (SLEEP_RETENTION_MODULE_WIFI_MAC | SLEEP_RETENTION_MODULE_WIFI_BB); const uint32_t mask_ble = (const uint32_t) (SLEEP_RETENTION_MODULE_BLE_MAC | - SLEEP_RETENTION_MODULE_BLE_BB); + SLEEP_RETENTION_MODULE_BT_BB); const uint32_t mask_154 = (const uint32_t) (SLEEP_RETENTION_MODULE_802154_MAC | - SLEEP_RETENTION_MODULE_802154_BB); + SLEEP_RETENTION_MODULE_BT_BB); return (((modules & mask_wifi) == mask_wifi) || ((modules & mask_ble) == mask_ble) || ((modules & mask_154) == mask_154)); diff --git a/components/esp_phy/src/btbb_init.c b/components/esp_phy/src/btbb_init.c index efe7b19013..6c8c9f6ab4 100644 --- a/components/esp_phy/src/btbb_init.c +++ b/components/esp_phy/src/btbb_init.c @@ -35,7 +35,7 @@ static esp_err_t btbb_sleep_retention_init(void) [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x01), BB_PART_1_ADDR, BB_PART_1_ADDR, BB_PART_1_SIZE, 0, 0), .owner = BTBB_LINK_OWNER }, [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x02), BB_PART_2_ADDR, BB_PART_2_ADDR, BB_PART_2_SIZE, 0, 0), .owner = BTBB_LINK_OWNER } }; - esp_err_t err = sleep_retention_entries_create(btbb_regs_retention, ARRAY_SIZE(btbb_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BLE_BB); + esp_err_t err = sleep_retention_entries_create(btbb_regs_retention, ARRAY_SIZE(btbb_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BT_BB); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for btbb retention"); ESP_LOGI(TAG, "btbb sleep retention initialization"); return ESP_OK; @@ -43,7 +43,7 @@ static esp_err_t btbb_sleep_retention_init(void) static void btbb_sleep_retention_deinit(void) { - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_BB); + sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BT_BB); } #endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE diff --git a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h index 15516a3981..d5b9383c06 100644 --- a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h +++ b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h @@ -47,7 +47,7 @@ #define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \ { \ - .storage_partition_name = "ot_storage", \ + .storage_partition_name = "nvs", \ .netif_queue_size = 10, \ .task_queue_size = 10, \ } From 043893a49f1217cee1c5c2034a42e2a5b30a6613 Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Mon, 19 Jun 2023 19:21:15 +0800 Subject: [PATCH 05/11] ieee802154: change light sleep config in ieee802154 --- components/ieee802154/Kconfig | 1 + components/ieee802154/driver/esp_ieee802154_dev.c | 12 ++++++------ .../private_include/esp_openthread_sleep.h | 2 +- components/openthread/src/esp_openthread.cpp | 9 ++++----- .../openthread/src/port/esp_openthread_sleep.c | 4 ++-- examples/openthread/README.md | 2 +- examples/openthread/ot_sleepy_device/partitions.csv | 1 - 7 files changed, 15 insertions(+), 16 deletions(-) diff --git a/components/ieee802154/Kconfig b/components/ieee802154/Kconfig index 6b01de4e72..981945e50c 100644 --- a/components/ieee802154/Kconfig +++ b/components/ieee802154/Kconfig @@ -76,6 +76,7 @@ menu "IEEE 802.15.4" config IEEE802154_SLEEP_ENABLE + # Todo: Remove when support safe power-down of the power domain (IDF-7317) bool "Enable IEEE802154 light sleep" depends on PM_ENABLE && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP default n diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index a8b6271d8f..e2048b7ec1 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -26,7 +26,7 @@ #include "esp_attr.h" #include "esp_phy_init.h" -#if CONFIG_IEEE802154_SLEEP_ENABLE +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "esp_pm.h" #include "esp_private/esp_clk.h" #include "esp_private/sleep_retention.h" @@ -762,7 +762,7 @@ esp_err_t ieee802154_receive_at(uint32_t time) static esp_err_t ieee802154_sleep_init(void) { esp_err_t err = ESP_OK; -#if CONFIG_IEEE802154_SLEEP_ENABLE +#if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE #define N_REGS_IEEE802154() (((IEEE802154_MAC_DATE_REG - IEEE802154_REG_BASE) / 4) + 1) const static sleep_retention_entries_config_t ieee802154_mac_regs_retention[] = { [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_IEEE802154_LINK(0x00), IEEE802154_REG_BASE, IEEE802154_REG_BASE, N_REGS_IEEE802154(), 0, 0), .owner = ENTRY(3) }, @@ -777,24 +777,24 @@ static esp_err_t ieee802154_sleep_init(void) IRAM_ATTR void ieee802154_enter_sleep(void) { -#if CONFIG_IEEE802154_SLEEP_ENABLE +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE esp_phy_disable(); #if SOC_PM_RETENTION_HAS_CLOCK_BUG sleep_retention_do_extra_retention(true);// backup #endif ieee802154_disable(); // IEEE802154 CLOCK Disable -#endif // CONFIG_IEEE802154_SLEEP_ENABLE +#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE } IRAM_ATTR void ieee802154_wakeup(void) { -#if CONFIG_IEEE802154_SLEEP_ENABLE +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE ieee802154_enable(); // IEEE802154 CLOCK Enable #if SOC_PM_RETENTION_HAS_CLOCK_BUG sleep_retention_do_extra_retention(false);// restore #endif esp_phy_enable(); -#endif //CONFIG_IEEE802154_SLEEP_ENABLE +#endif //CONFIG_FREERTOS_USE_TICKLESS_IDLE } esp_err_t ieee802154_sleep(void) diff --git a/components/openthread/private_include/esp_openthread_sleep.h b/components/openthread/private_include/esp_openthread_sleep.h index bae2913d4f..0a1bad56ca 100644 --- a/components/openthread/private_include/esp_openthread_sleep.h +++ b/components/openthread/private_include/esp_openthread_sleep.h @@ -12,7 +12,7 @@ extern "C" { #endif -#ifdef CONFIG_IEEE802154_SLEEP_ENABLE +#ifdef CONFIG_FREERTOS_USE_TICKLESS_IDLE /** * @brief This function initializes the OpenThread sleep. * diff --git a/components/openthread/src/esp_openthread.cpp b/components/openthread/src/esp_openthread.cpp index ded369ae24..796fcf0a25 100644 --- a/components/openthread/src/esp_openthread.cpp +++ b/components/openthread/src/esp_openthread.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,6 @@ #include "openthread/tasklet.h" #include "openthread/thread.h" - static int hex_digit_to_int(char hex) { if ('A' <= hex && hex <= 'F') { @@ -61,7 +60,7 @@ esp_err_t esp_openthread_init(const esp_openthread_platform_config_t *config) { ESP_RETURN_ON_ERROR(esp_openthread_platform_init(config), OT_PLAT_LOG_TAG, "Failed to initialize OpenThread platform driver"); -#if CONFIG_IEEE802154_SLEEP_ENABLE +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE ESP_RETURN_ON_ERROR(esp_openthread_sleep_init(), OT_PLAT_LOG_TAG, "Failed to initialize OpenThread esp pm_lock"); #endif @@ -165,7 +164,7 @@ esp_err_t esp_openthread_launch_mainloop(void) mainloop.timeout.tv_sec = 0; mainloop.timeout.tv_usec = 0; } -#if CONFIG_IEEE802154_SLEEP_ENABLE +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE esp_openthread_sleep_process(); #endif esp_openthread_lock_release(); @@ -173,7 +172,7 @@ esp_err_t esp_openthread_launch_mainloop(void) if (select(mainloop.max_fd + 1, &mainloop.read_fds, &mainloop.write_fds, &mainloop.error_fds, &mainloop.timeout) >= 0) { esp_openthread_lock_acquire(portMAX_DELAY); -#if CONFIG_IEEE802154_SLEEP_ENABLE +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE esp_openthread_wakeup_process(); #endif error = esp_openthread_platform_process(instance, &mainloop); diff --git a/components/openthread/src/port/esp_openthread_sleep.c b/components/openthread/src/port/esp_openthread_sleep.c index c4a1361b31..e59a45b898 100644 --- a/components/openthread/src/port/esp_openthread_sleep.c +++ b/components/openthread/src/port/esp_openthread_sleep.c @@ -8,7 +8,7 @@ #include "esp_check.h" #include "esp_ieee802154.h" -#if CONFIG_IEEE802154_SLEEP_ENABLE +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "esp_pm.h" static esp_pm_lock_handle_t s_pm_lock = NULL; static const char* TAG = "esp openthread sleep"; @@ -48,4 +48,4 @@ void esp_openthread_wakeup_process(void) s_ot_sleep = false; } } -#endif // CONFIG_IEEE802154_SLEEP_ENABLE +#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE diff --git a/examples/openthread/README.md b/examples/openthread/README.md index 459adf65c2..b8c16cf36f 100644 --- a/examples/openthread/README.md +++ b/examples/openthread/README.md @@ -12,4 +12,4 @@ In this folder, it contains following OpenThread examples: * [ot_br](ot_br) is an [OpenThread Border Router](https://openthread.io/guides/border-router) example. It runs on a Wi-Fi SoC such as ESP32, ESP32-C3 and ESP32-S3. It needs an 802.15.4 SoC like ESP32-H2 running [ot_rcp](ot_rcp) example to provide 802.15.4 radio. -* [ot_sleepy_device](ot_sleepy_device) is an OpenThread sleepy device example, it supports 802.15.4 radio light sleep. It runs on an 802.15.4 SoC like ESP32-C6. \ No newline at end of file +* [ot_sleepy_device](ot_sleepy_device) is an OpenThread sleepy device example, it supports 802.15.4 radio light sleep. It runs on an 802.15.4 SoC like ESP32-C6. diff --git a/examples/openthread/ot_sleepy_device/partitions.csv b/examples/openthread/ot_sleepy_device/partitions.csv index 1874ddc89f..6c0e048dba 100644 --- a/examples/openthread/ot_sleepy_device/partitions.csv +++ b/examples/openthread/ot_sleepy_device/partitions.csv @@ -3,4 +3,3 @@ nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, factory, app, factory, 0x10000, 0x120000, -ot_storage, data, 0x3a, , 0x2000, From 6b1e3924afb9d2488bfc99ca8b0a7545eb51b7e7 Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Mon, 19 Jun 2023 22:15:14 +0800 Subject: [PATCH 06/11] ieee802154: update radio state in test --- .../test_ieee802154/pytest_test_ieee802154.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/ieee802154/test_apps/test_ieee802154/pytest_test_ieee802154.py b/components/ieee802154/test_apps/test_ieee802154/pytest_test_ieee802154.py index 0073fb881f..74b8548349 100644 --- a/components/ieee802154/test_apps/test_ieee802154/pytest_test_ieee802154.py +++ b/components/ieee802154/test_apps/test_ieee802154/pytest_test_ieee802154.py @@ -129,17 +129,17 @@ def test_based_txrx(dut: Tuple[IdfDut, IdfDut]) -> None: receive.expect('RX Start', timeout=10) transmit.expect('ieee802154>', timeout=10) transmit.write('tx -l 10') - transmit.expect('tx sfd done, Radio state: 3', timeout=10) + transmit.expect('tx sfd done, Radio state: 4', timeout=10) transmit.expect('Tx Done 10 bytes', timeout=10) transmit.expect('00 01 02 03 04 05 06 07', timeout=10) transmit.expect('08 09 00 00 00 00 00 00', timeout=10) - receive.expect('rx sfd done, Radio state: 2', timeout=10) + receive.expect('rx sfd done, Radio state: 3', timeout=10) receive.expect('Rx Done 10 bytes', timeout=10) receive.expect('00 01 02 03 04 05 06 07', timeout=10) receive.write('rx -r 0') receive.expect('radio exit receive mode', timeout=10) transmit.write('tx -l 10') - transmit.expect('tx sfd done, Radio state: 3', timeout=10) + transmit.expect('tx sfd done, Radio state: 4', timeout=10) transmit.expect('Tx Done 10 bytes', timeout=10) transmit.expect('00 01 02 03 04 05 06 07', timeout=10) transmit.expect('08 09 00 00 00 00 00 00', timeout=10) @@ -344,13 +344,13 @@ def test_based_autoack(dut: Tuple[IdfDut, IdfDut]) -> None: receive.expect('RX Start', timeout=10) transmit.write('tx 0x20 0x88 0x00 0x0A 0x28 0xDB 0x6F 0xBC 0x94 0x5A 0x43 0x68 0x02 0xaa 0x15 0x30 0x01 0x02') - transmit.expect('tx sfd done, Radio state: 3', timeout=10) - transmit.expect('rx sfd done, Radio state: 3', timeout=10) + transmit.expect('tx sfd done, Radio state: 4', timeout=10) + transmit.expect('rx sfd done, Radio state: 4', timeout=10) transmit.expect('Tx Done 18 bytes', timeout=10) transmit.expect('20 88 00 0a 28 db 6f bc', timeout=10) transmit.expect('94 5a 43 68 02 aa 15 30', timeout=10) - receive.expect('rx sfd done, Radio state: 2', timeout=10) + receive.expect('rx sfd done, Radio state: 3', timeout=10) receive.expect('Rx Done 18 bytes', timeout=10) receive.expect('20 88 00 0a 28 db 6f bc', timeout=10) receive.expect('94 5a 43 68 02 aa 15 30', timeout=10) @@ -573,7 +573,7 @@ def test_based_transmit_failed(dut: IdfDut) -> None: transmit.write('tx -l 10 -C') transmit.expect('the Frame Transmission failed, Failure reason: 1', timeout=10) transmit.write('tx -l 10') - transmit.expect('tx sfd done, Radio state: 3', timeout=10) + transmit.expect('tx sfd done, Radio state: 4', timeout=10) transmit.expect('Tx Done 10 bytes', timeout=10) transmit.expect('00 01 02 03 04 05 06 07', timeout=10) transmit.expect('08 09 00 00 00 00 00 00', timeout=10) From 55d30cdf2ae347490f1a1644f63a8bc30b6fa453 Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Tue, 27 Jun 2023 12:00:06 +0800 Subject: [PATCH 07/11] openthread sleepy device: remove HW acceleration in sdkconfig --- examples/openthread/ot_sleepy_device/sdkconfig.defaults | 6 ------ 1 file changed, 6 deletions(-) diff --git a/examples/openthread/ot_sleepy_device/sdkconfig.defaults b/examples/openthread/ot_sleepy_device/sdkconfig.defaults index 5f64593d30..e9d3993e19 100644 --- a/examples/openthread/ot_sleepy_device/sdkconfig.defaults +++ b/examples/openthread/ot_sleepy_device/sdkconfig.defaults @@ -1,5 +1,3 @@ -CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2048 - # # Partition Table # @@ -11,10 +9,6 @@ CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" # # mbedTLS # -# ESP32H2-TODO: JIRA TZ-127, enable HW acceleration. -CONFIG_MBEDTLS_HARDWARE_AES=n -CONFIG_MBEDTLS_HARDWARE_MPI=n -CONFIG_MBEDTLS_HARDWARE_SHA=n CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_SSL_PROTO_DTLS=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y From b422504d10f36980512f35e59f131963b745d5d8 Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Thu, 29 Jun 2023 15:12:03 +0800 Subject: [PATCH 08/11] ieee802154: exclude sleep file when do not define CONFIG_FREERTOS_USE_TICKLESS_IDLE --- components/ieee802154/Kconfig | 1 - components/ieee802154/driver/esp_ieee802154_dev.c | 3 +-- components/ieee802154/include/esp_ieee802154.h | 1 - components/openthread/CMakeLists.txt | 5 +++++ components/openthread/private_include/esp_openthread_sleep.h | 1 + components/openthread/src/port/esp_openthread_sleep.c | 5 +++-- examples/openthread/ot_sleepy_device/README.md | 2 +- .../openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c | 5 +---- 8 files changed, 12 insertions(+), 11 deletions(-) diff --git a/components/ieee802154/Kconfig b/components/ieee802154/Kconfig index 981945e50c..09aea764ed 100644 --- a/components/ieee802154/Kconfig +++ b/components/ieee802154/Kconfig @@ -74,7 +74,6 @@ menu "IEEE 802.15.4" Enabling this option increases throughput by ~5% at the expense of ~2.1k IRAM code size increase. - config IEEE802154_SLEEP_ENABLE # Todo: Remove when support safe power-down of the power domain (IDF-7317) bool "Enable IEEE802154 light sleep" diff --git a/components/ieee802154/driver/esp_ieee802154_dev.c b/components/ieee802154/driver/esp_ieee802154_dev.c index e2048b7ec1..dd428c6f29 100644 --- a/components/ieee802154/driver/esp_ieee802154_dev.c +++ b/components/ieee802154/driver/esp_ieee802154_dev.c @@ -636,7 +636,7 @@ esp_err_t ieee802154_mac_init(void) ret = esp_intr_alloc(ieee802154_periph.irq_id, 0, ieee802154_isr, NULL, NULL); ESP_RETURN_ON_FALSE(ret == ESP_OK, ESP_FAIL, IEEE802154_TAG, "IEEE802154 MAC init failed"); - ret = ieee802154_sleep_init(); + ESP_RETURN_ON_FALSE(ieee802154_sleep_init() == ESP_OK, ESP_FAIL, IEEE802154_TAG, "IEEE802154 MAC sleep init failed"); return ret; } @@ -767,7 +767,6 @@ static esp_err_t ieee802154_sleep_init(void) const static sleep_retention_entries_config_t ieee802154_mac_regs_retention[] = { [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_IEEE802154_LINK(0x00), IEEE802154_REG_BASE, IEEE802154_REG_BASE, N_REGS_IEEE802154(), 0, 0), .owner = ENTRY(3) }, }; - err = sleep_retention_entries_create(ieee802154_mac_regs_retention, ARRAY_SIZE(ieee802154_mac_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_802154_MAC); ESP_RETURN_ON_ERROR(err, IEEE802154_TAG, "failed to allocate memory for ieee802154 mac retention"); ESP_LOGI(IEEE802154_TAG, "ieee802154 mac sleep retention initialization"); diff --git a/components/ieee802154/include/esp_ieee802154.h b/components/ieee802154/include/esp_ieee802154.h index a1a7bd03fa..22d3acb52d 100644 --- a/components/ieee802154/include/esp_ieee802154.h +++ b/components/ieee802154/include/esp_ieee802154.h @@ -114,7 +114,6 @@ esp_err_t esp_ieee802154_sleep(void); /** * @brief The IEEE 802.15.4 enter sleep. */ - void esp_ieee802154_enter_sleep(void); /** diff --git a/components/openthread/CMakeLists.txt b/components/openthread/CMakeLists.txt index 26c3d5706a..7b02627731 100644 --- a/components/openthread/CMakeLists.txt +++ b/components/openthread/CMakeLists.txt @@ -140,6 +140,11 @@ if(CONFIG_OPENTHREAD_ENABLED) "src/esp_openthread_dns64.c") endif() + if(NOT CONFIG_FREERTOS_USE_TICKLESS_IDLE) + list(APPEND exclude_srcs + "src/port/esp_openthread_sleep.c") + endif() + if(CONFIG_OPENTHREAD_FTD) set(device_type "OPENTHREAD_FTD=1") elseif(CONFIG_OPENTHREAD_MTD) diff --git a/components/openthread/private_include/esp_openthread_sleep.h b/components/openthread/private_include/esp_openthread_sleep.h index 0a1bad56ca..e8b2679514 100644 --- a/components/openthread/private_include/esp_openthread_sleep.h +++ b/components/openthread/private_include/esp_openthread_sleep.h @@ -7,6 +7,7 @@ #pragma once #include "esp_err.h" +#include "sdkconfig.h" #ifdef __cplusplus extern "C" { diff --git a/components/openthread/src/port/esp_openthread_sleep.c b/components/openthread/src/port/esp_openthread_sleep.c index e59a45b898..fa6fdb3fcd 100644 --- a/components/openthread/src/port/esp_openthread_sleep.c +++ b/components/openthread/src/port/esp_openthread_sleep.c @@ -4,11 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" + +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "esp_log.h" #include "esp_check.h" #include "esp_ieee802154.h" - -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "esp_pm.h" static esp_pm_lock_handle_t s_pm_lock = NULL; static const char* TAG = "esp openthread sleep"; diff --git a/examples/openthread/ot_sleepy_device/README.md b/examples/openthread/ot_sleepy_device/README.md index 0aa2907879..e96137dd7e 100644 --- a/examples/openthread/ot_sleepy_device/README.md +++ b/examples/openthread/ot_sleepy_device/README.md @@ -3,7 +3,7 @@ # OpenThread Sleepy Device Example -The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Light Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32h2/api-reference/system/sleep_modes.html#sleep-modes) during idle state. +The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Light Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/system/sleep_modes.html#sleep-modes) during idle state. ## How to use example ### Hardware Required diff --git a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c index 584208a75f..42e53f0f09 100644 --- a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c +++ b/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c @@ -16,7 +16,6 @@ #include #include #include - #include "esp_err.h" #include "esp_event.h" #include "esp_log.h" @@ -41,8 +40,7 @@ static void create_config_network(otInstance *instance) { - otLinkModeConfig linkMode; - memset(&linkMode, 0, sizeof(otLinkModeConfig)); + otLinkModeConfig linkMode = { 0 }; linkMode.mRxOnWhenIdle = false; linkMode.mDeviceType = false; @@ -136,7 +134,6 @@ void app_main(void) ESP_ERROR_CHECK(esp_event_loop_create_default()); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config)); - ESP_ERROR_CHECK(ot_power_save_init()); xTaskCreate(ot_task_worker, "ot_power_save_main", 4096, NULL, 5, NULL); From eb04ccaf0b2d3d6f509026e4702d20d514e0532e Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Thu, 29 Jun 2023 18:12:10 +0800 Subject: [PATCH 09/11] openthread: change readme about specific target to 802.15.4 Soc --- examples/openthread/README.md | 2 +- .../openthread/ot_sleepy_device/README.md | 20 +++++++------------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/examples/openthread/README.md b/examples/openthread/README.md index b8c16cf36f..93496e93b5 100644 --- a/examples/openthread/README.md +++ b/examples/openthread/README.md @@ -12,4 +12,4 @@ In this folder, it contains following OpenThread examples: * [ot_br](ot_br) is an [OpenThread Border Router](https://openthread.io/guides/border-router) example. It runs on a Wi-Fi SoC such as ESP32, ESP32-C3 and ESP32-S3. It needs an 802.15.4 SoC like ESP32-H2 running [ot_rcp](ot_rcp) example to provide 802.15.4 radio. -* [ot_sleepy_device](ot_sleepy_device) is an OpenThread sleepy device example, it supports 802.15.4 radio light sleep. It runs on an 802.15.4 SoC like ESP32-C6. +* [ot_sleepy_device](ot_sleepy_device) is an OpenThread sleepy device example, it supports 802.15.4 radio light sleep. It runs on an 802.15.4 SoC. diff --git a/examples/openthread/ot_sleepy_device/README.md b/examples/openthread/ot_sleepy_device/README.md index e96137dd7e..22da2be610 100644 --- a/examples/openthread/ot_sleepy_device/README.md +++ b/examples/openthread/ot_sleepy_device/README.md @@ -8,28 +8,22 @@ The example demonstrates the Thread Sleepy End Device (SED), the device will ent ### Hardware Required -* Prepare an ESP32-C6 development board as an OpenThread Sleepy End Device (SED). -* Connect the board using a USB cable for power supply and programming. -* Choose another ESP32-C6 as the OpenThread Leader. - +* Prepare an 802.15.4 SoC development board as an OpenThread Sleepy End Device (SED). +* Connect the board using a USB cable for power supply and programming. +* Choose another 802.15.4 SoC as the OpenThread Leader. ## Configure the Openthread Dataset -* Run [ot_cli](../ot_cli/) on another ESP32-C6 device to create openthread dataset configuration and start an openthread network as the leader. -* Configure the Openthread dataset using `idf.py menuconfig` in `Component config ---> Openthread ---> Thread Operation Dataset`, ensuring that the openthread sleepy device's dataset matches the dataset of the leader. - -## Erase the ot_storage - -If desired, erase the ot_storage by running `idf.py -p erase-flash` before flashing the board to remove previous examples or other project data. +* Run [ot_cli](../ot_cli/) on another 802.15.4 SoC device to create openthread dataset configuration and start an openthread network as the leader. +* Configure the Openthread dataset using `idf.py menuconfig` in `Component config ---> Openthread ---> Thread Operation Dataset`, ensuring that the openthread sleepy device's dataset matches the dataset of the leader. ### Build and Flash - Build the project and flash it to the board. Use the following command: `idf.py -p build flash monitor`. - +Build the project and flash it to the board. Use the following command: `idf.py -p erase-flash flash monitor`. ### Example Output -As the example runs, you will see the log output indicating the initialization and operation of OpenThread, including the device joining the OpenThread network as a Sleepy End Device (SED) and periodic polling of the leader. +As the example runs, you will see the log output indicating the initialization and operation of OpenThread, including the device joining the OpenThread network as a Sleepy End Device (SED) and periodic polling of the leader. ``` I (769) btbb_init: btbb sleep retention initialization From 68910618fcf0d43644cf40092cb4f95e3f884a38 Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Fri, 30 Jun 2023 14:15:55 +0800 Subject: [PATCH 10/11] openthread: disable HW AES (IDF-7704) --- examples/openthread/ot_sleepy_device/sdkconfig.defaults | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/openthread/ot_sleepy_device/sdkconfig.defaults b/examples/openthread/ot_sleepy_device/sdkconfig.defaults index e9d3993e19..2279111544 100644 --- a/examples/openthread/ot_sleepy_device/sdkconfig.defaults +++ b/examples/openthread/ot_sleepy_device/sdkconfig.defaults @@ -9,6 +9,10 @@ CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" # # mbedTLS # +# TODO: Re-enable HW acceleration when HW AES support pm_lock (IDF-7704) +CONFIG_MBEDTLS_HARDWARE_AES=n +CONFIG_MBEDTLS_HARDWARE_MPI=n +CONFIG_MBEDTLS_HARDWARE_SHA=n CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_SSL_PROTO_DTLS=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y From 7f722715b9a58fa8b2ff82eddf07ee55b0c3cf42 Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Wed, 5 Jul 2023 14:37:56 +0800 Subject: [PATCH 11/11] fix(openthread): Fixed light sleep lock issue --- components/openthread/src/esp_openthread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/openthread/src/esp_openthread.cpp b/components/openthread/src/esp_openthread.cpp index 796fcf0a25..c345a8bb99 100644 --- a/components/openthread/src/esp_openthread.cpp +++ b/components/openthread/src/esp_openthread.cpp @@ -58,12 +58,12 @@ static size_t hex_string_to_binary(const char *hex_string, uint8_t *buf, size_t esp_err_t esp_openthread_init(const esp_openthread_platform_config_t *config) { - ESP_RETURN_ON_ERROR(esp_openthread_platform_init(config), OT_PLAT_LOG_TAG, - "Failed to initialize OpenThread platform driver"); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE ESP_RETURN_ON_ERROR(esp_openthread_sleep_init(), OT_PLAT_LOG_TAG, "Failed to initialize OpenThread esp pm_lock"); #endif + ESP_RETURN_ON_ERROR(esp_openthread_platform_init(config), OT_PLAT_LOG_TAG, + "Failed to initialize OpenThread platform driver"); esp_openthread_lock_acquire(portMAX_DELAY); ESP_RETURN_ON_FALSE(otInstanceInitSingle() != NULL, ESP_FAIL, OT_PLAT_LOG_TAG, "Failed to initialize OpenThread instance");