diff --git a/examples/openthread/ot_br/main/esp_ot_br.c b/examples/openthread/ot_br/main/esp_ot_br.c index 4996935c2c..d29718c4ae 100644 --- a/examples/openthread/ot_br/main/esp_ot_br.c +++ b/examples/openthread/ot_br/main/esp_ot_br.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 * @@ -15,6 +15,7 @@ #include #include +#include "sdkconfig.h" #include "esp_check.h" #include "esp_err.h" #include "esp_event.h" @@ -35,7 +36,6 @@ #include "mdns.h" #include "nvs_flash.h" #include "protocol_examples_common.h" -#include "sdkconfig.h" #include "driver/uart.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -44,6 +44,10 @@ #include "openthread/logging.h" #include "openthread/tasklet.h" +#if CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE +#include "ot_led_strip.h" +#endif + #define TAG "esp_ot_br" #if CONFIG_EXTERNAL_COEX_ENABLE @@ -72,6 +76,9 @@ static void ot_task_worker(void *aContext) // Initialize border routing features esp_openthread_lock_acquire(portMAX_DELAY); +#if CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE + ESP_ERROR_CHECK(esp_openthread_state_indicator_init(esp_openthread_get_instance())); +#endif ESP_ERROR_CHECK(esp_netif_attach(openthread_netif, esp_openthread_netif_glue_init(&config))); (void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL); diff --git a/examples/openthread/ot_br/main/idf_component.yml b/examples/openthread/ot_br/main/idf_component.yml index 98376227fe..124501cc61 100644 --- a/examples/openthread/ot_br/main/idf_component.yml +++ b/examples/openthread/ot_br/main/idf_component.yml @@ -10,3 +10,5 @@ dependencies: path: ${IDF_PATH}/examples/common_components/protocol_examples_common iperf: path: ${IDF_PATH}/examples/common_components/iperf + ot_led: + path: ${IDF_PATH}/examples/openthread/ot_common_components/ot_led diff --git a/examples/openthread/ot_cli/main/esp_ot_cli.c b/examples/openthread/ot_cli/main/esp_ot_cli.c index 912881c362..96a8d1e22c 100644 --- a/examples/openthread/ot_cli/main/esp_ot_cli.c +++ b/examples/openthread/ot_cli/main/esp_ot_cli.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 * @@ -16,6 +16,7 @@ #include #include +#include "sdkconfig.h" #include "esp_err.h" #include "esp_event.h" #include "esp_log.h" @@ -38,6 +39,10 @@ #include "openthread/logging.h" #include "openthread/tasklet.h" +#if CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE +#include "ot_led_strip.h" +#endif + #if CONFIG_OPENTHREAD_CLI_ESP_EXTENSION #include "esp_ot_cli_extension.h" #endif // CONFIG_OPENTHREAD_CLI_ESP_EXTENSION @@ -65,6 +70,10 @@ static void ot_task_worker(void *aContext) // Initialize the OpenThread stack ESP_ERROR_CHECK(esp_openthread_init(&config)); +#if CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE + ESP_ERROR_CHECK(esp_openthread_state_indicator_init(esp_openthread_get_instance())); +#endif + #if CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC // The OpenThread log level directly matches ESP log level (void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL); diff --git a/examples/openthread/ot_cli/main/idf_component.yml b/examples/openthread/ot_cli/main/idf_component.yml index 6cb24e1008..2ed997286a 100644 --- a/examples/openthread/ot_cli/main/idf_component.yml +++ b/examples/openthread/ot_cli/main/idf_component.yml @@ -6,3 +6,5 @@ dependencies: version: ">=4.1.0" iperf: path: ${IDF_PATH}/examples/common_components/iperf + ot_led: + path: ${IDF_PATH}/examples/openthread/ot_common_components/ot_led diff --git a/examples/openthread/ot_common_components/ot_led/CMakeLists.txt b/examples/openthread/ot_common_components/ot_led/CMakeLists.txt new file mode 100644 index 0000000000..8aedc48686 --- /dev/null +++ b/examples/openthread/ot_common_components/ot_led/CMakeLists.txt @@ -0,0 +1,7 @@ +if(CONFIG_OPENTHREAD_STATE_INDICATOR_ENABLE) + set(srcs "ot_led_strip.c") +endif() + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "include" + PRIV_REQUIRES led_strip openthread) diff --git a/examples/openthread/ot_common_components/ot_led/Kconfig.projbuild b/examples/openthread/ot_common_components/ot_led/Kconfig.projbuild new file mode 100644 index 0000000000..91299217cc --- /dev/null +++ b/examples/openthread/ot_common_components/ot_led/Kconfig.projbuild @@ -0,0 +1,24 @@ +menu "OpenThread Device Role LED" + + orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" + + config OPENTHREAD_STATE_INDICATOR_ENABLE + depends on SOC_RMT_SUPPORTED + bool 'Enable the LED for openthread deivce' + default False + help + If enabled, the LED of ESP Openthread Device will display different colors based on the current role. + + config OPENTHREAD_STATE_INDICATOR_GPIO + depends on OPENTHREAD_STATE_INDICATOR_ENABLE + int "Blink GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX + default 5 if IDF_TARGET_ESP32 + default 18 if IDF_TARGET_ESP32S2 + default 48 if IDF_TARGET_ESP32S3 + default 8 + help + GPIO number (IOxx) to blink on and off the LED. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to blink. + +endmenu diff --git a/examples/openthread/ot_common_components/ot_led/idf_component.yml b/examples/openthread/ot_common_components/ot_led/idf_component.yml new file mode 100644 index 0000000000..8723a2e11a --- /dev/null +++ b/examples/openthread/ot_common_components/ot_led/idf_component.yml @@ -0,0 +1,2 @@ +dependencies: + espressif/led_strip: "^2.4.1" diff --git a/examples/openthread/ot_common_components/ot_led/include/ot_led_strip.h b/examples/openthread/ot_common_components/ot_led/include/ot_led_strip.h new file mode 100644 index 0000000000..a65c80db24 --- /dev/null +++ b/examples/openthread/ot_common_components/ot_led/include/ot_led_strip.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2024 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 "esp_err.h" +#include "esp_openthread.h" + +/** + * @brief Initilize the LED of OpenThread device. + * + * @return + * - ESP_OK on success + * - ESP_FAIL on failure + * + */ +esp_err_t esp_openthread_state_indicator_init(otInstance *instance); + +/** + * @brief Set the LED color of OpenThread device. + * + * @param[in] index index of pixel to set + * @param[in] red red part of color + * @param[in] green green part of color + * @param[in] blue blue part of color + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG: Set LED color failed because of invalid parameters + * - ESP_FAIL on other failure + * + */ +esp_err_t esp_openthread_state_indicator_set(uint32_t index, uint32_t red, uint32_t green, uint32_t blue); + +/** + * @brief Clear the LED color of OpenThread device. + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG: Clear LED color failed because of invalid parameters + * - ESP_FAIL on other failure + * + */ +esp_err_t esp_openthread_state_indicator_clear(void); diff --git a/examples/openthread/ot_common_components/ot_led/ot_led_strip.c b/examples/openthread/ot_common_components/ot_led/ot_led_strip.c new file mode 100644 index 0000000000..f9e829f12d --- /dev/null +++ b/examples/openthread/ot_common_components/ot_led/ot_led_strip.c @@ -0,0 +1,77 @@ +/* + * SPDX-FileCopyrightText: 2024 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 "ot_led_strip.h" +#include "esp_check.h" +#include "led_strip.h" +#include "esp_err.h" +#include "esp_openthread.h" + +static led_strip_handle_t s_led_strip; + +#define TAG "OT_LED" + +static void configure_led(void) +{ + /* LED strip initialization with the GPIO and pixels number*/ + led_strip_config_t strip_config = { + .strip_gpio_num = CONFIG_OPENTHREAD_STATE_INDICATOR_GPIO, + .max_leds = 1, // at least one LED on board + }; + led_strip_rmt_config_t rmt_config = { + .resolution_hz = 10 * 1000 * 1000, // 10MHz + .flags.with_dma = false, + }; + ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &s_led_strip)); + /* Set all LED off to clear all pixels */ + ESP_ERROR_CHECK(led_strip_clear(s_led_strip)); +} + +static void ot_indicator_change_callback(otChangedFlags changed_flags, void* ctx) +{ + otInstance *instance = esp_openthread_get_instance(); + otDeviceRole role = otThreadGetDeviceRole(instance); + if (role == OT_DEVICE_ROLE_DISABLED) { + esp_openthread_state_indicator_clear(); + } else if (role == OT_DEVICE_ROLE_DETACHED) { + esp_openthread_state_indicator_set(0, 40, 0, 0); + } else if (role == OT_DEVICE_ROLE_LEADER) { + esp_openthread_state_indicator_set(0, 0, 40, 0); + } else if (role == OT_DEVICE_ROLE_ROUTER) { + esp_openthread_state_indicator_set(0, 0, 0, 40); + } else if (role == OT_DEVICE_ROLE_CHILD) { + esp_openthread_state_indicator_set(0, 40, 8, 60); + } +} + +esp_err_t esp_openthread_state_indicator_init(otInstance *instance) +{ + configure_led(); + ESP_RETURN_ON_FALSE(otSetStateChangedCallback(instance, ot_indicator_change_callback, NULL) == OT_ERROR_NONE, + ESP_FAIL, TAG, "Failed to install state change callback"); + return ESP_OK; +} + +esp_err_t esp_openthread_state_indicator_set(uint32_t index, uint32_t red, uint32_t green, uint32_t blue) +{ + ESP_RETURN_ON_ERROR(led_strip_set_pixel(s_led_strip, index, red, green, blue), TAG, "Failed to set color for openthread state"); + ESP_RETURN_ON_ERROR(led_strip_refresh(s_led_strip), TAG, "Failed to refresh color for openthread state"); + return ESP_OK; +} + +esp_err_t esp_openthread_state_indicator_clear(void) +{ + ESP_RETURN_ON_ERROR(led_strip_clear(s_led_strip), TAG, "Failed to clear color for openthread state"); + return ESP_OK; +}