Przeglądaj źródła

ieee802154: add sleep state

xiaqilin 2 lat temu
rodzic
commit
485a9d44cf

+ 1 - 1
components/esp_hw_support/include/esp_private/esp_regdma.h

@@ -39,7 +39,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)
 

+ 7 - 3
components/ieee802154/driver/esp_ieee802154_dev.c

@@ -205,6 +205,10 @@ 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;
@@ -744,7 +748,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();
@@ -755,7 +759,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
@@ -771,7 +775,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;

+ 7 - 4
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)

+ 4 - 4
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.

+ 1 - 0
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 */

+ 5 - 4
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. **/
 /**

+ 0 - 107
components/openthread/port/esp_openthread.cpp

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

+ 12 - 0
components/openthread/src/esp_openthread.cpp

@@ -11,6 +11,7 @@
 #include "esp_openthread_dns64.h"
 #include "esp_openthread_lock.h"
 #include "esp_openthread_platform.h"
+#include "esp_openthread_sleep.h"
 #include "esp_openthread_task_queue.h"
 #include "esp_openthread_types.h"
 #include "freertos/FreeRTOS.h"
@@ -20,6 +21,7 @@
 #include "openthread/tasklet.h"
 #include "openthread/thread.h"
 
+
 static int hex_digit_to_int(char hex)
 {
     if ('A' <= hex && hex <= 'F') {
@@ -58,6 +60,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");
@@ -154,11 +160,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);

+ 11 - 28
components/openthread/port/esp_openthread_sleep.c → 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;
     }
 }

+ 9 - 8
examples/openthread/.build-test-rules.yml

@@ -41,14 +41,6 @@ examples/openthread/ot_cli:
       reason: only test on esp32h2
   <<: *openthread_dependencies
 
-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"]
@@ -57,3 +49,12 @@ examples/openthread/ot_rcp:
       temporary: true
       reason: only test on esp32c6
   <<: *openthread_dependencies
+
+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
+  <<: *openthread_dependencies

+ 1 - 1
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.
+* [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.

+ 0 - 2
examples/openthread/ot_power_save/main/CMakeLists.txt

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

+ 1 - 1
examples/openthread/ot_power_save/CMakeLists.txt → 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)

+ 2 - 2
examples/openthread/ot_power_save/README.md → 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

+ 2 - 0
examples/openthread/ot_sleepy_device/main/CMakeLists.txt

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

+ 2 - 2
examples/openthread/ot_power_save/main/esp_ot_power_save.c → 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"

+ 0 - 0
examples/openthread/ot_power_save/main/esp_ot_power_save_config.h → examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h


+ 0 - 0
examples/openthread/ot_power_save/partitions.csv → examples/openthread/ot_sleepy_device/partitions.csv


+ 0 - 0
examples/openthread/ot_power_save/sdkconfig.defaults → examples/openthread/ot_sleepy_device/sdkconfig.defaults