diff --git a/Drivers/AXP2101/CMakeLists.txt b/Drivers/AXP2101/CMakeLists.txt deleted file mode 100644 index 8074f3b38..000000000 --- a/Drivers/AXP2101/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility -) diff --git a/Drivers/AXP2101/README.md b/Drivers/AXP2101/README.md deleted file mode 100644 index bda3c583c..000000000 --- a/Drivers/AXP2101/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# AXP2101 - -Power management with I2C interface: a single cell NVDC PMU with E-gauge. - -- [Datasheet](http://file.whycan.com/files/members/6736/AXP2101_Datasheet_V1.0_en_3832.pdf) -- [M5Unified implementation](https://github.com/m5stack/M5Unified/blob/master/src/utility/AXP2101_Class.cpp) diff --git a/Drivers/AXP2101/Source/Axp2101.cpp b/Drivers/AXP2101/Source/Axp2101.cpp deleted file mode 100644 index 8f78252c2..000000000 --- a/Drivers/AXP2101/Source/Axp2101.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "Axp2101.h" - -bool Axp2101::getBatteryVoltage(float& vbatMillis) const { - return readRegister14(0x34, vbatMillis); -} - -bool Axp2101::getChargeStatus(ChargeStatus& status) const { - uint8_t value; - if (readRegister8(0x01, value)) { - value = (value >> 5) & 0b11; - status = (value == 1) ? CHARGE_STATUS_CHARGING : ((value == 2) ? CHARGE_STATUS_DISCHARGING : CHARGE_STATUS_STANDBY); - return true; - } else { - return false; - } -} - -bool Axp2101::isChargingEnabled(bool& enabled) const { - uint8_t value; - if (readRegister8(0x18, value)) { - enabled = value & 0b10; - return true; - } else { - return false; - } -} - -bool Axp2101::setChargingEnabled(bool enabled) const { - uint8_t value; - if (readRegister8(0x18, value)) { - return writeRegister8(0x18, (value & 0xFD) | (enabled << 1)); - } else { - return false; - } -} - -bool Axp2101::isVBus() const { - uint8_t value; - return readRegister8(0x00, value) && (value & 0x20); -} - -bool Axp2101::getVBusVoltage(float& out) const { - if (!isVBus()) { - return false; - } else { - float vbus; - if (readRegister14(0x38, vbus) && vbus < 16375) { - out = vbus / 1000.0f; - return true; - } else { - return false; - } - } -} - -bool Axp2101::setRegisters(uint8_t* bytePairs, size_t bytePairsSize) const { - return i2c_controller_write_register_array(controller, address, bytePairs, bytePairsSize, DEFAULT_TIMEOUT) == ERROR_NONE; -} diff --git a/Drivers/AXP2101/Source/Axp2101.h b/Drivers/AXP2101/Source/Axp2101.h deleted file mode 100644 index e6f63e5b0..000000000 --- a/Drivers/AXP2101/Source/Axp2101.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include - -#define AXP2101_ADDRESS 0x34 - -/** - * References: - * - https://github.com/m5stack/M5Unified/blob/master/src/utility/AXP2101_Class.cpp - * - http://file.whycan.com/files/members/6736/AXP2101_Datasheet_V1.0_en_3832.pdf - */ -class Axp2101 final : public tt::hal::i2c::I2cDevice { - -public: - - enum ChargeStatus { - CHARGE_STATUS_CHARGING = 0b01, - CHARGE_STATUS_DISCHARGING = 0b10, - CHARGE_STATUS_STANDBY = 0b00 - }; - - explicit Axp2101(::Device* controller) : I2cDevice(controller, AXP2101_ADDRESS) {} - - std::string getName() const override { return "AXP2101"; } - std::string getDescription() const override { return "Power management with I2C interface."; } - - bool setRegisters(uint8_t* bytePairs, size_t bytePairsSize) const; - - bool getBatteryVoltage(float& vbatMillis) const; - bool getChargeStatus(ChargeStatus& status) const; - bool isChargingEnabled(bool& enabled) const; - bool setChargingEnabled(bool enabled) const; - - bool isVBus() const; - bool getVBusVoltage(float& out) const; -}; diff --git a/Drivers/AXP2101/Source/Axp2101Power.cpp b/Drivers/AXP2101/Source/Axp2101Power.cpp deleted file mode 100644 index 48dc52986..000000000 --- a/Drivers/AXP2101/Source/Axp2101Power.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "Axp2101Power.h" - -bool Axp2101Power::supportsMetric(MetricType type) const { - switch (type) { - using enum MetricType; - case BatteryVoltage: - case IsCharging: - case ChargeLevel: - return true; - default: - return false; - } - - return false; // Safety guard for when new enum values are introduced -} - -bool Axp2101Power::getMetric(MetricType type, MetricData& data) { - switch (type) { - using enum MetricType; - case BatteryVoltage: { - float milliVolt; - if (axpDevice->getBatteryVoltage(milliVolt)) { - data.valueAsUint32 = (uint32_t)milliVolt; - return true; - } else { - return false; - } - } - case ChargeLevel: { - float vbatMillis; - if (axpDevice->getBatteryVoltage(vbatMillis)) { - float vbat = vbatMillis / 1000.f; - float max_voltage = 4.20f; - float min_voltage = 2.69f; // From M5Unified - if (vbat > 2.69f) { - float charge_factor = (vbat - min_voltage) / (max_voltage - min_voltage); - data.valueAsUint8 = (uint8_t)(charge_factor * 100.f); - } else { - data.valueAsUint8 = 0; - } - return true; - } else { - return false; - } - } - case IsCharging: { - Axp2101::ChargeStatus status; - if (axpDevice->getChargeStatus(status)) { - data.valueAsBool = (status == Axp2101::CHARGE_STATUS_CHARGING); - return true; - } else { - return false; - } - } - default: - return false; - } -} - -bool Axp2101Power::isAllowedToCharge() const { - bool enabled; - if (axpDevice->isChargingEnabled(enabled)) { - return enabled; - } else { - return false; - } -} - -void Axp2101Power::setAllowedToCharge(bool canCharge) { - axpDevice->setChargingEnabled(canCharge); -} diff --git a/Drivers/AXP2101/Source/Axp2101Power.h b/Drivers/AXP2101/Source/Axp2101Power.h deleted file mode 100644 index 56303a8a2..000000000 --- a/Drivers/AXP2101/Source/Axp2101Power.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include "Tactility/hal/power/PowerDevice.h" -#include -#include -#include - -using tt::hal::power::PowerDevice; - -class Axp2101Power final : public PowerDevice { - - std::shared_ptr axpDevice; - -public: - - explicit Axp2101Power(std::shared_ptr axp) : axpDevice(std::move(axp)) {} - ~Axp2101Power() override = default; - - std::string getName() const override { return "AXP2101 Power"; } - std::string getDescription() const override { return "Power management via AXP2101 over I2C"; } - - bool supportsMetric(MetricType type) const override; - bool getMetric(MetricType type, MetricData& data) override; - - bool supportsChargeControl() const override { return true; } - bool isAllowedToCharge() const override; - void setAllowedToCharge(bool canCharge) override; -}; diff --git a/Drivers/ButtonControl/CMakeLists.txt b/Drivers/ButtonControl/CMakeLists.txt deleted file mode 100644 index 811725f25..000000000 --- a/Drivers/ButtonControl/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -file(GLOB_RECURSE SOURCE_FILES Source/*.c*) - -idf_component_register( - SRCS ${SOURCE_FILES} - INCLUDE_DIRS "Source" - REQUIRES Tactility esp_lvgl_port driver -) diff --git a/Drivers/ButtonControl/README.md b/Drivers/ButtonControl/README.md deleted file mode 100644 index dbe50b1b2..000000000 --- a/Drivers/ButtonControl/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Button Control - -A driver for navigating apps with 1 or more GPIO buttons. \ No newline at end of file diff --git a/Drivers/ButtonControl/Source/ButtonControl.cpp b/Drivers/ButtonControl/Source/ButtonControl.cpp deleted file mode 100644 index 02a69635b..000000000 --- a/Drivers/ButtonControl/Source/ButtonControl.cpp +++ /dev/null @@ -1,222 +0,0 @@ -#include "ButtonControl.h" - -#include -#include - -#include - -constexpr auto* TAG = "ButtonControl"; - -ButtonControl::ButtonControl(const std::vector& pinConfigurations) - : buttonQueue(20, sizeof(ButtonEvent)), - pinConfigurations(pinConfigurations) { - - pinStates.resize(pinConfigurations.size()); - - // Build isrArgs with one entry per unique physical pin, then configure GPIO. - isrArgs.reserve(pinConfigurations.size()); - for (size_t i = 0; i < pinConfigurations.size(); i++) { - const auto pin = static_cast(pinConfigurations[i].pin); - - // Skip if this physical pin was already seen. - bool seen = false; - for (const auto& arg : isrArgs) { - if (arg.pin == pin) { seen = true; break; } - } - if (seen) continue; - - gpio_config_t io_conf = { - .pin_bit_mask = 1ULL << pin, - .mode = GPIO_MODE_INPUT, - .pull_up_en = GPIO_PULLUP_DISABLE, - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .intr_type = GPIO_INTR_ANYEDGE, - }; - esp_err_t err = gpio_config(&io_conf); - if (err != ESP_OK) { - LOG_E(TAG, "Failed to configure GPIO %d: %s", static_cast(pin), esp_err_to_name(err)); - continue; - } - - // isrArgs is reserved upfront; push_back will not reallocate, keeping addresses stable - // for gpio_isr_handler_add() called later in startThread(). - isrArgs.push_back({ .self = this, .pin = pin }); - } -} - -ButtonControl::~ButtonControl() { - if (driverThread != nullptr && driverThread->getState() != tt::Thread::State::Stopped) { - stopThread(); - } -} - -void ButtonControl::readCallback(lv_indev_t* indev, lv_indev_data_t* data) { - // Defaults - data->enc_diff = 0; - data->state = LV_INDEV_STATE_RELEASED; - - auto* self = static_cast(lv_indev_get_driver_data(indev)); - - if (self->mutex.lock(100)) { - - for (int i = 0; i < self->pinConfigurations.size(); i++) { - const auto& config = self->pinConfigurations[i]; - std::vector::reference state = self->pinStates[i]; - const bool trigger = (config.event == Event::ShortPress && state.triggerShortPress) || - (config.event == Event::LongPress && state.triggerLongPress); - state.triggerShortPress = false; - state.triggerLongPress = false; - if (trigger) { - switch (config.action) { - case Action::UiSelectNext: - data->enc_diff = 1; - break; - case Action::UiSelectPrevious: - data->enc_diff = -1; - break; - case Action::UiPressSelected: - data->state = LV_INDEV_STATE_PRESSED; - break; - case Action::AppClose: - tt::app::stop(); - break; - } - } - } - self->mutex.unlock(); - } -} - -void ButtonControl::updatePin(std::vector::const_reference configuration, std::vector::reference state, bool pressed) { - auto now = tt::kernel::getMillis(); - - // Software debounce: ignore edges within 20ms of the last state change. - if ((now - state.lastChangeTime) < 20) { - return; - } - state.lastChangeTime = now; - - if (pressed) { - state.pressStartTime = now; - state.pressState = true; - } else { // released - if (state.pressState) { - auto time_passed = now - state.pressStartTime; - if (time_passed < 500) { - LOG_I(TAG, "Short press (%dms)", (int)time_passed); - state.triggerShortPress = true; - } else { - LOG_I(TAG, "Long press (%dms)", (int)time_passed); - state.triggerLongPress = true; - } - state.pressState = false; - } - } -} - -void IRAM_ATTR ButtonControl::gpioIsrHandler(void* arg) { - auto* isrArg = static_cast(arg); - ButtonEvent event { - .pin = isrArg->pin, - .pressed = gpio_get_level(isrArg->pin) == 0, // active-low: LOW = pressed - }; - // tt::MessageQueue::put() is ISR-safe with timeout=0: it detects ISR context via - // xPortInIsrContext() and uses xQueueSendFromISR() + portYIELD_FROM_ISR() internally. - isrArg->self->buttonQueue.put(&event, 0); -} - -void ButtonControl::driverThreadMain() { - ButtonEvent event; - while (buttonQueue.get(&event, portMAX_DELAY)) { - if (event.pin == GPIO_NUM_NC) { - break; // shutdown sentinel - } - LOG_I(TAG, "Pin %d %s", static_cast(event.pin), event.pressed ? "down" : "up"); - if (mutex.lock(portMAX_DELAY)) { - // Update ALL PinConfiguration entries that share this physical pin. - for (size_t i = 0; i < pinConfigurations.size(); i++) { - if (static_cast(pinConfigurations[i].pin) == event.pin) { - updatePin(pinConfigurations[i], pinStates[i], event.pressed); - } - } - mutex.unlock(); - } - } -} - -bool ButtonControl::startThread() { - LOG_I(TAG, "Start"); - - esp_err_t err = gpio_install_isr_service(ESP_INTR_FLAG_IRAM); - if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { - LOG_E(TAG, "Failed to install GPIO ISR service: %s", esp_err_to_name(err)); - return false; - } - - // isrArgs has one entry per unique physical pin — no duplicate registrations. - // Addresses are stable: vector was reserved in constructor and is not modified after that. - int handlersAdded = 0; - for (auto& arg : isrArgs) { - err = gpio_isr_handler_add(arg.pin, gpioIsrHandler, &arg); - if (err != ESP_OK) { - LOG_E(TAG, "Failed to add ISR for GPIO %d: %s", static_cast(arg.pin), esp_err_to_name(err)); - for (int i = 0; i < handlersAdded; i++) { - gpio_isr_handler_remove(isrArgs[i].pin); - } - return false; - } - handlersAdded++; - } - - driverThread = std::make_shared("ButtonControl", 4096, [this] { - driverThreadMain(); - return 0; - }); - - driverThread->start(); - return true; -} - -void ButtonControl::stopThread() { - LOG_I(TAG, "Stop"); - - for (const auto& arg : isrArgs) { - gpio_isr_handler_remove(arg.pin); - } - - ButtonEvent sentinel { .pin = GPIO_NUM_NC, .pressed = false }; - buttonQueue.put(&sentinel, portMAX_DELAY); - - driverThread->join(); - driverThread = nullptr; -} - -bool ButtonControl::startLvgl(lv_display_t* display) { - if (deviceHandle != nullptr) { - return false; - } - - if (!startThread()) { - return false; - } - - deviceHandle = lv_indev_create(); - lv_indev_set_type(deviceHandle, LV_INDEV_TYPE_ENCODER); - lv_indev_set_driver_data(deviceHandle, this); - lv_indev_set_read_cb(deviceHandle, readCallback); - - return true; -} - -bool ButtonControl::stopLvgl() { - if (deviceHandle == nullptr) { - return false; - } - - lv_indev_delete(deviceHandle); - deviceHandle = nullptr; - - stopThread(); - - return true; -} diff --git a/Drivers/ButtonControl/Source/ButtonControl.h b/Drivers/ButtonControl/Source/ButtonControl.h deleted file mode 100644 index 053cdf91b..000000000 --- a/Drivers/ButtonControl/Source/ButtonControl.h +++ /dev/null @@ -1,127 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include - -class ButtonControl final : public tt::hal::encoder::EncoderDevice { - -public: - - enum class Event { - ShortPress, - LongPress - }; - - enum class Action { - UiSelectNext, - UiSelectPrevious, - UiPressSelected, - AppClose, - }; - - struct PinConfiguration { - tt::hal::gpio::Pin pin; - Event event; - Action action; - }; - -private: - - struct PinState { - long pressStartTime = 0; - long lastChangeTime = 0; - bool pressState = false; - bool triggerShortPress = false; - bool triggerLongPress = false; - }; - - /** Queued from ISR to worker thread. pin == GPIO_NUM_NC is a shutdown sentinel. */ - struct ButtonEvent { - gpio_num_t pin; - bool pressed; - }; - - /** One entry per unique physical pin; addresses must remain stable after construction. */ - struct IsrArg { - ButtonControl* self; - gpio_num_t pin; - }; - - lv_indev_t* deviceHandle = nullptr; - std::shared_ptr driverThread; - tt::Mutex mutex; - tt::MessageQueue buttonQueue; - std::vector pinConfigurations; - std::vector pinStates; - std::vector isrArgs; // one entry per unique physical pin - - static void updatePin(std::vector::const_reference config, std::vector::reference state, bool pressed); - - void driverThreadMain(); - - static void readCallback(lv_indev_t* indev, lv_indev_data_t* data); - - static void IRAM_ATTR gpioIsrHandler(void* arg); - - bool startThread(); - void stopThread(); - -public: - - explicit ButtonControl(const std::vector& pinConfigurations); - - ~ButtonControl() override; - - std::string getName() const override { return "ButtonControl"; } - std::string getDescription() const override { return "ButtonControl input driver"; } - - bool startLvgl(lv_display_t* display) override; - bool stopLvgl() override; - - /** Could return nullptr if not started */ - lv_indev_t* getLvglIndev() override { return deviceHandle; } - - static std::shared_ptr createOneButtonControl(tt::hal::gpio::Pin pin) { - return std::make_shared(std::vector { - PinConfiguration { - .pin = pin, - .event = Event::ShortPress, - .action = Action::UiSelectNext - }, - PinConfiguration { - .pin = pin, - .event = Event::LongPress, - .action = Action::UiPressSelected - } - }); - } - - static std::shared_ptr createTwoButtonControl(tt::hal::gpio::Pin primaryPin, tt::hal::gpio::Pin secondaryPin) { - return std::make_shared(std::vector { - PinConfiguration { - .pin = primaryPin, - .event = Event::ShortPress, - .action = Action::UiPressSelected - }, - PinConfiguration { - .pin = primaryPin, - .event = Event::LongPress, - .action = Action::AppClose - }, - PinConfiguration { - .pin = secondaryPin, - .event = Event::ShortPress, - .action = Action::UiSelectNext - }, - PinConfiguration { - .pin = secondaryPin, - .event = Event::LongPress, - .action = Action::UiSelectPrevious - } - }); - } -}; diff --git a/Drivers/CST816S/CMakeLists.txt b/Drivers/CST816S/CMakeLists.txt deleted file mode 100644 index 108babc48..000000000 --- a/Drivers/CST816S/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility EspLcdCompat esp_lcd_touch_cst816s driver -) diff --git a/Drivers/CST816S/README.md b/Drivers/CST816S/README.md deleted file mode 100644 index 4a21e0948..000000000 --- a/Drivers/CST816S/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# CST816S - -I2C touch driver for Tactility \ No newline at end of file diff --git a/Drivers/CST816S/Source/Cst816Touch.h b/Drivers/CST816S/Source/Cst816Touch.h deleted file mode 100644 index 67a0f1a0c..000000000 --- a/Drivers/CST816S/Source/Cst816Touch.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include - -class Cst816sTouch final : public EspLcdTouch { - -public: - - class Configuration { - public: - - Configuration( - i2c_port_t port, - uint16_t xMax, - uint16_t yMax, - bool swapXy = false, - bool mirrorX = false, - bool mirrorY = false, - gpio_num_t pinReset = GPIO_NUM_NC, - gpio_num_t pinInterrupt = GPIO_NUM_NC, - unsigned int pinResetLevel = 0, - unsigned int pinInterruptLevel = 0 - ) : port(port), - xMax(xMax), - yMax(yMax), - swapXY(swapXy), - mirrorX(mirrorX), - mirrorY(mirrorY), - pinReset(pinReset), - pinInterrupt(pinInterrupt), - pinResetLevel(pinResetLevel), - pinInterruptLevel(pinInterruptLevel) - {} - - i2c_port_t port; - uint16_t xMax; - uint16_t yMax; - bool swapXY; - bool mirrorX; - bool mirrorY; - gpio_num_t pinReset; - gpio_num_t pinInterrupt; - unsigned int pinResetLevel; - unsigned int pinInterruptLevel; - }; - -private: - - std::unique_ptr configuration; - esp_lcd_panel_io_handle_t ioHandle = nullptr; - esp_lcd_touch_handle_t touchHandle = nullptr; - lv_indev_t* deviceHandle = nullptr; - - void cleanup(); - - bool createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) override; - - bool createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& configuration, esp_lcd_touch_handle_t& touchHandle) override; - - esp_lcd_touch_config_t createEspLcdTouchConfig() override; - -public: - - explicit Cst816sTouch(std::unique_ptr inConfiguration) : configuration(std::move(inConfiguration)) { - assert(configuration != nullptr); - } - - std::string getName() const override { return "CST816S"; } - std::string getDescription() const override { return "CST816S I2C touch driver"; } -}; diff --git a/Drivers/CST816S/Source/Cst816sTouch.cpp b/Drivers/CST816S/Source/Cst816sTouch.cpp deleted file mode 100644 index a7088f4b6..000000000 --- a/Drivers/CST816S/Source/Cst816sTouch.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "Cst816Touch.h" - -#include - -bool Cst816sTouch::createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) { - constexpr esp_lcd_panel_io_i2c_config_t touch_io_config = ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG(); - return esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)configuration->port, &touch_io_config, &ioHandle) == ESP_OK; -} - -bool Cst816sTouch::createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& touchConfiguration, esp_lcd_touch_handle_t& touchHandle) { - return esp_lcd_touch_new_i2c_cst816s(ioHandle, &touchConfiguration, &touchHandle) == ESP_OK; -} - -esp_lcd_touch_config_t Cst816sTouch::createEspLcdTouchConfig() { - return { - .x_max = configuration->xMax, - .y_max = configuration->yMax, - .rst_gpio_num = configuration->pinReset, - .int_gpio_num = configuration->pinInterrupt, - .levels = { - .reset = configuration->pinResetLevel, - .interrupt = configuration->pinInterruptLevel, - }, - .flags = { - .swap_xy = configuration->swapXY, - .mirror_x = configuration->mirrorX, - .mirror_y = configuration->mirrorY, - }, - .process_coordinates = nullptr, - .interrupt_callback = nullptr, - .user_data = nullptr, - .driver_data = nullptr - }; -} diff --git a/Drivers/EPDiyDisplay/CMakeLists.txt b/Drivers/EPDiyDisplay/CMakeLists.txt deleted file mode 100644 index 559cb99b4..000000000 --- a/Drivers/EPDiyDisplay/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility epdiy esp_lvgl_port - PRIV_REQUIRES esp_timer -) diff --git a/Drivers/EPDiyDisplay/README.md b/Drivers/EPDiyDisplay/README.md deleted file mode 100644 index 5d53d805c..000000000 --- a/Drivers/EPDiyDisplay/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# EPDiy Display Driver - -A display driver for e-paper/e-ink displays using the EPDiy library. This driver provides LVGL integration and high-level display management for EPD panels. diff --git a/Drivers/EPDiyDisplay/Source/EpdiyDisplay.cpp b/Drivers/EPDiyDisplay/Source/EpdiyDisplay.cpp deleted file mode 100644 index bbe4af0e2..000000000 --- a/Drivers/EPDiyDisplay/Source/EpdiyDisplay.cpp +++ /dev/null @@ -1,472 +0,0 @@ -#include "EpdiyDisplay.h" - -#include -#include - -#include -#include - -constexpr const char* TAG = "EpdiyDisplay"; - -bool EpdiyDisplay::s_hlInitialized = false; -EpdiyHighlevelState EpdiyDisplay::s_hlState = {}; - -EpdiyDisplay::EpdiyDisplay(std::unique_ptr inConfiguration) - : configuration(std::move(inConfiguration)) { - check(configuration != nullptr); - check(configuration->board != nullptr); - check(configuration->display != nullptr); -} - -EpdiyDisplay::~EpdiyDisplay() { - if (lvglDisplay != nullptr) { - stopLvgl(); - } - if (initialized) { - stop(); - } -} - -bool EpdiyDisplay::start() { - if (initialized) { - LOG_W(TAG, "Already initialized"); - return true; - } - - // Initialize EPDiy low-level hardware - epd_init( - configuration->board, - configuration->display, - configuration->initOptions - ); - - // Set rotation BEFORE initializing highlevel state - epd_set_rotation(configuration->rotation); - LOG_I(TAG, "Display rotation set to %d", configuration->rotation); - - // Initialize the high-level API only once — epd_hl_init() sets a static flag internally - // and there is no matching epd_hl_deinit(). Reuse the existing state on subsequent starts. - if (!s_hlInitialized) { - s_hlState = epd_hl_init(configuration->waveform); - if (s_hlState.front_fb == nullptr) { - LOG_E(TAG, "Failed to initialize EPDiy highlevel state"); - epd_deinit(); - return false; - } - s_hlInitialized = true; - LOG_I(TAG, "EPDiy highlevel state initialized"); - } else { - LOG_I(TAG, "Reusing existing EPDiy highlevel state"); - } - - highlevelState = s_hlState; - framebuffer = epd_hl_get_framebuffer(&highlevelState); - - initialized = true; - LOG_I(TAG, "EPDiy initialized successfully (%dx%d native, %dx%d rotated)", epd_width(), epd_height(), epd_rotated_display_width(), epd_rotated_display_height()); - - // Perform initial clear to ensure clean state - LOG_I(TAG, "Performing initial screen clear..."); - clearScreen(); - LOG_I(TAG, "Screen cleared"); - - return true; -} - -bool EpdiyDisplay::stop() { - if (!initialized) { - return true; - } - - if (lvglDisplay != nullptr) { - stopLvgl(); - } - - // Power off the display - if (powered) { - setPowerOn(false); - } - - // Deinitialize EPDiy low-level hardware. - // The HL framebuffers (s_hlState) are intentionally kept alive: epd_hl_init() has no - // matching deinit and sets an internal already_initialized flag, so the HL state must - // persist across stop()/start() cycles and be reused on the next start(). - epd_deinit(); - - // Clear instance references to HL state (the static s_hlState still owns the memory) - highlevelState = {}; - framebuffer = nullptr; - - initialized = false; - LOG_I(TAG, "EPDiy deinitialized (HL state preserved for restart)"); - - return true; -} - -void EpdiyDisplay::setPowerOn(bool turnOn) { - if (!initialized) { - LOG_W(TAG, "Cannot change power state - EPD not initialized"); - return; - } - - if (powered == turnOn) { - return; - } - - if (turnOn) { - epd_poweron(); - powered = true; - LOG_D(TAG, "EPD power on"); - } else { - epd_poweroff(); - powered = false; - LOG_D(TAG, "EPD power off"); - } -} - -// LVGL functions -bool EpdiyDisplay::startLvgl() { - if (lvglDisplay != nullptr) { - LOG_W(TAG, "LVGL already initialized"); - return true; - } - - if (!initialized) { - LOG_E(TAG, "EPD not initialized, call start() first"); - return false; - } - - // Get the native display dimensions - uint16_t width = epd_width(); - uint16_t height = epd_height(); - - LOG_I(TAG, "Creating LVGL display: %dx%d (EPDiy rotation: %d)", width, height, configuration->rotation); - - // Create LVGL display with native dimensions - lvglDisplay = lv_display_create(width, height); - if (lvglDisplay == nullptr) { - LOG_E(TAG, "Failed to create LVGL display"); - return false; - } - - // EPD uses 4-bit grayscale (16 levels) - // Map to LVGL's L8 format (8-bit grayscale) - lv_display_set_color_format(lvglDisplay, LV_COLOR_FORMAT_L8); - auto lv_rotation = epdRotationToLvgl(configuration->rotation); - lv_display_set_rotation(lvglDisplay, lv_rotation); - - // Allocate LVGL draw buffer (L8 format: 1 byte per pixel) - size_t draw_buffer_size = static_cast(width) * height; - - lvglDrawBuffer = static_cast(heap_caps_malloc(draw_buffer_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT)); - if (lvglDrawBuffer == nullptr) { - LOG_W(TAG, "PSRAM allocation failed for draw buffer, falling back to internal memory"); - lvglDrawBuffer = static_cast(heap_caps_malloc(draw_buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL)); - } - - if (lvglDrawBuffer == nullptr) { - LOG_E(TAG, "Failed to allocate draw buffer"); - lv_display_delete(lvglDisplay); - lvglDisplay = nullptr; - return false; - } - - // Pre-allocate 4-bit packed pixel buffer used in flushInternal (avoids per-flush heap allocation) - // Row stride with odd-width padding: (width + 1) / 2 bytes per row - size_t packed_buffer_size = static_cast((width + 1) / 2) * static_cast(height); - packedBuffer = static_cast(heap_caps_malloc(packed_buffer_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT)); - if (packedBuffer == nullptr) { - LOG_W(TAG, "PSRAM allocation failed for packed buffer, falling back to internal memory"); - packedBuffer = static_cast(heap_caps_malloc(packed_buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL)); - } - - if (packedBuffer == nullptr) { - LOG_E(TAG, "Failed to allocate packed pixel buffer"); - heap_caps_free(lvglDrawBuffer); - lvglDrawBuffer = nullptr; - lv_display_delete(lvglDisplay); - lvglDisplay = nullptr; - return false; - } - - // For EPD, we want full refresh mode based on configuration - lv_display_render_mode_t render_mode = configuration->fullRefresh - ? LV_DISPLAY_RENDER_MODE_FULL - : LV_DISPLAY_RENDER_MODE_PARTIAL; - - lv_display_set_buffers(lvglDisplay, lvglDrawBuffer, NULL, draw_buffer_size, render_mode); - - // Set flush callback - lv_display_set_flush_cb(lvglDisplay, flushCallback); - lv_display_set_user_data(lvglDisplay, this); - - // Register rotation change event callback - lv_display_add_event_cb(lvglDisplay, rotationEventCallback, LV_EVENT_RESOLUTION_CHANGED, this); - LOG_D(TAG, "Registered rotation change event callback"); - - // Start touch device if present - auto touch_device = getTouchDevice(); - if (touch_device != nullptr && touch_device->supportsLvgl()) { - LOG_D(TAG, "Starting touch device for LVGL"); - if (!touch_device->startLvgl(lvglDisplay)) { - LOG_W(TAG, "Failed to start touch device for LVGL"); - } - } - - LOG_I(TAG, "LVGL display initialized"); - return true; -} - -bool EpdiyDisplay::stopLvgl() { - if (lvglDisplay == nullptr) { - return true; - } - - LOG_I(TAG, "Stopping LVGL display"); - - // Stop touch device - auto touch_device = getTouchDevice(); - if (touch_device != nullptr) { - touch_device->stopLvgl(); - } - - if (lvglDrawBuffer != nullptr) { - heap_caps_free(lvglDrawBuffer); - lvglDrawBuffer = nullptr; - } - - if (packedBuffer != nullptr) { - heap_caps_free(packedBuffer); - packedBuffer = nullptr; - } - - // Delete the LVGL display object - lv_display_delete(lvglDisplay); - lvglDisplay = nullptr; - - - LOG_I(TAG, "LVGL display stopped"); - return true; -} - -void EpdiyDisplay::flushCallback(lv_display_t* display, const lv_area_t* area, uint8_t* pixelMap) { - auto* instance = static_cast(lv_display_get_user_data(display)); - if (instance != nullptr) { - uint64_t t0 = esp_timer_get_time(); - const bool isLast = lv_display_flush_is_last(display); - instance->flushInternal(area, pixelMap, isLast); - LOG_D(TAG, "flush took %llu us", (unsigned long long)(esp_timer_get_time() - t0)); - } else { - LOG_W(TAG, "flush callback called with null instance"); - } - lv_display_flush_ready(display); -} - - -// EPD functions -void EpdiyDisplay::clearScreen() { - if (!initialized) { - LOG_E(TAG, "EPD not initialized"); - return; - } - - if (!powered) { - setPowerOn(true); - } - - epd_clear(); - - // Also clear the framebuffer - epd_hl_set_all_white(&highlevelState); -} - -void EpdiyDisplay::clearArea(EpdRect area) { - if (!initialized) { - LOG_E(TAG, "EPD not initialized"); - return; - } - - if (!powered) { - setPowerOn(true); - } - - epd_clear_area(area); -} - -enum EpdDrawError EpdiyDisplay::updateScreen(enum EpdDrawMode mode, int temperature) { - if (!initialized) { - LOG_E(TAG, "EPD not initialized"); - return EPD_DRAW_FAILED_ALLOC; - } - - if (!powered) { - setPowerOn(true); - } - - // Use defaults if not specified - if (mode == MODE_UNKNOWN_WAVEFORM) { - mode = configuration->defaultDrawMode; - } - if (temperature == -1) { - temperature = configuration->defaultTemperature; - } - - return epd_hl_update_screen(&highlevelState, mode, temperature); -} - -enum EpdDrawError EpdiyDisplay::updateArea(EpdRect area, enum EpdDrawMode mode, int temperature) { - if (!initialized) { - LOG_E(TAG, "EPD not initialized"); - return EPD_DRAW_FAILED_ALLOC; - } - - if (!powered) { - setPowerOn(true); - } - - // Use defaults if not specified - if (mode == MODE_UNKNOWN_WAVEFORM) { - mode = configuration->defaultDrawMode; - } - if (temperature == -1) { - temperature = configuration->defaultTemperature; - } - - return epd_hl_update_area(&highlevelState, mode, temperature, area); -} - -void EpdiyDisplay::setAllWhite() { - if (!initialized) { - LOG_E(TAG, "EPD not initialized"); - return; - } - - epd_hl_set_all_white(&highlevelState); -} - -// Internal functions -void EpdiyDisplay::flushInternal(const lv_area_t* area, uint8_t* pixelMap, bool isLast) { - if (!initialized) { - LOG_E(TAG, "Cannot flush - EPD not initialized"); - return; - } - - if (!powered) { - setPowerOn(true); - } - - const int x = area->x1; - const int y = area->y1; - const int width = lv_area_get_width(area); - const int height = lv_area_get_height(area); - - LOG_D(TAG, "Flushing area: x=%d, y=%d, w=%d, h=%d isLast=%d", x, y, width, height, (int)isLast); - - // Convert L8 (8-bit grayscale, 0=black/255=white) to EPDiy 4-bit (0=black/15=white). - // Pack 2 pixels per byte: lower nibble = even column, upper nibble = odd column. - // Row stride includes one padding nibble for odd widths to keep rows aligned. - // Threshold at 128 (matching FastEPD BB_MODE_1BPP): pixels > 127 → full white (15), - // pixels ≤ 127 → full black (0). Maximum contrast for the Mono theme and correct for - // MODE_DU which only drives two levels. For greyscale content / MODE_GL16, replace - // the threshold with `src[col] >> 4` to preserve intermediate grey levels. - const int row_stride = (width + 1) / 2; - for (int row = 0; row < height; ++row) { - const uint8_t* src = pixelMap + static_cast(row) * width; - uint8_t* dst = packedBuffer + static_cast(row) * row_stride; - for (int col = 0; col < width; col += 2) { - const uint8_t p0 = (src[col] > 127) ? 15u : 0u; - const uint8_t p1 = (col + 1 < width) ? ((src[col + 1] > 127) ? 15u : 0u) : 0u; - dst[col / 2] = static_cast((p1 << 4) | p0); - } - } - - const EpdRect update_area = { - .x = x, - .y = y, - .width = static_cast(width), - .height = static_cast(height) - }; - - // Write pixels into EPDiy's framebuffer (no hardware I/O, just memory) - epd_draw_rotated_image(update_area, packedBuffer, framebuffer); - - // Only trigger EPD hardware update on the last flush of this render cycle. - // EPDiy's epd_prep tasks run at configMAX_PRIORITIES-1 with busy-wait loops; calling - // epd_hl_update_area on every partial flush starves IDLE and triggers the task watchdog - // during scroll animations. Batching to one hardware update per LVGL render cycle fixes this. - if (isLast) { - epd_hl_update_screen( - &highlevelState, - static_cast(configuration->defaultDrawMode | MODE_PACKING_2PPB), - configuration->defaultTemperature - ); - } -} - -lv_display_rotation_t EpdiyDisplay::epdRotationToLvgl(enum EpdRotation epdRotation) { - // Static lookup table for EPD -> LVGL rotation mapping - // EPDiy: LANDSCAPE = 0°, PORTRAIT = 90° CW, INVERTED_LANDSCAPE = 180°, INVERTED_PORTRAIT = 270° CW - // LVGL: 0 = 0°, 90 = 90° CW, 180 = 180°, 270 = 270° CW - static const lv_display_rotation_t rotationMap[] = { - LV_DISPLAY_ROTATION_0, // EPD_ROT_LANDSCAPE (0) - LV_DISPLAY_ROTATION_270, // EPD_ROT_PORTRAIT (1) - 90° CW in EPD is 270° in LVGL - LV_DISPLAY_ROTATION_180, // EPD_ROT_INVERTED_LANDSCAPE (2) - LV_DISPLAY_ROTATION_90 // EPD_ROT_INVERTED_PORTRAIT (3) - 270° CW in EPD is 90° in LVGL - }; - - // Validate input and return mapped value - if (epdRotation >= 0 && epdRotation < 4) { - return rotationMap[epdRotation]; - } - - // Default to landscape if invalid - return LV_DISPLAY_ROTATION_0; -} - -enum EpdRotation EpdiyDisplay::lvglRotationToEpd(lv_display_rotation_t lvglRotation) { - // Static lookup table for LVGL -> EPD rotation mapping - static const enum EpdRotation rotationMap[] = { - EPD_ROT_LANDSCAPE, // LV_DISPLAY_ROTATION_0 (0) - EPD_ROT_INVERTED_PORTRAIT, // LV_DISPLAY_ROTATION_90 (1) - EPD_ROT_INVERTED_LANDSCAPE, // LV_DISPLAY_ROTATION_180 (2) - EPD_ROT_PORTRAIT // LV_DISPLAY_ROTATION_270 (3) - }; - - // Validate input and return mapped value - if (lvglRotation >= LV_DISPLAY_ROTATION_0 && lvglRotation <= LV_DISPLAY_ROTATION_270) { - return rotationMap[lvglRotation]; - } - - // Default to landscape if invalid - return EPD_ROT_LANDSCAPE; -} - -void EpdiyDisplay::rotationEventCallback(lv_event_t* event) { - auto* display = static_cast(lv_event_get_user_data(event)); - if (display == nullptr) { - return; - } - - lv_display_t* lvgl_display = static_cast(lv_event_get_target(event)); - if (lvgl_display == nullptr) { - return; - } - - lv_display_rotation_t rotation = lv_display_get_rotation(lvgl_display); - display->handleRotationChange(rotation); -} - -void EpdiyDisplay::handleRotationChange(lv_display_rotation_t lvgl_rotation) { - // Map LVGL rotation to EPDiy rotation using lookup table - enum EpdRotation epd_rotation = lvglRotationToEpd(lvgl_rotation); - - // Update EPDiy rotation - LOG_I(TAG, "LVGL rotation changed to %d, setting EPDiy rotation to %d", lvgl_rotation, epd_rotation); - epd_set_rotation(epd_rotation); - - // Update configuration to keep it in sync - configuration->rotation = epd_rotation; - - // Log the new dimensions - LOG_I(TAG, "Display dimensions after rotation: %dx%d", epd_rotated_display_width(), epd_rotated_display_height()); -} diff --git a/Drivers/EPDiyDisplay/Source/EpdiyDisplay.h b/Drivers/EPDiyDisplay/Source/EpdiyDisplay.h deleted file mode 100644 index 4fdf8907d..000000000 --- a/Drivers/EPDiyDisplay/Source/EpdiyDisplay.h +++ /dev/null @@ -1,163 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include -#include -#include -#include - -class EpdiyDisplay final : public tt::hal::display::DisplayDevice { - -public: - - class Configuration { - public: - - Configuration( - const EpdBoardDefinition* board, - const EpdDisplay_t* display, - std::shared_ptr touch = nullptr, - enum EpdInitOptions initOptions = EPD_OPTIONS_DEFAULT, - const EpdWaveform* waveform = EPD_BUILTIN_WAVEFORM, - int defaultTemperature = 25, - enum EpdDrawMode defaultDrawMode = MODE_GL16, - bool fullRefresh = false, - enum EpdRotation rotation = EPD_ROT_LANDSCAPE - ) : board(board), - display(display), - touch(std::move(touch)), - initOptions(initOptions), - waveform(waveform), - defaultTemperature(defaultTemperature), - defaultDrawMode(defaultDrawMode), - fullRefresh(fullRefresh), - rotation(rotation) { - check(board != nullptr); - check(display != nullptr); - } - - const EpdBoardDefinition* board; - const EpdDisplay_t* display; - std::shared_ptr touch; - enum EpdInitOptions initOptions; - const EpdWaveform* waveform; - int defaultTemperature; - enum EpdDrawMode defaultDrawMode; - bool fullRefresh; - enum EpdRotation rotation; - }; - -private: - - std::unique_ptr configuration; - lv_display_t* _Nullable lvglDisplay = nullptr; - EpdiyHighlevelState highlevelState = {}; - uint8_t* framebuffer = nullptr; - uint8_t* lvglDrawBuffer = nullptr; - uint8_t* packedBuffer = nullptr; // Pre-allocated 4-bit packed pixel buffer for flushInternal - bool initialized = false; - bool powered = false; - - // epd_hl_init() sets an internal already_initialized flag and has no matching deinit. - // We track first-time init statically and keep the HL state alive across stop()/start() cycles. - static bool s_hlInitialized; - static EpdiyHighlevelState s_hlState; - - static void flushCallback(lv_display_t* display, const lv_area_t* area, uint8_t* pixelMap); - void flushInternal(const lv_area_t* area, uint8_t* pixelMap, bool isLast); - - static void rotationEventCallback(lv_event_t* event); - void handleRotationChange(lv_display_rotation_t rotation); - - // Rotation mapping helpers - static lv_display_rotation_t epdRotationToLvgl(enum EpdRotation epdRotation); - static enum EpdRotation lvglRotationToEpd(lv_display_rotation_t lvglRotation); - -public: - - explicit EpdiyDisplay(std::unique_ptr inConfiguration); - - ~EpdiyDisplay() override; - - std::string getName() const override { return "EPDiy"; } - - std::string getDescription() const override { - return "E-Ink display powered by EPDiy library"; - } - - // Device lifecycle - bool start() override; - bool stop() override; - - // Power control - void setPowerOn(bool turnOn) override; - bool isPoweredOn() const override { return powered; } - bool supportsPowerControl() const override { return true; } - - // Touch device - std::shared_ptr _Nullable getTouchDevice() override { - return configuration->touch; - } - - // LVGL support - bool supportsLvgl() const override { return true; } - bool startLvgl() override; - bool stopLvgl() override; - lv_display_t* _Nullable getLvglDisplay() const override { return lvglDisplay; } - - // DisplayDriver (not supported for EPD) - bool supportsDisplayDriver() const override { return false; } - std::shared_ptr _Nullable getDisplayDriver() override { - return nullptr; - } - - // EPD specific functions - - /** - * Get a reference to the framebuffer - */ - uint8_t* getFramebuffer() { - return epd_hl_get_framebuffer(&highlevelState); - } - - /** - * Clear the screen by flashing it - */ - void clearScreen(); - - /** - * Clear an area by flashing it - */ - void clearArea(EpdRect area); - - /** - * Manually trigger a screen update - * @param mode The draw mode to use (defaults to configuration default) - * @param temperature Temperature in °C (defaults to configuration default) - */ - enum EpdDrawError updateScreen( - enum EpdDrawMode mode = MODE_UNKNOWN_WAVEFORM, - int temperature = -1 - ); - - /** - * Update a specific area of the screen - * @param area The area to update - * @param mode The draw mode to use (defaults to configuration default) - * @param temperature Temperature in °C (defaults to configuration default) - */ - enum EpdDrawError updateArea( - EpdRect area, - enum EpdDrawMode mode = MODE_UNKNOWN_WAVEFORM, - int temperature = -1 - ); - - /** - * Set the display to all white - */ - void setAllWhite(); -}; diff --git a/Drivers/EPDiyDisplay/Source/EpdiyDisplayHelper.h b/Drivers/EPDiyDisplay/Source/EpdiyDisplayHelper.h deleted file mode 100644 index 31bc3c8a5..000000000 --- a/Drivers/EPDiyDisplay/Source/EpdiyDisplayHelper.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "EpdiyDisplay.h" -#include -#include -#include - -/** - * Helper class to create EPDiy displays with common configurations - */ -class EpdiyDisplayHelper { -public: - - /** - * Create a display for M5Paper S3 - * @param touch Optional touch device - * @param temperature Display temperature in °C (default: 20) - * @param drawMode Default draw mode (default: MODE_DU) - * @param fullRefresh Use full refresh mode (default: false for partial updates) - * @param rotation Display rotation (default: EPD_ROT_PORTRAIT) - */ - static std::shared_ptr createM5PaperS3Display( - std::shared_ptr touch = nullptr, - int temperature = 20, - enum EpdDrawMode drawMode = MODE_DU, - bool fullRefresh = false, - enum EpdRotation rotation = EPD_ROT_PORTRAIT - ) { - auto config = std::make_unique( - &epd_board_m5papers3, - &ED047TC1, - touch, - static_cast(EPD_LUT_1K | EPD_FEED_QUEUE_32), - static_cast(EPD_BUILTIN_WAVEFORM), - temperature, - drawMode, - fullRefresh, - rotation - ); - - return std::make_shared(std::move(config)); - } -}; diff --git a/Drivers/FT5x06/CMakeLists.txt b/Drivers/FT5x06/CMakeLists.txt deleted file mode 100644 index 3e4eabdc5..000000000 --- a/Drivers/FT5x06/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility EspLcdCompat esp_lcd_touch_ft5x06 driver -) diff --git a/Drivers/FT5x06/README.md b/Drivers/FT5x06/README.md deleted file mode 100644 index 8bff4bc59..000000000 --- a/Drivers/FT5x06/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# FT5x06 - -A Tactility driver for FT5x06 touch. diff --git a/Drivers/FT5x06/Source/Ft5x06Touch.cpp b/Drivers/FT5x06/Source/Ft5x06Touch.cpp deleted file mode 100644 index 974c70a6b..000000000 --- a/Drivers/FT5x06/Source/Ft5x06Touch.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "Ft5x06Touch.h" - -#include -#include -#include - -bool Ft5x06Touch::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) { - esp_lcd_panel_io_i2c_config_t io_config = ESP_LCD_TOUCH_IO_I2C_FT5x06_CONFIG(); - return esp_lcd_new_panel_io_i2c(configuration->port, &io_config, &outHandle) == ESP_OK; -} - -bool Ft5x06Touch::createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& configuration, esp_lcd_touch_handle_t& panelHandle) { - return esp_lcd_touch_new_i2c_ft5x06(ioHandle, &configuration, &panelHandle) == ESP_OK; -} - -esp_lcd_touch_config_t Ft5x06Touch::createEspLcdTouchConfig() { - return { - .x_max = configuration->xMax, - .y_max = configuration->yMax, - .rst_gpio_num = configuration->pinReset, - .int_gpio_num = configuration->pinInterrupt, - .levels = { - .reset = configuration->pinResetLevel, - .interrupt = configuration->pinInterruptLevel, - }, - .flags = { - .swap_xy = configuration->swapXy, - .mirror_x = configuration->mirrorX, - .mirror_y = configuration->mirrorY, - }, - .process_coordinates = nullptr, - .interrupt_callback = nullptr, - .user_data = nullptr, - .driver_data = nullptr - }; -} diff --git a/Drivers/FT5x06/Source/Ft5x06Touch.h b/Drivers/FT5x06/Source/Ft5x06Touch.h deleted file mode 100644 index 76a004665..000000000 --- a/Drivers/FT5x06/Source/Ft5x06Touch.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -class Ft5x06Touch final : public EspLcdTouch { - -public: - - class Configuration { - public: - - Configuration( - i2c_port_t port, - uint16_t xMax, - uint16_t yMax, - bool swapXy = false, - bool mirrorX = false, - bool mirrorY = false, - gpio_num_t pinReset = GPIO_NUM_NC, - gpio_num_t pinInterrupt = GPIO_NUM_NC, - unsigned int pinResetLevel = 0, - unsigned int pinInterruptLevel = 0 - ) : port(port), - xMax(xMax), - yMax(yMax), - swapXy(swapXy), - mirrorX(mirrorX), - mirrorY(mirrorY), - pinReset(pinReset), - pinInterrupt(pinInterrupt), - pinResetLevel(pinResetLevel), - pinInterruptLevel(pinInterruptLevel) - {} - - i2c_port_t port; - uint16_t xMax; - uint16_t yMax; - bool swapXy; - bool mirrorX; - bool mirrorY; - gpio_num_t pinReset; - gpio_num_t pinInterrupt; - unsigned int pinResetLevel; - unsigned int pinInterruptLevel; - }; - -private: - - std::unique_ptr configuration; - - bool createIoHandle(esp_lcd_panel_io_handle_t& outHandle) override; - - bool createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& configuration, esp_lcd_touch_handle_t& panelHandle) override; - - esp_lcd_touch_config_t createEspLcdTouchConfig() override; - -public: - - explicit Ft5x06Touch(std::unique_ptr inConfiguration) : configuration(std::move(inConfiguration)) { - assert(configuration != nullptr); - } - - std::string getName() const override { return "FT5x06"; } - - std::string getDescription() const override { return "FT5x06 I2C touch driver"; } -}; diff --git a/Drivers/FT6x36/CMakeLists.txt b/Drivers/FT6x36/CMakeLists.txt deleted file mode 100644 index 83b9fcc06..000000000 --- a/Drivers/FT6x36/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility EspLcdCompat esp_lcd_touch_ft6336u driver -) diff --git a/Drivers/FT6x36/README.md b/Drivers/FT6x36/README.md deleted file mode 100644 index 2066e0ea6..000000000 --- a/Drivers/FT6x36/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# FT6x36 - -A Tactility driver for FT6x36 touch. diff --git a/Drivers/FT6x36/Source/Ft6x36Touch.cpp b/Drivers/FT6x36/Source/Ft6x36Touch.cpp deleted file mode 100644 index 45a7fdb8b..000000000 --- a/Drivers/FT6x36/Source/Ft6x36Touch.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "Ft6x36Touch.h" - -#include -#include -#include - -bool Ft6x36Touch::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) { - esp_lcd_panel_io_i2c_config_t io_config = ESP_LCD_TOUCH_IO_I2C_FT6x36_CONFIG(); - return esp_lcd_new_panel_io_i2c(configuration->port, &io_config, &outHandle) == ESP_OK; -} - -bool Ft6x36Touch::createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& configuration, esp_lcd_touch_handle_t& panelHandle) { - return esp_lcd_touch_new_i2c_ft6x36(ioHandle, &configuration, &panelHandle) == ESP_OK; -} - -esp_lcd_touch_config_t Ft6x36Touch::createEspLcdTouchConfig() { - return { - .x_max = configuration->xMax, - .y_max = configuration->yMax, - .rst_gpio_num = configuration->pinReset, - .int_gpio_num = configuration->pinInterrupt, - .levels = { - .reset = configuration->pinResetLevel, - .interrupt = configuration->pinInterruptLevel, - }, - .flags = { - .swap_xy = configuration->swapXy, - .mirror_x = configuration->mirrorX, - .mirror_y = configuration->mirrorY, - }, - .process_coordinates = nullptr, - .interrupt_callback = nullptr, - .user_data = nullptr, - .driver_data = nullptr - }; -} diff --git a/Drivers/FT6x36/Source/Ft6x36Touch.h b/Drivers/FT6x36/Source/Ft6x36Touch.h deleted file mode 100644 index b1bfd8540..000000000 --- a/Drivers/FT6x36/Source/Ft6x36Touch.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -class Ft6x36Touch final : public EspLcdTouch { - -public: - - class Configuration { - public: - - Configuration( - i2c_port_t port, - uint16_t xMax, - uint16_t yMax, - bool swapXy = false, - bool mirrorX = false, - bool mirrorY = false, - gpio_num_t pinReset = GPIO_NUM_NC, - gpio_num_t pinInterrupt = GPIO_NUM_NC, - unsigned int pinResetLevel = 0, - unsigned int pinInterruptLevel = 0 - ) : port(port), - xMax(xMax), - yMax(yMax), - swapXy(swapXy), - mirrorX(mirrorX), - mirrorY(mirrorY), - pinReset(pinReset), - pinInterrupt(pinInterrupt), - pinResetLevel(pinResetLevel), - pinInterruptLevel(pinInterruptLevel) - {} - - i2c_port_t port; - uint16_t xMax; - uint16_t yMax; - bool swapXy; - bool mirrorX; - bool mirrorY; - gpio_num_t pinReset; - gpio_num_t pinInterrupt; - unsigned int pinResetLevel; - unsigned int pinInterruptLevel; - }; - -private: - - std::unique_ptr configuration; - - bool createIoHandle(esp_lcd_panel_io_handle_t& outHandle) override; - - bool createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& configuration, esp_lcd_touch_handle_t& panelHandle) override; - - esp_lcd_touch_config_t createEspLcdTouchConfig() override; - -public: - - explicit Ft6x36Touch(std::unique_ptr inConfiguration) : configuration(std::move(inConfiguration)) { - assert(configuration != nullptr); - } - - std::string getName() const override { return "FT6x36"; } - - std::string getDescription() const override { return "FT6x36 I2C touch driver"; } -}; diff --git a/Drivers/GC9A01/CMakeLists.txt b/Drivers/GC9A01/CMakeLists.txt deleted file mode 100644 index 4f64a8c13..000000000 --- a/Drivers/GC9A01/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility driver esp_lcd_gc9a01 EspLcdCompat -) diff --git a/Drivers/GC9A01/README.md b/Drivers/GC9A01/README.md deleted file mode 100644 index 4b8db2e70..000000000 --- a/Drivers/GC9A01/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# GC9A01 - -A basic ESP32 LVGL driver for GC9A01 displays. diff --git a/Drivers/GC9A01/Source/Gc9a01Display.cpp b/Drivers/GC9A01/Source/Gc9a01Display.cpp deleted file mode 100644 index 98d7bce1b..000000000 --- a/Drivers/GC9A01/Source/Gc9a01Display.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "Gc9a01Display.h" - -#include - -#include -#include -#include - -constexpr auto* TAG = "GC9A01"; - -bool Gc9a01Display::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) { - LOG_I(TAG, "Starting"); - - const esp_lcd_panel_io_spi_config_t panel_io_config = { - .cs_gpio_num = configuration->csPin, - .dc_gpio_num = configuration->dcPin, - .spi_mode = 0, - .pclk_hz = configuration->pixelClockFrequency, - .trans_queue_depth = configuration->transactionQueueDepth, - .on_color_trans_done = nullptr, - .user_ctx = nullptr, - .lcd_cmd_bits = 8, - .lcd_param_bits = 8, - .cs_ena_pretrans = 0, - .cs_ena_posttrans = 0, - .flags = { - .dc_high_on_cmd = 0, - .dc_low_on_data = 0, - .dc_low_on_param = 0, - .octal_mode = 0, - .quad_mode = 0, - .sio_mode = 0, - .lsb_first = 0, - .cs_high_active = 0 - } - }; - - if (esp_lcd_new_panel_io_spi(configuration->spiHostDevice, &panel_io_config, &outHandle) != ESP_OK) { - LOG_E(TAG, "Failed to create panel"); - return false; - } - - return true; -} - -bool Gc9a01Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) { - const esp_lcd_panel_dev_config_t panel_config = { - .reset_gpio_num = configuration->resetPin, - .rgb_ele_order = configuration->rgbElementOrder, - .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, - .bits_per_pixel = 16, - .flags = { - .reset_active_high = false - }, - .vendor_config = nullptr - }; - - if (esp_lcd_new_panel_gc9a01(ioHandle, &panel_config, &panelHandle) != ESP_OK) { - LOG_E(TAG, "Failed to create panel"); - return false; - } - - if (esp_lcd_panel_reset(panelHandle) != ESP_OK) { - LOG_E(TAG, "Failed to reset panel"); - return false; - } - - if (esp_lcd_panel_init(panelHandle) != ESP_OK) { - LOG_E(TAG, "Failed to init panel"); - return false; - } - - if (esp_lcd_panel_swap_xy(panelHandle, configuration->swapXY) != ESP_OK) { - LOG_E(TAG, "Failed to swap XY "); - return false; - } - - if (esp_lcd_panel_mirror(panelHandle, configuration->mirrorX, configuration->mirrorY) != ESP_OK) { - LOG_E(TAG, "Failed to set panel to mirror"); - return false; - } - - if (esp_lcd_panel_invert_color(panelHandle, configuration->invertColor) != ESP_OK) { - LOG_E(TAG, "Failed to set panel to invert"); - return false; - } - - if (esp_lcd_panel_disp_on_off(panelHandle, true) != ESP_OK) { - LOG_E(TAG, "Failed to turn display on"); - return false; - } - - return true; -} - -lvgl_port_display_cfg_t Gc9a01Display::getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { - return lvgl_port_display_cfg_t { - .io_handle = ioHandle, - .panel_handle = panelHandle, - .control_handle = nullptr, - .buffer_size = configuration->bufferSize, - .double_buffer = true, - .trans_size = 0, - .hres = configuration->horizontalResolution, - .vres = configuration->verticalResolution, - .monochrome = false, - .rotation = { - .swap_xy = configuration->swapXY, - .mirror_x = configuration->mirrorX, - .mirror_y = configuration->mirrorY, - }, - .color_format = LV_COLOR_FORMAT_RGB565, - .flags = { - .buff_dma = true, - .buff_spiram = false, - .sw_rotate = false, - .swap_bytes = true, - .full_refresh = false, - .direct_mode = false - } - }; -} diff --git a/Drivers/GC9A01/Source/Gc9a01Display.h b/Drivers/GC9A01/Source/Gc9a01Display.h deleted file mode 100644 index d9a270ed2..000000000 --- a/Drivers/GC9A01/Source/Gc9a01Display.h +++ /dev/null @@ -1,101 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include -#include -#include -#include - -class Gc9a01Display final : public EspLcdDisplay { - -public: - - class Configuration { - - public: - - Configuration( - spi_host_device_t spiHostDevice, - gpio_num_t csPin, - gpio_num_t dcPin, - unsigned int horizontalResolution, - unsigned int verticalResolution, - std::shared_ptr touch, - bool swapXY = false, - bool mirrorX = false, - bool mirrorY = false, - bool invertColor = false, - uint32_t bufferSize = 0, // Size in pixel count. 0 means default, which is 1/10 of the screen size - lcd_rgb_element_order_t rgbElementOrder = LCD_RGB_ELEMENT_ORDER_RGB - ) : spiHostDevice(spiHostDevice), - csPin(csPin), - dcPin(dcPin), - horizontalResolution(horizontalResolution), - verticalResolution(verticalResolution), - swapXY(swapXY), - mirrorX(mirrorX), - mirrorY(mirrorY), - invertColor(invertColor), - bufferSize(bufferSize), - rgbElementOrder(rgbElementOrder), - touch(std::move(touch)) - { - if (this->bufferSize == 0) { - this->bufferSize = horizontalResolution * verticalResolution / 10; - } - } - - spi_host_device_t spiHostDevice; - gpio_num_t csPin; - gpio_num_t dcPin; - gpio_num_t resetPin = GPIO_NUM_NC; - unsigned int pixelClockFrequency = 80'000'000; // Hertz - size_t transactionQueueDepth = 10; - unsigned int horizontalResolution; - unsigned int verticalResolution; - bool swapXY = false; - bool mirrorX = false; - bool mirrorY = false; - bool invertColor = false; - uint32_t bufferSize = 0; // Size in pixel count. 0 means default, which is 1/10 of the screen size - lcd_rgb_element_order_t rgbElementOrder; - std::shared_ptr touch; - std::function _Nullable backlightDutyFunction = nullptr; - }; - -private: - - std::unique_ptr configuration; - - bool createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) override; - - bool createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) override; - - lvgl_port_display_cfg_t getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) override; - -public: - - explicit Gc9a01Display(std::unique_ptr inConfiguration) : - configuration(std::move(inConfiguration) - ) {} - - std::string getName() const override { return "GC9A01"; } - - std::string getDescription() const override { return "GC9A01 display"; } - - std::shared_ptr _Nullable getTouchDevice() override { return configuration->touch; } - - void setBacklightDuty(uint8_t backlightDuty) override { - if (configuration->backlightDutyFunction != nullptr) { - configuration->backlightDutyFunction(backlightDuty); - } - } - - bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; } -}; - -std::shared_ptr createDisplay(); diff --git a/Drivers/GT911/CMakeLists.txt b/Drivers/GT911/CMakeLists.txt deleted file mode 100644 index cb0bb61c4..000000000 --- a/Drivers/GT911/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility EspLcdCompat esp_lcd_touch_gt911 driver -) diff --git a/Drivers/GT911/README.md b/Drivers/GT911/README.md deleted file mode 100644 index d2eba0bb3..000000000 --- a/Drivers/GT911/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# GT911 - -GT911 touch driver for Tactility. \ No newline at end of file diff --git a/Drivers/GT911/Source/Gt911Touch.cpp b/Drivers/GT911/Source/Gt911Touch.cpp deleted file mode 100644 index c60dc8f2b..000000000 --- a/Drivers/GT911/Source/Gt911Touch.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "Gt911Touch.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -constexpr auto* TAG = "GT911"; - -bool Gt911Touch::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) { - esp_lcd_panel_io_i2c_config_t io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG(); - - auto* i2c = configuration->i2cController; - - if (i2c_controller_has_device_at_address(i2c, ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS, pdMS_TO_TICKS(10)) == ERROR_NONE) { - io_config.dev_addr = ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS; - } else if (i2c_controller_has_device_at_address(i2c, ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS_BACKUP, pdMS_TO_TICKS(10)) == ERROR_NONE) { - io_config.dev_addr = ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS_BACKUP; - } else { - LOG_E(TAG, "No device found on I2C bus"); - return false; - } - - // Legacy I2C implementation - auto* driver = device_get_driver(i2c); - if (driver_is_compatible(driver, "espressif,esp32-i2c")) { - auto port = static_cast(i2c->config)->port; - return esp_lcd_new_panel_io_i2c_v1(port, &io_config, &outHandle) == ESP_OK; - } else if (driver_is_compatible(driver, "espressif,esp32-i2c-master")) { - auto bus = esp32_i2c_master_get_bus_handle(i2c); - io_config.scl_speed_hz = esp32_i2c_master_get_clock_frequency(configuration->i2cController); - return esp_lcd_new_panel_io_i2c_v2(bus, &io_config, &outHandle) == ESP_OK; - } - - LOG_E(TAG, "Unsupported I2C driver"); - return false; -} - -bool Gt911Touch::createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& configuration, esp_lcd_touch_handle_t& panelHandle) { - return esp_lcd_touch_new_i2c_gt911(ioHandle, &configuration, &panelHandle) == ESP_OK; -} - -esp_lcd_touch_config_t Gt911Touch::createEspLcdTouchConfig() { - return { - .x_max = configuration->xMax, - .y_max = configuration->yMax, - .rst_gpio_num = configuration->pinReset, - .int_gpio_num = configuration->pinInterrupt, - .levels = { - .reset = configuration->pinResetLevel, - .interrupt = configuration->pinInterruptLevel, - }, - .flags = { - .swap_xy = static_cast(configuration->swapXy), - .mirror_x = static_cast(configuration->mirrorX), - .mirror_y = static_cast(configuration->mirrorY), - }, - .process_coordinates = nullptr, - .interrupt_callback = nullptr, - .user_data = nullptr, - .driver_data = nullptr - }; -} diff --git a/Drivers/GT911/Source/Gt911Touch.h b/Drivers/GT911/Source/Gt911Touch.h deleted file mode 100644 index fcb8da4e1..000000000 --- a/Drivers/GT911/Source/Gt911Touch.h +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include -#include - -#include - -struct Device; - -class Gt911Touch final : public EspLcdTouch { - -public: - - class Configuration { - public: - - Configuration( - ::Device* i2cController, - uint16_t xMax, - uint16_t yMax, - bool swapXy = false, - bool mirrorX = false, - bool mirrorY = false, - gpio_num_t pinReset = GPIO_NUM_NC, - gpio_num_t pinInterrupt = GPIO_NUM_NC, - unsigned int pinResetLevel = 0, - unsigned int pinInterruptLevel = 0 - ) : i2cController(i2cController), - xMax(xMax), - yMax(yMax), - swapXy(swapXy), - mirrorX(mirrorX), - mirrorY(mirrorY), - pinReset(pinReset), - pinInterrupt(pinInterrupt), - pinResetLevel(pinResetLevel), - pinInterruptLevel(pinInterruptLevel) - {} - - ::Device* i2cController; - uint16_t xMax; - uint16_t yMax; - bool swapXy; - bool mirrorX; - bool mirrorY; - gpio_num_t pinReset; - gpio_num_t pinInterrupt; - unsigned int pinResetLevel; - unsigned int pinInterruptLevel; - }; - -private: - - std::unique_ptr configuration; - - bool createIoHandle(esp_lcd_panel_io_handle_t& outHandle) override; - - bool createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& configuration, esp_lcd_touch_handle_t& panelHandle) override; - - esp_lcd_touch_config_t createEspLcdTouchConfig() override; - -public: - - explicit Gt911Touch(std::unique_ptr inConfiguration) : configuration(std::move(inConfiguration)) { - assert(configuration != nullptr); - } - - std::string getName() const override { return "GT911"; } - - std::string getDescription() const override { return "GT911 I2C touch driver"; } -}; diff --git a/Drivers/ILI934x/CMakeLists.txt b/Drivers/ILI934x/CMakeLists.txt deleted file mode 100644 index ec97215be..000000000 --- a/Drivers/ILI934x/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility EspLcdCompat esp_lcd_ili9341 driver -) diff --git a/Drivers/ILI934x/README.md b/Drivers/ILI934x/README.md deleted file mode 100644 index a87608920..000000000 --- a/Drivers/ILI934x/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# ILI934x - -A basic ESP32 LVGL driver for ILI9341 and ILI9342 displays. diff --git a/Drivers/ILI934x/Source/Ili934xDisplay.cpp b/Drivers/ILI934x/Source/Ili934xDisplay.cpp deleted file mode 100644 index 5cfab7835..000000000 --- a/Drivers/ILI934x/Source/Ili934xDisplay.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "Ili934xDisplay.h" - -#include -#include - -std::shared_ptr Ili934xDisplay::createEspLcdConfiguration(const Configuration& configuration) { - return std::make_shared(EspLcdConfiguration { - .horizontalResolution = configuration.horizontalResolution, - .verticalResolution = configuration.verticalResolution, - .gapX = configuration.gapX, - .gapY = configuration.gapY, - .monochrome = false, - .swapXY = configuration.swapXY, - .mirrorX = configuration.mirrorX, - .mirrorY = configuration.mirrorY, - .invertColor = configuration.invertColor, - .bufferSize = configuration.bufferSize, - .touch = configuration.touch, - .backlightDutyFunction = configuration.backlightDutyFunction, - .resetPin = configuration.resetPin, - .lvglColorFormat = LV_COLOR_FORMAT_RGB565, - .lvglSwapBytes = configuration.swapBytes, - .rgbElementOrder = configuration.rgbElementOrder, - .bitsPerPixel = 16 - }); -} - -esp_lcd_panel_dev_config_t Ili934xDisplay::createPanelConfig(std::shared_ptr espLcdConfiguration, gpio_num_t resetPin) { - return { - .reset_gpio_num = resetPin, - .rgb_ele_order = espLcdConfiguration->rgbElementOrder, - .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, - .bits_per_pixel = espLcdConfiguration->bitsPerPixel, - .flags = { - .reset_active_high = 0 - }, - .vendor_config = nullptr - }; -} - -bool Ili934xDisplay::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_panel_dev_config_t& panelConfig, esp_lcd_panel_handle_t& panelHandle) { - return esp_lcd_new_panel_ili9341(ioHandle, &panelConfig, &panelHandle) == ESP_OK; -} diff --git a/Drivers/ILI934x/Source/Ili934xDisplay.h b/Drivers/ILI934x/Source/Ili934xDisplay.h deleted file mode 100644 index 1e1845197..000000000 --- a/Drivers/ILI934x/Source/Ili934xDisplay.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -class Ili934xDisplay final : public EspLcdSpiDisplay { - -public: - - /** Minimal set of overrides for EspLcdConfiguration */ - struct Configuration { - unsigned int horizontalResolution; - unsigned int verticalResolution; - int gapX; - int gapY; - bool swapXY; - bool mirrorX; - bool mirrorY; - bool invertColor; - bool swapBytes; - uint32_t bufferSize; // Pixel count, not byte count. Set to 0 for default (1/10th of display size) - std::shared_ptr touch; - std::function backlightDutyFunction; // Nullable - gpio_num_t resetPin; - lcd_rgb_element_order_t rgbElementOrder; - }; - -private: - - static std::shared_ptr createEspLcdConfiguration(const Configuration& configuration); - - esp_lcd_panel_dev_config_t createPanelConfig(std::shared_ptr espLcdConfiguration, gpio_num_t resetPin) override; - - bool createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_panel_dev_config_t& panelConfig, esp_lcd_panel_handle_t& panelHandle) override; - -public: - - explicit Ili934xDisplay(const Configuration& configuration, const std::shared_ptr& spiConfiguration, bool hasGammaCurves) : - EspLcdSpiDisplay( - createEspLcdConfiguration(configuration), - spiConfiguration, - (hasGammaCurves ? 4 : 0) - ) - { - } - - std::string getName() const override { return "ILI934x"; } - - std::string getDescription() const override { return "ILI934x display"; } -}; diff --git a/Drivers/JD9853/CMakeLists.txt b/Drivers/JD9853/CMakeLists.txt deleted file mode 100644 index 4d433e024..000000000 --- a/Drivers/JD9853/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -idf_component_register(SRCS "esp_lcd_jd9853.c" - INCLUDE_DIRS "include" - REQUIRES "esp_lcd" "driver") diff --git a/Drivers/JD9853/README.md b/Drivers/JD9853/README.md deleted file mode 100644 index ae5e72385..000000000 --- a/Drivers/JD9853/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# JD9853 - -SPI display driver. - -Source: https://files.waveshare.com/wiki/1.47inch%20Touch%20LCD/1.47inch_Touch_LCD_Demo_ESP32.zip - -License: Apache 2.0 diff --git a/Drivers/PwmBacklight/CMakeLists.txt b/Drivers/PwmBacklight/CMakeLists.txt deleted file mode 100644 index f604c373c..000000000 --- a/Drivers/PwmBacklight/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility driver -) diff --git a/Drivers/PwmBacklight/README.md b/Drivers/PwmBacklight/README.md deleted file mode 100644 index 25bd8be18..000000000 --- a/Drivers/PwmBacklight/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# PWM Backlight Driver - -A very basic driver to control an LCD panel backlight with a PWM signal. diff --git a/Drivers/PwmBacklight/Source/PwmBacklight.cpp b/Drivers/PwmBacklight/Source/PwmBacklight.cpp deleted file mode 100644 index 44ee5720a..000000000 --- a/Drivers/PwmBacklight/Source/PwmBacklight.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "PwmBacklight.h" - -#include - -constexpr auto* TAG = "PwmBacklight"; - -namespace driver::pwmbacklight { - -static bool isBacklightInitialized = false; -static gpio_num_t backlightPin = GPIO_NUM_NC; -static ledc_timer_t backlightTimer; -static ledc_channel_t backlightChannel; - -bool init(gpio_num_t pin, uint32_t frequencyHz, ledc_timer_t timer, ledc_channel_t channel) { - backlightPin = pin; - backlightTimer = timer; - backlightChannel = channel; - - LOG_I(TAG, "Init"); - ledc_timer_config_t ledc_timer = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .duty_resolution = LEDC_TIMER_8_BIT, - .timer_num = backlightTimer, - .freq_hz = frequencyHz, - .clk_cfg = LEDC_AUTO_CLK, - .deconfigure = false - }; - - if (ledc_timer_config(&ledc_timer) != ESP_OK) { - LOG_E(TAG, "Timer config failed"); - return false; - } - - ledc_channel_config_t ledc_channel = { - .gpio_num = backlightPin, - .speed_mode = LEDC_LOW_SPEED_MODE, - .channel = backlightChannel, - .intr_type = LEDC_INTR_DISABLE, - .timer_sel = backlightTimer, - .duty = 0, - .hpoint = 0, - .sleep_mode = LEDC_SLEEP_MODE_NO_ALIVE_NO_PD, - .flags = { - .output_invert = 0 - } - }; - - if (ledc_channel_config(&ledc_channel) != ESP_OK) { - LOG_E(TAG, "Channel config failed"); - return false; - } - - isBacklightInitialized = true; - - return true; -} - -bool setBacklightDuty(uint8_t duty) { - if (!isBacklightInitialized) { - LOG_E(TAG, "Not initialized"); - return false; - } - return ledc_set_duty(LEDC_LOW_SPEED_MODE, backlightChannel, duty) == ESP_OK && - ledc_update_duty(LEDC_LOW_SPEED_MODE, backlightChannel) == ESP_OK; -} - -} diff --git a/Drivers/PwmBacklight/Source/PwmBacklight.h b/Drivers/PwmBacklight/Source/PwmBacklight.h deleted file mode 100644 index f32705cb3..000000000 --- a/Drivers/PwmBacklight/Source/PwmBacklight.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include -#include - -namespace driver::pwmbacklight { - -bool init(gpio_num_t pin, uint32_t frequencyHz = 40000, ledc_timer_t timer = LEDC_TIMER_0, ledc_channel_t channel = LEDC_CHANNEL_0); - -bool setBacklightDuty(uint8_t duty); - -} diff --git a/Drivers/RgbDisplay/CMakeLists.txt b/Drivers/RgbDisplay/CMakeLists.txt deleted file mode 100644 index f0e2b6c2d..000000000 --- a/Drivers/RgbDisplay/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility EspLcdCompat -) diff --git a/Drivers/RgbDisplay/README.md b/Drivers/RgbDisplay/README.md deleted file mode 100644 index 48af5bb31..000000000 --- a/Drivers/RgbDisplay/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# RGB Display Driver - -This driver is used for displays that use multiple parallel data lanes. diff --git a/Drivers/RgbDisplay/Source/RgbDisplay.cpp b/Drivers/RgbDisplay/Source/RgbDisplay.cpp deleted file mode 100644 index 55b40a715..000000000 --- a/Drivers/RgbDisplay/Source/RgbDisplay.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include "RgbDisplay.h" - -#include -#include -#include - -#include -#include -#include -#include - -constexpr auto* TAG = "RgbDisplay"; - -RgbDisplay::~RgbDisplay() { - check( - displayDriver == nullptr || displayDriver.use_count() == 0, - "DisplayDriver is still in use. This will cause memory access violations." - ); -} - -bool RgbDisplay::start() { - LOG_I(TAG, "Starting"); - - if (esp_lcd_new_rgb_panel(&configuration->panelConfig, &panelHandle) != ESP_OK) { - LOG_E(TAG, "Failed to create panel"); - return false; - } - - if (esp_lcd_panel_reset(panelHandle) != ESP_OK) { - LOG_E(TAG, "Failed to reset panel"); - return false; - } - - if (esp_lcd_panel_init(panelHandle) != ESP_OK) { - LOG_E(TAG, "Failed to init panel"); - return false; - } - - if (esp_lcd_panel_swap_xy(panelHandle, configuration->swapXY) != ESP_OK) { - LOG_E(TAG, "Failed to swap XY"); - return false; - } - - if (esp_lcd_panel_mirror(panelHandle, configuration->mirrorX, configuration->mirrorY) != ESP_OK) { - LOG_E(TAG, "Failed to set panel to mirror"); - return false; - } - - if (esp_lcd_panel_invert_color(panelHandle, configuration->invertColor) != ESP_OK) { - LOG_E(TAG, "Failed to set panel to invert"); - return false; - } - - return true; -} - -bool RgbDisplay::stop() { - if (lvglDisplay != nullptr) { - stopLvgl(); - lvglDisplay = nullptr; - } - - if (panelHandle != nullptr && esp_lcd_panel_del(panelHandle) != ESP_OK) { - return false; - } - - if (displayDriver != nullptr && displayDriver.use_count() > 1) { - LOG_W(TAG, "DisplayDriver is still in use."); - } - - auto touch_device = getTouchDevice(); - if (touch_device != nullptr) { - touch_device->startLvgl(lvglDisplay); - } - - return true; -} - - -bool RgbDisplay::startLvgl() { - assert(lvglDisplay == nullptr); - - if (displayDriver != nullptr && displayDriver.use_count() > 1) { - LOG_W(TAG, "DisplayDriver is still in use."); - } - - auto display_config = getLvglPortDisplayConfig(); - - const lvgl_port_display_rgb_cfg_t rgb_config = { - .flags = { - .bb_mode = configuration->bufferConfiguration.bounceBufferMode, - .avoid_tearing = configuration->bufferConfiguration.avoidTearing - } - }; - - lvglDisplay = lvgl_port_add_disp_rgb(&display_config, &rgb_config); - LOG_I(TAG, "Finished"); - - auto touch_device = getTouchDevice(); - if (touch_device != nullptr) { - touch_device->startLvgl(lvglDisplay); - } - - return lvglDisplay != nullptr; -} - -bool RgbDisplay::stopLvgl() { - if (lvglDisplay == nullptr) { - return false; - } - - auto touch_device = getTouchDevice(); - if (touch_device != nullptr) { - touch_device->stopLvgl(); - } - - lvgl_port_remove_disp(lvglDisplay); - lvglDisplay = nullptr; - - return true; -} - -lvgl_port_display_cfg_t RgbDisplay::getLvglPortDisplayConfig() const { - return { - .io_handle = nullptr, - .panel_handle = panelHandle, - .control_handle = nullptr, - .buffer_size = configuration->bufferConfiguration.size, - .double_buffer = configuration->bufferConfiguration.doubleBuffer, - .trans_size = 0, - .hres = configuration->panelConfig.timings.h_res, - .vres = configuration->panelConfig.timings.v_res, - .monochrome = false, - .rotation = { - .swap_xy = configuration->swapXY, - .mirror_x = configuration->mirrorX, - .mirror_y = configuration->mirrorY, - }, - .color_format = configuration->colorFormat, - .flags = { - .buff_dma = !configuration->bufferConfiguration.useSpi, - .buff_spiram = configuration->bufferConfiguration.useSpi, - .sw_rotate = false, - .swap_bytes = false, - .full_refresh = false, - .direct_mode = false - } - }; -} - diff --git a/Drivers/RgbDisplay/Source/RgbDisplay.h b/Drivers/RgbDisplay/Source/RgbDisplay.h deleted file mode 100644 index 46635cd03..000000000 --- a/Drivers/RgbDisplay/Source/RgbDisplay.h +++ /dev/null @@ -1,114 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -class RgbDisplay final : public tt::hal::display::DisplayDevice { - -public: - - struct BufferConfiguration final { - uint32_t size; // Size in pixel count. 0 means default, which is 1/15 of the screen size - bool useSpi; - bool doubleBuffer; - bool bounceBufferMode; - bool avoidTearing; - }; - - class Configuration final { - public: - - esp_lcd_rgb_panel_config_t panelConfig; - BufferConfiguration bufferConfiguration; - std::shared_ptr touch; - lv_color_format_t colorFormat; - bool swapXY; - bool mirrorX; - bool mirrorY; - bool invertColor; - std::function _Nullable backlightDutyFunction; - - Configuration( - esp_lcd_rgb_panel_config_t panelConfig, - BufferConfiguration bufferConfiguration, - std::shared_ptr touch, - lv_color_format_t colorFormat, - bool swapXY = false, - bool mirrorX = false, - bool mirrorY = false, - bool invertColor = false, - std::function _Nullable backlightDutyFunction = nullptr - ) : panelConfig(panelConfig), - bufferConfiguration(bufferConfiguration), - touch(std::move(touch)), - colorFormat(colorFormat), - swapXY(swapXY), - mirrorX(mirrorX), - mirrorY(mirrorY), - invertColor(invertColor), - backlightDutyFunction(std::move(backlightDutyFunction)) { - if (this->bufferConfiguration.size == 0) { - auto horizontal_resolution = panelConfig.timings.h_res; - auto vertical_resolution = panelConfig.timings.v_res; - this->bufferConfiguration.size = horizontal_resolution * vertical_resolution / 15; - } - } - }; - -private: - - std::unique_ptr _Nullable configuration = nullptr; - esp_lcd_panel_handle_t _Nullable panelHandle = nullptr; - lv_display_t* _Nullable lvglDisplay = nullptr; - std::shared_ptr _Nullable displayDriver; - - lvgl_port_display_cfg_t getLvglPortDisplayConfig() const; - -public: - - explicit RgbDisplay(std::unique_ptr inConfiguration) : configuration(std::move(inConfiguration)) { - assert(configuration != nullptr); - } - - ~RgbDisplay() override; - - std::string getName() const override { return "RGB Display"; } - std::string getDescription() const override { return "RGB Display"; } - - bool start() override; - - bool stop() override; - - bool supportsLvgl() const override { return true; } - - bool startLvgl() override; - - bool stopLvgl() override; - - std::shared_ptr _Nullable getTouchDevice() override { return configuration->touch; } - - void setBacklightDuty(uint8_t backlightDuty) override { - if (configuration->backlightDutyFunction != nullptr) { - configuration->backlightDutyFunction(backlightDuty); - } - } - - bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; } - - lv_display_t* _Nullable getLvglDisplay() const override { return lvglDisplay; } - - // TODO: Fix driver and re-enable - bool supportsDisplayDriver() const override { return false; } - - std::shared_ptr _Nullable getDisplayDriver() override { - if (displayDriver == nullptr) { - auto config = getLvglPortDisplayConfig(); - displayDriver = std::make_shared(panelHandle, config.hres, config.vres, tt::hal::display::ColorFormat::RGB888); - } - return displayDriver; - } -}; - -std::shared_ptr createDisplay(); diff --git a/Drivers/ST7789/CMakeLists.txt b/Drivers/ST7789/CMakeLists.txt deleted file mode 100644 index 7cd677c7a..000000000 --- a/Drivers/ST7789/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility driver EspLcdCompat -) diff --git a/Drivers/ST7789/README.md b/Drivers/ST7789/README.md deleted file mode 100644 index 2f6c6fb70..000000000 --- a/Drivers/ST7789/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# ST7789 - -A basic ESP32 LVGL driver for ST7789 displays. diff --git a/Drivers/ST7789/Source/St7789Display.cpp b/Drivers/ST7789/Source/St7789Display.cpp deleted file mode 100644 index 817786749..000000000 --- a/Drivers/ST7789/Source/St7789Display.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "St7789Display.h" - -#include - -std::shared_ptr St7789Display::createEspLcdConfiguration(const Configuration& configuration) { - return std::make_shared(EspLcdConfiguration { - .horizontalResolution = configuration.horizontalResolution, - .verticalResolution = configuration.verticalResolution, - .gapX = configuration.gapX, - .gapY = configuration.gapY, - .monochrome = false, - .swapXY = configuration.swapXY, - .mirrorX = configuration.mirrorX, - .mirrorY = configuration.mirrorY, - .invertColor = configuration.invertColor, - .bufferSize = configuration.bufferSize, - .buffSpiram = configuration.buffSpiram, - .touch = configuration.touch, - .backlightDutyFunction = configuration.backlightDutyFunction, - .resetPin = configuration.resetPin, - .lvglColorFormat = LV_COLOR_FORMAT_RGB565, - .lvglSwapBytes = configuration.lvglSwapBytes, - .rgbElementOrder = configuration.rgbElementOrder, - .bitsPerPixel = 16, - }); -} - -esp_lcd_panel_dev_config_t St7789Display::createPanelConfig(std::shared_ptr espLcdConfiguration, gpio_num_t resetPin) { - return { - .reset_gpio_num = resetPin, - .rgb_ele_order = espLcdConfiguration->rgbElementOrder, - .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, - .bits_per_pixel = espLcdConfiguration->bitsPerPixel, - .flags = { - .reset_active_high = false - }, - .vendor_config = nullptr - }; -} - -bool St7789Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_panel_dev_config_t& panelConfig, esp_lcd_panel_handle_t& panelHandle) { - return esp_lcd_new_panel_st7789(ioHandle, &panelConfig, &panelHandle) == ESP_OK; -} diff --git a/Drivers/ST7789/Source/St7789Display.h b/Drivers/ST7789/Source/St7789Display.h deleted file mode 100644 index b67b7b580..000000000 --- a/Drivers/ST7789/Source/St7789Display.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -class St7789Display final : public EspLcdSpiDisplay { - -public: - - /** Minimal set of overrides for EspLcdConfiguration */ - struct Configuration { - unsigned int horizontalResolution; - unsigned int verticalResolution; - int gapX; - int gapY; - bool swapXY; - bool mirrorX; - bool mirrorY; - bool invertColor; - uint32_t bufferSize; // Pixel count, not byte count. Set to 0 for default (1/10th of display size) - std::shared_ptr touch; - std::function _Nullable backlightDutyFunction; - gpio_num_t resetPin; - bool lvglSwapBytes; - bool buffSpiram = false; - lcd_rgb_element_order_t rgbElementOrder = LCD_RGB_ELEMENT_ORDER_RGB; - }; - -private: - - static std::shared_ptr createEspLcdConfiguration(const Configuration& configuration); - - esp_lcd_panel_dev_config_t createPanelConfig(std::shared_ptr espLcdConfiguration, gpio_num_t resetPin) override; - - bool createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_panel_dev_config_t& panelConfig, esp_lcd_panel_handle_t& panelHandle) override; - -public: - - explicit St7789Display(const Configuration& configuration, const std::shared_ptr& spiConfiguration) : - EspLcdSpiDisplay( - createEspLcdConfiguration(configuration), - spiConfiguration, - 4 - ) - { - } - - std::string getName() const override { return "ST7789"; } - - std::string getDescription() const override { return "ST7789 display"; } -}; - -std::shared_ptr createDisplay(); diff --git a/Drivers/ST7796-i8080/CMakeLists.txt b/Drivers/ST7796-i8080/CMakeLists.txt deleted file mode 100644 index b57e8985f..000000000 --- a/Drivers/ST7796-i8080/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register( - SRC_DIRS "Source" - INCLUDE_DIRS "Source" - REQUIRES Tactility EspLcdCompat esp_lcd_st7796 driver -) \ No newline at end of file diff --git a/Drivers/ST7796-i8080/README.md b/Drivers/ST7796-i8080/README.md deleted file mode 100644 index 2d79eb727..000000000 --- a/Drivers/ST7796-i8080/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# ST7796 - -A basic ESP32 LVGL driver for ST7796 parallel i8080 displays. \ No newline at end of file diff --git a/Drivers/ST7796-i8080/Source/St7796i8080Display.cpp b/Drivers/ST7796-i8080/Source/St7796i8080Display.cpp deleted file mode 100644 index 22e388f55..000000000 --- a/Drivers/ST7796-i8080/Source/St7796i8080Display.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#include "St7796i8080Display.h" -#include -#include -#include -#include -#include -#include -#include -#include - -constexpr auto* TAG = "St7796i8080Display"; -static St7796i8080Display* g_display_instance = nullptr; - -St7796i8080Display::St7796i8080Display(const Configuration& config) - : configuration(config), lock(std::make_shared()) { - - // Validate configuration - if (!configuration.isValid()) { - LOG_E(TAG, "Invalid configuration: resolution must be set"); - return; - } -} - -bool St7796i8080Display::createI80Bus() { - LOG_I(TAG, "Creating I80 bus"); - - // Create I80 bus configuration - esp_lcd_i80_bus_config_t bus_cfg = { - .dc_gpio_num = configuration.dcPin, - .wr_gpio_num = configuration.wrPin, - .clk_src = LCD_CLK_SRC_PLL160M, - .data_gpio_nums = { - configuration.dataPins[0], configuration.dataPins[1], - configuration.dataPins[2], configuration.dataPins[3], - configuration.dataPins[4], configuration.dataPins[5], - configuration.dataPins[6], configuration.dataPins[7], - }, - .bus_width = configuration.busWidth, - .max_transfer_bytes = configuration.bufferSize * sizeof(uint16_t), - .psram_trans_align = 64, - .sram_trans_align = 4 - }; - - if (esp_lcd_new_i80_bus(&bus_cfg, &i80BusHandle) != ESP_OK) { - LOG_E(TAG, "Failed to create I80 bus"); - return false; - } - - return true; -} - -bool St7796i8080Display::createPanelIO() { - LOG_I(TAG, "Creating panel IO"); - - // Create panel IO - esp_lcd_panel_io_i80_config_t io_cfg = { - .cs_gpio_num = configuration.csPin, - .pclk_hz = configuration.pixelClockFrequency, - .trans_queue_depth = configuration.transactionQueueDepth, - .on_color_trans_done = nullptr, - .user_ctx = nullptr, - .lcd_cmd_bits = configuration.lcdCmdBits, - .lcd_param_bits = configuration.lcdParamBits, - .dc_levels = { - .dc_idle_level = configuration.dcLevels.dcIdleLevel, - .dc_cmd_level = configuration.dcLevels.dcCmdLevel, - .dc_dummy_level = configuration.dcLevels.dcDummyLevel, - .dc_data_level = configuration.dcLevels.dcDataLevel, - }, - .flags = { - .cs_active_high = configuration.flags.csActiveHigh, - .reverse_color_bits = configuration.flags.reverseColorBits, - .swap_color_bytes = configuration.flags.swapColorBytes, - .pclk_active_neg = configuration.flags.pclkActiveNeg, - .pclk_idle_low = configuration.flags.pclkIdleLow - } - }; - - if (esp_lcd_new_panel_io_i80(i80BusHandle, &io_cfg, &ioHandle) != ESP_OK) { - LOG_E(TAG, "Failed to create panel"); - return false; - } - - return true; -} - -bool St7796i8080Display::createPanel() { - LOG_I(TAG, "Configuring panel"); - - // Create ST7796 panel - esp_lcd_panel_dev_config_t panel_config = { - .reset_gpio_num = configuration.resetPin, - .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR, - .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, - .bits_per_pixel = 16, - .flags = { - .reset_active_high = false - }, - .vendor_config = nullptr - }; - - if (esp_lcd_new_panel_st7796(ioHandle, &panel_config, &panelHandle) != ESP_OK) { - LOG_E(TAG, "Failed to create panel"); - return false; - } - - // Reset panel - if (esp_lcd_panel_reset(panelHandle) != ESP_OK) { - LOG_E(TAG, "Failed to reset panel"); - return false; - } - - // Initialize panel - if (esp_lcd_panel_init(panelHandle) != ESP_OK) { - LOG_E(TAG, "Failed to init panel"); - return false; - } - - // Set swap XY - if (esp_lcd_panel_swap_xy(panelHandle, configuration.swapXY) != ESP_OK) { - LOG_E(TAG, "Failed to swap XY "); - return false; - } - - // Set mirror - if (esp_lcd_panel_mirror(panelHandle, configuration.mirrorX, configuration.mirrorY) != ESP_OK) { - LOG_E(TAG, "Failed to set panel to mirror"); - return false; - } - - // Set inversion - if (esp_lcd_panel_invert_color(panelHandle, configuration.invertColor) != ESP_OK) { - LOG_E(TAG, "Failed to set panel to invert"); - return false; - } - - // Turn on display - if (esp_lcd_panel_disp_on_off(panelHandle, true) != ESP_OK) { - LOG_E(TAG, "Failed to turn display on"); - return false; - } - - return true; -} - -bool St7796i8080Display::start() { - LOG_I(TAG, "Initializing I8080 ST7796 Display hardware..."); - - // Calculate buffer size if needed - configuration.calculateBufferSize(); - - // Allocate buffer - size_t buffer_size = configuration.bufferSize * LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565); - displayBuffer = (uint8_t*)heap_caps_malloc(buffer_size, MALLOC_CAP_DMA); - if (!displayBuffer) { - LOG_E(TAG, "Failed to allocate display buffer"); - return false; - } - - // Create I80 bus - if (!createI80Bus()) { - stop(); - return false; - } - - // Create panel IO - if (!createPanelIO()) { - stop(); - return false; - } - - // Create panel - if (!createPanel()) { - stop(); - return false; - } - - LOG_I(TAG, "Display hardware initialized"); - return true; -} - -bool St7796i8080Display::stop() { - // Turn off display - if (panelHandle) { - esp_lcd_panel_disp_on_off(panelHandle, false); - } - - // Destroy in reverse order: panel, IO, bus - if (panelHandle) { - esp_lcd_panel_del(panelHandle); - panelHandle = nullptr; - } - if (ioHandle) { - esp_lcd_panel_io_del(ioHandle); - ioHandle = nullptr; - } - if (i80BusHandle) { - esp_lcd_del_i80_bus(i80BusHandle); - i80BusHandle = nullptr; - } - - // Free buffer 1 - if (displayBuffer) { - heap_caps_free(displayBuffer); - displayBuffer = nullptr; - } - - // Turn off backlight - if (configuration.backlightDutyFunction) { - configuration.backlightDutyFunction(0); - } - - return true; -} - -bool St7796i8080Display::startLvgl() { - LOG_I(TAG, "Initializing LVGL for ST7796 display"); - - // Don't reinitialize hardware if it's already done - if (!ioHandle) { - LOG_I(TAG, "Hardware not initialized, calling start()"); - if (!start()) { - LOG_E(TAG, "Hardware initialization failed"); - return false; - } - } else { - LOG_I(TAG, "Hardware already initialized, skipping"); - } - - // Create LVGL display using lvgl_port - lvgl_port_display_cfg_t display_cfg = { - .io_handle = ioHandle, - .panel_handle = panelHandle, - .control_handle = nullptr, - .buffer_size = configuration.bufferSize, - .double_buffer = false, - .trans_size = 0, - .hres = configuration.horizontalResolution, - .vres = configuration.verticalResolution, - .monochrome = false, - .rotation = { - .swap_xy = configuration.swapXY, - .mirror_x = configuration.mirrorX, - .mirror_y = configuration.mirrorY, - }, - .color_format = LV_COLOR_FORMAT_RGB565, - .flags = { - .buff_dma = true, - .buff_spiram = false, - .sw_rotate = false, - .swap_bytes = false, - .full_refresh = false, - .direct_mode = false - } - }; - - // Create the LVGL display - lvglDisplay = lvgl_port_add_disp(&display_cfg); - if (!lvglDisplay) { - LOG_E(TAG, "Failed to create LVGL display"); - return false; - } - - g_display_instance = this; - LOG_I(TAG, "LVGL display created successfully"); - return true; -} - -bool St7796i8080Display::stopLvgl() { - if (lvglDisplay) { - lvgl_port_remove_disp(lvglDisplay); - lvglDisplay = nullptr; - } - return true; -} \ No newline at end of file diff --git a/Drivers/ST7796-i8080/Source/St7796i8080Display.h b/Drivers/ST7796-i8080/Source/St7796i8080Display.h deleted file mode 100644 index 786a7bab6..000000000 --- a/Drivers/ST7796-i8080/Source/St7796i8080Display.h +++ /dev/null @@ -1,136 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class St7796i8080Display : public tt::hal::display::DisplayDevice { -public: - struct Configuration { - // Pin configuration - gpio_num_t csPin; - gpio_num_t dcPin; - gpio_num_t wrPin; - std::array dataPins; - gpio_num_t resetPin; - gpio_num_t backlightPin; - - // Display resolution configuration - uint16_t horizontalResolution; - uint16_t verticalResolution; - - // Bus configuration - unsigned int pixelClockFrequency = 20 * 1000 * 1000; // 20MHz default - size_t busWidth = 8; // 8-bit bus - size_t transactionQueueDepth = 10; - size_t bufferSize = 0; // Will be calculated if 0 - - // LCD command/parameter configuration - int lcdCmdBits = 8; - int lcdParamBits = 8; - - // DC line level configuration - struct { - bool dcIdleLevel = 0; - bool dcCmdLevel = 0; - bool dcDummyLevel = 0; - bool dcDataLevel = 1; - } dcLevels; - - // Bus flags - struct { - bool csActiveHigh = false; - bool reverseColorBits = false; - bool swapColorBytes = true; - bool pclkActiveNeg = false; - bool pclkIdleLow = false; - } flags; - - // Display configuration - bool swapXY = false; - bool mirrorX = false; - bool mirrorY = false; - bool invertColor = true; - - // Additional features - std::shared_ptr touch = nullptr; - std::function backlightDutyFunction = nullptr; - - // Basic constructor - requires resolution to be set separately - Configuration(gpio_num_t cs, gpio_num_t dc, gpio_num_t wr, - std::array data, gpio_num_t rst, gpio_num_t bl) - : csPin(cs), dcPin(dc), wrPin(wr), dataPins(data), resetPin(rst), backlightPin(bl), - horizontalResolution(0), verticalResolution(0) {} // Initialize to 0 - - // Method to calculate buffer size after resolution is set - void calculateBufferSize() { - if (bufferSize == 0 && horizontalResolution > 0 && verticalResolution > 0) { - bufferSize = horizontalResolution * verticalResolution / 10; - } - } - - // Validation method - bool isValid() const { - return horizontalResolution > 0 && verticalResolution > 0; - } - }; - -private: - Configuration configuration; - esp_lcd_i80_bus_handle_t i80BusHandle = nullptr; - esp_lcd_panel_io_handle_t ioHandle = nullptr; - esp_lcd_panel_handle_t panelHandle = nullptr; - lv_display_t* lvglDisplay = nullptr; - std::shared_ptr lock; - uint8_t* displayBuffer = nullptr; - - // Internal initialization methods - bool createI80Bus(); - bool createPanelIO(); - bool createPanel(); - -public: - explicit St7796i8080Display(const Configuration& config); - lv_display_t* getLvglDisplay() const override { return lvglDisplay; } - std::string getName() const override { return "I8080 ST7796"; } - std::string getDescription() const override { return "I8080-based ST7796 display"; } - - // Lifecycle - bool start() override; - bool stop() override; - bool startLvgl() override; - bool stopLvgl() override; - - // Capabilities - bool supportsLvgl() const override { return true; } - bool supportsDisplayDriver() const override { return false; } - bool supportsBacklightDuty() const override { return configuration.backlightDutyFunction != nullptr; } - - // Touch and backlight - std::shared_ptr getTouchDevice() override { return configuration.touch; } - std::shared_ptr getDisplayDriver() override { return nullptr; } - - void setBacklightDuty(uint8_t backlightDuty) override { - if (configuration.backlightDutyFunction != nullptr) { - configuration.backlightDutyFunction(backlightDuty); - } - } - - // Hardware access methods - esp_lcd_panel_io_handle_t getIoHandle() const { return ioHandle; } - esp_lcd_panel_handle_t getPanelHandle() const { return panelHandle; } - - // Resolution access methods - uint16_t getHorizontalResolution() const { return configuration.horizontalResolution; } - uint16_t getVerticalResolution() const { return configuration.verticalResolution; } -}; - -// Factory function for registration -std::shared_ptr createDisplay(); \ No newline at end of file diff --git a/Drivers/jd9853-module/CMakeLists.txt b/Drivers/jd9853-module/CMakeLists.txt index 558c8f620..64d600472 100644 --- a/Drivers/jd9853-module/CMakeLists.txt +++ b/Drivers/jd9853-module/CMakeLists.txt @@ -7,5 +7,5 @@ file(GLOB_RECURSE SOURCE_FILES "source/*.c*") tactility_add_module(jd9853-module SRCS ${SOURCE_FILES} INCLUDE_DIRS include/ - REQUIRES TactilityKernel platform-esp32 JD9853 esp_lcd driver + REQUIRES TactilityKernel platform-esp32 esp_lcd ) diff --git a/Drivers/jd9853-module/devicetree.yaml b/Drivers/jd9853-module/devicetree.yaml index a07d6f334..cdbdab294 100644 --- a/Drivers/jd9853-module/devicetree.yaml +++ b/Drivers/jd9853-module/devicetree.yaml @@ -1,3 +1,4 @@ dependencies: - TactilityKernel + - Platforms/platform-esp32 bindings: bindings diff --git a/Drivers/JD9853/include/esp_lcd_jd9853.h b/Drivers/jd9853-module/include/esp_lcd_jd9853.h similarity index 100% rename from Drivers/JD9853/include/esp_lcd_jd9853.h rename to Drivers/jd9853-module/include/esp_lcd_jd9853.h diff --git a/Drivers/JD9853/esp_lcd_jd9853.c b/Drivers/jd9853-module/source/esp_lcd_jd9853.c similarity index 98% rename from Drivers/JD9853/esp_lcd_jd9853.c rename to Drivers/jd9853-module/source/esp_lcd_jd9853.c index dea68f2e6..eb55a1847 100644 --- a/Drivers/JD9853/esp_lcd_jd9853.c +++ b/Drivers/jd9853-module/source/esp_lcd_jd9853.c @@ -1,5 +1,5 @@ +#include #include -#include "esp_lcd_jd9853.h" /* * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * @@ -8,16 +8,16 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_lcd_panel_interface.h" -#include "esp_lcd_panel_io.h" -#include "esp_lcd_panel_vendor.h" -#include "esp_lcd_panel_ops.h" -#include "esp_lcd_panel_commands.h" -#include "driver/gpio.h" -#include "esp_log.h" -#include "esp_check.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include static const char *TAG = "JD9853";