Skip to content

Commit

Permalink
Add M5Stack specific builds for esp32 light (#25550)
Browse files Browse the repository at this point in the history
* Enable builds for m5stack for more apps as m5stack and devkitc are the same MCU except screen support -i.e. defaults should work

* start adding some compile options for ESP32 display ... still made a TODO for actual integration

* Enable m5stack in Kconfig

* Things compile now

* Restyle

* Remove demo items

* Add more config variables to get displays working

* Cleanup unused widgets, add callbacks for the wifi one

* Make wifi green

* Cleanup device with display: no more virtual devices

* Restyle

* Remove unnedded log

* Remove unused variable

* Remove useless commment in QRCodeScreen.h

* Remove one more useless coment

* Update examples/lighting-app/esp32/main/Button.cpp

Co-authored-by: Cliff Chung <[email protected]>

* Update examples/lighting-app/esp32/main/DeviceWithDisplay.cpp

Co-authored-by: Cliff Chung <[email protected]>

* Update examples/lighting-app/esp32/main/Globals.cpp

Co-authored-by: Cliff Chung <[email protected]>

* Update examples/lighting-app/esp32/main/StatusScreen.cpp

Co-authored-by: Cliff Chung <[email protected]>

* Update copyright dates and remove a bunch of @file comments

* Move ifdefs around

* Remove useless button.h comments

* Move ifdefs a bit - HAVE_DISPLAY is a result of a header

---------

Co-authored-by: Andrei Litvin <[email protected]>
Co-authored-by: Cliff Chung <[email protected]>
  • Loading branch information
3 people authored and pull[bot] committed Oct 15, 2023
1 parent c1b553a commit 1483282
Show file tree
Hide file tree
Showing 26 changed files with 1,099 additions and 81 deletions.
12 changes: 2 additions & 10 deletions examples/common/screen-framework/Display.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2020-2023 Project CHIP Authors
* Copyright (c) 2018 Nest Labs, Inc.
* All rights reserved.
*
Expand All @@ -16,14 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @file Display.cpp
*
* This file implements helper APIs for the M5Stack's display
*
*/

#include <string.h>

#include "driver/ledc.h"
Expand Down Expand Up @@ -54,7 +46,7 @@
// The M5Stack's backlight is on Channel 7
#define BACKLIGHT_CHANNEL LEDC_CHANNEL_7

extern const char * TAG;
static const char * TAG = "Display";

uint16_t DisplayHeight = 0;
uint16_t DisplayWidth = 0;
Expand Down
8 changes: 7 additions & 1 deletion examples/lighting-app/esp32/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2021 Project CHIP Authors
# Copyright (c) 2021-2023 Project CHIP Authors
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -29,6 +29,12 @@ set(EXTRA_COMPONENT_DIRS
"${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/examples/common/QRCode"
)

if(${IDF_TARGET} STREQUAL "esp32")
list(APPEND EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/examples/common/m5stack-tft/repo/components/tft"
"${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/examples/common/m5stack-tft/repo/components/spidriver"
"${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/examples/common/screen-framework")
endif()

project(chip-lighting-app)

# C++17 is required for RPC build.
Expand Down
62 changes: 50 additions & 12 deletions examples/lighting-app/esp32/main/AppTask.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
* Copyright (c) 2022-2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -20,6 +20,8 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"

#include "DeviceWithDisplay.h"

#include <app-common/zap-generated/attributes/Accessors.h>

#define APP_TASK_NAME "APP"
Expand All @@ -36,7 +38,6 @@ using namespace ::chip::DeviceLayer;
static const char * TAG = "app-task";

LEDWidget AppLED;
Button AppButton;

namespace {
constexpr EndpointId kLightEndpointId = 1;
Expand All @@ -61,14 +62,59 @@ CHIP_ERROR AppTask::StartAppTask()
return (xReturned == pdPASS) ? CHIP_NO_ERROR : APP_ERROR_CREATE_TASK_FAILED;
}

void AppTask::ButtonEventHandler(const uint8_t buttonHandle, uint8_t btnAction)
{
if (btnAction != APP_BUTTON_PRESSED)
{
return;
}

AppEvent button_event = {};
button_event.Type = AppEvent::kEventType_Button;

#if CONFIG_HAVE_DISPLAY
button_event.ButtonEvent.PinNo = buttonHandle;
button_event.ButtonEvent.Action = btnAction;
button_event.mHandler = ButtonPressedAction;
#else
button_event.mHandler = AppTask::LightingActionEventHandler;
#endif

sAppTask.PostEvent(&button_event);
}

#if CONFIG_DEVICE_TYPE_M5STACK
void AppTask::ButtonPressedAction(AppEvent * aEvent)
{
uint32_t io_num = aEvent->ButtonEvent.PinNo;
int level = gpio_get_level((gpio_num_t) io_num);
if (level == 0)
{
bool woken = WakeDisplay();
if (woken)
{
return;
}
// Button 1 is connected to the pin 39
// Button 2 is connected to the pin 38
// Button 3 is connected to the pin 37
// So we use 40 - io_num to map the pin number to button number
ScreenManager::ButtonPressed(40 - io_num);
}
}
#endif

CHIP_ERROR AppTask::Init()
{
CHIP_ERROR err = CHIP_NO_ERROR;

AppLED.Init();
AppButton.Init();

AppButton.SetButtonPressCallback(ButtonPressCallback);
#if CONFIG_HAVE_DISPLAY
InitDeviceDisplay();

AppLED.SetVLED(ScreenManager::AddVLED(TFT_YELLOW));
#endif

return err;
}
Expand Down Expand Up @@ -139,14 +185,6 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent)
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, "Writing to OnOff cluster");
Expand Down
93 changes: 68 additions & 25 deletions examples/lighting-app/esp32/main/Button.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
* Copyright (c) 2022-2023 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.
Expand All @@ -14,53 +15,95 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "driver/gpio.h"
#include "esp_check.h"
#include "esp_log.h"
#include "esp_system.h"

#include "AppTask.h"
#include "Button.h"
#include "esp_attr.h"
#include "Globals.h"
#include "ScreenManager.h"
#include <lib/support/CodeUtils.h>
#include <platform/CHIPDeviceLayer.h>
#include <vector>

#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.cpp";

static const char * TAG = "Button";
extern Button gButtons[BUTTON_NUMBER];

static Button::ButtonPressCallback button_press_handler = nullptr;
Button::Button() {}

static void IRAM_ATTR gpio_isr_handler(void * arg)
Button::Button(gpio_num_t gpioNum)
{
if (button_press_handler != nullptr)
mGPIONum = gpioNum;
}

int32_t Find_Button_Via_Pin(gpio_num_t gpioNum)
{
for (int i = 0; i < BUTTON_NUMBER; i++)
{
button_press_handler();
if (gButtons[i].GetGPIONum() == gpioNum)
{
return i;
}
}
return -1;
}

void Button::Init()
void IRAM_ATTR button_isr_handler(void * arg)
{
/* Initialize button interrupt*/
// zero-initialize the config structure.
uint32_t gpio_num = (uint32_t) arg;
int32_t idx = Find_Button_Via_Pin((gpio_num_t) gpio_num);
if (idx == -1)
{
return;
}
BaseType_t taskWoken = pdFALSE;
xTimerStartFromISR(gButtons[idx].mbuttonTimer,
&taskWoken); // If the timer had already been started ,restart it will reset its expiry time
}

esp_err_t Button::Init()
{
return Init(mGPIONum);
}

esp_err_t Button::Init(gpio_num_t gpioNum)
{
esp_err_t ret = ESP_OK;

mGPIONum = gpioNum;
// zero-initialize the config structure.
gpio_config_t io_conf = {};
// interrupt of rising edge
// interrupt of falling 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;
io_conf.pin_bit_mask = 1ULL << gpioNum;
// 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);
ret = gpio_isr_handler_add(gpioNum, button_isr_handler, (void *) gpioNum);
ESP_RETURN_ON_ERROR(ret, TAG, "gpio_isr_handler_add failed: %s", esp_err_to_name(ret));

ESP_LOGI(TAG, "Button initialized..");
}
mbuttonTimer = xTimerCreate("BtnTmr", // Just a text name, not used by the RTOS kernel
pdMS_TO_TICKS(50), // timer period
false, // no timer reload (==one-shot)
(void *) (int) gpioNum, // init timer id = gpioNum index
TimerCallback // timer callback handler (all buttons use
// the same timer cn function)
);

void Button::SetButtonPressCallback(ButtonPressCallback button_callback)
return ESP_OK;
}
void Button::TimerCallback(TimerHandle_t xTimer)
{
if (button_callback != nullptr)
{
button_press_handler = button_callback;
}
// Get the button index of the expired timer and call button event Handler.
uint32_t gpio_num = (uint32_t) pvTimerGetTimerID(xTimer);
GetAppTask().ButtonEventHandler(gpio_num, APP_BUTTON_PRESSED);
}
6 changes: 5 additions & 1 deletion examples/lighting-app/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2021 Project CHIP Authors
# Copyright (c) 2021-2023 Project CHIP Authors
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -85,6 +85,10 @@ set(SRC_DIRS_LIST "${SRC_DIRS_LIST}"
)
endif (CONFIG_ENABLE_PW_RPC)

if ("${CONFIG_DEVICE_TYPE_M5STACK}" STREQUAL "y")
list(APPEND PRIV_REQUIRES_LIST tft screen-framework)
endif()

idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST}
SRC_DIRS ${SRC_DIRS_LIST}
PRIV_REQUIRES ${PRIV_REQUIRES_LIST})
Expand Down
21 changes: 12 additions & 9 deletions examples/lighting-app/esp32/main/DeviceCallbacks.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
* Copyright (c) 2021-2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -15,17 +15,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @file DeviceCallbacks.cpp
*
* Implements all the callbacks to the application from the CHIP Stack
*
**/

#include "AppTask.h"

#include "DeviceCallbacks.h"
#include "Globals.h"
#include "LEDWidget.h"

#include <app/util/util.h>
Expand Down Expand Up @@ -147,3 +140,13 @@ void emberAfOnOffClusterInitCallback(EndpointId endpoint)
ESP_LOGI(TAG, "emberAfOnOffClusterInitCallback");
GetAppTask().UpdateClusterState();
}

void AppDeviceCallbacksDelegate::OnIPv4ConnectivityEstablished()
{
wifiLED.Set(true);
}

void AppDeviceCallbacksDelegate::OnIPv4ConnectivityLost()
{
wifiLED.Set(false);
}
Loading

0 comments on commit 1483282

Please sign in to comment.