mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-04 00:51:42 +01:00 
			
		
		
		
	Merge branch 'support/ot_deep_sleep_device' into 'master'
feat(openthread): Add deep sleep support for SED See merge request espressif/esp-idf!26630
This commit is contained in:
		
							
								
								
									
										64
									
								
								examples/openthread/ot_sleepy_device/deep_sleep/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								examples/openthread/ot_sleepy_device/deep_sleep/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
| Supported Targets | ESP32-H2 |
 | 
			
		||||
| ----------------- | -------- |
 | 
			
		||||
 | 
			
		||||
# OpenThread Sleepy Device Example
 | 
			
		||||
 | 
			
		||||
The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Deep Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/system/sleep_modes.html#sleep-modes) during idle state.
 | 
			
		||||
 | 
			
		||||
This example is designed to address a specific deep sleep application scenario. First, it connects to the Thread network, and after 5 seconds when the state changes to CHILD, it enters deep sleep mode. There are two ways to wake up in this example: one is by using a 20-second periodic RTC timer, and the other is through GPIO input. Deep sleep is part of the upper-layer logic, and it's the user's responsibility to manage it in their own applications. If you need more wake-up methods, you can refer to the [Exapmle deep sleep](../../../system/deep_sleep/). Additionally, Espressif provides a stub for handling wake-ups, which allows for a quick check, and the user can decide whether to wake up or continue deep sleep in this stub, as explained in the [Example deep sleep stub](../../../system/deep_sleep_wake_stub).
 | 
			
		||||
 | 
			
		||||
Note: Implementing a standard Thread Sleepy Device is recommended using the [Light Sleep example](../light_sleep). Deep sleep triggers a reboot, and the device needs to undergo a re-attach process to rejoin the network. This means additional packet interactions are necessary after each wake-up from deep sleep. It can be advantageous in reducing power consumption, especially when the device remains in a sleep state for extended periods, such as more than 30 minutes.
 | 
			
		||||
## How to use example
 | 
			
		||||
 | 
			
		||||
### Hardware Required
 | 
			
		||||
 | 
			
		||||
* Prepare two 802.15.4 SoC development boards, one for an OpenThread Leader and the other one for an OpenThread Sleepy End Device (SED).
 | 
			
		||||
* Connect the board using a USB cable for power supply and programming.
 | 
			
		||||
 | 
			
		||||
## Configure the Openthread Dataset
 | 
			
		||||
 | 
			
		||||
* 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 device.
 | 
			
		||||
 | 
			
		||||
### Build and Flash
 | 
			
		||||
 | 
			
		||||
Build the project and flash it to the board. Use the following command: `idf.py -p <PORT> 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).
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
I(281) OPENTHREAD:[I] Settings------: Read NetworkInfo {rloc:0x4001, extaddr:623954c9725869e6, role:child, mode:0x04, version:4, keyseq:0x0, ...
 | 
			
		||||
I(291) OPENTHREAD:[I] Settings------: ... pid:0x3b33d767, mlecntr:0x3ba17, maccntr:0x3baa8, mliid:868f19ce8c3f6207}
 | 
			
		||||
I(301) OPENTHREAD:[I] Settings------: Read ParentInfo {extaddr:3afe8db4802dc1aa, version:4}
 | 
			
		||||
I (311) ot_esp_power_save: Wake up from timer. Time spent in deep sleep and boot: 20321ms
 | 
			
		||||
I (331) ot_esp_power_save: Enabling timer wakeup, 20s
 | 
			
		||||
I (331) OPENTHREAD: OpenThread attached to netif
 | 
			
		||||
I(341) OPENTHREAD:[N] Mle-----------: Role disabled -> detached
 | 
			
		||||
I (291) main_task: Returned from app_main()
 | 
			
		||||
I (371) OT_STATE: netif up
 | 
			
		||||
I(511) OPENTHREAD:[N] Mle-----------: Role detached -> child
 | 
			
		||||
I (531) ot_esp_power_save: Start one-shot timer for 5s to enter the deep sleep
 | 
			
		||||
I (5531) ot_esp_power_save: Enter deep sleep
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
When the device enter deep sleep, GPIO9 also can wake up the device, you can push down the BOOT button then you can see the device wakes up:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
I(281) OPENTHREAD:[I] Settings------: Read NetworkInfo {rloc:0x4001, extaddr:623954c9725869e6, role:child, mode:0x04, version:4, keyseq:0x0, ...
 | 
			
		||||
I(291) OPENTHREAD:[I] Settings------: ... pid:0x3b33d767, mlecntr:0x3d576, maccntr:0x3d609, mliid:868f19ce8c3f6207}
 | 
			
		||||
I(301) OPENTHREAD:[I] Settings------: Read ParentInfo {extaddr:3afe8db4802dc1aa, version:4}
 | 
			
		||||
I (321) ot_esp_power_save: Wake up from GPIO. Time spent in deep sleep and boot: 8470ms
 | 
			
		||||
I (331) ot_esp_power_save: Enabling timer wakeup, 20s
 | 
			
		||||
I (331) OPENTHREAD: OpenThread attached to netif
 | 
			
		||||
I(341) OPENTHREAD:[N] Mle-----------: Role disabled -> detached
 | 
			
		||||
I (291) main_task: Returned from app_main()
 | 
			
		||||
I (371) OT_STATE: netif up
 | 
			
		||||
I(511) OPENTHREAD:[N] Mle-----------: Role detached -> child
 | 
			
		||||
I (531) ot_esp_power_save: Start one-shot timer for 5s to enter the deep sleep
 | 
			
		||||
I (5531) ot_esp_power_save: Enter deep sleep
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
During the deep sleep, a typical power consumption is shown below:
 | 
			
		||||

 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 90 KiB  | 
@@ -0,0 +1,220 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "esp_err.h"
 | 
			
		||||
#include "esp_event.h"
 | 
			
		||||
#include "esp_log.h"
 | 
			
		||||
#include "esp_sleep.h"
 | 
			
		||||
#include "esp_timer.h"
 | 
			
		||||
#include "esp_openthread.h"
 | 
			
		||||
#include "esp_openthread_netif_glue.h"
 | 
			
		||||
#include "esp_ot_sleepy_device_config.h"
 | 
			
		||||
#include "esp_vfs_eventfd.h"
 | 
			
		||||
#include "nvs_flash.h"
 | 
			
		||||
#include "driver/rtc_io.h"
 | 
			
		||||
#include "driver/uart.h"
 | 
			
		||||
#include "openthread/logging.h"
 | 
			
		||||
#include "openthread/thread.h"
 | 
			
		||||
 | 
			
		||||
#if !SOC_IEEE802154_SUPPORTED
 | 
			
		||||
#error "Openthread sleepy device is only supported for the SoCs which have IEEE 802.15.4 module"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define TAG "ot_esp_power_save"
 | 
			
		||||
 | 
			
		||||
static RTC_DATA_ATTR struct timeval s_sleep_enter_time;
 | 
			
		||||
static esp_timer_handle_t s_oneshot_timer;
 | 
			
		||||
 | 
			
		||||
static void create_config_network(otInstance *instance)
 | 
			
		||||
{
 | 
			
		||||
    otLinkModeConfig linkMode = { 0 };
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
    }
 | 
			
		||||
    ESP_ERROR_CHECK(esp_openthread_auto_start(NULL));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_state_change_callback(otChangedFlags changed_flags, void* ctx)
 | 
			
		||||
{
 | 
			
		||||
    OT_UNUSED_VARIABLE(ctx);
 | 
			
		||||
    static otDeviceRole s_previous_role = OT_DEVICE_ROLE_DISABLED;
 | 
			
		||||
    otInstance* instance = esp_openthread_get_instance();
 | 
			
		||||
    if (!instance) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    otDeviceRole role = otThreadGetDeviceRole(instance);
 | 
			
		||||
    if (role == OT_DEVICE_ROLE_CHILD && s_previous_role != OT_DEVICE_ROLE_CHILD) {
 | 
			
		||||
        // Start the one-shot timer
 | 
			
		||||
        const int before_deep_sleep_time_sec = 5;
 | 
			
		||||
        ESP_LOGI(TAG, "Start one-shot timer for %ds to enter the deep sleep", before_deep_sleep_time_sec);
 | 
			
		||||
        ESP_ERROR_CHECK(esp_timer_start_once(s_oneshot_timer, before_deep_sleep_time_sec * 1000000));
 | 
			
		||||
    }
 | 
			
		||||
    s_previous_role = role;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void s_oneshot_timer_callback(void* arg)
 | 
			
		||||
{
 | 
			
		||||
    // Enter deep sleep
 | 
			
		||||
    ESP_LOGI(TAG, "Enter deep sleep");
 | 
			
		||||
    gettimeofday(&s_sleep_enter_time, NULL);
 | 
			
		||||
    esp_deep_sleep_start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ot_deep_sleep_init(void)
 | 
			
		||||
{
 | 
			
		||||
    // Within this function, we print the reason for the wake-up and configure the method of waking up from deep sleep.
 | 
			
		||||
    // This example provides support for two wake-up sources from deep sleep: RTC timer and GPIO.
 | 
			
		||||
 | 
			
		||||
    // The one-shot timer will start when the device transitions to the CHILD state for the first time.
 | 
			
		||||
    // After a 5-second delay, the device will enter deep sleep.
 | 
			
		||||
 | 
			
		||||
    const esp_timer_create_args_t s_oneshot_timer_args = {
 | 
			
		||||
            .callback = &s_oneshot_timer_callback,
 | 
			
		||||
            .name = "one-shot"
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    ESP_ERROR_CHECK(esp_timer_create(&s_oneshot_timer_args, &s_oneshot_timer));
 | 
			
		||||
 | 
			
		||||
    // Print the wake-up reason:
 | 
			
		||||
    struct timeval now;
 | 
			
		||||
    gettimeofday(&now, NULL);
 | 
			
		||||
    int sleep_time_ms = (now.tv_sec - s_sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - s_sleep_enter_time.tv_usec) / 1000;
 | 
			
		||||
    esp_sleep_wakeup_cause_t wake_up_cause = esp_sleep_get_wakeup_cause();
 | 
			
		||||
    switch (wake_up_cause) {
 | 
			
		||||
    case ESP_SLEEP_WAKEUP_TIMER: {
 | 
			
		||||
        ESP_LOGI(TAG, "Wake up from timer. Time spent in deep sleep and boot: %dms", sleep_time_ms);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case ESP_SLEEP_WAKEUP_EXT1: {
 | 
			
		||||
        ESP_LOGI(TAG, "Wake up from GPIO. Time spent in deep sleep and boot: %dms", sleep_time_ms);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case ESP_SLEEP_WAKEUP_UNDEFINED:
 | 
			
		||||
    default:
 | 
			
		||||
        ESP_LOGI(TAG, "Not a deep sleep reset");
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set the methods of how to wake up:
 | 
			
		||||
    // 1. RTC timer waking-up
 | 
			
		||||
    const int wakeup_time_sec = 20;
 | 
			
		||||
    ESP_LOGI(TAG, "Enabling timer wakeup, %ds\n", wakeup_time_sec);
 | 
			
		||||
    ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000));
 | 
			
		||||
 | 
			
		||||
    // 2. GPIO waking-up
 | 
			
		||||
#if CONFIG_IDF_TARGET_ESP32C6
 | 
			
		||||
    // For ESP32C6 boards, RTCIO only supports GPIO0~GPIO7
 | 
			
		||||
    // GPIO7 pull down to wake up
 | 
			
		||||
    const int gpio_wakeup_pin = 7;
 | 
			
		||||
#elif CONFIG_IDF_TARGET_ESP32H2
 | 
			
		||||
    // You can wake up by pulling down GPIO9. On ESP32H2 development boards, the BOOT button is connected to GPIO9.
 | 
			
		||||
    // You can use the BOOT button to wake up the boards directly.
 | 
			
		||||
    const int gpio_wakeup_pin = 9;
 | 
			
		||||
#endif
 | 
			
		||||
    const uint64_t gpio_wakeup_pin_mask = 1ULL << gpio_wakeup_pin;
 | 
			
		||||
    // The configuration mode depends on your hardware design.
 | 
			
		||||
    // Since the BOOT button is connected to a pull-up resistor, the wake-up mode is configured as LOW.
 | 
			
		||||
    const uint64_t ext_wakeup_mode = 0 << gpio_wakeup_pin;
 | 
			
		||||
    ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_with_level_mask(gpio_wakeup_pin_mask, ext_wakeup_mode));
 | 
			
		||||
 | 
			
		||||
    // Also these two GPIO configurations are also depended on the hardware design.
 | 
			
		||||
    // The BOOT button is connected to the pull-up resistor, so enable the pull-up mode and disable the pull-down mode.
 | 
			
		||||
 | 
			
		||||
    // Notice: if these GPIO configurations do not match the hardware design, the deep sleep module will enable the GPIO hold
 | 
			
		||||
    // feature to hold the GPIO voltage when enter the sleep, which will ensure the board be waked up by GPIO. But it will cause
 | 
			
		||||
    // 3~4 times power consumption increasing during sleep.
 | 
			
		||||
    ESP_ERROR_CHECK(gpio_pullup_en(gpio_wakeup_pin));
 | 
			
		||||
    ESP_ERROR_CHECK(gpio_pulldown_dis(gpio_wakeup_pin));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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));
 | 
			
		||||
 | 
			
		||||
    ot_deep_sleep_init();
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
    otSetStateChangedCallback(esp_openthread_get_instance(), ot_state_change_callback, NULL);
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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));
 | 
			
		||||
 | 
			
		||||
    xTaskCreate(ot_task_worker, "ot_power_save_main", 4096, NULL, 5, NULL);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,53 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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_POLLPERIOD_TIME 30000
 | 
			
		||||
 | 
			
		||||
#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 = "nvs", \
 | 
			
		||||
        .netif_queue_size = 10,                 \
 | 
			
		||||
        .task_queue_size = 10,                  \
 | 
			
		||||
    }
 | 
			
		||||
@@ -0,0 +1,54 @@
 | 
			
		||||
#
 | 
			
		||||
# 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
 | 
			
		||||
#
 | 
			
		||||
# 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
 | 
			
		||||
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_IPV4=n
 | 
			
		||||
CONFIG_LWIP_ND6=n
 | 
			
		||||
# end of lwIP
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# IEEE 802.15.4
 | 
			
		||||
#
 | 
			
		||||
CONFIG_IEEE802154_ENABLED=y
 | 
			
		||||
# end of IEEE 802.15.4
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# deep sleep
 | 
			
		||||
#
 | 
			
		||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80=y
 | 
			
		||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=80
 | 
			
		||||
CONFIG_ULP_COPROC_ENABLED=y
 | 
			
		||||
CONFIG_ULP_COPROC_RESERVE_MEM=512
 | 
			
		||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y
 | 
			
		||||
CONFIG_RTC_CLK_SRC_INT_RC=y
 | 
			
		||||
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y
 | 
			
		||||
@@ -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_sleepy_device)
 | 
			
		||||
@@ -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/esp32c6/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/esp32h2/api-reference/system/sleep_modes.html#sleep-modes) during idle state.
 | 
			
		||||
## How to use example
 | 
			
		||||
 | 
			
		||||
### Hardware Required
 | 
			
		||||
@@ -14,7 +14,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 802.15.4 SoC device to create openthread dataset configuration and start an openthread network as the leader.
 | 
			
		||||
* 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
 | 
			
		||||
@@ -0,0 +1,2 @@
 | 
			
		||||
idf_component_register(SRCS "esp_ot_sleepy_device.c"
 | 
			
		||||
                       INCLUDE_DIRS ".")
 | 
			
		||||
@@ -0,0 +1,5 @@
 | 
			
		||||
# 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,
 | 
			
		||||
		
		
			
  | 
@@ -0,0 +1,6 @@
 | 
			
		||||
CONFIG_IDF_TARGET="esp32c6"
 | 
			
		||||
CONFIG_IDF_TARGET_ESP32C6=y
 | 
			
		||||
CONFIG_OPENTHREAD_NETWORK_CHANNEL=12
 | 
			
		||||
CONFIG_OPENTHREAD_NETWORK_MASTERKEY="aabbccddeeff00112233445566778899"
 | 
			
		||||
CONFIG_ESP_SLEEP_DEBUG=y
 | 
			
		||||
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
 | 
			
		||||
		Reference in New Issue
	
	Block a user