#pragma once #include "Tactility/hal/touch/TouchDevice.h" #include "Tactility/hal/touch/TouchDriver.h" #include "lvgl.h" #include #include #include #ifndef TFT_WIDTH #define TFT_WIDTH 240 #endif #ifndef TFT_HEIGHT #define TFT_HEIGHT 320 #endif struct Point { int x; int y; }; class Xpt2046SoftSpi : public tt::hal::touch::TouchDevice { public: class Configuration { public: Configuration( gpio_num_t mosiPin, gpio_num_t misoPin, gpio_num_t clkPin, gpio_num_t csPin, uint16_t xMax = TFT_WIDTH, uint16_t yMax = TFT_HEIGHT, bool swapXy = false, bool mirrorX = false, bool mirrorY = false ) : mosiPin(mosiPin), misoPin(misoPin), clkPin(clkPin), csPin(csPin), xMax(xMax), yMax(yMax), swapXy(swapXy), mirrorX(mirrorX), mirrorY(mirrorY) {} gpio_num_t mosiPin; gpio_num_t misoPin; gpio_num_t clkPin; gpio_num_t csPin; uint16_t xMax; uint16_t yMax; bool swapXy; bool mirrorX; bool mirrorY; }; private: class Xpt2046SoftSpiDriver final : public tt::hal::touch::TouchDriver { Xpt2046SoftSpi* device; public: Xpt2046SoftSpiDriver(Xpt2046SoftSpi* device) : device(device) {} bool getTouchedPoints(uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* pointCount, uint8_t maxPointCount) override { Point point; if (device->isTouched() && device->getTouchPoint(point)) { *x = point.x; *y = point.y; *pointCount = 1; return true; } else { *pointCount = 0; return false; } } }; std::unique_ptr configuration; lv_indev_t* lvglDevice = nullptr; std::shared_ptr touchDriver; int readSPI(uint8_t command); bool loadCalibration(); void saveCalibration(); static void touchReadCallback(lv_indev_t* indev, lv_indev_data_t* data); public: explicit Xpt2046SoftSpi(std::unique_ptr inConfiguration); // TouchDevice interface std::string getName() const final { return "Xpt2046SoftSpi"; } std::string getDescription() const final { return "Xpt2046 Soft SPI touch driver"; } bool start() override; bool stop() override; bool supportsLvgl() const override { return true; } bool startLvgl(lv_display_t* display) override; bool stopLvgl() override; bool supportsTouchDriver() override { return true; } std::shared_ptr getTouchDriver() override; lv_indev_t* getLvglIndev() override { return lvglDevice; } // XPT2046-specific methods bool getTouchPoint(Point& point); void calibrate(); void setCalibration(int xMin, int yMin, int xMax, int yMax); bool isTouched(); };