diff --git a/src/input/TouchScreenCST226SE.cpp b/src/input/TouchScreenCST226SE.cpp new file mode 100644 index 000000000..3151797c2 --- /dev/null +++ b/src/input/TouchScreenCST226SE.cpp @@ -0,0 +1,103 @@ +#include "TouchScreenCST226SE.h" +#include "variant.h" + +#ifdef HAS_CST226SE + +#include "PowerFSM.h" +#include "Wire.h" +#include "configuration.h" +#include "modules/ExternalNotificationModule.h" + +volatile bool CST_IRQ = false; + +TouchScreenCST226SE *touchScreenCST226SE; + +TouchScreenCST226SE::TouchScreenCST226SE(uint16_t width, uint16_t height, bool (*getTouch)(int16_t *, int16_t *)) + : TouchScreenBase("touchscreen1", width, height), _getTouch(getTouch) +{ +} + +void TouchScreenCST226SE::init() +{ + for (uint8_t addr : PossibleAddresses) { + if (touch.begin(Wire, addr, I2C_SDA, I2C_SCL)) { + i2cAddress = addr; + +#ifdef TOUCHSCREEN_INT + pinMode(TOUCHSCREEN_INT, INPUT); + attachInterrupt( + TOUCHSCREEN_INT, [] { CST_IRQ = true; }, RISING); +#endif + + LOG_DEBUG("CST226SE init OK at address 0x%02X", addr); + return; + } + } + + LOG_ERROR("CST226SE init failed at all known addresses"); +} + +bool TouchScreenCST226SE::getTouch(int16_t &x, int16_t &y) +{ + if (!touch.isPressed()) + return false; + + int16_t x_array[1], y_array[1]; + uint8_t count = touch.getPoint(x_array, y_array, 1); + if (count > 0) { + x = x_array[0]; + y = y_array[0]; + return true; + } + + return false; +} + +void TouchScreenCST226SE::onEvent(const TouchEvent &event) +{ + InputEvent e; + e.source = event.source; + + e.touchX = event.x; + e.touchY = event.y; + + switch (event.touchEvent) { + case TOUCH_ACTION_LEFT: { + e.inputEvent = static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT); + break; + } + case TOUCH_ACTION_RIGHT: { + e.inputEvent = static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT); + break; + } + case TOUCH_ACTION_UP: { + e.inputEvent = static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP); + break; + } + case TOUCH_ACTION_DOWN: { + e.inputEvent = static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN); + break; + } + case TOUCH_ACTION_DOUBLE_TAP: { + e.inputEvent = static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT); + break; + } + case TOUCH_ACTION_LONG_PRESS: { + e.inputEvent = static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL); + break; + } + case TOUCH_ACTION_TAP: { + if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) { + externalNotificationModule->stopNow(); + } else { + powerFSM.trigger(EVENT_INPUT); + } + break; + } + default: + return; + } + this->notifyObservers(&e); +} + +#endif \ No newline at end of file diff --git a/src/input/TouchScreenCST226SE.h b/src/input/TouchScreenCST226SE.h new file mode 100644 index 000000000..71d037724 --- /dev/null +++ b/src/input/TouchScreenCST226SE.h @@ -0,0 +1,32 @@ +#pragma once + +#include "variant.h" + +#ifdef HAS_CST226SE + +#include "TouchScreenBase.h" +#include "touch/TouchClassCST226.h" + +class TouchScreenCST226SE : public TouchScreenBase +{ + public: + TouchScreenCST226SE(uint16_t width, uint16_t height, bool (*getTouch)(int16_t *, int16_t *)); + void init(void); + + protected: + virtual bool getTouch(int16_t &x, int16_t &y); + virtual void onEvent(const TouchEvent &event); + + bool (*_getTouch)(int16_t *, int16_t *); + + private: + TouchClassCST226 touch; + uint8_t i2cAddress = 0; + + static constexpr uint8_t PossibleAddresses[2] = {CST226SE_ADDR, CST226SE_ADDR_ALT}; +}; + +// For global reference in other code +extern TouchScreenCST226SE *touchScreenCST226SE; + +#endif \ No newline at end of file diff --git a/variants/tbeam/variant.h b/variants/tbeam/variant.h index 4c89bd2be..04801e678 100644 --- a/variants/tbeam/variant.h +++ b/variants/tbeam/variant.h @@ -51,8 +51,9 @@ #undef LED_STATE_ON #undef LED_PIN +#define HAS_CST226SE 1 #define HAS_TOUCHSCREEN 1 -#define SCREEN_TOUCH_INT 35 +#define TOUCHSCREEN_INT 35 #define ST7796_NSS 25 #define ST7796_RS 13 // DC