-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds BOOT button as switch to toggle LED (#19496)
* Adds BOOt button as switch to toggle LED * Restyled by whitespace Co-authored-by: Restyled.io <[email protected]>
- Loading branch information
Showing
9 changed files
with
435 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
/* | ||
* | ||
* Copyright (c) 2022 Project CHIP Authors | ||
* All rights reserved. | ||
* | ||
* 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 "AppTask.h" | ||
#include "esp_log.h" | ||
#include "freertos/FreeRTOS.h" | ||
|
||
#include <app-common/zap-generated/attribute-id.h> | ||
#include <app-common/zap-generated/attribute-type.h> | ||
#include <app-common/zap-generated/attributes/Accessors.h> | ||
#include <app-common/zap-generated/cluster-id.h> | ||
|
||
#define APP_TASK_NAME "APP" | ||
#define APP_EVENT_QUEUE_SIZE 10 | ||
#define APP_TASK_STACK_SIZE (3072) | ||
#define BUTTON_PRESSED 1 | ||
#define APP_LIGHT_SWITCH 1 | ||
|
||
using namespace ::chip; | ||
using namespace ::chip::app; | ||
using namespace ::chip::Credentials; | ||
using namespace ::chip::DeviceLayer; | ||
|
||
static const char * TAG = "app-task"; | ||
|
||
LEDWidget AppLED; | ||
Button AppButton; | ||
|
||
namespace { | ||
constexpr EndpointId kLightEndpointId = 1; | ||
QueueHandle_t sAppEventQueue; | ||
TaskHandle_t sAppTaskHandle; | ||
|
||
} // namespace | ||
|
||
AppTask AppTask::sAppTask; | ||
|
||
CHIP_ERROR AppTask::StartAppTask() | ||
{ | ||
sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); | ||
if (sAppEventQueue == NULL) | ||
{ | ||
ESP_LOGE(TAG, "Failed to allocate app event queue"); | ||
return APP_ERROR_EVENT_QUEUE_FAILED; | ||
} | ||
|
||
// Start App task. | ||
BaseType_t xReturned; | ||
xReturned = xTaskCreate(AppTaskMain, APP_TASK_NAME, APP_TASK_STACK_SIZE, NULL, 1, &sAppTaskHandle); | ||
return (xReturned == pdPASS) ? CHIP_NO_ERROR : APP_ERROR_CREATE_TASK_FAILED; | ||
} | ||
|
||
CHIP_ERROR AppTask::Init() | ||
{ | ||
CHIP_ERROR err = CHIP_NO_ERROR; | ||
|
||
AppLED.Init(); | ||
AppButton.Init(); | ||
|
||
AppButton.SetButtonPressCallback(ButtonPressCallback); | ||
|
||
return err; | ||
} | ||
|
||
void AppTask::AppTaskMain(void * pvParameter) | ||
{ | ||
AppEvent event; | ||
CHIP_ERROR err = sAppTask.Init(); | ||
if (err != CHIP_NO_ERROR) | ||
{ | ||
ESP_LOGI(TAG, "AppTask.Init() failed due to %" CHIP_ERROR_FORMAT, err.Format()); | ||
return; | ||
} | ||
|
||
ESP_LOGI(TAG, "App Task started"); | ||
|
||
while (true) | ||
{ | ||
BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, pdMS_TO_TICKS(10)); | ||
while (eventReceived == pdTRUE) | ||
{ | ||
sAppTask.DispatchEvent(&event); | ||
eventReceived = xQueueReceive(sAppEventQueue, &event, 0); // return immediately if the queue is empty | ||
} | ||
} | ||
} | ||
|
||
void AppTask::PostEvent(const AppEvent * aEvent) | ||
{ | ||
if (sAppEventQueue != NULL) | ||
{ | ||
BaseType_t status; | ||
if (xPortInIsrContext()) | ||
{ | ||
BaseType_t higherPrioTaskWoken = pdFALSE; | ||
status = xQueueSendFromISR(sAppEventQueue, aEvent, &higherPrioTaskWoken); | ||
} | ||
else | ||
{ | ||
status = xQueueSend(sAppEventQueue, aEvent, 1); | ||
} | ||
if (!status) | ||
ESP_LOGE(TAG, "Failed to post event to app task event queue"); | ||
} | ||
else | ||
{ | ||
ESP_LOGE(TAG, "Event Queue is NULL should never happen"); | ||
} | ||
} | ||
|
||
void AppTask::DispatchEvent(AppEvent * aEvent) | ||
{ | ||
if (aEvent->mHandler) | ||
{ | ||
aEvent->mHandler(aEvent); | ||
} | ||
else | ||
{ | ||
ESP_LOGI(TAG, "Event received with no handler. Dropping event."); | ||
} | ||
} | ||
|
||
void AppTask::LightingActionEventHandler(AppEvent * aEvent) | ||
{ | ||
AppLED.Toggle(); | ||
chip::DeviceLayer::PlatformMgr().LockChipStack(); | ||
sAppTask.UpdateClusterState(); | ||
chip::DeviceLayer::PlatformMgr().UnlockChipStack(); | ||
} | ||
|
||
void AppTask::ButtonPressCallback() | ||
{ | ||
AppEvent button_event; | ||
button_event.Type = AppEvent::kEventType_Button; | ||
button_event.mHandler = AppTask::LightingActionEventHandler; | ||
sAppTask.PostEvent(&button_event); | ||
} | ||
|
||
void AppTask::UpdateClusterState() | ||
{ | ||
ESP_LOGI(TAG, "Writting to OnOff cluster"); | ||
// write the new on/off value | ||
EmberAfStatus status = Clusters::OnOff::Attributes::OnOff::Set(kLightEndpointId, AppLED.IsTurnedOn()); | ||
|
||
if (status != EMBER_ZCL_STATUS_SUCCESS) | ||
{ | ||
ESP_LOGE(TAG, "Updating on/off cluster failed: %x", status); | ||
} | ||
|
||
ESP_LOGE(TAG, "Writting to Current Level cluster"); | ||
status = Clusters::LevelControl::Attributes::CurrentLevel::Set(kLightEndpointId, AppLED.GetLevel()); | ||
|
||
if (status != EMBER_ZCL_STATUS_SUCCESS) | ||
{ | ||
ESP_LOGE(TAG, "Updating level cluster failed: %x", status); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#include "Button.h" | ||
|
||
#define GPIO_INPUT_IO_0 9 | ||
#define GPIO_INPUT_PIN_SEL (1ULL << GPIO_INPUT_IO_0) | ||
#define ESP_INTR_FLAG_DEFAULT 0 | ||
|
||
static const char * TAG = "Button"; | ||
|
||
static Button::ButtonPressCallback button_press_handler = nullptr; | ||
|
||
static void IRAM_ATTR gpio_isr_handler(void * arg) | ||
{ | ||
if (button_press_handler != nullptr) | ||
{ | ||
button_press_handler(); | ||
} | ||
} | ||
|
||
void Button::Init() | ||
{ | ||
/* Initialize button interrupt*/ | ||
// zero-initialize the config structure. | ||
gpio_config_t io_conf = {}; | ||
// interrupt of rising edge | ||
io_conf.intr_type = GPIO_INTR_NEGEDGE; | ||
// bit mask of the pins, use GPIO4/5 here | ||
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL; | ||
// set as input mode | ||
io_conf.mode = GPIO_MODE_INPUT; | ||
// enable pull-up mode | ||
io_conf.pull_up_en = GPIO_PULLUP_ENABLE; | ||
gpio_config(&io_conf); | ||
|
||
// install gpio isr service | ||
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); | ||
// hook isr handler for specific gpio pin | ||
gpio_isr_handler_add(static_cast<gpio_num_t>(GPIO_INPUT_IO_0), gpio_isr_handler, (void *) GPIO_INPUT_IO_0); | ||
|
||
ESP_LOGI(TAG, "Button initialized.."); | ||
} | ||
|
||
void Button::SetButtonPressCallback(ButtonPressCallback button_callback) | ||
{ | ||
if (button_callback != nullptr) | ||
{ | ||
button_press_handler = button_callback; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* | ||
* Copyright (c) 2022 Project CHIP Authors | ||
* All rights reserved. | ||
* | ||
* 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 | ||
|
||
struct AppEvent; | ||
typedef void (*EventHandler)(AppEvent *); | ||
|
||
struct AppEvent | ||
{ | ||
enum AppEventTypes | ||
{ | ||
kEventType_Button = 0, | ||
kEventType_Timer, | ||
kEventType_Light, | ||
kEventType_Install, | ||
}; | ||
|
||
uint16_t Type; | ||
|
||
union | ||
{ | ||
struct | ||
{ | ||
uint8_t Action; | ||
} ButtonEvent; | ||
struct | ||
{ | ||
void * Context; | ||
} TimerEvent; | ||
struct | ||
{ | ||
uint8_t Action; | ||
int32_t Actor; | ||
} LightEvent; | ||
}; | ||
|
||
EventHandler mHandler; | ||
}; |
Oops, something went wrong.