diff --git a/esphome/components/esp32_m5stack_core_s3/__init__.py b/esphome/components/esp32_m5stack_core_s3/__init__.py index 0652f80..909176b 100644 --- a/esphome/components/esp32_m5stack_core_s3/__init__.py +++ b/esphome/components/esp32_m5stack_core_s3/__init__.py @@ -1,14 +1,16 @@ """M5-Stack Core S3 Component.""" import esphome.codegen as cg +from esphome import pins from esphome.components import i2c +from esphome.components import touchscreen import esphome.config_validation as cv -from esphome.const import CONF_ID +from esphome.const import CONF_ID, CONF_INTERRUPT_PIN from ..aw9523 import AW9523Component CODEOWNERS = ["@gnumpi"] -DEPENDENCIES = ["i2c", "aw9523"] +DEPENDENCIES = ["i2c", "aw9523", "touchscreen"] m5stack_ns = cg.esphome_ns.namespace("m5stack") M5StackCoreS3 = m5stack_ns.class_("M5StackCoreS3", i2c.I2CDevice, cg.Component) @@ -16,6 +18,7 @@ CONF_AW9523 = "aw9523" CONF_USB_OTG_EN = "usb_otg_en" CONF_BUS_OUT_EN = "bus_out_en" +CONF_TOUCHSCREEN = "touchscreen" CONFIG_SCHEMA = cv.Schema( { @@ -23,6 +26,10 @@ cv.Optional(CONF_AW9523): cv.use_id(AW9523Component), cv.Optional(CONF_USB_OTG_EN, default=False): cv.boolean, cv.Optional(CONF_BUS_OUT_EN, default=False): cv.boolean, + cv.Optional(CONF_INTERRUPT_PIN): cv.All( + pins.internal_gpio_input_pin_schema + ), + cv.Optional(CONF_TOUCHSCREEN): cv.use_id(touchscreen.Touchscreen), } ).extend(i2c.i2c_device_schema(0x36)) @@ -36,3 +43,9 @@ async def to_code(config): cg.add(var.set_aw9523(aw9523)) cg.add(var.set_usb_otg_en(config[CONF_USB_OTG_EN])) cg.add(var.set_bus_out_en(config[CONF_BUS_OUT_EN])) + if CONF_INTERRUPT_PIN in config: + interrupt_pin = await cg.gpio_pin_expression(config[CONF_INTERRUPT_PIN]) + cg.add(var.set_interrupt_pin(interrupt_pin)) + if CONF_TOUCHSCREEN in config: + touchscreen = await cg.get_variable(config[CONF_TOUCHSCREEN]) + cg.add(var.set_touchscreen(touchscreen)) diff --git a/esphome/components/esp32_m5stack_core_s3/m5stack_core_s3.cpp b/esphome/components/esp32_m5stack_core_s3/m5stack_core_s3.cpp index 3478a17..ca9a510 100644 --- a/esphome/components/esp32_m5stack_core_s3/m5stack_core_s3.cpp +++ b/esphome/components/esp32_m5stack_core_s3/m5stack_core_s3.cpp @@ -169,6 +169,22 @@ void M5StackCoreS3::setup(){ aw9523.reg(0x12) = 0b11111111; // LEDMODE_P0 aw9523.reg(0x13) = 0b11111111; // LEDMODE_P1 + if (this->interrupt_pin_ != nullptr) { + this->store_.trigger_ = false; + this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP); + this->interrupt_pin_->setup(); + this->store_.interrupt_pin_ = this->interrupt_pin_->to_isr(); + this->interrupt_pin_->attach_interrupt(M5StackCoreS3Store::aw9523_intr, &this->store_, gpio::INTERRUPT_ANY_EDGE); + if (this->touchscreen_ != nullptr) { + this->touchscreen_->setup_external_interrupt(); + } + } + aw9523.reg(0x06) = 0b11111111; // INT_P0 + aw9523.reg(0x07) = 0b11111011; // INT_P1 + uint8_t p0 = aw9523.reg(0x00).get(); // Clear INT_P0 + uint8_t p1 = aw9523.reg(0x01).get(); // Clear INT_P1 + + if(this->aw9523_ != nullptr){ this->write_bus_out_en(this->bus_out_en_); this->write_usb_otg_en(this->usb_otg_en_); @@ -183,6 +199,28 @@ void M5StackCoreS3::write_bus_out_en(bool flag){ this->aw9523_->set_pin_value( AW9523Port::PORT_0, 1, flag); } +void IRAM_ATTR M5StackCoreS3Store::aw9523_intr(M5StackCoreS3Store *arg) { + arg->trigger_ = true; +} + +void IRAM_ATTR M5StackCoreS3::loop() { + if (this->store_.trigger_) { + { + InterruptLock lock; + this->store_.trigger_ = false; + } + i2c::I2CDevice aw9523; + aw9523.set_i2c_bus( this->bus_); + aw9523.set_i2c_address(0x58); + uint8_t p0 = aw9523.reg(0x00).get(); + uint8_t p1 = aw9523.reg(0x01).get(); + bool touch_irq = ((p1 & 0b00000100) >> 2) == 1; + if (touch_irq && this->touchscreen_ != nullptr) { + this->touchscreen_->trigger_external_interrupt(); + this->touchscreen_->loop(); + } + } +} } diff --git a/esphome/components/esp32_m5stack_core_s3/m5stack_core_s3.h b/esphome/components/esp32_m5stack_core_s3/m5stack_core_s3.h index a3d8e9c..1160a68 100644 --- a/esphome/components/esp32_m5stack_core_s3/m5stack_core_s3.h +++ b/esphome/components/esp32_m5stack_core_s3/m5stack_core_s3.h @@ -1,6 +1,7 @@ #pragma once #include "esphome/components/i2c/i2c.h" +#include "esphome/components/touchscreen/touchscreen.h" #include "esphome/core/component.h" #include "../aw9523/aw9523.h" @@ -9,9 +10,17 @@ namespace m5stack { class AXP2101Component; +struct M5StackCoreS3Store { + ISRInternalGPIOPin interrupt_pin_; + bool trigger_; + + static void aw9523_intr(M5StackCoreS3Store *arg); +}; + class M5StackCoreS3 : public i2c::I2CDevice, public Component { public: void setup() override; + void loop() override; void dump_config() override {}; float get_setup_priority() const override { return setup_priority::DATA; }; @@ -26,9 +35,15 @@ class M5StackCoreS3 : public i2c::I2CDevice, public Component { void set_usb_otg_en(bool flag){this->usb_otg_en_ = flag;} void set_bus_out_en(bool flag){this->bus_out_en_ = flag;} + void set_interrupt_pin(InternalGPIOPin *pin) { this->interrupt_pin_ = pin; } + void set_touchscreen(touchscreen::Touchscreen *touchscreen) { touchscreen_ = touchscreen; } + protected: + M5StackCoreS3Store store_{}; AXP2101Component* axp2101_{nullptr}; aw9523::AW9523Component* aw9523_{nullptr}; + InternalGPIOPin *interrupt_pin_{nullptr}; + touchscreen::Touchscreen *touchscreen_{nullptr}; bool usb_otg_en_{false}; bool bus_out_en_{false};