Skip to content

Commit 168581c

Browse files
authored
Merge branch 'master' into AA/mDNSnlunit
2 parents 9c73702 + a860932 commit 168581c

File tree

4 files changed

+229
-5
lines changed

4 files changed

+229
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
*
3+
* Copyright (c) 2024 Project CHIP Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "IcdUatButton.h"
19+
20+
#include "driver/gpio.h"
21+
#include "esp_attr.h"
22+
#include "esp_log.h"
23+
#include "freertos/FreeRTOS.h"
24+
#include "freertos/queue.h"
25+
#include "freertos/task.h"
26+
#include "hal/gpio_types.h"
27+
#include <cstdint>
28+
29+
#define ESP_INTR_FLAG_DEFAULT 0
30+
31+
static const char TAG[] = "Button";
32+
QueueHandle_t UatButton::sEventQueue = nullptr;
33+
TaskHandle_t UatButton::sTaskHandle = nullptr;
34+
35+
static void IRAM_ATTR gpio_isr_handler(void * arg)
36+
{
37+
if (UatButton::sEventQueue)
38+
{
39+
UatButton * button = (UatButton *) arg;
40+
button->GpioIntrEnable(false);
41+
xQueueSendFromISR(UatButton::sEventQueue, &button, NULL);
42+
}
43+
}
44+
45+
void UatButton::RunEventLoop(void * arg)
46+
{
47+
bool eventDone = true;
48+
UatButton * button = nullptr;
49+
50+
for (;;)
51+
{
52+
if (xQueueReceive(sEventQueue, &button, portMAX_DELAY) == pdTRUE && button)
53+
{
54+
button->GpioIntrEnable(false);
55+
eventDone = false;
56+
}
57+
while (!eventDone)
58+
{
59+
// GPIO Pull up is enabled so the button is pressed when this value is false.
60+
bool value = gpio_get_level(button->mGpioNum);
61+
switch (button->mState)
62+
{
63+
case ButtonState::kIdle:
64+
button->mState = value == false ? ButtonState::kPressed : ButtonState::kIdle;
65+
break;
66+
case ButtonState::kPressed:
67+
button->mState = value == false ? ButtonState::kPressed : ButtonState::kReleased;
68+
break;
69+
case ButtonState::kReleased:
70+
button->mState = ButtonState::kIdle;
71+
if (button->mUatButtonPressCallback)
72+
{
73+
button->mUatButtonPressCallback(button);
74+
}
75+
break;
76+
default:
77+
break;
78+
}
79+
if (button->mState == ButtonState::kIdle)
80+
{
81+
button->GpioIntrEnable(true);
82+
eventDone = true;
83+
break;
84+
}
85+
vTaskDelay(10 / portTICK_PERIOD_MS);
86+
}
87+
}
88+
}
89+
90+
void UatButton::GpioIntrEnable(bool enable)
91+
{
92+
if (enable)
93+
{
94+
gpio_intr_enable(mGpioNum);
95+
}
96+
else
97+
{
98+
gpio_intr_disable(mGpioNum);
99+
}
100+
}
101+
102+
void UatButton::Init(gpio_num_t gpioNum, esp_sleep_ext1_wakeup_mode_t wakeupMode)
103+
{
104+
mGpioNum = gpioNum;
105+
mState = ButtonState::kIdle;
106+
gpio_config_t io_conf = {};
107+
io_conf.intr_type = GPIO_INTR_LOW_LEVEL;
108+
io_conf.pin_bit_mask = (1ULL << static_cast<uint8_t>(mGpioNum));
109+
io_conf.mode = GPIO_MODE_INPUT;
110+
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
111+
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
112+
// configure GPIO with the given settings
113+
gpio_config(&io_conf);
114+
if (!sEventQueue)
115+
{
116+
// create a queue to handle gpio event from isr
117+
sEventQueue = xQueueCreate(10, sizeof(UatButton *));
118+
if (!sEventQueue)
119+
{
120+
ESP_LOGE(TAG, "Failed to create GPIO EventQueue");
121+
return;
122+
}
123+
}
124+
if (!sTaskHandle)
125+
{
126+
// start gpio task
127+
xTaskCreate(RunEventLoop, "UatButton", 4096, nullptr, 10, &sTaskHandle);
128+
if (!sTaskHandle)
129+
{
130+
ESP_LOGE(TAG, "Failed to create GPIO Task");
131+
return;
132+
}
133+
}
134+
// install gpio isr service
135+
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
136+
// hook isr handler for specific gpio pin
137+
gpio_isr_handler_add(mGpioNum, gpio_isr_handler, (void *) this);
138+
ESP_LOGI(TAG, "UAT Button initialized..");
139+
// Configure RTC IO wake up
140+
esp_sleep_enable_ext1_wakeup(1ULL << static_cast<uint8_t>(mGpioNum), wakeupMode);
141+
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
142+
rtc_gpio_pulldown_dis(mGpioNum);
143+
rtc_gpio_pullup_en(mGpioNum);
144+
#else
145+
gpio_pulldown_dis(mGpioNum);
146+
gpio_pullup_en(mGpioNum);
147+
#endif
148+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
*
3+
* Copyright (c) 2024 Project CHIP Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#pragma once
19+
20+
#include <driver/gpio.h>
21+
#include <esp_sleep.h>
22+
#include <freertos/FreeRTOS.h>
23+
#include <freertos/queue.h>
24+
#include <freertos/task.h>
25+
26+
class UatButton
27+
{
28+
public:
29+
using UatButtonPressCallback = void (*)(UatButton *);
30+
31+
enum class ButtonState : uint8_t
32+
{
33+
kIdle = 0,
34+
kPressed,
35+
kReleased,
36+
};
37+
38+
void Init(gpio_num_t gpioNum, esp_sleep_ext1_wakeup_mode_t wakeMode);
39+
void SetUatButtonPressCallback(UatButtonPressCallback buttonCallback) { mUatButtonPressCallback = buttonCallback; }
40+
void GpioIntrEnable(bool enable);
41+
42+
static void RunEventLoop(void * arg);
43+
static TaskHandle_t sTaskHandle;
44+
static QueueHandle_t sEventQueue;
45+
46+
private:
47+
gpio_num_t mGpioNum;
48+
ButtonState mState;
49+
UatButtonPressCallback mUatButtonPressCallback;
50+
};

examples/lit-icd-app/esp32/main/main.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18+
#include "app/icd/server/ICDNotifier.h"
1819
#include "esp_log.h"
1920
#include "esp_netif.h"
2021
#include "esp_system.h"
@@ -24,13 +25,16 @@
2425
#include "nvs_flash.h"
2526

2627
#include <DeviceCallbacks.h>
28+
#include <IcdUatButton.h>
29+
#include <app/icd/server/ICDManager.h>
2730
#include <app/server/Server.h>
2831
#include <common/CHIPDeviceManager.h>
2932
#include <common/Esp32AppServer.h>
3033
#include <common/Esp32ThreadInit.h>
3134
#include <credentials/DeviceAttestationCredsProvider.h>
3235
#include <credentials/examples/DeviceAttestationCredsExample.h>
3336
#include <platform/ESP32/ESP32Utils.h>
37+
#include <platform/PlatformManager.h>
3438

3539
#if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
3640
#include <platform/ESP32/ESP32FactoryDataProvider.h>
@@ -58,6 +62,18 @@ chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
5862
#error "Currently this example only support Thread chips"
5963
#endif
6064

65+
#ifdef CONFIG_IDF_TARGET_ESP32H2
66+
// GPIO9-GPIO14 could be used to wake up ESP32-H2.
67+
// For ESP32-H2 DevKitM, the boot button is GPIO9.
68+
#define UAT_GPIO GPIO_NUM_9
69+
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
70+
// GPIO0-GPIO7 could be used to wake up ESP32-C6.
71+
// For ESP32-C6 DevKitC, the boot button is GPIO9, we cannot use it to wake up the chip.
72+
#define UAT_GPIO GPIO_NUM_7
73+
#else
74+
#error "Unsupport IDF target"
75+
#endif
76+
6177
using namespace ::chip;
6278
using namespace ::chip::DeviceManager;
6379
using namespace ::chip::Credentials;
@@ -66,6 +82,11 @@ extern const char TAG[] = "lit-icd-app";
6682

6783
static AppDeviceCallbacks EchoCallbacks;
6884

85+
static void UatButtonHandler(UatButton * button)
86+
{
87+
DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { app::ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); });
88+
}
89+
6990
static void InitServer(intptr_t context)
7091
{
7192
Esp32AppServer::Init(); // Init ZCL Data Model and CHIP App Server AND Initialize device attestation config
@@ -110,6 +131,9 @@ extern "C" void app_main()
110131
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
111132
#endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER
112133
ESPOpenThreadInit();
134+
static UatButton sButton;
135+
sButton.Init(UAT_GPIO, ESP_EXT1_WAKEUP_ANY_LOW);
136+
sButton.SetUatButtonPressCallback(UatButtonHandler);
113137

114138
chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer, reinterpret_cast<intptr_t>(nullptr));
115139
}

examples/platform/esp32/common/Esp32AppServer.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ static app::Clusters::NetworkCommissioning::Instance
6161
sEthernetNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::ESPEthernetDriver::GetInstance()));
6262
#endif
6363

64-
#if CONFIG_TEST_EVENT_TRIGGER_ENABLED && CONFIG_ENABLE_OTA_REQUESTOR
64+
#if CONFIG_TEST_EVENT_TRIGGER_ENABLED
6565
static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
6666
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
6767
0xcc, 0xdd, 0xee, 0xff };
6868
#endif
6969
} // namespace
7070

71-
#if CONFIG_TEST_EVENT_TRIGGER_ENABLED && CONFIG_ENABLE_OTA_REQUESTOR
71+
#if CONFIG_TEST_EVENT_TRIGGER_ENABLED
7272
static int hex_digit_to_int(char hex)
7373
{
7474
if ('A' <= hex && hex <= 'F')
@@ -107,7 +107,7 @@ static size_t hex_string_to_binary(const char * hex_string, uint8_t * buf, size_
107107

108108
return buf_size;
109109
}
110-
#endif // CONFIG_TEST_EVENT_TRIGGER_ENABLED && CONFIG_ENABLE_OTA_REQUESTOR
110+
#endif // CONFIG_TEST_EVENT_TRIGGER_ENABLED
111111

112112
void Esp32AppServer::DeInitBLEIfCommissioned(void)
113113
{
@@ -158,17 +158,19 @@ void Esp32AppServer::Init(AppDelegate * sAppDelegate)
158158
{
159159
// Init ZCL Data Model and CHIP App Server
160160
static chip::CommonCaseDeviceServerInitParams initParams;
161-
#if CONFIG_TEST_EVENT_TRIGGER_ENABLED && CONFIG_ENABLE_OTA_REQUESTOR
161+
#if CONFIG_TEST_EVENT_TRIGGER_ENABLED
162162
if (hex_string_to_binary(CONFIG_TEST_EVENT_TRIGGER_ENABLE_KEY, sTestEventTriggerEnableKey,
163163
sizeof(sTestEventTriggerEnableKey)) == 0)
164164
{
165165
ESP_LOGE(TAG, "Failed to convert the EnableKey string to octstr type value");
166166
memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey));
167167
}
168168
static SimpleTestEventTriggerDelegate sTestEventTriggerDelegate{};
169-
static OTATestEventTriggerHandler sOtaTestEventTriggerHandler{};
170169
VerifyOrDie(sTestEventTriggerDelegate.Init(ByteSpan(sTestEventTriggerEnableKey)) == CHIP_NO_ERROR);
170+
#if CONFIG_ENABLE_OTA_REQUESTOR
171+
static OTATestEventTriggerHandler sOtaTestEventTriggerHandler{};
171172
VerifyOrDie(sTestEventTriggerDelegate.AddHandler(&sOtaTestEventTriggerHandler) == CHIP_NO_ERROR);
173+
#endif
172174
initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate;
173175
#endif // CONFIG_TEST_EVENT_TRIGGER_ENABLED && CONFIG_ENABLE_OTA_REQUESTOR
174176
(void) initParams.InitializeStaticResourcesBeforeServerInit();

0 commit comments

Comments
 (0)