From 49ae9ad0792422dfa7472709fa8e2f5f8aba554e Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Thu, 18 Apr 2024 19:35:19 +0800 Subject: [PATCH 1/5] ESP32: Add UAT button for lit-icd-app --- .../lit-icd-app/esp32/main/IcdUatButton.cpp | 149 ++++++++++++++++++ .../esp32/main/include/IcdUatButton.h | 51 ++++++ examples/lit-icd-app/esp32/main/main.cpp | 25 +++ .../platform/esp32/common/Esp32AppServer.cpp | 12 +- 4 files changed, 232 insertions(+), 5 deletions(-) create mode 100644 examples/lit-icd-app/esp32/main/IcdUatButton.cpp create mode 100644 examples/lit-icd-app/esp32/main/include/IcdUatButton.h diff --git a/examples/lit-icd-app/esp32/main/IcdUatButton.cpp b/examples/lit-icd-app/esp32/main/IcdUatButton.cpp new file mode 100644 index 00000000000000..ab791b77958415 --- /dev/null +++ b/examples/lit-icd-app/esp32/main/IcdUatButton.cpp @@ -0,0 +1,149 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "IcdUatButton.h" + +#include "driver/gpio.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "hal/gpio_types.h" +#include "soc/gpio_num.h" +#include + +#define ESP_INTR_FLAG_DEFAULT 0 + +static const char TAG[] = "Button"; +QueueHandle_t UatButton::sEventQueue = nullptr; +TaskHandle_t UatButton::sTaskHandle = nullptr; + +static void IRAM_ATTR gpio_isr_handler(void * arg) +{ + if (UatButton::sEventQueue) + { + UatButton * button = (UatButton *) arg; + button->GpioIntrEnable(false); + xQueueSendFromISR(UatButton::sEventQueue, &button, NULL); + } +} + +void UatButton::RunEventLoop(void * arg) +{ + bool eventDone = true; + UatButton * button = nullptr; + + for (;;) + { + if (xQueueReceive(sEventQueue, &button, portMAX_DELAY) == pdTRUE && button) + { + button->GpioIntrEnable(false); + eventDone = false; + } + while (!eventDone) + { + // GPIO Pull up is enabled so the button is pressed when this value is false. + bool value = gpio_get_level(button->mGpioNum); + switch (button->mState) + { + case ButtonState::kIdle: + button->mState = value == false ? ButtonState::kPressed : ButtonState::kIdle; + break; + case ButtonState::kPressed: + button->mState = value == false ? ButtonState::kPressed : ButtonState::kReleased; + break; + case ButtonState::kReleased: + button->mState = ButtonState::kIdle; + if (button->mUatButtonPressCallback) + { + button->mUatButtonPressCallback(button); + } + break; + default: + break; + } + if (button->mState == ButtonState::kIdle) + { + button->GpioIntrEnable(true); + eventDone = true; + break; + } + vTaskDelay(10 / portTICK_PERIOD_MS); + } + } +} + +void UatButton::GpioIntrEnable(bool enable) +{ + if (enable) + { + gpio_intr_enable(mGpioNum); + } + else + { + gpio_intr_disable(mGpioNum); + } +} + +void UatButton::Init(gpio_num_t gpioNum, esp_sleep_ext1_wakeup_mode_t wakeupMode) +{ + mGpioNum = gpioNum; + mState = ButtonState::kIdle; + gpio_config_t io_conf = {}; + io_conf.intr_type = GPIO_INTR_LOW_LEVEL; + io_conf.pin_bit_mask = (1ULL << static_cast(mGpioNum)); + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pull_up_en = GPIO_PULLUP_ENABLE; + // configure GPIO with the given settings + gpio_config(&io_conf); + if (!sEventQueue) + { + // create a queue to handle gpio event from isr + sEventQueue = xQueueCreate(10, sizeof(UatButton *)); + if (!sEventQueue) + { + ESP_LOGE(TAG, "Failed to create GPIO EventQueue"); + return; + } + } + if (!sTaskHandle) + { + // start gpio task + xTaskCreate(RunEventLoop, "UatButton", 4096, nullptr, 10, &sTaskHandle); + if (!sTaskHandle) + { + ESP_LOGE(TAG, "Failed to create GPIO Task"); + return; + } + } + // install gpio isr service + gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); + // hook isr handler for specific gpio pin + gpio_isr_handler_add(mGpioNum, gpio_isr_handler, (void *) this); + ESP_LOGI(TAG, "UAT Button initialized.."); + // Configure RTC IO wake up + esp_sleep_enable_ext1_wakeup(1ULL << static_cast(mGpioNum), wakeupMode); +#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED + rtc_gpio_pulldown_dis(mGpioNum); + rtc_gpio_pullup_en(mGpioNum); +#else + gpio_pulldown_dis(mGpioNum); + gpio_pullup_en(mGpioNum); +#endif +} diff --git a/examples/lit-icd-app/esp32/main/include/IcdUatButton.h b/examples/lit-icd-app/esp32/main/include/IcdUatButton.h new file mode 100644 index 00000000000000..92f90daf0e1a06 --- /dev/null +++ b/examples/lit-icd-app/esp32/main/include/IcdUatButton.h @@ -0,0 +1,51 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +class UatButton +{ +public: + using UatButtonPressCallback = void (*)(UatButton *); + + enum class ButtonState : uint8_t + { + kIdle = 0, + kPressed, + kReleased, + }; + + void Init(gpio_num_t gpioNum, esp_sleep_ext1_wakeup_mode_t wakeMode); + void SetUatButtonPressCallback(UatButtonPressCallback buttonCallback) { mUatButtonPressCallback = buttonCallback; } + void GpioIntrEnable(bool enable); + + static void RunEventLoop(void * arg); + static TaskHandle_t sTaskHandle; + static QueueHandle_t sEventQueue; + +private: + gpio_num_t mGpioNum; + ButtonState mState; + UatButtonPressCallback mUatButtonPressCallback; +}; diff --git a/examples/lit-icd-app/esp32/main/main.cpp b/examples/lit-icd-app/esp32/main/main.cpp index 340ae124d816c3..735055be1468c0 100644 --- a/examples/lit-icd-app/esp32/main/main.cpp +++ b/examples/lit-icd-app/esp32/main/main.cpp @@ -24,6 +24,8 @@ #include "nvs_flash.h" #include +#include +#include #include #include #include @@ -31,6 +33,7 @@ #include #include #include +#include #if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER #include @@ -58,6 +61,18 @@ chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; #error "Currently this example only support Thread chips" #endif +#ifdef CONFIG_IDF_TARGET_ESP32H2 +// GPIO9-GPIO14 could be used to wake up ESP32-H2. +// For ESP32-H2 DevKitM, the boot button is GPIO9. +#define UAT_GPIO GPIO_NUM_9 +#elif defined(CONFIG_IDF_TARGET_ESP32C6) +// GPIO0-GPIO7 could be used to wake up ESP32-C6. +// For ESP32-C6 DevKitC, the boot button is GPIO9, we cannot use it to wake up the chip. +#define UAT_GPIO GPIO_NUM_7 +#else +#error "Unsupport IDF target" +#endif + using namespace ::chip; using namespace ::chip::DeviceManager; using namespace ::chip::Credentials; @@ -66,6 +81,13 @@ extern const char TAG[] = "lit-icd-app"; static AppDeviceCallbacks EchoCallbacks; +static void UatButtonHandler(UatButton *button) +{ + DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { + Server::GetInstance().GetICDManager().UpdateOperationState(app::ICDManager::OperationalState::ActiveMode); + }); +} + static void InitServer(intptr_t context) { Esp32AppServer::Init(); // Init ZCL Data Model and CHIP App Server AND Initialize device attestation config @@ -110,6 +132,9 @@ extern "C" void app_main() SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); #endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER ESPOpenThreadInit(); + static UatButton sButton; + sButton.Init(UAT_GPIO, ESP_EXT1_WAKEUP_ANY_LOW); + sButton.SetUatButtonPressCallback(UatButtonHandler); chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer, reinterpret_cast(nullptr)); } diff --git a/examples/platform/esp32/common/Esp32AppServer.cpp b/examples/platform/esp32/common/Esp32AppServer.cpp index 53957784b8c5f5..873115c25ab1af 100644 --- a/examples/platform/esp32/common/Esp32AppServer.cpp +++ b/examples/platform/esp32/common/Esp32AppServer.cpp @@ -61,14 +61,14 @@ static app::Clusters::NetworkCommissioning::Instance sEthernetNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::ESPEthernetDriver::GetInstance())); #endif -#if CONFIG_TEST_EVENT_TRIGGER_ENABLED && CONFIG_ENABLE_OTA_REQUESTOR +#if CONFIG_TEST_EVENT_TRIGGER_ENABLED static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; #endif } // namespace -#if CONFIG_TEST_EVENT_TRIGGER_ENABLED && CONFIG_ENABLE_OTA_REQUESTOR +#if CONFIG_TEST_EVENT_TRIGGER_ENABLED static int hex_digit_to_int(char hex) { if ('A' <= hex && hex <= 'F') @@ -107,7 +107,7 @@ static size_t hex_string_to_binary(const char * hex_string, uint8_t * buf, size_ return buf_size; } -#endif // CONFIG_TEST_EVENT_TRIGGER_ENABLED && CONFIG_ENABLE_OTA_REQUESTOR +#endif // CONFIG_TEST_EVENT_TRIGGER_ENABLED void Esp32AppServer::DeInitBLEIfCommissioned(void) { @@ -158,7 +158,7 @@ void Esp32AppServer::Init(AppDelegate * sAppDelegate) { // Init ZCL Data Model and CHIP App Server static chip::CommonCaseDeviceServerInitParams initParams; -#if CONFIG_TEST_EVENT_TRIGGER_ENABLED && CONFIG_ENABLE_OTA_REQUESTOR +#if CONFIG_TEST_EVENT_TRIGGER_ENABLED if (hex_string_to_binary(CONFIG_TEST_EVENT_TRIGGER_ENABLE_KEY, sTestEventTriggerEnableKey, sizeof(sTestEventTriggerEnableKey)) == 0) { @@ -166,9 +166,11 @@ void Esp32AppServer::Init(AppDelegate * sAppDelegate) memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); } static SimpleTestEventTriggerDelegate sTestEventTriggerDelegate{}; - static OTATestEventTriggerHandler sOtaTestEventTriggerHandler{}; VerifyOrDie(sTestEventTriggerDelegate.Init(ByteSpan(sTestEventTriggerEnableKey)) == CHIP_NO_ERROR); +#if CONFIG_ENABLE_OTA_REQUESTOR + static OTATestEventTriggerHandler sOtaTestEventTriggerHandler{}; VerifyOrDie(sTestEventTriggerDelegate.AddHandler(&sOtaTestEventTriggerHandler) == CHIP_NO_ERROR); +#endif initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; #endif // CONFIG_TEST_EVENT_TRIGGER_ENABLED && CONFIG_ENABLE_OTA_REQUESTOR (void) initParams.InitializeStaticResourcesBeforeServerInit(); From fd7aff5665befae001ab542e2ab33beffc76b242 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Thu, 18 Apr 2024 11:42:58 +0000 Subject: [PATCH 2/5] Restyled by clang-format --- examples/lit-icd-app/esp32/main/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lit-icd-app/esp32/main/main.cpp b/examples/lit-icd-app/esp32/main/main.cpp index 735055be1468c0..f92effa0538c3d 100644 --- a/examples/lit-icd-app/esp32/main/main.cpp +++ b/examples/lit-icd-app/esp32/main/main.cpp @@ -81,7 +81,7 @@ extern const char TAG[] = "lit-icd-app"; static AppDeviceCallbacks EchoCallbacks; -static void UatButtonHandler(UatButton *button) +static void UatButtonHandler(UatButton * button) { DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { Server::GetInstance().GetICDManager().UpdateOperationState(app::ICDManager::OperationalState::ActiveMode); From 446f04b8856036aee460fcd383eff607cdf8439b Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Fri, 19 Apr 2024 15:24:21 +0800 Subject: [PATCH 3/5] Add some review changes --- examples/lit-icd-app/esp32/main/IcdUatButton.cpp | 1 - examples/lit-icd-app/esp32/main/main.cpp | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/lit-icd-app/esp32/main/IcdUatButton.cpp b/examples/lit-icd-app/esp32/main/IcdUatButton.cpp index ab791b77958415..b45b17c634b877 100644 --- a/examples/lit-icd-app/esp32/main/IcdUatButton.cpp +++ b/examples/lit-icd-app/esp32/main/IcdUatButton.cpp @@ -24,7 +24,6 @@ #include "freertos/queue.h" #include "freertos/task.h" #include "hal/gpio_types.h" -#include "soc/gpio_num.h" #include #define ESP_INTR_FLAG_DEFAULT 0 diff --git a/examples/lit-icd-app/esp32/main/main.cpp b/examples/lit-icd-app/esp32/main/main.cpp index f92effa0538c3d..a1666caa6417e4 100644 --- a/examples/lit-icd-app/esp32/main/main.cpp +++ b/examples/lit-icd-app/esp32/main/main.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ +#include "app/icd/server/ICDNotifier.h" #include "esp_log.h" #include "esp_netif.h" #include "esp_system.h" @@ -84,7 +85,7 @@ static AppDeviceCallbacks EchoCallbacks; static void UatButtonHandler(UatButton * button) { DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { - Server::GetInstance().GetICDManager().UpdateOperationState(app::ICDManager::OperationalState::ActiveMode); + app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); }); } From 1c18b87b878db2e470077deadea61f35dee31f89 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Fri, 19 Apr 2024 07:25:07 +0000 Subject: [PATCH 4/5] Restyled by clang-format --- examples/lit-icd-app/esp32/main/main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/lit-icd-app/esp32/main/main.cpp b/examples/lit-icd-app/esp32/main/main.cpp index a1666caa6417e4..4bb736b219eabd 100644 --- a/examples/lit-icd-app/esp32/main/main.cpp +++ b/examples/lit-icd-app/esp32/main/main.cpp @@ -84,9 +84,7 @@ static AppDeviceCallbacks EchoCallbacks; static void UatButtonHandler(UatButton * button) { - DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { - app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); - }); + DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); }); } static void InitServer(intptr_t context) From 432f688365b93a6ddfeb78ec295e06653619d2bf Mon Sep 17 00:00:00 2001 From: WanqQixiang Date: Mon, 22 Apr 2024 15:16:33 +0800 Subject: [PATCH 5/5] fix compile error --- examples/lit-icd-app/esp32/main/include/IcdUatButton.h | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/lit-icd-app/esp32/main/include/IcdUatButton.h b/examples/lit-icd-app/esp32/main/include/IcdUatButton.h index 92f90daf0e1a06..2104d1a7c4079d 100644 --- a/examples/lit-icd-app/esp32/main/include/IcdUatButton.h +++ b/examples/lit-icd-app/esp32/main/include/IcdUatButton.h @@ -22,7 +22,6 @@ #include #include #include -#include class UatButton {