Touch and display driver subsystems reworked (and more) (#302)
- Refactored `TouchDevice`: it can now start/stop LVGL separately, and it has an optional `TouchDriver` interface - Refactored `DisplayDevice`: it can now start/stop LVGL separately, and it has an optional `DisplayDriver` interface - Updated all boards and drivers for above changes - LVGL can now be stopped and (re)started on the fly - Fixed issues with restarting Gui and Statusbar services - Refactored `Gui` service to be class and renamed `Gui` to `GuiService` - Fixed `Statusbar` service: forgot to deregister one of the icons - Updated `esp_lcd_st7701` to v1.1.3 - `lv_textarea_create()` now automatically registers the hardware keyboard hooks (by wrapping the function) - Fixed and updated `tactility.py` - Cleanup of a lot of code - `BootInitLvglBegin` and `BootInitLvglEnd` are replaced by `LvglStarted` and `LvglStopped`. - Introduced `tt::service::State` which is accessible via `tt::service::getState()` (and internally via `ServiceInstance`) - Started replacing `#define TAG` with `constexpr auto TAG = "..";`
This commit is contained in:
parent
15f4fbfdc6
commit
d875ade8cb
@ -5,7 +5,7 @@
|
|||||||
#include "tt_init.h"
|
#include "tt_init.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// extern const tt::app::AppManifest hello_world_app;
|
extern const tt::app::AppManifest hello_world_app;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ dependencies:
|
|||||||
espressif/esp_io_expander: "1.0.1"
|
espressif/esp_io_expander: "1.0.1"
|
||||||
espressif/esp_io_expander_tca95xx_16bit: "1.0.1"
|
espressif/esp_io_expander_tca95xx_16bit: "1.0.1"
|
||||||
espressif/esp_lcd_st7701:
|
espressif/esp_lcd_st7701:
|
||||||
version: "1.1.1"
|
version: "1.1.3"
|
||||||
rules:
|
rules:
|
||||||
- if: "target in [esp32s3, esp32p4]"
|
- if: "target in [esp32s3, esp32p4]"
|
||||||
espressif/esp_lcd_st7796:
|
espressif/esp_lcd_st7796:
|
||||||
|
|||||||
@ -32,5 +32,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
configuration->mirrorX = true;
|
configuration->mirrorX = true;
|
||||||
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||||
|
|
||||||
return std::make_shared<Ili934xDisplay>(std::move(configuration));
|
auto display = std::make_shared<Ili934xDisplay>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ bool initBoot() {
|
|||||||
|
|
||||||
// This display has a weird glitch with gamma during boot, which results in uneven dark gray colours.
|
// This display has a weird glitch with gamma during boot, which results in uneven dark gray colours.
|
||||||
// Setting gamma curve index to 0 doesn't work at boot for an unknown reason, so we set the curve index to 1:
|
// Setting gamma curve index to 0 doesn't work at boot for an unknown reason, so we set the curve index to 1:
|
||||||
tt::kernel::subscribeSystemEvent(tt::kernel::SystemEvent::BootInitLvglEnd, [](auto event) {
|
tt::kernel::subscribeSystemEvent(tt::kernel::SystemEvent::BootSplash, [](auto) {
|
||||||
auto display = tt::hal::findFirstDevice<tt::hal::display::DisplayDevice>(tt::hal::Device::Type::Display);
|
auto display = tt::hal::findFirstDevice<tt::hal::display::DisplayDevice>(tt::hal::Device::Type::Display);
|
||||||
assert(display != nullptr);
|
assert(display != nullptr);
|
||||||
tt::lvgl::lock(portMAX_DELAY);
|
tt::lvgl::lock(portMAX_DELAY);
|
||||||
|
|||||||
@ -35,5 +35,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
|
|
||||||
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||||
|
|
||||||
return std::make_shared<Ili934xDisplay>(std::move(configuration));
|
auto display = std::make_shared<Ili934xDisplay>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,5 +3,5 @@ file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS ${SOURCE_FILES}
|
SRCS ${SOURCE_FILES}
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd esp_lcd_st7701 esp_lcd_panel_io_additions GT911 PwmBacklight driver vfs fatfs
|
REQUIRES Tactility EspLcdCompat esp_lcd_st7701 esp_lcd_panel_io_additions GT911 PwmBacklight driver vfs fatfs
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,19 +1,17 @@
|
|||||||
#include "CydDisplay.h"
|
#include "CydDisplay.h"
|
||||||
#include "PwmBacklight.h"
|
|
||||||
|
|
||||||
#include <Gt911Touch.h>
|
#include <Gt911Touch.h>
|
||||||
|
#include <PwmBacklight.h>
|
||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
|
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include <esp_lcd_panel_rgb.h>
|
#include <esp_lcd_panel_rgb.h>
|
||||||
#include <esp_lcd_panel_ops.h>
|
#include <esp_lcd_panel_ops.h>
|
||||||
#include <esp_lcd_panel_io.h>
|
|
||||||
#include <esp_lcd_panel_io_additions.h>
|
#include <esp_lcd_panel_io_additions.h>
|
||||||
#include <esp_lcd_st7701.h>
|
#include <esp_lcd_st7701.h>
|
||||||
#include <esp_lvgl_port.h>
|
|
||||||
|
|
||||||
#define TAG "cyd_display"
|
constexpr auto TAG = "ST7701";
|
||||||
|
|
||||||
static const st7701_lcd_init_cmd_t st7701_lcd_init_cmds[] = {
|
static const st7701_lcd_init_cmd_t st7701_lcd_init_cmds[] = {
|
||||||
// {cmd, { data }, data_size, delay_ms}
|
// {cmd, { data }, data_size, delay_ms}
|
||||||
@ -58,9 +56,7 @@ static const st7701_lcd_init_cmd_t st7701_lcd_init_cmds[] = {
|
|||||||
{0x29, (uint8_t[]) {0x00}, 0, 0}, //Display On
|
{0x29, (uint8_t[]) {0x00}, 0, 0}, //Display On
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CydDisplay::start() {
|
bool CydDisplay::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) {
|
||||||
TT_LOG_I(TAG, "Starting");
|
|
||||||
|
|
||||||
spi_line_config_t line_config = {
|
spi_line_config_t line_config = {
|
||||||
.cs_io_type = IO_TYPE_GPIO,
|
.cs_io_type = IO_TYPE_GPIO,
|
||||||
.cs_gpio_num = GPIO_NUM_39,
|
.cs_gpio_num = GPIO_NUM_39,
|
||||||
@ -68,11 +64,13 @@ bool CydDisplay::start() {
|
|||||||
.scl_gpio_num = GPIO_NUM_48,
|
.scl_gpio_num = GPIO_NUM_48,
|
||||||
.sda_io_type = IO_TYPE_GPIO,
|
.sda_io_type = IO_TYPE_GPIO,
|
||||||
.sda_gpio_num = GPIO_NUM_47,
|
.sda_gpio_num = GPIO_NUM_47,
|
||||||
.io_expander = NULL,
|
.io_expander = nullptr,
|
||||||
};
|
};
|
||||||
esp_lcd_panel_io_3wire_spi_config_t panel_io_config = ST7701_PANEL_IO_3WIRE_SPI_CONFIG(line_config, 0);
|
esp_lcd_panel_io_3wire_spi_config_t panel_io_config = ST7701_PANEL_IO_3WIRE_SPI_CONFIG(line_config, 0);
|
||||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_3wire_spi(&panel_io_config, &ioHandle));
|
return esp_lcd_new_panel_io_3wire_spi(&panel_io_config, &outHandle) == ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CydDisplay::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) {
|
||||||
const esp_lcd_rgb_panel_config_t rgb_config = {
|
const esp_lcd_rgb_panel_config_t rgb_config = {
|
||||||
.clk_src = LCD_CLK_SRC_DEFAULT,
|
.clk_src = LCD_CLK_SRC_DEFAULT,
|
||||||
.timings = {
|
.timings = {
|
||||||
@ -179,7 +177,11 @@ bool CydDisplay::start() {
|
|||||||
TT_LOG_E(TAG, "Failed to turn display on");
|
TT_LOG_E(TAG, "Failed to turn display on");
|
||||||
}
|
}
|
||||||
|
|
||||||
const lvgl_port_display_cfg_t disp_cfg = {
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lvgl_port_display_cfg_t CydDisplay::getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) {
|
||||||
|
return {
|
||||||
.io_handle = ioHandle,
|
.io_handle = ioHandle,
|
||||||
.panel_handle = panelHandle,
|
.panel_handle = panelHandle,
|
||||||
.control_handle = nullptr,
|
.control_handle = nullptr,
|
||||||
@ -204,44 +206,29 @@ bool CydDisplay::start() {
|
|||||||
.direct_mode = false
|
.direct_mode = false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const lvgl_port_display_rgb_cfg_t rgb_cfg = {
|
lvgl_port_display_rgb_cfg_t CydDisplay::getLvglPortDisplayRgbConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) {
|
||||||
|
return {
|
||||||
.flags = {
|
.flags = {
|
||||||
.bb_mode = true,
|
.bb_mode = true,
|
||||||
.avoid_tearing = false
|
.avoid_tearing = false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
displayHandle = lvgl_port_add_disp_rgb(&disp_cfg, &rgb_cfg);
|
|
||||||
TT_LOG_I(TAG, "Finished");
|
|
||||||
return displayHandle != nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CydDisplay::stop() {
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable CydDisplay::getTouchDevice() {
|
||||||
assert(displayHandle != nullptr);
|
if (touchDevice == nullptr) {
|
||||||
|
|
||||||
lvgl_port_remove_disp(displayHandle);
|
|
||||||
|
|
||||||
if (esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayHandle = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable CydDisplay::createTouch() {
|
|
||||||
auto configuration = std::make_unique<Gt911Touch::Configuration>(
|
auto configuration = std::make_unique<Gt911Touch::Configuration>(
|
||||||
I2C_NUM_0,
|
I2C_NUM_0,
|
||||||
480,
|
480,
|
||||||
480
|
480
|
||||||
);
|
);
|
||||||
|
|
||||||
return std::make_shared<Gt911Touch>(std::move(configuration));
|
touchDevice = std::make_shared<Gt911Touch>(std::move(configuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
return touchDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CydDisplay::setBacklightDuty(uint8_t backlightDuty) {
|
void CydDisplay::setBacklightDuty(uint8_t backlightDuty) {
|
||||||
@ -249,5 +236,6 @@ void CydDisplay::setBacklightDuty(uint8_t backlightDuty) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
return std::make_shared<CydDisplay>();
|
auto display = std::make_shared<CydDisplay>();
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <EspLcdDisplay.h>
|
||||||
#include <esp_lcd_types.h>
|
#include<lvgl.h>
|
||||||
#include <lvgl.h>
|
|
||||||
|
|
||||||
class CydDisplay : public tt::hal::display::DisplayDevice {
|
class CydDisplay final : public EspLcdDisplay {
|
||||||
|
|
||||||
private:
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable touchDevice;
|
||||||
|
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
bool createIoHandle(esp_lcd_panel_io_handle_t& outHandle) override;
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
|
||||||
lv_display_t* displayHandle = nullptr;
|
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;
|
||||||
|
|
||||||
|
bool isRgbPanel() const override { return true; }
|
||||||
|
|
||||||
|
lvgl_port_display_rgb_cfg_t getLvglPortDisplayRgbConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::string getName() const final { return "ST7701S"; }
|
std::string getName() const override { return "ST7701S"; }
|
||||||
std::string getDescription() const final { return "RGB Display"; }
|
|
||||||
|
|
||||||
bool start() override;
|
std::string getDescription() const override { return "ST7701S RGB display"; }
|
||||||
|
|
||||||
bool stop() override;
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable getTouchDevice() override;
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() override;
|
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) override;
|
void setBacklightDuty(uint8_t backlightDuty) override;
|
||||||
bool supportsBacklightDuty() const override { return true; }
|
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
bool supportsBacklightDuty() const override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -34,5 +34,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
|
|
||||||
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||||
|
|
||||||
return std::make_shared<St7789Display>(std::move(configuration));
|
auto display = std::make_shared<St7789Display>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,5 +3,5 @@ file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS ${SOURCE_FILES}
|
SRCS ${SOURCE_FILES}
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port FT5x06 ST7789 PwmBacklight driver
|
REQUIRES Tactility FT5x06 ST7789 PwmBacklight driver
|
||||||
)
|
)
|
||||||
|
|||||||
@ -5,8 +5,6 @@
|
|||||||
#include <PwmBacklight.h>
|
#include <PwmBacklight.h>
|
||||||
#include <St7789Display.h>
|
#include <St7789Display.h>
|
||||||
|
|
||||||
#define TAG "crowpanel_display"
|
|
||||||
|
|
||||||
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
||||||
// Note for future changes: Reset pin is 48 and interrupt pin is 47
|
// Note for future changes: Reset pin is 48 and interrupt pin is 47
|
||||||
auto configuration = std::make_unique<Ft5x06Touch::Configuration>(
|
auto configuration = std::make_unique<Ft5x06Touch::Configuration>(
|
||||||
@ -39,5 +37,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
|
|
||||||
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||||
|
|
||||||
return std::make_shared<St7789Display>(std::move(configuration));
|
auto display = std::make_shared<St7789Display>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
#include <esp_lcd_types.h>
|
|
||||||
#include <lvgl.h>
|
|
||||||
|
|
||||||
class CrowPanelDisplay : public tt::hal::display::DisplayDevice {
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
bool poweredOn = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
std::string getName() const final { return "ST7789"; }
|
|
||||||
std::string getDescription() const final { return "SPI display"; }
|
|
||||||
|
|
||||||
bool start() override;
|
|
||||||
|
|
||||||
bool stop() override;
|
|
||||||
|
|
||||||
void setPowerOn(bool turnOn) override;
|
|
||||||
bool isPoweredOn() const override { return poweredOn; };
|
|
||||||
bool supportsPowerControl() const override { return true; }
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() override;
|
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) override;
|
|
||||||
bool supportsBacklightDuty() const override { return true; }
|
|
||||||
|
|
||||||
void setGammaCurve(uint8_t index) override;
|
|
||||||
uint8_t getGammaCurveCount() const override { return 4; };
|
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -36,5 +36,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
|
|
||||||
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||||
|
|
||||||
return std::make_shared<Ili9488Display>(std::move(configuration));
|
auto display = std::make_shared<Ili9488Display>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
#include <esp_lcd_types.h>
|
|
||||||
#include <lvgl.h>
|
|
||||||
|
|
||||||
class CrowPanelDisplay : public tt::hal::display::DisplayDevice {
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
bool poweredOn = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
std::string getName() const final { return "ST7789"; }
|
|
||||||
std::string getDescription() const final { return "SPI display"; }
|
|
||||||
|
|
||||||
bool start() override;
|
|
||||||
|
|
||||||
bool stop() override;
|
|
||||||
|
|
||||||
void setPowerOn(bool turnOn) override;
|
|
||||||
bool isPoweredOn() const override { return poweredOn; };
|
|
||||||
bool supportsPowerControl() const override { return true; }
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() override;
|
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) override;
|
|
||||||
bool supportsBacklightDuty() const override { return true; }
|
|
||||||
|
|
||||||
void setGammaCurve(uint8_t index) override;
|
|
||||||
uint8_t getGammaCurveCount() const override { return 4; };
|
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -35,5 +35,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
configuration->mirrorX = true;
|
configuration->mirrorX = true;
|
||||||
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||||
|
|
||||||
return std::make_shared<Ili934xDisplay>(std::move(configuration));
|
auto display = std::make_shared<Ili934xDisplay>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include "Tactility/hal/display/DisplayDevice.h"
|
||||||
#include <esp_lcd_types.h>
|
|
||||||
#include <lvgl.h>
|
|
||||||
|
|
||||||
class CrowPanelDisplay : public tt::hal::display::DisplayDevice {
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
bool poweredOn = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
std::string getName() const final { return "ST7789"; }
|
|
||||||
std::string getDescription() const final { return "SPI display"; }
|
|
||||||
|
|
||||||
bool start() override;
|
|
||||||
|
|
||||||
bool stop() override;
|
|
||||||
|
|
||||||
void setPowerOn(bool turnOn) override;
|
|
||||||
bool isPoweredOn() const override { return poweredOn; };
|
|
||||||
bool supportsPowerControl() const override { return true; }
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() override;
|
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) override;
|
|
||||||
bool supportsBacklightDuty() const override { return true; }
|
|
||||||
|
|
||||||
void setGammaCurve(uint8_t index) override;
|
|
||||||
uint8_t getGammaCurveCount() const override { return 4; };
|
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -42,5 +42,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
configuration->mirrorX = true;
|
configuration->mirrorX = true;
|
||||||
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||||
|
|
||||||
return std::make_shared<Ili9488Display>(std::move(configuration));
|
auto display = std::make_shared<Ili9488Display>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
#include <esp_lcd_types.h>
|
|
||||||
#include <lvgl.h>
|
|
||||||
|
|
||||||
class CrowPanelDisplay : public tt::hal::display::DisplayDevice {
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
bool poweredOn = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
std::string getName() const final { return "ST7789"; }
|
|
||||||
std::string getDescription() const final { return "SPI display"; }
|
|
||||||
|
|
||||||
bool start() override;
|
|
||||||
|
|
||||||
bool stop() override;
|
|
||||||
|
|
||||||
void setPowerOn(bool turnOn) override;
|
|
||||||
bool isPoweredOn() const override { return poweredOn; };
|
|
||||||
bool supportsPowerControl() const override { return true; }
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() override;
|
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) override;
|
|
||||||
bool supportsBacklightDuty() const override { return true; }
|
|
||||||
|
|
||||||
void setGammaCurve(uint8_t index) override;
|
|
||||||
uint8_t getGammaCurveCount() const override { return 4; };
|
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -3,8 +3,6 @@
|
|||||||
#include <Tactility/lvgl/LvglSync.h>
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||||
|
|
||||||
#include <esp_vfs_fat.h>
|
|
||||||
|
|
||||||
using tt::hal::sdcard::SpiSdCardDevice;
|
using tt::hal::sdcard::SpiSdCardDevice;
|
||||||
|
|
||||||
std::shared_ptr<SdCardDevice> createSdCard() {
|
std::shared_ptr<SdCardDevice> createSdCard() {
|
||||||
|
|||||||
@ -101,5 +101,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
driver::pwmbacklight::setBacklightDuty
|
driver::pwmbacklight::setBacklightDuty
|
||||||
);
|
);
|
||||||
|
|
||||||
return std::make_shared<RgbDisplay>(std::move(configuration));
|
auto display = std::make_shared<RgbDisplay>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -3,5 +3,5 @@ file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS ${SOURCE_FILES}
|
SRCS ${SOURCE_FILES}
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd ST7796 BQ27220 TCA8418 PwmBacklight driver esp_adc
|
REQUIRES Tactility esp_lcd ST7796 BQ27220 TCA8418 PwmBacklight driver esp_adc
|
||||||
)
|
)
|
||||||
|
|||||||
@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
#include <driver/spi_master.h>
|
#include <driver/spi_master.h>
|
||||||
|
|
||||||
#define TAG "TPAGER_display"
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
auto configuration = std::make_unique<St7796Display::Configuration>(
|
auto configuration = std::make_unique<St7796Display::Configuration>(
|
||||||
TPAGER_LCD_SPI_HOST,
|
TPAGER_LCD_SPI_HOST,
|
||||||
@ -26,5 +24,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
|
|
||||||
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||||
|
|
||||||
return std::make_shared<St7796Display>(std::move(configuration));
|
auto display = std::make_shared<St7796Display>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
#include <esp_lcd_types.h>
|
|
||||||
#include <lvgl.h>
|
|
||||||
|
|
||||||
class TpagerDisplay : public tt::hal::display::DisplayDevice {
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
bool poweredOn = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
std::string getName() const final { return "ST7796"; }
|
|
||||||
std::string getDescription() const final { return "SPI display"; }
|
|
||||||
|
|
||||||
bool start() override;
|
|
||||||
|
|
||||||
bool stop() override;
|
|
||||||
|
|
||||||
void setPowerOn(bool turnOn) override;
|
|
||||||
bool isPoweredOn() const override { return poweredOn; };
|
|
||||||
bool supportsPowerControl() const override { return true; }
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() override;
|
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) override;
|
|
||||||
bool supportsBacklightDuty() const override { return true; }
|
|
||||||
|
|
||||||
void setGammaCurve(uint8_t index) override;
|
|
||||||
uint8_t getGammaCurveCount() const override { return 4; };
|
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -161,7 +161,7 @@ void TpagerKeyboard::processKeyboard() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TpagerKeyboard::start(lv_display_t* display) {
|
bool TpagerKeyboard::startLvgl(lv_display_t* display) {
|
||||||
backlightOkay = initBacklight(BACKLIGHT, 30000, LEDC_TIMER_0, LEDC_CHANNEL_1);
|
backlightOkay = initBacklight(BACKLIGHT, 30000, LEDC_TIMER_0, LEDC_CHANNEL_1);
|
||||||
initEncoder();
|
initEncoder();
|
||||||
keypad->init(KB_ROWS, KB_COLS);
|
keypad->init(KB_ROWS, KB_COLS);
|
||||||
@ -195,7 +195,7 @@ bool TpagerKeyboard::start(lv_display_t* display) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TpagerKeyboard::stop() {
|
bool TpagerKeyboard::stopLvgl() {
|
||||||
assert(inputTimer);
|
assert(inputTimer);
|
||||||
inputTimer->stop();
|
inputTimer->stop();
|
||||||
inputTimer = nullptr;
|
inputTimer = nullptr;
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Tactility/TactilityCore.h>
|
|
||||||
#include <Tactility/hal/keyboard/KeyboardDevice.h>
|
#include <Tactility/hal/keyboard/KeyboardDevice.h>
|
||||||
|
|
||||||
#include <Tca8418.h>
|
#include <Tca8418.h>
|
||||||
@ -10,10 +9,7 @@
|
|||||||
|
|
||||||
#include <Tactility/Timer.h>
|
#include <Tactility/Timer.h>
|
||||||
|
|
||||||
|
class TpagerKeyboard final : public tt::hal::keyboard::KeyboardDevice {
|
||||||
class TpagerKeyboard : public tt::hal::keyboard::KeyboardDevice {
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
lv_indev_t* _Nullable kbHandle = nullptr;
|
lv_indev_t* _Nullable kbHandle = nullptr;
|
||||||
lv_indev_t* _Nullable encHandle = nullptr;
|
lv_indev_t* _Nullable encHandle = nullptr;
|
||||||
@ -36,13 +32,13 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
TpagerKeyboard(std::shared_ptr<Tca8418> tca) : keypad(std::move(tca)) {}
|
TpagerKeyboard(std::shared_ptr<Tca8418> tca) : keypad(std::move(tca)) {}
|
||||||
~TpagerKeyboard() {}
|
|
||||||
|
|
||||||
std::string getName() const final { return "T-Lora Pager Keyboard"; }
|
std::string getName() const override { return "T-Lora Pager Keyboard"; }
|
||||||
std::string getDescription() const final { return "I2C keyboard with encoder"; }
|
std::string getDescription() const override { return "T-Lora Pager I2C keyboard with encoder"; }
|
||||||
|
|
||||||
|
bool startLvgl(lv_display_t* display) override;
|
||||||
|
bool stopLvgl() override;
|
||||||
|
|
||||||
bool start(lv_display_t* display) override;
|
|
||||||
bool stop() override;
|
|
||||||
bool isAttached() const override;
|
bool isAttached() const override;
|
||||||
lv_indev_t* _Nullable getLvglIndev() override { return kbHandle; }
|
lv_indev_t* _Nullable getLvglIndev() override { return kbHandle; }
|
||||||
|
|
||||||
|
|||||||
@ -3,5 +3,5 @@ file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS ${SOURCE_FILES}
|
SRCS ${SOURCE_FILES}
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd ST7789 GT911 PwmBacklight driver esp_adc
|
REQUIRES Tactility EspLcdCompat ST7789 GT911 PwmBacklight driver esp_adc
|
||||||
)
|
)
|
||||||
|
|||||||
@ -41,5 +41,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
|
|
||||||
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
configuration->backlightDutyFunction = driver::pwmbacklight::setBacklightDuty;
|
||||||
|
|
||||||
return std::make_shared<St7789Display>(std::move(configuration));
|
auto display = std::make_shared<St7789Display>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include "Tactility/hal/display/DisplayDevice.h"
|
||||||
#include <esp_lcd_types.h>
|
|
||||||
#include <lvgl.h>
|
|
||||||
|
|
||||||
class TdeckDisplay : public tt::hal::display::DisplayDevice {
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
bool poweredOn = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
std::string getName() const final { return "ST7789"; }
|
|
||||||
std::string getDescription() const final { return "SPI display"; }
|
|
||||||
|
|
||||||
bool start() override;
|
|
||||||
|
|
||||||
bool stop() override;
|
|
||||||
|
|
||||||
void setPowerOn(bool turnOn) override;
|
|
||||||
bool isPoweredOn() const override { return poweredOn; };
|
|
||||||
bool supportsPowerControl() const override { return true; }
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() override;
|
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) override;
|
|
||||||
bool supportsBacklightDuty() const override { return true; }
|
|
||||||
|
|
||||||
void setGammaCurve(uint8_t index) override;
|
|
||||||
uint8_t getGammaCurveCount() const override { return 4; };
|
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
#define TDECK_KEYBOARD_I2C_BUS_HANDLE I2C_NUM_0
|
#define TDECK_KEYBOARD_I2C_BUS_HANDLE I2C_NUM_0
|
||||||
#define TDECK_KEYBOARD_SLAVE_ADDRESS 0x55
|
#define TDECK_KEYBOARD_SLAVE_ADDRESS 0x55
|
||||||
|
|
||||||
static inline bool keyboard_i2c_read(uint8_t* output) {
|
static bool keyboard_i2c_read(uint8_t* output) {
|
||||||
return tt::hal::i2c::masterRead(TDECK_KEYBOARD_I2C_BUS_HANDLE, TDECK_KEYBOARD_SLAVE_ADDRESS, output, 1, 100 / portTICK_PERIOD_MS);
|
return tt::hal::i2c::masterRead(TDECK_KEYBOARD_I2C_BUS_HANDLE, TDECK_KEYBOARD_SLAVE_ADDRESS, output, 1, 100 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ static void keyboard_read_callback(TT_UNUSED lv_indev_t* indev, lv_indev_data_t*
|
|||||||
last_buffer = read_buffer;
|
last_buffer = read_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TdeckKeyboard::start(lv_display_t* display) {
|
bool TdeckKeyboard::startLvgl(lv_display_t* display) {
|
||||||
deviceHandle = lv_indev_create();
|
deviceHandle = lv_indev_create();
|
||||||
lv_indev_set_type(deviceHandle, LV_INDEV_TYPE_KEYPAD);
|
lv_indev_set_type(deviceHandle, LV_INDEV_TYPE_KEYPAD);
|
||||||
lv_indev_set_read_cb(deviceHandle, &keyboard_read_callback);
|
lv_indev_set_read_cb(deviceHandle, &keyboard_read_callback);
|
||||||
@ -52,7 +52,7 @@ bool TdeckKeyboard::start(lv_display_t* display) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TdeckKeyboard::stop() {
|
bool TdeckKeyboard::stopLvgl() {
|
||||||
lv_indev_delete(deviceHandle);
|
lv_indev_delete(deviceHandle);
|
||||||
deviceHandle = nullptr;
|
deviceHandle = nullptr;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -5,19 +5,17 @@
|
|||||||
#include <esp_lcd_panel_io_interface.h>
|
#include <esp_lcd_panel_io_interface.h>
|
||||||
#include <esp_lcd_touch.h>
|
#include <esp_lcd_touch.h>
|
||||||
|
|
||||||
class TdeckKeyboard : public tt::hal::keyboard::KeyboardDevice {
|
class TdeckKeyboard final : public tt::hal::keyboard::KeyboardDevice {
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
lv_indev_t* _Nullable deviceHandle = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::string getName() const final { return "T-Deck Keyboard"; }
|
std::string getName() const override { return "T-Deck Keyboard"; }
|
||||||
std::string getDescription() const final { return "I2C keyboard"; }
|
std::string getDescription() const override { return "I2C keyboard"; }
|
||||||
|
|
||||||
bool start(lv_display_t* display) override;
|
bool startLvgl(lv_display_t* display) override;
|
||||||
bool stop() override;
|
bool stopLvgl() override;
|
||||||
bool isAttached() const override;
|
bool isAttached() const override;
|
||||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,10 +6,13 @@
|
|||||||
std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
||||||
auto configuration = std::make_unique<Ft6x36Touch::Configuration>(
|
auto configuration = std::make_unique<Ft6x36Touch::Configuration>(
|
||||||
I2C_NUM_0,
|
I2C_NUM_0,
|
||||||
GPIO_NUM_39
|
GPIO_NUM_39,
|
||||||
|
CORE2_LCD_HORIZONTAL_RESOLUTION,
|
||||||
|
CORE2_LCD_VERTICAL_RESOLUTION
|
||||||
);
|
);
|
||||||
|
|
||||||
return std::make_shared<Ft6x36Touch>(std::move(configuration));
|
auto touch = std::make_shared<Ft6x36Touch>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::touch::TouchDevice>(touch);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
@ -28,5 +31,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
return std::make_shared<Ili934xDisplay>(std::move(configuration));
|
auto display = std::make_shared<Ili934xDisplay>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#include <Tactility/TactilityCore.h>
|
#include <Tactility/TactilityCore.h>
|
||||||
#include "axp192/axp192.h"
|
#include "axp192/axp192.h"
|
||||||
|
|
||||||
#define TAG "core2_power"
|
constexpr auto TAG = "Core2Power";
|
||||||
|
|
||||||
extern axp192_t axpDevice;
|
extern axp192_t axpDevice;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "CoreS3Display.h"
|
#include "CoreS3Display.h"
|
||||||
|
|
||||||
#include "CoreS3Constants.h"
|
#include "CoreS3Constants.h"
|
||||||
|
|
||||||
#include <Ft5x06Touch.h>
|
#include <Ft5x06Touch.h>
|
||||||
@ -7,7 +6,7 @@
|
|||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
#include <Tactility/hal/i2c/I2c.h>
|
#include <Tactility/hal/i2c/I2c.h>
|
||||||
|
|
||||||
#define TAG "cores3"
|
constexpr auto TAG = "CoreS3Display";
|
||||||
|
|
||||||
static void setBacklightDuty(uint8_t backlightDuty) {
|
static void setBacklightDuty(uint8_t backlightDuty) {
|
||||||
const uint8_t voltage = 20 + ((8 * backlightDuty) / 255); // [0b00000, 0b11100] - under 20 is too dark
|
const uint8_t voltage = 20 + ((8 * backlightDuty) / 255); // [0b00000, 0b11100] - under 20 is too dark
|
||||||
@ -25,7 +24,8 @@ static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
|||||||
240
|
240
|
||||||
);
|
);
|
||||||
|
|
||||||
return std::make_shared<Ft5x06Touch>(std::move(configuration));
|
auto touch = std::make_shared<Ft5x06Touch>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::touch::TouchDevice>(touch);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
@ -46,5 +46,6 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
|
|
||||||
configuration->backlightDutyFunction = ::setBacklightDuty;
|
configuration->backlightDutyFunction = ::setBacklightDuty;
|
||||||
|
|
||||||
return std::make_shared<Ili934xDisplay>(std::move(configuration));
|
auto display = std::make_shared<Ili934xDisplay>(std::move(configuration));
|
||||||
|
return std::reinterpret_pointer_cast<tt::hal::display::DisplayDevice>(display);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "SdlTouch.h"
|
#include "SdlTouch.h"
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
/** Hack: variable comes from LvglTask.cpp */
|
/** Hack: variable comes from LvglTask.cpp */
|
||||||
extern lv_disp_t* displayHandle;
|
extern lv_disp_t* displayHandle;
|
||||||
@ -11,8 +10,8 @@ class SdlDisplay final : public tt::hal::display::DisplayDevice {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::string getName() const final { return "SDL Display"; }
|
std::string getName() const override { return "SDL Display"; }
|
||||||
std::string getDescription() const final { return ""; }
|
std::string getDescription() const override { return ""; }
|
||||||
|
|
||||||
bool start() override {
|
bool start() override {
|
||||||
return displayHandle != nullptr;
|
return displayHandle != nullptr;
|
||||||
@ -20,7 +19,11 @@ public:
|
|||||||
|
|
||||||
bool stop() override { tt_crash("Not supported"); }
|
bool stop() override { tt_crash("Not supported"); }
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() override { return std::make_shared<SdlTouch>(); }
|
bool supportsLvgl() const override { return true; }
|
||||||
|
bool startLvgl() override { return true; }
|
||||||
|
bool stopLvgl() override { tt_crash("Not supported"); }
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable getTouchDevice() override { return std::make_shared<SdlTouch>(); }
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,20 +4,20 @@
|
|||||||
#include <Tactility/TactilityCore.h>
|
#include <Tactility/TactilityCore.h>
|
||||||
|
|
||||||
class SdlKeyboard final : public tt::hal::keyboard::KeyboardDevice {
|
class SdlKeyboard final : public tt::hal::keyboard::KeyboardDevice {
|
||||||
private:
|
|
||||||
lv_indev_t* _Nullable handle = nullptr;
|
lv_indev_t* _Nullable handle = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::string getName() const final { return "SDL Keyboard"; }
|
std::string getName() const override { return "SDL Keyboard"; }
|
||||||
std::string getDescription() const final { return "SDL keyboard device"; }
|
std::string getDescription() const override { return "SDL keyboard device"; }
|
||||||
|
|
||||||
bool start(lv_display_t* display) override {
|
bool startLvgl(lv_display_t* display) override {
|
||||||
handle = lv_sdl_keyboard_create();
|
handle = lv_sdl_keyboard_create();
|
||||||
return handle != nullptr;
|
return handle != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stop() override { tt_crash("Not supported"); }
|
bool stopLvgl() override { tt_crash("Not supported"); }
|
||||||
|
|
||||||
bool isAttached() const override { return true; }
|
bool isAttached() const override { return true; }
|
||||||
|
|
||||||
|
|||||||
@ -4,21 +4,32 @@
|
|||||||
#include <Tactility/TactilityCore.h>
|
#include <Tactility/TactilityCore.h>
|
||||||
|
|
||||||
class SdlTouch final : public tt::hal::touch::TouchDevice {
|
class SdlTouch final : public tt::hal::touch::TouchDevice {
|
||||||
private:
|
|
||||||
lv_indev_t* _Nullable handle = nullptr;
|
lv_indev_t* _Nullable handle = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
std::string getName() const final { return "SDL Pointer"; }
|
std::string getName() const override { return "SDL Mouse"; }
|
||||||
std::string getDescription() const final { return "SDL mouse/touch pointer device"; }
|
|
||||||
|
|
||||||
bool start(lv_display_t* display) override {
|
std::string getDescription() const override { return "SDL mouse/touch pointer device"; }
|
||||||
|
|
||||||
|
bool start() override { return true; }
|
||||||
|
|
||||||
|
bool stop() override { tt_crash("Not supported"); }
|
||||||
|
|
||||||
|
bool supportsLvgl() const override { return true; }
|
||||||
|
|
||||||
|
bool startLvgl(lv_display_t* display) override {
|
||||||
handle = lv_sdl_mouse_create();
|
handle = lv_sdl_mouse_create();
|
||||||
return handle != nullptr;
|
return handle != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stop() override { tt_crash("Not supported"); }
|
bool stopLvgl() override { tt_crash("Not supported"); }
|
||||||
|
|
||||||
lv_indev_t* _Nullable getLvglIndev() override { return handle; }
|
lv_indev_t* _Nullable getLvglIndev() override { return handle; }
|
||||||
|
|
||||||
|
bool supportsTouchDriver() override { return false; }
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDriver> _Nullable getTouchDriver() override { return nullptr; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -9,13 +9,13 @@
|
|||||||
#include <hx8357/disp_spi.h>
|
#include <hx8357/disp_spi.h>
|
||||||
#include <hx8357/hx8357.h>
|
#include <hx8357/hx8357.h>
|
||||||
|
|
||||||
#define TAG "unphone_display"
|
constexpr auto TAG = "UnPhoneDisplay";
|
||||||
#define BUFFER_SIZE (UNPHONE_LCD_HORIZONTAL_RESOLUTION * UNPHONE_LCD_DRAW_BUFFER_HEIGHT * LV_COLOR_DEPTH / 8)
|
constexpr auto BUFFER_SIZE = (UNPHONE_LCD_HORIZONTAL_RESOLUTION * UNPHONE_LCD_DRAW_BUFFER_HEIGHT * LV_COLOR_DEPTH / 8);
|
||||||
|
|
||||||
extern std::shared_ptr<UnPhoneFeatures> unPhoneFeatures;
|
extern std::shared_ptr<UnPhoneFeatures> unPhoneFeatures;
|
||||||
|
|
||||||
bool UnPhoneDisplay::start() {
|
bool UnPhoneDisplay::start() {
|
||||||
TT_LOG_I(TAG, "Starting");
|
TT_LOG_I(TAG, "start");
|
||||||
|
|
||||||
disp_spi_add_device(SPI2_HOST);
|
disp_spi_add_device(SPI2_HOST);
|
||||||
|
|
||||||
@ -24,39 +24,75 @@ bool UnPhoneDisplay::start() {
|
|||||||
uint8_t madctl = (1U << MADCTL_BIT_INDEX_COLUMN_ADDRESS_ORDER);
|
uint8_t madctl = (1U << MADCTL_BIT_INDEX_COLUMN_ADDRESS_ORDER);
|
||||||
hx8357_set_madctl(madctl);
|
hx8357_set_madctl(madctl);
|
||||||
|
|
||||||
displayHandle = lv_display_create(UNPHONE_LCD_HORIZONTAL_RESOLUTION, UNPHONE_LCD_VERTICAL_RESOLUTION);
|
return true;
|
||||||
lv_display_set_physical_resolution(displayHandle, UNPHONE_LCD_HORIZONTAL_RESOLUTION, UNPHONE_LCD_VERTICAL_RESOLUTION);
|
}
|
||||||
lv_display_set_color_format(displayHandle, LV_COLOR_FORMAT_NATIVE);
|
|
||||||
|
bool UnPhoneDisplay::stop() {
|
||||||
|
TT_LOG_I(TAG, "stop");
|
||||||
|
disp_spi_remove_device();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnPhoneDisplay::startLvgl() {
|
||||||
|
TT_LOG_I(TAG, "startLvgl");
|
||||||
|
|
||||||
|
if (lvglDisplay != nullptr) {
|
||||||
|
TT_LOG_W(TAG, "LVGL was already started");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lvglDisplay = lv_display_create(UNPHONE_LCD_HORIZONTAL_RESOLUTION, UNPHONE_LCD_VERTICAL_RESOLUTION);
|
||||||
|
lv_display_set_physical_resolution(lvglDisplay, UNPHONE_LCD_HORIZONTAL_RESOLUTION, UNPHONE_LCD_VERTICAL_RESOLUTION);
|
||||||
|
lv_display_set_color_format(lvglDisplay, LV_COLOR_FORMAT_NATIVE);
|
||||||
|
|
||||||
// TODO malloc to use SPIRAM
|
// TODO malloc to use SPIRAM
|
||||||
buffer = (uint8_t*)heap_caps_malloc(BUFFER_SIZE, MALLOC_CAP_DMA);
|
buffer = static_cast<uint8_t*>(heap_caps_malloc(BUFFER_SIZE, MALLOC_CAP_DMA));
|
||||||
assert(buffer != nullptr);
|
assert(buffer != nullptr);
|
||||||
|
|
||||||
lv_display_set_buffers(
|
lv_display_set_buffers(
|
||||||
displayHandle,
|
lvglDisplay,
|
||||||
buffer,
|
buffer,
|
||||||
nullptr,
|
nullptr,
|
||||||
BUFFER_SIZE,
|
BUFFER_SIZE,
|
||||||
LV_DISPLAY_RENDER_MODE_PARTIAL
|
LV_DISPLAY_RENDER_MODE_PARTIAL
|
||||||
);
|
);
|
||||||
|
|
||||||
lv_display_set_flush_cb(displayHandle, hx8357_flush);
|
lv_display_set_flush_cb(lvglDisplay, hx8357_flush);
|
||||||
|
|
||||||
if (displayHandle != nullptr) {
|
if (lvglDisplay == nullptr) {
|
||||||
TT_LOG_I(TAG, "Finished");
|
|
||||||
unPhoneFeatures->setBacklightPower(true);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
TT_LOG_I(TAG, "Failed");
|
TT_LOG_I(TAG, "Failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unPhoneFeatures->setBacklightPower(true);
|
||||||
|
|
||||||
|
auto touch_device = getTouchDevice();
|
||||||
|
if (touch_device != nullptr) {
|
||||||
|
touch_device->startLvgl(lvglDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UnPhoneDisplay::stop() {
|
bool UnPhoneDisplay::stopLvgl() {
|
||||||
assert(displayHandle != nullptr);
|
TT_LOG_I(TAG, "stopLvgl");
|
||||||
|
|
||||||
lv_display_delete(displayHandle);
|
if (lvglDisplay == nullptr) {
|
||||||
displayHandle = nullptr;
|
TT_LOG_W(TAG, "LVGL was already stopped");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just in case
|
||||||
|
disp_wait_for_pending_transactions();
|
||||||
|
|
||||||
|
auto touch_device = getTouchDevice();
|
||||||
|
if (touch_device != nullptr && touch_device->getLvglIndev() != nullptr) {
|
||||||
|
TT_LOG_I(TAG, "Stopping touch device");
|
||||||
|
touch_device->stopLvgl();
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_display_delete(lvglDisplay);
|
||||||
|
lvglDisplay = nullptr;
|
||||||
|
|
||||||
heap_caps_free(buffer);
|
heap_caps_free(buffer);
|
||||||
buffer = nullptr;
|
buffer = nullptr;
|
||||||
@ -64,10 +100,21 @@ bool UnPhoneDisplay::stop() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable UnPhoneDisplay::createTouch() {
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable UnPhoneDisplay::getTouchDevice() {
|
||||||
return ::createTouch();
|
if (touchDevice == nullptr) {
|
||||||
|
touchDevice = std::reinterpret_pointer_cast<tt::hal::touch::TouchDevice>(createTouch());
|
||||||
|
TT_LOG_I(TAG, "Created touch device");
|
||||||
|
}
|
||||||
|
|
||||||
|
return touchDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
return std::make_shared<UnPhoneDisplay>();
|
return std::make_shared<UnPhoneDisplay>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UnPhoneDisplay::UnPhoneDisplayDriver::drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) {
|
||||||
|
lv_area_t area = { xStart, yStart, xEnd, yEnd };
|
||||||
|
hx8357_flush(nullptr, &area, (uint8_t*)pixelData);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@ -3,13 +3,24 @@
|
|||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include "Tactility/hal/display/DisplayDevice.h"
|
||||||
#include <esp_lcd_types.h>
|
#include <esp_lcd_types.h>
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
#include <Tactility/hal/display/DisplayDriver.h>
|
||||||
|
|
||||||
|
#include "UnPhoneDisplayConstants.h"
|
||||||
|
|
||||||
class UnPhoneDisplay : public tt::hal::display::DisplayDevice {
|
class UnPhoneDisplay : public tt::hal::display::DisplayDevice {
|
||||||
|
|
||||||
private:
|
uint8_t* _Nullable buffer = nullptr;
|
||||||
|
lv_display_t* _Nullable lvglDisplay = nullptr;
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable touchDevice;
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable nativeDisplay;
|
||||||
|
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
uint8_t* buffer = nullptr;
|
class UnPhoneDisplayDriver : public tt::hal::display::DisplayDriver {
|
||||||
|
tt::hal::display::ColorFormat getColorFormat() const override { return tt::hal::display::ColorFormat::RGB888; }
|
||||||
|
uint16_t getPixelWidth() const override { return UNPHONE_LCD_HORIZONTAL_RESOLUTION; }
|
||||||
|
uint16_t getPixelHeight() const override { return UNPHONE_LCD_VERTICAL_RESOLUTION; }
|
||||||
|
bool drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) override;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -20,9 +31,26 @@ public:
|
|||||||
|
|
||||||
bool stop() override;
|
bool stop() override;
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() override;
|
bool supportsLvgl() const override { return true; }
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
bool startLvgl() override;
|
||||||
|
|
||||||
|
bool stopLvgl() override;
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable getTouchDevice() override;
|
||||||
|
|
||||||
|
lv_display_t* _Nullable getLvglDisplay() const override { return lvglDisplay; }
|
||||||
|
|
||||||
|
// TODO: Set to true after fixing UnPhoneDisplayDriver
|
||||||
|
bool supportsDisplayDriver() const override { return false; }
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable getDisplayDriver() override {
|
||||||
|
if (nativeDisplay == nullptr) {
|
||||||
|
nativeDisplay = std::make_shared<UnPhoneDisplayDriver>();
|
||||||
|
}
|
||||||
|
assert(nativeDisplay != nullptr);
|
||||||
|
return nativeDisplay;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -55,6 +55,7 @@ if (DEFINED ENV{ESP_IDF_VERSION})
|
|||||||
add_compile_definitions(LV_CONF_PATH="${LVGL_CONFIG_FULL_PATH}/lv_conf_kconfig.h")
|
add_compile_definitions(LV_CONF_PATH="${LVGL_CONFIG_FULL_PATH}/lv_conf_kconfig.h")
|
||||||
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=esp_panic_handler" APPEND)
|
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=esp_panic_handler" APPEND)
|
||||||
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=esp_log_write" APPEND)
|
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=esp_log_write" APPEND)
|
||||||
|
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=lv_textarea_create" APPEND)
|
||||||
else ()
|
else ()
|
||||||
message("Building for sim target")
|
message("Building for sim target")
|
||||||
add_compile_definitions(CONFIG_TT_BOARD_ID="simulator")
|
add_compile_definitions(CONFIG_TT_BOARD_ID="simulator")
|
||||||
|
|||||||
@ -1,22 +1,22 @@
|
|||||||
# TODOs
|
# TODOs
|
||||||
|
|
||||||
|
- Revisit TinyUSB mouse idea: the bugs related to cleanup seem to be fixed in the library.
|
||||||
- Bug: When a Wi-Fi SSID is too long, then it fails to save the credentials
|
- Bug: When a Wi-Fi SSID is too long, then it fails to save the credentials
|
||||||
- Add a Keyboard setting app to override the behaviour of soft keyboard hiding (e.g. keyboard hardware is present, but user wants soft keyboard)
|
- Add a Keyboard setting app to override the behaviour of soft keyboard hiding (e.g. keyboard hardware is present, but the user wants to use a soft keyboard)
|
||||||
- HAL for display touch calibration
|
- HAL for display touch calibration
|
||||||
- Start using non_null (either via MS GSL, or custom)
|
- Start using non_null (either via MS GSL, or custom)
|
||||||
- `hal/Configuration.h` defines C function types: Use C++ std::function instead
|
- `hal/Configuration.h` defines C function types: Use C++ std::function instead
|
||||||
- Fix system time to not be 1980 (use build year as minimum)
|
- Fix system time to not be 1980 (use build year as a minimum). Consider keeping track of the last known time.
|
||||||
- Use std::span or string_view in StringUtils https://youtu.be/FRkJCvHWdwQ?t=2754
|
- Use std::span or string_view in StringUtils https://youtu.be/FRkJCvHWdwQ?t=2754
|
||||||
- Fix bug in T-Deck/etc: esp_lvgl_port settings has a large stack size (~9kB) to fix an issue where the T-Deck would get a stackoverflow. This sometimes happens when WiFi is auto-enabled and you open the app while it is still connecting.
|
- Fix bug in T-Deck/etc: esp_lvgl_port settings has a large stack size (~9kB) to fix an issue where the T-Deck would get a stackoverflow. This sometimes happens when WiFi is auto-enabled and you open the app while it is still connecting.
|
||||||
- Mutex: Implement give/take from ISR support (works only for non-recursive ones)
|
- Mutex: Implement give/take from ISR support (works only for non-recursive ones)
|
||||||
- Extend unPhone power driver: add charging status, usb connection status, etc.
|
- Extend unPhone power driver: add charging status, usb connection status, etc.
|
||||||
- Expose app::Paths to TactilityC
|
- Expose app::Paths to TactilityC
|
||||||
- Experiment with what happens when using C++ code in an external app (without using standard library!)
|
|
||||||
- Make a ledger for setting CPU affinity of various services and tasks
|
- Make a ledger for setting CPU affinity of various services and tasks
|
||||||
- CrashHandler: use "corrupted" flag
|
- CrashHandler: use "corrupted" flag
|
||||||
- CrashHandler: process other types of crashes (WDT?)
|
- CrashHandler: process other types of crashes (WDT?)
|
||||||
- Call tt::lvgl::isSyncSet after HAL init and show error (and crash?) when it is not set.
|
- Call tt::lvgl::isSyncSet after HAL init and show an error (and crash?) when it is not set.
|
||||||
- Create different partitions files for different ESP flash size targets (N4, N8, N16, N32)
|
- Create different partition files for different ESP flash size targets (N4, N8, N16, N32)
|
||||||
- T-Deck: Clear screen before turning on blacklight
|
- T-Deck: Clear screen before turning on blacklight
|
||||||
- T-Deck: Use knob for UI selection?
|
- T-Deck: Use knob for UI selection?
|
||||||
- Crash monitoring: Keep track of which system phase the app crashed in (e.g. which app in which state)
|
- Crash monitoring: Keep track of which system phase the app crashed in (e.g. which app in which state)
|
||||||
@ -26,28 +26,27 @@
|
|||||||
- Show a warning screen when a user plugs in the SD card on a device that only supports mounting at boot.
|
- Show a warning screen when a user plugs in the SD card on a device that only supports mounting at boot.
|
||||||
- Localisation of texts (load in boot app from sd?)
|
- Localisation of texts (load in boot app from sd?)
|
||||||
- Explore LVGL9's FreeRTOS functionality
|
- Explore LVGL9's FreeRTOS functionality
|
||||||
- External app loading: Check version of Tactility and check ESP target hardware, to check for compatibility.
|
- External app loading: Check version of Tactility and check ESP target hardware to check for compatibility.
|
||||||
- Scanning SD card for external apps and auto-register them (in a temporary register?)
|
- Scanning SD card for external apps and auto-register them (in a temporary register?)
|
||||||
- Support hot-plugging SD card
|
- Support hot-plugging SD card
|
||||||
- All drivers (e.g. display, touch, etc.) should call stop() in their destructor, or at least assert that they should not be running.
|
- All drivers (e.g. display, touch, etc.) should call stop() in their destructor, or at least assert that they should not be running.
|
||||||
- Use GPS time to set/update the current time
|
- Use GPS time to set/update the current time
|
||||||
- Investigate EEZ Studio
|
|
||||||
- Remove flex_flow from app_container in Gui.cpp
|
- Remove flex_flow from app_container in Gui.cpp
|
||||||
|
|
||||||
# Nice-to-haves
|
# Nice-to-haves
|
||||||
|
|
||||||
- Give external app a different icon. Allow an external app update their id, icon, type and name once they are running(and persist that info?). Loader will need to be able to find app by (external) location.
|
- Give external app a different icon. Allow an external app to update their id, icon, type and name once they are running (and persist that info?). Loader will need to be able to find app by (external) location.
|
||||||
- Audio player app
|
- Audio player app
|
||||||
- Audio recording app
|
- Audio recording app
|
||||||
- OTA updates
|
- OTA updates
|
||||||
- T-Deck Plus: Create separate board config?
|
- T-Deck Plus: Create separate board config?
|
||||||
- Support for displays with different DPI. Consider the layer-based system like on Android.
|
- Support for displays with different DPI. Consider the layer-based system like on Android.
|
||||||
- If present, use LED to show boot/wifi status
|
- If present, use LED to show boot/wifi status
|
||||||
- Capacity based on voltage: estimation for various devices uses linear voltage curve, but it should use some sort of battery discharge curve.
|
- Capacity based on voltage: estimation for various devices uses a linear voltage curve, but it should use some sort of battery discharge curve.
|
||||||
- Statusbar widget to show how much memory is in use?
|
- Statusbar widget to show how much memory is in use?
|
||||||
- Wrapper for Slider that shows "+" and "-" buttons, and also the value in a label.
|
- Wrapper for lvgl slider widget that shows "+" and "-" buttons, and also the value in a label.
|
||||||
- Files app: copy/paste actions
|
- Files app: copy/paste actions
|
||||||
- On crash, try to save current log to flash or SD card? (this is risky, though, so ask in Discord first)
|
- On crash, try to save the current log to flash or SD card? (this is risky, though, so ask in Discord first)
|
||||||
- Support more than 1 hardware keyboard (see lvgl::hardware_keyboard_set_indev()). LVGL init currently calls keyboard init, but that part should probably be done from the KeyboardDevice base class.
|
- Support more than 1 hardware keyboard (see lvgl::hardware_keyboard_set_indev()). LVGL init currently calls keyboard init, but that part should probably be done from the KeyboardDevice base class.
|
||||||
|
|
||||||
# App Ideas
|
# App Ideas
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "Source"
|
SRC_DIRS "Source"
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd_touch esp_lcd_touch_cst816s driver
|
REQUIRES Tactility EspLcdCompat esp_lcd_touch_cst816s driver
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Tactility/hal/touch/TouchDevice.h>
|
#include <EspLcdTouch.h>
|
||||||
#include <esp_lcd_touch.h>
|
|
||||||
|
|
||||||
class Cst816sTouch final : public tt::hal::touch::TouchDevice {
|
class Cst816sTouch final : public EspLcdTouch {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -54,16 +53,18 @@ private:
|
|||||||
|
|
||||||
void cleanup();
|
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:
|
public:
|
||||||
|
|
||||||
explicit Cst816sTouch(std::unique_ptr<Configuration> inConfiguration) : configuration(std::move(inConfiguration)) {
|
explicit Cst816sTouch(std::unique_ptr<Configuration> inConfiguration) : configuration(std::move(inConfiguration)) {
|
||||||
assert(configuration != nullptr);
|
assert(configuration != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getName() const final { return "CST816S"; }
|
std::string getName() const override { return "CST816S"; }
|
||||||
std::string getDescription() const final { return "I2C touch driver"; }
|
std::string getDescription() const override { return "CST816S I2C touch driver"; }
|
||||||
|
|
||||||
bool start(lv_display_t* display) override;
|
|
||||||
bool stop() override;
|
|
||||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,25 +1,18 @@
|
|||||||
#include "Cst816Touch.h"
|
#include "Cst816Touch.h"
|
||||||
|
|
||||||
#include <Tactility/Log.h>
|
|
||||||
|
|
||||||
#include <driver/i2c.h>
|
|
||||||
#include <esp_err.h>
|
|
||||||
#include <esp_lcd_touch.h>
|
|
||||||
#include <esp_lcd_touch_cst816s.h>
|
#include <esp_lcd_touch_cst816s.h>
|
||||||
#include <esp_lvgl_port.h>
|
|
||||||
|
|
||||||
#define TAG "cst816s"
|
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::start(lv_display_t* display) {
|
bool Cst816sTouch::createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& touchConfiguration, esp_lcd_touch_handle_t& touchHandle) {
|
||||||
TT_LOG_I(TAG, "Starting");
|
return esp_lcd_touch_new_i2c_cst816s(ioHandle, &touchConfiguration, &touchHandle) == ESP_OK;
|
||||||
const esp_lcd_panel_io_i2c_config_t touch_io_config = ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG();
|
}
|
||||||
|
|
||||||
if (esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)configuration->port, &touch_io_config, &ioHandle) != ESP_OK) {
|
esp_lcd_touch_config_t Cst816sTouch::createEspLcdTouchConfig() {
|
||||||
TT_LOG_E(TAG, "Touch I2C IO init failed");
|
return {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_lcd_touch_config_t config = {
|
|
||||||
.x_max = configuration->xMax,
|
.x_max = configuration->xMax,
|
||||||
.y_max = configuration->yMax,
|
.y_max = configuration->yMax,
|
||||||
.rst_gpio_num = configuration->pinReset,
|
.rst_gpio_num = configuration->pinReset,
|
||||||
@ -38,47 +31,4 @@ bool Cst816sTouch::start(lv_display_t* display) {
|
|||||||
.user_data = nullptr,
|
.user_data = nullptr,
|
||||||
.driver_data = nullptr
|
.driver_data = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_touch_new_i2c_cst816s(ioHandle, &config, &touchHandle) != ESP_OK) {
|
|
||||||
TT_LOG_E(TAG, "Driver init failed");
|
|
||||||
cleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
|
||||||
.disp = display,
|
|
||||||
.handle = touchHandle,
|
|
||||||
};
|
|
||||||
|
|
||||||
deviceHandle = lvgl_port_add_touch(&touch_cfg);
|
|
||||||
if (deviceHandle == nullptr) {
|
|
||||||
TT_LOG_E(TAG, "Adding touch failed");
|
|
||||||
cleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TT_LOG_I(TAG, "Finished");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Cst816sTouch::stop() {
|
|
||||||
cleanup();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cst816sTouch::cleanup() {
|
|
||||||
if (deviceHandle != nullptr) {
|
|
||||||
lv_indev_delete(deviceHandle);
|
|
||||||
deviceHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touchHandle != nullptr) {
|
|
||||||
esp_lcd_touch_del(touchHandle);
|
|
||||||
touchHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioHandle != nullptr) {
|
|
||||||
esp_lcd_panel_io_del(ioHandle);
|
|
||||||
ioHandle = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
5
Drivers/EspLcdCompat/CMakeLists.txt
Normal file
5
Drivers/EspLcdCompat/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
idf_component_register(
|
||||||
|
SRC_DIRS "Source"
|
||||||
|
INCLUDE_DIRS "Source"
|
||||||
|
REQUIRES Tactility esp_lcd esp_lcd_touch esp_lvgl_port
|
||||||
|
)
|
||||||
3
Drivers/EspLcdCompat/README.md
Normal file
3
Drivers/EspLcdCompat/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# EspLcdCompat
|
||||||
|
|
||||||
|
A set of helper classes to implement `esp_lcd` drivers in Tactility.
|
||||||
102
Drivers/EspLcdCompat/Source/EspLcdDisplay.cpp
Normal file
102
Drivers/EspLcdCompat/Source/EspLcdDisplay.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include "EspLcdDisplay.h"
|
||||||
|
#include "EspLcdDisplayDriver.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <esp_lvgl_port_disp.h>
|
||||||
|
#include <Tactility/Check.h>
|
||||||
|
#include <Tactility/LogEsp.h>
|
||||||
|
#include <Tactility/hal/touch/TouchDevice.h>
|
||||||
|
|
||||||
|
constexpr const char* TAG = "EspLcdDispDrv";
|
||||||
|
|
||||||
|
EspLcdDisplay::~EspLcdDisplay() {
|
||||||
|
if (displayDriver != nullptr && displayDriver.use_count() > 1) {
|
||||||
|
tt_crash("DisplayDriver is still in use. This will cause memory access violations.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EspLcdDisplay::start() {
|
||||||
|
if (!createIoHandle(ioHandle)) {
|
||||||
|
TT_LOG_E(TAG, "Failed to create IO handle");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!createPanelHandle(ioHandle, panelHandle)) {
|
||||||
|
TT_LOG_E(TAG, "Failed to create panel handle");
|
||||||
|
esp_lcd_panel_io_del(ioHandle);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EspLcdDisplay::stop() {
|
||||||
|
if (lvglDisplay != nullptr) {
|
||||||
|
stopLvgl();
|
||||||
|
lvglDisplay = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panelHandle != nullptr && esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioHandle != nullptr && esp_lcd_panel_io_del(ioHandle) != ESP_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayDriver != nullptr && displayDriver.use_count() > 1) {
|
||||||
|
TT_LOG_W(TAG, "DisplayDriver is still in use.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EspLcdDisplay::startLvgl() {
|
||||||
|
assert(lvglDisplay == nullptr);
|
||||||
|
|
||||||
|
if (displayDriver != nullptr && displayDriver.use_count() > 1) {
|
||||||
|
TT_LOG_W(TAG, "DisplayDriver is still in use.");
|
||||||
|
}
|
||||||
|
|
||||||
|
lvglPortDisplayConfig = getLvglPortDisplayConfig(ioHandle, panelHandle);
|
||||||
|
|
||||||
|
if (isRgbPanel()) {
|
||||||
|
auto rgb_config = getLvglPortDisplayRgbConfig(ioHandle, panelHandle);
|
||||||
|
lvglDisplay = lvgl_port_add_disp_rgb(&lvglPortDisplayConfig, &rgb_config);
|
||||||
|
} else {
|
||||||
|
lvglDisplay = lvgl_port_add_disp(&lvglPortDisplayConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto touch_device = getTouchDevice();
|
||||||
|
if (touch_device != nullptr) {
|
||||||
|
touch_device->startLvgl(lvglDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lvglDisplay != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EspLcdDisplay::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<display::DisplayDriver> EspLcdDisplay::getDisplayDriver() {
|
||||||
|
assert(lvglDisplay == nullptr); // Still attached to LVGL context. Call stopLvgl() first.
|
||||||
|
if (displayDriver == nullptr) {
|
||||||
|
displayDriver = std::make_shared<EspLcdDisplayDriver>(
|
||||||
|
panelHandle,
|
||||||
|
lvglPortDisplayConfig
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return displayDriver;
|
||||||
|
}
|
||||||
60
Drivers/EspLcdCompat/Source/EspLcdDisplay.h
Normal file
60
Drivers/EspLcdCompat/Source/EspLcdDisplay.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
|
||||||
|
#include <esp_lcd_types.h>
|
||||||
|
#include <esp_lvgl_port_disp.h>
|
||||||
|
#include <Tactility/Check.h>
|
||||||
|
|
||||||
|
class EspLcdDisplay : tt::hal::display::DisplayDevice {
|
||||||
|
|
||||||
|
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
|
||||||
|
esp_lcd_panel_handle_t _Nullable panelHandle = nullptr;
|
||||||
|
lv_display_t* _Nullable lvglDisplay = nullptr;
|
||||||
|
lvgl_port_display_cfg_t _Nullable lvglPortDisplayConfig;
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable displayDriver;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Used for sending commands such as setting curves
|
||||||
|
esp_lcd_panel_io_handle_t getIoHandle() const { return ioHandle; }
|
||||||
|
|
||||||
|
virtual bool createIoHandle(esp_lcd_panel_io_handle_t& outHandle) = 0;
|
||||||
|
|
||||||
|
virtual bool createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) = 0;
|
||||||
|
|
||||||
|
virtual lvgl_port_display_cfg_t getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) = 0;
|
||||||
|
|
||||||
|
virtual bool isRgbPanel() const { return false; }
|
||||||
|
|
||||||
|
virtual lvgl_port_display_rgb_cfg_t getLvglPortDisplayRgbConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { tt_crash("Not supported"); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
~EspLcdDisplay() override;
|
||||||
|
|
||||||
|
bool start() final;
|
||||||
|
|
||||||
|
bool stop() final;
|
||||||
|
|
||||||
|
// region LVGL
|
||||||
|
|
||||||
|
bool supportsLvgl() const final { return true; }
|
||||||
|
|
||||||
|
bool startLvgl() final;
|
||||||
|
|
||||||
|
bool stopLvgl() final;
|
||||||
|
|
||||||
|
lv_display_t* _Nullable getLvglDisplay() const final { return lvglDisplay; }
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region NativeDisplay
|
||||||
|
|
||||||
|
bool supportsDisplayDriver() const override { return true; }
|
||||||
|
|
||||||
|
/** @return a NativeDisplay instance if this device supports it */
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable getDisplayDriver() final;
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
};
|
||||||
44
Drivers/EspLcdCompat/Source/EspLcdDisplayDriver.h
Normal file
44
Drivers/EspLcdCompat/Source/EspLcdDisplayDriver.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Tactility/hal/display/DisplayDriver.h>
|
||||||
|
#include <esp_lcd_panel_ops.h>
|
||||||
|
#include <esp_lvgl_port_disp.h>
|
||||||
|
|
||||||
|
using namespace tt::hal;
|
||||||
|
|
||||||
|
class EspLcdDisplayDriver : public display::DisplayDriver {
|
||||||
|
|
||||||
|
esp_lcd_panel_handle_t panelHandle;
|
||||||
|
const lvgl_port_display_cfg_t& lvglPortDisplayConfig;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EspLcdDisplayDriver(
|
||||||
|
esp_lcd_panel_handle_t panelHandle,
|
||||||
|
const lvgl_port_display_cfg_t& lvglPortDisplayConfig
|
||||||
|
) : panelHandle(panelHandle), lvglPortDisplayConfig(lvglPortDisplayConfig) {}
|
||||||
|
|
||||||
|
display::ColorFormat getColorFormat() const override {
|
||||||
|
using display::ColorFormat;
|
||||||
|
switch (lvglPortDisplayConfig.color_format) {
|
||||||
|
case LV_COLOR_FORMAT_I1:
|
||||||
|
return ColorFormat::Monochrome;
|
||||||
|
case LV_COLOR_FORMAT_RGB565:
|
||||||
|
// swap_bytes is only used for the 565 color format
|
||||||
|
// see lvgl_port_flush_callback() in esp_lvgl_port_disp.c
|
||||||
|
return lvglPortDisplayConfig.flags.swap_bytes ? ColorFormat::BGR565 : ColorFormat::RGB565;
|
||||||
|
case LV_COLOR_FORMAT_RGB888:
|
||||||
|
return ColorFormat::RGB888;
|
||||||
|
default:
|
||||||
|
return ColorFormat::RGB565;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) override {
|
||||||
|
return esp_lcd_panel_draw_bitmap(panelHandle, xStart, yStart, xEnd, yEnd, pixelData) == ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getPixelWidth() const override { return lvglPortDisplayConfig.hres; }
|
||||||
|
|
||||||
|
uint16_t getPixelHeight() const override { return lvglPortDisplayConfig.vres; }
|
||||||
|
};
|
||||||
92
Drivers/EspLcdCompat/Source/EspLcdTouch.cpp
Normal file
92
Drivers/EspLcdCompat/Source/EspLcdTouch.cpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include "EspLcdTouch.h"
|
||||||
|
|
||||||
|
#include <EspLcdTouchDriver.h>
|
||||||
|
#include <esp_lvgl_port_touch.h>
|
||||||
|
#include <Tactility/LogEsp.h>
|
||||||
|
|
||||||
|
constexpr const char* TAG = "EspLcdTouch";
|
||||||
|
|
||||||
|
bool EspLcdTouch::start() {
|
||||||
|
if (!createIoHandle(ioHandle) != ESP_OK) {
|
||||||
|
TT_LOG_E(TAG, "Touch IO failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = createEspLcdTouchConfig();
|
||||||
|
|
||||||
|
if (!createTouchHandle(ioHandle, config, touchHandle)) {
|
||||||
|
TT_LOG_E(TAG, "Driver init failed");
|
||||||
|
esp_lcd_panel_io_del(ioHandle);
|
||||||
|
ioHandle = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EspLcdTouch::stop() {
|
||||||
|
if (lvglDevice != nullptr) {
|
||||||
|
stopLvgl();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioHandle != nullptr) {
|
||||||
|
esp_lcd_panel_io_del(ioHandle);
|
||||||
|
ioHandle = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touchHandle != nullptr) {
|
||||||
|
esp_lcd_touch_del(touchHandle);
|
||||||
|
touchHandle = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EspLcdTouch::startLvgl(lv_disp_t* display) {
|
||||||
|
if (lvglDevice != nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touchDriver != nullptr && touchDriver.use_count() > 1) {
|
||||||
|
TT_LOG_W(TAG, "TouchDriver is still in use.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||||
|
.disp = display,
|
||||||
|
.handle = touchHandle,
|
||||||
|
};
|
||||||
|
|
||||||
|
TT_LOG_I(TAG, "Adding touch to LVGL");
|
||||||
|
lvglDevice = lvgl_port_add_touch(&touch_cfg);
|
||||||
|
if (lvglDevice == nullptr) {
|
||||||
|
TT_LOG_E(TAG, "Adding touch failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EspLcdTouch::stopLvgl() {
|
||||||
|
if (lvglDevice == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lvgl_port_remove_touch(lvglDevice);
|
||||||
|
lvglDevice = nullptr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDriver> _Nullable EspLcdTouch::getTouchDriver() {
|
||||||
|
assert(lvglDevice == nullptr); // Still attached to LVGL context. Call stopLvgl() first.
|
||||||
|
|
||||||
|
if (touchHandle == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touchDriver == nullptr) {
|
||||||
|
touchDriver = std::make_shared<EspLcdTouchDriver>(touchHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return touchDriver;
|
||||||
|
}
|
||||||
44
Drivers/EspLcdCompat/Source/EspLcdTouch.h
Normal file
44
Drivers/EspLcdCompat/Source/EspLcdTouch.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <esp_lcd_touch.h>
|
||||||
|
#include <esp_lcd_types.h>
|
||||||
|
#include <lvgl.h>
|
||||||
|
#include <Tactility/hal/touch/TouchDevice.h>
|
||||||
|
#include <Tactility/hal/touch/TouchDriver.h>
|
||||||
|
|
||||||
|
class EspLcdTouch : public tt::hal::touch::TouchDevice {
|
||||||
|
|
||||||
|
esp_lcd_touch_config_t config;
|
||||||
|
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
|
||||||
|
esp_lcd_touch_handle_t _Nullable touchHandle = nullptr;
|
||||||
|
lv_indev_t* _Nullable lvglDevice = nullptr;
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDriver> touchDriver;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
esp_lcd_touch_handle_t _Nullable getTouchHandle() const { return touchHandle; }
|
||||||
|
|
||||||
|
virtual bool createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) = 0;
|
||||||
|
|
||||||
|
virtual bool createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& configuration, esp_lcd_touch_handle_t& touchHandle) = 0;
|
||||||
|
|
||||||
|
virtual esp_lcd_touch_config_t createEspLcdTouchConfig() = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool start() final;
|
||||||
|
|
||||||
|
bool stop() final;
|
||||||
|
|
||||||
|
bool supportsLvgl() const final { return true; }
|
||||||
|
|
||||||
|
bool startLvgl(lv_display_t* display) final;
|
||||||
|
|
||||||
|
bool stopLvgl() final;
|
||||||
|
|
||||||
|
lv_indev_t* _Nullable getLvglIndev() final { return lvglDevice; }
|
||||||
|
|
||||||
|
bool supportsTouchDriver() override { return true; }
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDriver> _Nullable getTouchDriver() final;
|
||||||
|
};
|
||||||
13
Drivers/EspLcdCompat/Source/EspLcdTouchDriver.cpp
Normal file
13
Drivers/EspLcdCompat/Source/EspLcdTouchDriver.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "EspLcdTouchDriver.h"
|
||||||
|
|
||||||
|
#include <Tactility/LogEsp.h>
|
||||||
|
|
||||||
|
constexpr const char* TAG = "EspLcdTouchDriver";
|
||||||
|
|
||||||
|
bool EspLcdTouchDriver::getTouchedPoints(uint16_t* x, uint16_t* y, uint16_t* _Nullable strength, uint8_t* pointCount, uint8_t maxPointCount) {
|
||||||
|
if (esp_lcd_touch_read_data(handle) != ESP_OK) {
|
||||||
|
TT_LOG_E(TAG, "Read data failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return esp_lcd_touch_get_coordinates(handle, x, y, strength, pointCount, maxPointCount) == ESP_OK;
|
||||||
|
}
|
||||||
15
Drivers/EspLcdCompat/Source/EspLcdTouchDriver.h
Normal file
15
Drivers/EspLcdCompat/Source/EspLcdTouchDriver.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <esp_lcd_touch.h>
|
||||||
|
#include <Tactility/hal/touch/TouchDriver.h>
|
||||||
|
|
||||||
|
class EspLcdTouchDriver final : public tt::hal::touch::TouchDriver {
|
||||||
|
|
||||||
|
esp_lcd_touch_handle_t handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EspLcdTouchDriver(esp_lcd_touch_handle_t handle) : handle(handle) {}
|
||||||
|
|
||||||
|
bool getTouchedPoints(uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* pointCount, uint8_t maxPointCount) override;
|
||||||
|
};
|
||||||
@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "Source"
|
SRC_DIRS "Source"
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd_touch esp_lcd_touch_ft5x06 driver
|
REQUIRES Tactility EspLcdCompat esp_lcd_touch_ft5x06 driver
|
||||||
)
|
)
|
||||||
|
|||||||
@ -8,15 +8,17 @@
|
|||||||
|
|
||||||
#define TAG "ft5x06"
|
#define TAG "ft5x06"
|
||||||
|
|
||||||
bool Ft5x06Touch::start(lv_display_t* display) {
|
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();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if (esp_lcd_new_panel_io_i2c(configuration->port, &io_config, &ioHandle) != 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) {
|
||||||
TT_LOG_E(TAG, "Touch IO I2C creation failed");
|
return esp_lcd_touch_new_i2c_ft5x06(ioHandle, &configuration, &panelHandle) == ESP_OK;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
esp_lcd_touch_config_t config = {
|
esp_lcd_touch_config_t Ft5x06Touch::createEspLcdTouchConfig() {
|
||||||
|
return {
|
||||||
.x_max = configuration->xMax,
|
.x_max = configuration->xMax,
|
||||||
.y_max = configuration->yMax,
|
.y_max = configuration->yMax,
|
||||||
.rst_gpio_num = configuration->pinReset,
|
.rst_gpio_num = configuration->pinReset,
|
||||||
@ -35,47 +37,4 @@ bool Ft5x06Touch::start(lv_display_t* display) {
|
|||||||
.user_data = nullptr,
|
.user_data = nullptr,
|
||||||
.driver_data = nullptr
|
.driver_data = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_touch_new_i2c_ft5x06(ioHandle, &config, &touchHandle) != ESP_OK) {
|
|
||||||
TT_LOG_E(TAG, "Driver init failed");
|
|
||||||
cleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
|
||||||
.disp = display,
|
|
||||||
.handle = touchHandle,
|
|
||||||
};
|
|
||||||
|
|
||||||
TT_LOG_I(TAG, "Adding touch to LVGL");
|
|
||||||
deviceHandle = lvgl_port_add_touch(&touch_cfg);
|
|
||||||
if (deviceHandle == nullptr) {
|
|
||||||
TT_LOG_E(TAG, "Adding touch failed");
|
|
||||||
cleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Ft5x06Touch::stop() {
|
|
||||||
cleanup();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Ft5x06Touch::cleanup() {
|
|
||||||
if (deviceHandle != nullptr) {
|
|
||||||
lv_indev_delete(deviceHandle);
|
|
||||||
deviceHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touchHandle != nullptr) {
|
|
||||||
esp_lcd_touch_del(touchHandle);
|
|
||||||
touchHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioHandle != nullptr) {
|
|
||||||
esp_lcd_panel_io_del(ioHandle);
|
|
||||||
ioHandle = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,10 +4,9 @@
|
|||||||
#include <Tactility/TactilityCore.h>
|
#include <Tactility/TactilityCore.h>
|
||||||
#include <driver/i2c.h>
|
#include <driver/i2c.h>
|
||||||
|
|
||||||
#include <esp_lcd_panel_io_interface.h>
|
#include <EspLcdTouch.h>
|
||||||
#include <esp_lcd_touch.h>
|
|
||||||
|
|
||||||
class Ft5x06Touch final : public tt::hal::touch::TouchDevice {
|
class Ft5x06Touch final : public EspLcdTouch {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -52,11 +51,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<Configuration> configuration;
|
std::unique_ptr<Configuration> configuration;
|
||||||
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
|
|
||||||
esp_lcd_touch_handle_t _Nullable touchHandle = nullptr;
|
|
||||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
|
||||||
|
|
||||||
void cleanup();
|
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:
|
public:
|
||||||
|
|
||||||
@ -64,10 +64,7 @@ public:
|
|||||||
assert(configuration != nullptr);
|
assert(configuration != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start(lv_display_t* display) override;
|
std::string getName() const override { return "FT5x06"; }
|
||||||
bool stop() override;
|
|
||||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
|
||||||
|
|
||||||
std::string getName() const final { return "FT5x06"; }
|
std::string getDescription() const override { return "FT5x06 I2C touch driver"; }
|
||||||
std::string getDescription() const final { return "I2C Touch Driver"; }
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include "Ft6x36Touch.h"
|
#include "Ft6x36Touch.h"
|
||||||
|
|
||||||
|
#include <Ft6x36Touch.h>
|
||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
|
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
@ -7,22 +8,23 @@
|
|||||||
|
|
||||||
#define TAG "ft6x36"
|
#define TAG "ft6x36"
|
||||||
|
|
||||||
static void touchReadCallback(lv_indev_t* indev, lv_indev_data_t* data) {
|
void Ft6x36Touch::touchReadCallback(lv_indev_t* indev, lv_indev_data_t* data) {
|
||||||
auto* touch = (Ft6x36Touch*)lv_indev_get_driver_data(indev);
|
auto* touch = (Ft6x36Touch*)lv_indev_get_driver_data(indev);
|
||||||
touch->readLast(data);
|
touch->mutex.lock();
|
||||||
|
data->point = touch->lastPoint;
|
||||||
|
data->state = touch->lastState;
|
||||||
|
touch->mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ft6x36Touch::Ft6x36Touch(std::unique_ptr<Configuration> inConfiguration) :
|
Ft6x36Touch::Ft6x36Touch(std::unique_ptr<Configuration> inConfiguration) :
|
||||||
configuration(std::move(inConfiguration)),
|
configuration(std::move(inConfiguration)) {
|
||||||
driverThread(tt::Thread("ft6x36", 4096, [this]() {
|
nativeTouch = std::make_shared<Ft6TouchDriver>(*this);
|
||||||
driverThreadMain();
|
}
|
||||||
return 0;
|
|
||||||
}))
|
|
||||||
{}
|
|
||||||
|
|
||||||
Ft6x36Touch::~Ft6x36Touch() {
|
Ft6x36Touch::~Ft6x36Touch() {
|
||||||
if (driverThread.getState() != tt::Thread::State::Stopped) {
|
if (driverThread != nullptr && driverThread->getState() != tt::Thread::State::Stopped) {
|
||||||
stop();
|
interruptDriverThread = true;
|
||||||
|
driverThread->join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +61,7 @@ void Ft6x36Touch::driverThreadMain() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Ft6x36Touch::shouldInterruptDriverThread() {
|
bool Ft6x36Touch::shouldInterruptDriverThread() const {
|
||||||
bool interrupt = false;
|
bool interrupt = false;
|
||||||
if (mutex.lock(50 / portTICK_PERIOD_MS)) {
|
if (mutex.lock(50 / portTICK_PERIOD_MS)) {
|
||||||
interrupt = interruptDriverThread;
|
interrupt = interruptDriverThread;
|
||||||
@ -68,35 +70,65 @@ bool Ft6x36Touch::shouldInterruptDriverThread() {
|
|||||||
return interrupt;
|
return interrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Ft6x36Touch::start(lv_display_t* display) {
|
bool Ft6x36Touch::start() {
|
||||||
TT_LOG_I(TAG, "start");
|
TT_LOG_I(TAG, "Start");
|
||||||
|
|
||||||
driverThread.start();
|
if (!driver.begin(FT6X36_DEFAULT_THRESHOLD, configuration->width, configuration->height)) {
|
||||||
|
|
||||||
uint16_t width = lv_display_get_horizontal_resolution(display);
|
|
||||||
uint16_t height = lv_display_get_vertical_resolution(display);
|
|
||||||
if (!driver.begin(FT6X36_DEFAULT_THRESHOLD, width, height)) {
|
|
||||||
TT_LOG_E(TAG, "driver.begin() failed");
|
TT_LOG_E(TAG, "driver.begin() failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex.lock();
|
||||||
|
|
||||||
|
interruptDriverThread = false;
|
||||||
|
|
||||||
|
driverThread = std::make_shared<tt::Thread>("ft6x36", 4096, [this] {
|
||||||
|
driverThreadMain();
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
driverThread->start();
|
||||||
|
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Ft6x36Touch::stop() {
|
||||||
|
TT_LOG_I(TAG, "Stop");
|
||||||
|
|
||||||
|
mutex.lock();
|
||||||
|
interruptDriverThread = true;
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
driverThread->join();
|
||||||
|
|
||||||
|
mutex.lock();
|
||||||
|
driverThread = nullptr;
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Ft6x36Touch::startLvgl(lv_display_t* display) {
|
||||||
|
if (deviceHandle != nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
deviceHandle = lv_indev_create();
|
deviceHandle = lv_indev_create();
|
||||||
lv_indev_set_type(deviceHandle, LV_INDEV_TYPE_POINTER);
|
lv_indev_set_type(deviceHandle, LV_INDEV_TYPE_POINTER);
|
||||||
lv_indev_set_driver_data(deviceHandle, this);
|
lv_indev_set_driver_data(deviceHandle, this);
|
||||||
lv_indev_set_read_cb(deviceHandle, touchReadCallback);
|
lv_indev_set_read_cb(deviceHandle, touchReadCallback);
|
||||||
|
|
||||||
TT_LOG_I(TAG, "start success");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Ft6x36Touch::stop() {
|
bool Ft6x36Touch::stopLvgl() {
|
||||||
|
if (deviceHandle == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
lv_indev_delete(deviceHandle);
|
lv_indev_delete(deviceHandle);
|
||||||
interruptDriverThread = true;
|
deviceHandle = nullptr;
|
||||||
driverThread.join();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ft6x36Touch::readLast(lv_indev_data_t* data) {
|
|
||||||
data->point = lastPoint;
|
|
||||||
data->state = lastState;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -15,41 +15,78 @@ public:
|
|||||||
|
|
||||||
Configuration(
|
Configuration(
|
||||||
i2c_port_t port,
|
i2c_port_t port,
|
||||||
gpio_num_t pinInterrupt
|
gpio_num_t pinInterrupt,
|
||||||
|
uint16_t width,
|
||||||
|
uint16_t height
|
||||||
) : port(port),
|
) : port(port),
|
||||||
pinInterrupt(pinInterrupt)
|
pinInterrupt(pinInterrupt),
|
||||||
|
width(width),
|
||||||
|
height(height)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
i2c_port_t port;
|
i2c_port_t port;
|
||||||
gpio_num_t pinInterrupt;
|
gpio_num_t pinInterrupt;
|
||||||
};
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<Configuration> configuration;
|
std::unique_ptr<Configuration> configuration;
|
||||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
lv_indev_t* _Nullable deviceHandle = nullptr;
|
||||||
FT6X36 driver = FT6X36(configuration->port, configuration->pinInterrupt);
|
FT6X36 driver = FT6X36(configuration->port, configuration->pinInterrupt);
|
||||||
tt::Thread driverThread;
|
std::shared_ptr<tt::Thread> driverThread;
|
||||||
bool interruptDriverThread = false;
|
bool interruptDriverThread = false;
|
||||||
tt::Mutex mutex;
|
tt::Mutex mutex;
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDriver> nativeTouch;
|
||||||
|
|
||||||
lv_point_t lastPoint = { .x = 0, .y = 0 };
|
lv_point_t lastPoint = { .x = 0, .y = 0 };
|
||||||
lv_indev_state_t lastState = LV_INDEV_STATE_RELEASED;
|
lv_indev_state_t lastState = LV_INDEV_STATE_RELEASED;
|
||||||
|
|
||||||
bool shouldInterruptDriverThread();
|
bool shouldInterruptDriverThread() const;
|
||||||
|
|
||||||
|
void driverThreadMain();
|
||||||
|
|
||||||
|
static void touchReadCallback(lv_indev_t* indev, lv_indev_data_t* data);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit Ft6x36Touch(std::unique_ptr<Configuration> inConfiguration);
|
explicit Ft6x36Touch(std::unique_ptr<Configuration> inConfiguration);
|
||||||
~Ft6x36Touch() final;
|
~Ft6x36Touch() override;
|
||||||
|
|
||||||
std::string getName() const final { return "FT6x36"; }
|
std::string getName() const override { return "FT6x36"; }
|
||||||
std::string getDescription() const final { return "I2C touch driver"; }
|
std::string getDescription() const override { return "FT6x36 I2C touch driver"; }
|
||||||
|
|
||||||
bool start(lv_display_t* display) override;
|
bool start() override;
|
||||||
bool stop() override;
|
bool stop() override;
|
||||||
|
|
||||||
void readLast(lv_indev_data_t* data);
|
bool supportsLvgl() const override { return true; }
|
||||||
|
bool startLvgl(lv_display_t* display) override;
|
||||||
|
bool stopLvgl() override;
|
||||||
|
|
||||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||||
void driverThreadMain();
|
|
||||||
|
class Ft6TouchDriver : public tt::hal::touch::TouchDriver {
|
||||||
|
public:
|
||||||
|
const Ft6x36Touch& parent;
|
||||||
|
Ft6TouchDriver(const Ft6x36Touch& parent) : parent(parent) {}
|
||||||
|
|
||||||
|
bool getTouchedPoints(uint16_t* x, uint16_t* y, uint16_t* _Nullable strength, uint8_t* pointCount, uint8_t maxPointCount) {
|
||||||
|
auto lock = parent.mutex.asScopedLock();
|
||||||
|
lock.lock();
|
||||||
|
if (parent.lastState == LV_INDEV_STATE_PRESSED) {
|
||||||
|
*x = parent.lastPoint.x;
|
||||||
|
*y = parent.lastPoint.y;
|
||||||
|
*pointCount = 1;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
*pointCount = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool supportsTouchDriver() override { return true; }
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDriver> _Nullable getTouchDriver() override { return nativeTouch; }
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "Source"
|
SRC_DIRS "Source"
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd_touch esp_lcd_touch_gt911 driver
|
REQUIRES Tactility EspLcdCompat esp_lcd_touch_gt911 driver
|
||||||
)
|
)
|
||||||
|
|||||||
@ -5,11 +5,10 @@
|
|||||||
|
|
||||||
#include <esp_lcd_touch_gt911.h>
|
#include <esp_lcd_touch_gt911.h>
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include <esp_lvgl_port.h>
|
|
||||||
|
|
||||||
#define TAG "GT911"
|
#define TAG "GT911"
|
||||||
|
|
||||||
bool Gt911Touch::start(lv_display_t* display) {
|
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();
|
esp_lcd_panel_io_i2c_config_t io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,12 +25,15 @@ bool Gt911Touch::start(lv_display_t* display) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_lcd_new_panel_io_i2c(configuration->port, &io_config, &ioHandle) != ESP_OK) {
|
return esp_lcd_new_panel_io_i2c(configuration->port, &io_config, &outHandle) == ESP_OK;
|
||||||
TT_LOG_E(TAG, "Touch IO I2C creation failed");
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_lcd_touch_config_t config = {
|
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,
|
.x_max = configuration->xMax,
|
||||||
.y_max = configuration->yMax,
|
.y_max = configuration->yMax,
|
||||||
.rst_gpio_num = configuration->pinReset,
|
.rst_gpio_num = configuration->pinReset,
|
||||||
@ -50,43 +52,4 @@ bool Gt911Touch::start(lv_display_t* display) {
|
|||||||
.user_data = nullptr,
|
.user_data = nullptr,
|
||||||
.driver_data = nullptr
|
.driver_data = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_touch_new_i2c_gt911(ioHandle, &config, &touchHandle) != ESP_OK) {
|
|
||||||
TT_LOG_E(TAG, "Driver init failed");
|
|
||||||
cleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
|
||||||
.disp = display,
|
|
||||||
.handle = touchHandle,
|
|
||||||
};
|
|
||||||
|
|
||||||
TT_LOG_I(TAG, "Adding touch to LVGL");
|
|
||||||
deviceHandle = lvgl_port_add_touch(&touch_cfg);
|
|
||||||
if (deviceHandle == nullptr) {
|
|
||||||
TT_LOG_E(TAG, "Adding touch failed");
|
|
||||||
cleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Gt911Touch::stop() {
|
|
||||||
cleanup();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gt911Touch::cleanup() {
|
|
||||||
if (deviceHandle != nullptr) {
|
|
||||||
lv_indev_delete(deviceHandle);
|
|
||||||
deviceHandle = nullptr;
|
|
||||||
touchHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioHandle != nullptr) {
|
|
||||||
esp_lcd_panel_io_del(ioHandle);
|
|
||||||
ioHandle = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,10 +4,9 @@
|
|||||||
#include <Tactility/TactilityCore.h>
|
#include <Tactility/TactilityCore.h>
|
||||||
#include <driver/i2c.h>
|
#include <driver/i2c.h>
|
||||||
|
|
||||||
#include <esp_lcd_panel_io_interface.h>
|
#include <EspLcdTouch.h>
|
||||||
#include <esp_lcd_touch.h>
|
|
||||||
|
|
||||||
class Gt911Touch final : public tt::hal::touch::TouchDevice {
|
class Gt911Touch final : public EspLcdTouch {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -52,11 +51,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<Configuration> configuration;
|
std::unique_ptr<Configuration> configuration;
|
||||||
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
|
|
||||||
esp_lcd_touch_handle_t _Nullable touchHandle = nullptr;
|
|
||||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
|
||||||
|
|
||||||
void cleanup();
|
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:
|
public:
|
||||||
|
|
||||||
@ -64,10 +64,7 @@ public:
|
|||||||
assert(configuration != nullptr);
|
assert(configuration != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start(lv_display_t* display) override;
|
std::string getName() const override { return "GT911"; }
|
||||||
bool stop() override;
|
|
||||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
|
||||||
|
|
||||||
std::string getName() const final { return "GT911"; }
|
std::string getDescription() const override { return "GT911 I2C touch driver"; }
|
||||||
std::string getDescription() const final { return "I2C Touch Driver"; }
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "Source"
|
SRC_DIRS "Source"
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd esp_lcd_ili9341 driver
|
REQUIRES Tactility EspLcdCompat esp_lcd_ili9341 driver
|
||||||
)
|
)
|
||||||
|
|||||||
@ -6,11 +6,9 @@
|
|||||||
#include <esp_lcd_panel_commands.h>
|
#include <esp_lcd_panel_commands.h>
|
||||||
#include <esp_lvgl_port.h>
|
#include <esp_lvgl_port.h>
|
||||||
|
|
||||||
#define TAG "ili934x"
|
constexpr const char* TAG = "ILI934x";
|
||||||
|
|
||||||
bool Ili934xDisplay::start() {
|
|
||||||
TT_LOG_I(TAG, "Starting");
|
|
||||||
|
|
||||||
|
bool Ili934xDisplay::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) {
|
||||||
const esp_lcd_panel_io_spi_config_t panel_io_config = {
|
const esp_lcd_panel_io_spi_config_t panel_io_config = {
|
||||||
.cs_gpio_num = configuration->csPin,
|
.cs_gpio_num = configuration->csPin,
|
||||||
.dc_gpio_num = configuration->dcPin,
|
.dc_gpio_num = configuration->dcPin,
|
||||||
@ -35,11 +33,10 @@ bool Ili934xDisplay::start() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_new_panel_io_spi(configuration->spiBusHandle, &panel_io_config, &ioHandle) != ESP_OK) {
|
return esp_lcd_new_panel_io_spi(configuration->spiBusHandle, &panel_io_config, &outHandle) == ESP_OK;
|
||||||
TT_LOG_E(TAG, "Failed to create panel");
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
bool Ili934xDisplay::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) {
|
||||||
const esp_lcd_panel_dev_config_t panel_config = {
|
const esp_lcd_panel_dev_config_t panel_config = {
|
||||||
.reset_gpio_num = configuration->resetPin,
|
.reset_gpio_num = configuration->resetPin,
|
||||||
.rgb_ele_order = configuration->rgbElementOrder,
|
.rgb_ele_order = configuration->rgbElementOrder,
|
||||||
@ -86,18 +83,15 @@ bool Ili934xDisplay::start() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t buffer_size;
|
return true;
|
||||||
if (configuration->bufferSize == 0) {
|
}
|
||||||
buffer_size = configuration->horizontalResolution * configuration->verticalResolution / 10;
|
|
||||||
} else {
|
|
||||||
buffer_size = configuration->bufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lvgl_port_display_cfg_t disp_cfg = {
|
lvgl_port_display_cfg_t Ili934xDisplay::getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) {
|
||||||
|
return {
|
||||||
.io_handle = ioHandle,
|
.io_handle = ioHandle,
|
||||||
.panel_handle = panelHandle,
|
.panel_handle = panelHandle,
|
||||||
.control_handle = nullptr,
|
.control_handle = nullptr,
|
||||||
.buffer_size = buffer_size,
|
.buffer_size = configuration->bufferSize,
|
||||||
.double_buffer = false,
|
.double_buffer = false,
|
||||||
.trans_size = 0,
|
.trans_size = 0,
|
||||||
.hres = configuration->horizontalResolution,
|
.hres = configuration->horizontalResolution,
|
||||||
@ -118,28 +112,6 @@ bool Ili934xDisplay::start() {
|
|||||||
.direct_mode = false
|
.direct_mode = false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
displayHandle = lvgl_port_add_disp(&disp_cfg);
|
|
||||||
|
|
||||||
TT_LOG_I(TAG, "Finished");
|
|
||||||
return displayHandle != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Ili934xDisplay::stop() {
|
|
||||||
assert(displayHandle != nullptr);
|
|
||||||
|
|
||||||
lvgl_port_remove_disp(displayHandle);
|
|
||||||
|
|
||||||
if (esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayHandle = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,7 +146,7 @@ void Ili934xDisplay::setGammaCurve(uint8_t index) {
|
|||||||
gamma_curve
|
gamma_curve
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_panel_io_tx_param(ioHandle , LCD_CMD_GAMSET, param, 1) != ESP_OK) {
|
if (esp_lcd_panel_io_tx_param(getIoHandle() , LCD_CMD_GAMSET, param, 1) != ESP_OK) {
|
||||||
TT_LOG_E(TAG, "Failed to set gamma");
|
TT_LOG_E(TAG, "Failed to set gamma");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,9 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
|
||||||
class Ili934xDisplay final : public tt::hal::display::DisplayDevice {
|
#include <EspLcdDisplay.h>
|
||||||
|
|
||||||
|
class Ili934xDisplay final : public EspLcdDisplay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -41,8 +43,12 @@ public:
|
|||||||
invertColor(invertColor),
|
invertColor(invertColor),
|
||||||
bufferSize(bufferSize),
|
bufferSize(bufferSize),
|
||||||
rgbElementOrder(rgbElementOrder),
|
rgbElementOrder(rgbElementOrder),
|
||||||
touch(std::move(touch))
|
touch(std::move(touch)
|
||||||
{}
|
) {
|
||||||
|
if (this->bufferSize == 0) {
|
||||||
|
this->bufferSize = horizontalResolution * verticalResolution / 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esp_lcd_spi_bus_handle_t spiBusHandle;
|
esp_lcd_spi_bus_handle_t spiBusHandle;
|
||||||
gpio_num_t csPin;
|
gpio_num_t csPin;
|
||||||
@ -65,9 +71,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<Configuration> configuration;
|
std::unique_ptr<Configuration> configuration;
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
bool createIoHandle(esp_lcd_panel_io_handle_t& outHandle) override;
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
|
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:
|
public:
|
||||||
|
|
||||||
@ -75,25 +84,21 @@ public:
|
|||||||
assert(configuration != nullptr);
|
assert(configuration != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getName() const final { return "ILI934x"; }
|
std::string getName() const override { return "ILI934x"; }
|
||||||
std::string getDescription() const final { return "ILI934x display"; }
|
|
||||||
|
|
||||||
bool start() final;
|
std::string getDescription() const override { return "ILI934x display"; }
|
||||||
|
|
||||||
bool stop() final;
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable getTouchDevice() override { return configuration->touch; }
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() final { return configuration->touch; }
|
void setBacklightDuty(uint8_t backlightDuty) override {
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) final {
|
|
||||||
if (configuration->backlightDutyFunction != nullptr) {
|
if (configuration->backlightDutyFunction != nullptr) {
|
||||||
configuration->backlightDutyFunction(backlightDuty);
|
configuration->backlightDutyFunction(backlightDuty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportsBacklightDuty() const final { return configuration->backlightDutyFunction != nullptr; }
|
bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; }
|
||||||
|
|
||||||
void setGammaCurve(uint8_t index) final;
|
void setGammaCurve(uint8_t index) override;
|
||||||
uint8_t getGammaCurveCount() const final { return 4; };
|
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const final { return displayHandle; }
|
uint8_t getGammaCurveCount() const override { return 4; };
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "Source"
|
SRC_DIRS "Source"
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd esp_lcd_ili9488 driver
|
REQUIRES Tactility EspLcdCompat esp_lcd_ili9488 driver
|
||||||
)
|
)
|
||||||
|
|||||||
@ -6,11 +6,9 @@
|
|||||||
#include <esp_lcd_panel_commands.h>
|
#include <esp_lcd_panel_commands.h>
|
||||||
#include <esp_lvgl_port.h>
|
#include <esp_lvgl_port.h>
|
||||||
|
|
||||||
#define TAG "ili9488"
|
#define TAG "ILI9488"
|
||||||
|
|
||||||
bool Ili9488Display::start() {
|
|
||||||
TT_LOG_I(TAG, "Starting");
|
|
||||||
|
|
||||||
|
bool Ili9488Display::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) {
|
||||||
const esp_lcd_panel_io_spi_config_t panel_io_config = {
|
const esp_lcd_panel_io_spi_config_t panel_io_config = {
|
||||||
.cs_gpio_num = configuration->csPin,
|
.cs_gpio_num = configuration->csPin,
|
||||||
.dc_gpio_num = configuration->dcPin,
|
.dc_gpio_num = configuration->dcPin,
|
||||||
@ -35,10 +33,10 @@ bool Ili9488Display::start() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_new_panel_io_spi(configuration->spiBusHandle, &panel_io_config, &ioHandle) != ESP_OK) {
|
return esp_lcd_new_panel_io_spi(configuration->spiBusHandle, &panel_io_config, &outHandle) == ESP_OK;
|
||||||
TT_LOG_E(TAG, "Failed to create panel");
|
}
|
||||||
return false;
|
|
||||||
}
|
bool Ili9488Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) {
|
||||||
|
|
||||||
const esp_lcd_panel_dev_config_t panel_config = {
|
const esp_lcd_panel_dev_config_t panel_config = {
|
||||||
.reset_gpio_num = configuration->resetPin,
|
.reset_gpio_num = configuration->resetPin,
|
||||||
@ -51,14 +49,7 @@ bool Ili9488Display::start() {
|
|||||||
.vendor_config = nullptr
|
.vendor_config = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t buffer_size;
|
if (esp_lcd_new_panel_ili9488(ioHandle, &panel_config, configuration->bufferSize, &panelHandle) != ESP_OK) {
|
||||||
if (configuration->bufferSize == 0) {
|
|
||||||
buffer_size = configuration->horizontalResolution * configuration->verticalResolution / 20;
|
|
||||||
} else {
|
|
||||||
buffer_size = configuration->bufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_lcd_new_panel_ili9488(ioHandle, &panel_config, buffer_size, &panelHandle) != ESP_OK) {
|
|
||||||
TT_LOG_E(TAG, "Failed to create panel");
|
TT_LOG_E(TAG, "Failed to create panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -93,11 +84,16 @@ bool Ili9488Display::start() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lvgl_port_display_cfg_t disp_cfg = {
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lvgl_port_display_cfg_t Ili9488Display::getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) {
|
||||||
|
return {
|
||||||
.io_handle = ioHandle,
|
.io_handle = ioHandle,
|
||||||
.panel_handle = panelHandle,
|
.panel_handle = panelHandle,
|
||||||
.control_handle = nullptr,
|
.control_handle = nullptr,
|
||||||
.buffer_size = buffer_size,
|
.buffer_size = configuration->bufferSize,
|
||||||
.double_buffer = false,
|
.double_buffer = false,
|
||||||
.trans_size = 0,
|
.trans_size = 0,
|
||||||
.hres = configuration->horizontalResolution,
|
.hres = configuration->horizontalResolution,
|
||||||
@ -118,26 +114,4 @@ bool Ili9488Display::start() {
|
|||||||
.direct_mode = false
|
.direct_mode = false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
displayHandle = lvgl_port_add_disp(&disp_cfg);
|
|
||||||
|
|
||||||
TT_LOG_I(TAG, "Finished");
|
|
||||||
return displayHandle != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Ili9488Display::stop() {
|
|
||||||
assert(displayHandle != nullptr);
|
|
||||||
|
|
||||||
lvgl_port_remove_disp(displayHandle);
|
|
||||||
|
|
||||||
if (esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayHandle = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,14 +2,13 @@
|
|||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include "Tactility/hal/display/DisplayDevice.h"
|
||||||
|
|
||||||
#include <driver/spi_common.h>
|
#include <EspLcdDisplay.h>
|
||||||
|
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <esp_lcd_panel_io.h>
|
|
||||||
#include <esp_lcd_types.h>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
|
||||||
class Ili9488Display final : public tt::hal::display::DisplayDevice {
|
class Ili9488Display final : public EspLcdDisplay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -39,8 +38,11 @@ public:
|
|||||||
mirrorY(mirrorY),
|
mirrorY(mirrorY),
|
||||||
invertColor(invertColor),
|
invertColor(invertColor),
|
||||||
bufferSize(bufferSize),
|
bufferSize(bufferSize),
|
||||||
touch(std::move(touch))
|
touch(std::move(touch)) {
|
||||||
{}
|
if (this->bufferSize == 0) {
|
||||||
|
this->bufferSize = horizontalResolution * verticalResolution / 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esp_lcd_spi_bus_handle_t spiBusHandle;
|
esp_lcd_spi_bus_handle_t spiBusHandle;
|
||||||
gpio_num_t csPin;
|
gpio_num_t csPin;
|
||||||
@ -62,9 +64,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<Configuration> configuration;
|
std::unique_ptr<Configuration> configuration;
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
bool createIoHandle(esp_lcd_panel_io_handle_t& outHandle) override;
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
|
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:
|
public:
|
||||||
|
|
||||||
@ -72,24 +77,19 @@ public:
|
|||||||
assert(configuration != nullptr);
|
assert(configuration != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getName() const final { return "ILI9488"; }
|
std::string getName() const override { return "ILI9488"; }
|
||||||
std::string getDescription() const final { return "ILI9488 display"; }
|
|
||||||
|
|
||||||
bool start() final;
|
std::string getDescription() const override { return "ILI9488 display"; }
|
||||||
|
|
||||||
bool stop() final;
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable getTouchDevice() override { return configuration->touch; }
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() final { return configuration->touch; }
|
void setBacklightDuty(uint8_t backlightDuty) override {
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) final {
|
|
||||||
if (configuration->backlightDutyFunction != nullptr) {
|
if (configuration->backlightDutyFunction != nullptr) {
|
||||||
configuration->backlightDutyFunction(backlightDuty);
|
configuration->backlightDutyFunction(backlightDuty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportsBacklightDuty() const final { return configuration->backlightDutyFunction != nullptr; }
|
bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; }
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const final { return displayHandle; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "Source"
|
SRC_DIRS "Source"
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd
|
REQUIRES Tactility EspLcdCompat
|
||||||
)
|
)
|
||||||
|
|||||||
@ -6,8 +6,16 @@
|
|||||||
#include <esp_lcd_panel_rgb.h>
|
#include <esp_lcd_panel_rgb.h>
|
||||||
#include <esp_lcd_panel_ops.h>
|
#include <esp_lcd_panel_ops.h>
|
||||||
#include <esp_lvgl_port.h>
|
#include <esp_lvgl_port.h>
|
||||||
|
#include <Tactility/Check.h>
|
||||||
|
#include <Tactility/hal/touch/TouchDevice.h>
|
||||||
|
|
||||||
#define TAG "RgbDisplay"
|
constexpr auto TAG = "RgbDisplay";
|
||||||
|
|
||||||
|
RgbDisplay::~RgbDisplay() {
|
||||||
|
if (displayDriver != nullptr && displayDriver.use_count() > 1) {
|
||||||
|
tt_crash("DisplayDriver is still in use. This will cause memory access violations.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool RgbDisplay::start() {
|
bool RgbDisplay::start() {
|
||||||
TT_LOG_I(TAG, "Starting");
|
TT_LOG_I(TAG, "Starting");
|
||||||
@ -42,25 +50,85 @@ bool RgbDisplay::start() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto horizontal_resolution = configuration->panelConfig.timings.h_res;
|
return true;
|
||||||
auto vertical_resolution = configuration->panelConfig.timings.v_res;
|
}
|
||||||
|
|
||||||
uint32_t buffer_size;
|
bool RgbDisplay::stop() {
|
||||||
if (configuration->bufferConfiguration.size == 0) {
|
if (lvglDisplay != nullptr) {
|
||||||
buffer_size = horizontal_resolution * vertical_resolution / 15;
|
stopLvgl();
|
||||||
} else {
|
lvglDisplay = nullptr;
|
||||||
buffer_size = configuration->bufferConfiguration.size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const lvgl_port_display_cfg_t display_config = {
|
if (panelHandle != nullptr && esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
||||||
.io_handle = ioHandle,
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayDriver != nullptr && displayDriver.use_count() > 1) {
|
||||||
|
TT_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) {
|
||||||
|
TT_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);
|
||||||
|
TT_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,
|
.panel_handle = panelHandle,
|
||||||
.control_handle = nullptr,
|
.control_handle = nullptr,
|
||||||
.buffer_size = buffer_size,
|
.buffer_size = configuration->bufferConfiguration.size,
|
||||||
.double_buffer = configuration->bufferConfiguration.doubleBuffer,
|
.double_buffer = configuration->bufferConfiguration.doubleBuffer,
|
||||||
.trans_size = 0,
|
.trans_size = 0,
|
||||||
.hres = horizontal_resolution,
|
.hres = configuration->panelConfig.timings.h_res,
|
||||||
.vres = vertical_resolution,
|
.vres = configuration->panelConfig.timings.v_res,
|
||||||
.monochrome = false,
|
.monochrome = false,
|
||||||
.rotation = {
|
.rotation = {
|
||||||
.swap_xy = configuration->swapXY,
|
.swap_xy = configuration->swapXY,
|
||||||
@ -77,33 +145,5 @@ bool RgbDisplay::start() {
|
|||||||
.direct_mode = false
|
.direct_mode = false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const lvgl_port_display_rgb_cfg_t rgb_config = {
|
|
||||||
.flags = {
|
|
||||||
.bb_mode = configuration->bufferConfiguration.bounceBufferMode,
|
|
||||||
.avoid_tearing = configuration->bufferConfiguration.avoidTearing
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
displayHandle = lvgl_port_add_disp_rgb(&display_config, &rgb_config);
|
|
||||||
TT_LOG_I(TAG, "Finished");
|
|
||||||
|
|
||||||
return displayHandle != nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RgbDisplay::stop() {
|
|
||||||
assert(displayHandle != nullptr);
|
|
||||||
|
|
||||||
lvgl_port_remove_disp(displayHandle);
|
|
||||||
|
|
||||||
if (esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayHandle = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,14 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
#include <EspLcdDisplayDriver.h>
|
||||||
#include <esp_lcd_panel_rgb.h>
|
#include <esp_lcd_panel_rgb.h>
|
||||||
#include <esp_lcd_types.h>
|
|
||||||
#include <lvgl.h>
|
|
||||||
|
|
||||||
#include <utility>
|
class RgbDisplay final : public display::DisplayDevice {
|
||||||
|
|
||||||
class RgbDisplay : public tt::hal::display::DisplayDevice {
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -25,7 +21,7 @@ public:
|
|||||||
|
|
||||||
esp_lcd_rgb_panel_config_t panelConfig;
|
esp_lcd_rgb_panel_config_t panelConfig;
|
||||||
BufferConfiguration bufferConfiguration;
|
BufferConfiguration bufferConfiguration;
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> touch;
|
std::shared_ptr<touch::TouchDevice> touch;
|
||||||
lv_color_format_t colorFormat;
|
lv_color_format_t colorFormat;
|
||||||
bool swapXY;
|
bool swapXY;
|
||||||
bool mirrorX;
|
bool mirrorX;
|
||||||
@ -36,7 +32,7 @@ public:
|
|||||||
Configuration(
|
Configuration(
|
||||||
esp_lcd_rgb_panel_config_t panelConfig,
|
esp_lcd_rgb_panel_config_t panelConfig,
|
||||||
BufferConfiguration bufferConfiguration,
|
BufferConfiguration bufferConfiguration,
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> touch,
|
std::shared_ptr<touch::TouchDevice> touch,
|
||||||
lv_color_format_t colorFormat,
|
lv_color_format_t colorFormat,
|
||||||
bool swapXY = false,
|
bool swapXY = false,
|
||||||
bool mirrorX = false,
|
bool mirrorX = false,
|
||||||
@ -51,16 +47,23 @@ public:
|
|||||||
mirrorX(mirrorX),
|
mirrorX(mirrorX),
|
||||||
mirrorY(mirrorY),
|
mirrorY(mirrorY),
|
||||||
invertColor(invertColor),
|
invertColor(invertColor),
|
||||||
backlightDutyFunction(std::move(backlightDutyFunction))
|
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:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<Configuration> configuration = nullptr;
|
std::unique_ptr<Configuration> _Nullable configuration = nullptr;
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
esp_lcd_panel_handle_t _Nullable panelHandle = nullptr;
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
lv_display_t* _Nullable lvglDisplay = nullptr;
|
||||||
lv_display_t* displayHandle = nullptr;
|
std::shared_ptr<display::DisplayDriver> _Nullable displayDriver;
|
||||||
|
|
||||||
|
lvgl_port_display_cfg_t getLvglPortDisplayConfig() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -68,24 +71,41 @@ public:
|
|||||||
assert(configuration != nullptr);
|
assert(configuration != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getName() const final { return "RGB Display"; }
|
~RgbDisplay();
|
||||||
std::string getDescription() const final { return "RGB Display"; }
|
|
||||||
|
std::string getName() const override { return "RGB Display"; }
|
||||||
|
std::string getDescription() const override { return "RGB Display"; }
|
||||||
|
|
||||||
bool start() override;
|
bool start() override;
|
||||||
|
|
||||||
bool stop() override;
|
bool stop() override;
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() final { return configuration->touch; }
|
bool supportsLvgl() const override { return true; }
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) final {
|
bool startLvgl() override;
|
||||||
|
|
||||||
|
bool stopLvgl() override;
|
||||||
|
|
||||||
|
std::shared_ptr<touch::TouchDevice> _Nullable getTouchDevice() override { return configuration->touch; }
|
||||||
|
|
||||||
|
void setBacklightDuty(uint8_t backlightDuty) override {
|
||||||
if (configuration->backlightDutyFunction != nullptr) {
|
if (configuration->backlightDutyFunction != nullptr) {
|
||||||
configuration->backlightDutyFunction(backlightDuty);
|
configuration->backlightDutyFunction(backlightDuty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportsBacklightDuty() const final { return configuration->backlightDutyFunction != nullptr; }
|
bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; }
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
lv_display_t* _Nullable getLvglDisplay() const override { return lvglDisplay; }
|
||||||
|
|
||||||
|
bool supportsDisplayDriver() const override { return true; }
|
||||||
|
|
||||||
|
std::shared_ptr<display::DisplayDriver> _Nullable getDisplayDriver() override {
|
||||||
|
if (displayDriver == nullptr) {
|
||||||
|
displayDriver = std::make_shared<EspLcdDisplayDriver>(panelHandle, getLvglPortDisplayConfig());
|
||||||
|
}
|
||||||
|
return displayDriver;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "Source"
|
SRC_DIRS "Source"
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd driver
|
REQUIRES Tactility driver EspLcdCompat
|
||||||
)
|
)
|
||||||
|
|||||||
@ -7,9 +7,9 @@
|
|||||||
#include <esp_lcd_panel_st7789.h>
|
#include <esp_lcd_panel_st7789.h>
|
||||||
#include <esp_lvgl_port.h>
|
#include <esp_lvgl_port.h>
|
||||||
|
|
||||||
#define TAG "st7789"
|
constexpr auto TAG = "ST7789";
|
||||||
|
|
||||||
bool St7789Display::start() {
|
bool St7789Display::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) {
|
||||||
TT_LOG_I(TAG, "Starting");
|
TT_LOG_I(TAG, "Starting");
|
||||||
|
|
||||||
const esp_lcd_panel_io_spi_config_t panel_io_config = {
|
const esp_lcd_panel_io_spi_config_t panel_io_config = {
|
||||||
@ -36,11 +36,16 @@ bool St7789Display::start() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_new_panel_io_spi(configuration->spiBusHandle, &panel_io_config, &ioHandle) != ESP_OK) {
|
if (esp_lcd_new_panel_io_spi(configuration->spiBusHandle, &panel_io_config, &outHandle) != ESP_OK) {
|
||||||
TT_LOG_E(TAG, "Failed to create panel");
|
TT_LOG_E(TAG, "Failed to create panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool St7789Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) {
|
||||||
|
|
||||||
const esp_lcd_panel_dev_config_t panel_config = {
|
const esp_lcd_panel_dev_config_t panel_config = {
|
||||||
.reset_gpio_num = configuration->resetPin,
|
.reset_gpio_num = configuration->resetPin,
|
||||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
|
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
|
||||||
@ -86,18 +91,16 @@ bool St7789Display::start() {
|
|||||||
TT_LOG_E(TAG, "Failed to turn display on");
|
TT_LOG_E(TAG, "Failed to turn display on");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint32_t buffer_size;
|
|
||||||
if (configuration->bufferSize == 0) {
|
|
||||||
buffer_size = configuration->horizontalResolution * configuration->verticalResolution / 10;
|
|
||||||
} else {
|
|
||||||
buffer_size = configuration->bufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lvgl_port_display_cfg_t disp_cfg = {
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lvgl_port_display_cfg_t St7789Display::getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) {
|
||||||
|
return lvgl_port_display_cfg_t {
|
||||||
.io_handle = ioHandle,
|
.io_handle = ioHandle,
|
||||||
.panel_handle = panelHandle,
|
.panel_handle = panelHandle,
|
||||||
.control_handle = nullptr,
|
.control_handle = nullptr,
|
||||||
.buffer_size = buffer_size,
|
.buffer_size = configuration->bufferSize,
|
||||||
.double_buffer = false,
|
.double_buffer = false,
|
||||||
.trans_size = 0,
|
.trans_size = 0,
|
||||||
.hres = configuration->horizontalResolution,
|
.hres = configuration->horizontalResolution,
|
||||||
@ -118,30 +121,7 @@ bool St7789Display::start() {
|
|||||||
.direct_mode = false
|
.direct_mode = false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
displayHandle = lvgl_port_add_disp(&disp_cfg);
|
|
||||||
|
|
||||||
TT_LOG_I(TAG, "Finished");
|
|
||||||
return displayHandle != nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool St7789Display::stop() {
|
|
||||||
assert(displayHandle != nullptr);
|
|
||||||
|
|
||||||
lvgl_port_remove_disp(displayHandle);
|
|
||||||
|
|
||||||
if (esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayHandle = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note:
|
* Note:
|
||||||
* The datasheet implies this should work, but it doesn't:
|
* The datasheet implies this should work, but it doesn't:
|
||||||
@ -174,7 +154,9 @@ void St7789Display::setGammaCurve(uint8_t index) {
|
|||||||
gamma_curve
|
gamma_curve
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_panel_io_tx_param(ioHandle , LCD_CMD_GAMSET, param, 1) != ESP_OK) {
|
auto io_handle = getIoHandle();
|
||||||
|
assert(io_handle != nullptr);
|
||||||
|
if (esp_lcd_panel_io_tx_param(io_handle, LCD_CMD_GAMSET, param, 1) != ESP_OK) {
|
||||||
TT_LOG_E(TAG, "Failed to set gamma");
|
TT_LOG_E(TAG, "Failed to set gamma");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <EspLcdDisplay.h>
|
||||||
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
|
||||||
#include <driver/spi_common.h>
|
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <esp_lcd_panel_io.h>
|
#include <esp_lcd_panel_io.h>
|
||||||
#include <esp_lcd_types.h>
|
#include <esp_lcd_types.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
|
||||||
class St7789Display final : public tt::hal::display::DisplayDevice {
|
class St7789Display final : public EspLcdDisplay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -40,7 +40,11 @@ public:
|
|||||||
invertColor(invertColor),
|
invertColor(invertColor),
|
||||||
bufferSize(bufferSize),
|
bufferSize(bufferSize),
|
||||||
touch(std::move(touch))
|
touch(std::move(touch))
|
||||||
{}
|
{
|
||||||
|
if (this->bufferSize == 0) {
|
||||||
|
this->bufferSize = horizontalResolution * verticalResolution / 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esp_lcd_spi_bus_handle_t spiBusHandle;
|
esp_lcd_spi_bus_handle_t spiBusHandle;
|
||||||
gpio_num_t csPin;
|
gpio_num_t csPin;
|
||||||
@ -62,9 +66,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<Configuration> configuration;
|
std::unique_ptr<Configuration> configuration;
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
bool createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) override;
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
|
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:
|
public:
|
||||||
|
|
||||||
@ -72,27 +79,22 @@ public:
|
|||||||
assert(configuration != nullptr);
|
assert(configuration != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getName() const final { return "ST7789"; }
|
std::string getName() const override { return "ST7789"; }
|
||||||
std::string getDescription() const final { return "ST7789 display"; }
|
|
||||||
|
|
||||||
bool start() final;
|
std::string getDescription() const override { return "ST7789 display"; }
|
||||||
|
|
||||||
bool stop() final;
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable getTouchDevice() override { return configuration->touch; }
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() final { return configuration->touch; }
|
void setBacklightDuty(uint8_t backlightDuty) override {
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) final {
|
|
||||||
if (configuration->backlightDutyFunction != nullptr) {
|
if (configuration->backlightDutyFunction != nullptr) {
|
||||||
configuration->backlightDutyFunction(backlightDuty);
|
configuration->backlightDutyFunction(backlightDuty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportsBacklightDuty() const final { return configuration->backlightDutyFunction != nullptr; }
|
bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; }
|
||||||
|
|
||||||
void setGammaCurve(uint8_t index) final;
|
void setGammaCurve(uint8_t index) override;
|
||||||
uint8_t getGammaCurveCount() const final { return 4; };
|
uint8_t getGammaCurveCount() const override { return 4; };
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const final { return displayHandle; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "Source"
|
SRC_DIRS "Source"
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port esp_lcd_st7796 driver
|
REQUIRES Tactility EspLcdCompat esp_lcd_st7796 driver
|
||||||
)
|
)
|
||||||
|
|||||||
@ -2,16 +2,13 @@
|
|||||||
|
|
||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
|
|
||||||
#include <esp_lcd_panel_commands.h>
|
|
||||||
#include <esp_lcd_panel_dev.h>
|
#include <esp_lcd_panel_dev.h>
|
||||||
#include <esp_lcd_st7796.h>
|
#include <esp_lcd_st7796.h>
|
||||||
#include <esp_lvgl_port.h>
|
#include <esp_lvgl_port.h>
|
||||||
|
|
||||||
#define TAG "st7796"
|
constexpr auto TAG = "ST7796";
|
||||||
|
|
||||||
bool St7796Display::start() {
|
|
||||||
TT_LOG_I(TAG, "Starting");
|
|
||||||
|
|
||||||
|
bool St7796Display::createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) {
|
||||||
const esp_lcd_panel_io_spi_config_t panel_io_config = {
|
const esp_lcd_panel_io_spi_config_t panel_io_config = {
|
||||||
.cs_gpio_num = configuration->csPin,
|
.cs_gpio_num = configuration->csPin,
|
||||||
.dc_gpio_num = configuration->dcPin,
|
.dc_gpio_num = configuration->dcPin,
|
||||||
@ -36,11 +33,10 @@ bool St7796Display::start() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_new_panel_io_spi(configuration->spiBusHandle, &panel_io_config, &ioHandle) != ESP_OK) {
|
return esp_lcd_new_panel_io_spi(configuration->spiBusHandle, &panel_io_config, &ioHandle) == ESP_OK;
|
||||||
TT_LOG_E(TAG, "Failed to create panel");
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
bool St7796Display::createPanelHandle(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t& panelHandle) {
|
||||||
static const st7796_lcd_init_cmd_t lcd_init_cmds[] = {
|
static const st7796_lcd_init_cmd_t lcd_init_cmds[] = {
|
||||||
{0x01, (uint8_t[]) {0x00}, 0, 120},
|
{0x01, (uint8_t[]) {0x00}, 0, 120},
|
||||||
{0x11, (uint8_t[]) {0x00}, 0, 120},
|
{0x11, (uint8_t[]) {0x00}, 0, 120},
|
||||||
@ -69,7 +65,6 @@ bool St7796Display::start() {
|
|||||||
.init_cmds_size = sizeof(lcd_init_cmds) / sizeof(st7796_lcd_init_cmd_t),
|
.init_cmds_size = sizeof(lcd_init_cmds) / sizeof(st7796_lcd_init_cmd_t),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const esp_lcd_panel_dev_config_t panel_config = {
|
const esp_lcd_panel_dev_config_t panel_config = {
|
||||||
.reset_gpio_num = configuration->resetPin, // Set to -1 if not use
|
.reset_gpio_num = configuration->resetPin, // Set to -1 if not use
|
||||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||||
@ -92,7 +87,7 @@ bool St7796Display::start() {
|
|||||||
},
|
},
|
||||||
.vendor_config = nullptr
|
.vendor_config = nullptr
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
if (esp_lcd_new_panel_st7796(ioHandle, &panel_config, &panelHandle) != ESP_OK) {
|
if (esp_lcd_new_panel_st7796(ioHandle, &panel_config, &panelHandle) != ESP_OK) {
|
||||||
TT_LOG_E(TAG, "Failed to create panel");
|
TT_LOG_E(TAG, "Failed to create panel");
|
||||||
return false;
|
return false;
|
||||||
@ -133,18 +128,15 @@ bool St7796Display::start() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t buffer_size;
|
return true;
|
||||||
if (configuration->bufferSize == 0) {
|
}
|
||||||
buffer_size = configuration->horizontalResolution * configuration->verticalResolution / 10;
|
|
||||||
} else {
|
|
||||||
buffer_size = configuration->bufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lvgl_port_display_cfg_t disp_cfg = {
|
lvgl_port_display_cfg_t St7796Display::getLvglPortDisplayConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) {
|
||||||
|
return {
|
||||||
.io_handle = ioHandle,
|
.io_handle = ioHandle,
|
||||||
.panel_handle = panelHandle,
|
.panel_handle = panelHandle,
|
||||||
.control_handle = nullptr,
|
.control_handle = nullptr,
|
||||||
.buffer_size = buffer_size,
|
.buffer_size = configuration->bufferSize,
|
||||||
.double_buffer = false,
|
.double_buffer = false,
|
||||||
.trans_size = 0,
|
.trans_size = 0,
|
||||||
.hres = configuration->horizontalResolution,
|
.hres = configuration->horizontalResolution,
|
||||||
@ -158,28 +150,6 @@ bool St7796Display::start() {
|
|||||||
.color_format = LV_COLOR_FORMAT_NATIVE,
|
.color_format = LV_COLOR_FORMAT_NATIVE,
|
||||||
.flags = {.buff_dma = true, .buff_spiram = false, .sw_rotate = false, .swap_bytes = true, .full_refresh = false, .direct_mode = false}
|
.flags = {.buff_dma = true, .buff_spiram = false, .sw_rotate = false, .swap_bytes = true, .full_refresh = false, .direct_mode = false}
|
||||||
};
|
};
|
||||||
|
|
||||||
displayHandle = lvgl_port_add_disp(&disp_cfg);
|
|
||||||
|
|
||||||
TT_LOG_I(TAG, "Finished");
|
|
||||||
return displayHandle != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool St7796Display::stop() {
|
|
||||||
assert(displayHandle != nullptr);
|
|
||||||
|
|
||||||
lvgl_port_remove_disp(displayHandle);
|
|
||||||
|
|
||||||
if (esp_lcd_panel_del(panelHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_lcd_panel_io_del(ioHandle) != ESP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayHandle = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void St7796Display::setGammaCurve(uint8_t index) {
|
void St7796Display::setGammaCurve(uint8_t index) {
|
||||||
@ -200,6 +170,7 @@ void St7796Display::setGammaCurve(uint8_t index) {
|
|||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t param[] = {
|
const uint8_t param[] = {
|
||||||
gamma_curve
|
gamma_curve
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,15 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
#include <EspLcdDisplay.h>
|
||||||
|
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <driver/spi_common.h>
|
|
||||||
#include <esp_lcd_panel_io.h>
|
|
||||||
#include <esp_lcd_types.h>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <lvgl.h>
|
|
||||||
|
|
||||||
class St7796Display final : public tt::hal::display::DisplayDevice {
|
class St7796Display final : public EspLcdDisplay {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -43,7 +38,11 @@ public:
|
|||||||
gapX(gapX),
|
gapX(gapX),
|
||||||
gapY(gapY),
|
gapY(gapY),
|
||||||
bufferSize(bufferSize),
|
bufferSize(bufferSize),
|
||||||
touch(std::move(touch)) {}
|
touch(std::move(touch)) {
|
||||||
|
if (this->bufferSize == 0) {
|
||||||
|
this->bufferSize = horizontalResolution * verticalResolution / 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
esp_lcd_spi_bus_handle_t spiBusHandle;
|
esp_lcd_spi_bus_handle_t spiBusHandle;
|
||||||
gpio_num_t csPin;
|
gpio_num_t csPin;
|
||||||
@ -67,9 +66,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<Configuration> configuration;
|
std::unique_ptr<Configuration> configuration;
|
||||||
esp_lcd_panel_io_handle_t ioHandle = nullptr;
|
|
||||||
esp_lcd_panel_handle_t panelHandle = nullptr;
|
bool createIoHandle(esp_lcd_panel_io_handle_t& ioHandle) override;
|
||||||
lv_display_t* displayHandle = nullptr;
|
|
||||||
|
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:
|
public:
|
||||||
|
|
||||||
@ -77,27 +79,23 @@ public:
|
|||||||
assert(configuration != nullptr);
|
assert(configuration != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getName() const final { return "ST7796"; }
|
std::string getName() const override { return "ST7796"; }
|
||||||
std::string getDescription() const final { return "ST7796 display"; }
|
|
||||||
|
|
||||||
bool start() final;
|
std::string getDescription() const override { return "ST7796 display"; }
|
||||||
|
|
||||||
bool stop() final;
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable getTouchDevice() override { return configuration->touch; }
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable createTouch() final { return configuration->touch; }
|
void setBacklightDuty(uint8_t backlightDuty) override {
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t backlightDuty) final {
|
|
||||||
if (configuration->backlightDutyFunction != nullptr) {
|
if (configuration->backlightDutyFunction != nullptr) {
|
||||||
configuration->backlightDutyFunction(backlightDuty);
|
configuration->backlightDutyFunction(backlightDuty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGammaCurve(uint8_t index) final;
|
void setGammaCurve(uint8_t index) override;
|
||||||
uint8_t getGammaCurveCount() const final { return 4; };
|
|
||||||
|
|
||||||
bool supportsBacklightDuty() const final { return configuration->backlightDutyFunction != nullptr; }
|
uint8_t getGammaCurveCount() const override { return 4; };
|
||||||
|
|
||||||
lv_display_t* _Nullable getLvglDisplay() const final { return displayHandle; }
|
bool supportsBacklightDuty() const override { return configuration->backlightDutyFunction != nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "Source"
|
SRC_DIRS "Source"
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lcd_touch esp_lcd_touch_xpt2046
|
REQUIRES Tactility EspLcdCompat esp_lcd_touch_xpt2046
|
||||||
)
|
)
|
||||||
|
|||||||
@ -2,11 +2,28 @@
|
|||||||
#include "Xpt2046Touch.h"
|
#include "Xpt2046Touch.h"
|
||||||
|
|
||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
|
#include <Tactility/hal/Device.h>
|
||||||
|
|
||||||
#define TAG "xpt2046_power"
|
constexpr auto TAG = "Xpt2046Power";
|
||||||
|
constexpr auto BATTERY_VOLTAGE_MIN = 3.2f;
|
||||||
|
constexpr auto BATTERY_VOLTAGE_MAX = 4.2f;
|
||||||
|
constexpr auto MAX_VOLTAGE_SAMPLES = 15;
|
||||||
|
|
||||||
#define BATTERY_VOLTAGE_MIN 3.2f
|
static std::shared_ptr<Xpt2046Touch> findXp2046TouchDevice() {
|
||||||
#define BATTERY_VOLTAGE_MAX 4.2f
|
// Make a safe copy
|
||||||
|
auto touch = tt::hal::findFirstDevice<tt::hal::touch::TouchDevice>(tt::hal::Device::Type::Touch);
|
||||||
|
if (touch == nullptr) {
|
||||||
|
TT_LOG_E(TAG, "Touch device not found");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touch->getName() != "XPT2046") {
|
||||||
|
TT_LOG_E(TAG, "Touch device name mismatch");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::reinterpret_pointer_cast<Xpt2046Touch>(touch);
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t estimateChargeLevelFromVoltage(uint32_t milliVolt) {
|
static uint8_t estimateChargeLevelFromVoltage(uint32_t milliVolt) {
|
||||||
float volts = std::min((float)milliVolt / 1000.f, BATTERY_VOLTAGE_MAX);
|
float volts = std::min((float)milliVolt / 1000.f, BATTERY_VOLTAGE_MAX);
|
||||||
@ -47,25 +64,26 @@ bool Xpt2046Power::getMetric(MetricType type, MetricData& data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Xpt2046Power::readBatteryVoltageOnce(uint32_t& output) const {
|
bool Xpt2046Power::readBatteryVoltageOnce(uint32_t& output) {
|
||||||
// Make a safe copy
|
if (xptTouch == nullptr) {
|
||||||
auto touch = Xpt2046Touch::getInstance();
|
xptTouch = findXp2046TouchDevice();
|
||||||
if (touch != nullptr) {
|
if (xptTouch == nullptr) {
|
||||||
|
TT_LOG_E(TAG, "XPT2046 touch device not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float vbat;
|
float vbat;
|
||||||
if (touch->getVBat(vbat)) {
|
if (!xptTouch->getVBat(vbat)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert to mV
|
// Convert to mV
|
||||||
output = (uint32_t)(vbat * 1000.f);
|
output = (uint32_t)(vbat * 1000.f);
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Xpt2046Power::readBatteryVoltageSampled(uint32_t& output) {
|
||||||
#define MAX_VOLTAGE_SAMPLES 15
|
|
||||||
|
|
||||||
bool Xpt2046Power::readBatteryVoltageSampled(uint32_t& output) const {
|
|
||||||
size_t samples_read = 0;
|
size_t samples_read = 0;
|
||||||
uint32_t sample_accumulator = 0;
|
uint32_t sample_accumulator = 0;
|
||||||
uint32_t sample_read_buffer;
|
uint32_t sample_read_buffer;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Tactility/hal/power/PowerDevice.h>
|
#include <Tactility/hal/power/PowerDevice.h>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
|
class Xpt2046Touch;
|
||||||
using tt::hal::power::PowerDevice;
|
using tt::hal::power::PowerDevice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,9 +11,13 @@ using tt::hal::power::PowerDevice;
|
|||||||
*/
|
*/
|
||||||
class Xpt2046Power : public PowerDevice {
|
class Xpt2046Power : public PowerDevice {
|
||||||
|
|
||||||
|
std::shared_ptr<Xpt2046Touch> xptTouch;
|
||||||
|
|
||||||
|
bool readBatteryVoltageOnce(uint32_t& output);
|
||||||
|
bool readBatteryVoltageSampled(uint32_t& output);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Xpt2046Power() = default;
|
|
||||||
~Xpt2046Power() = default;
|
~Xpt2046Power() = default;
|
||||||
|
|
||||||
std::string getName() const final { return "XPT2046 Power Measurement"; }
|
std::string getName() const final { return "XPT2046 Power Measurement"; }
|
||||||
@ -22,10 +26,6 @@ public:
|
|||||||
bool supportsMetric(MetricType type) const override;
|
bool supportsMetric(MetricType type) const override;
|
||||||
bool getMetric(MetricType type, MetricData& data) override;
|
bool getMetric(MetricType type, MetricData& data) override;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
bool readBatteryVoltageOnce(uint32_t& output) const;
|
|
||||||
bool readBatteryVoltageSampled(uint32_t& output) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<PowerDevice> getOrCreatePower();
|
std::shared_ptr<PowerDevice> getOrCreatePower();
|
||||||
|
|||||||
@ -7,19 +7,19 @@
|
|||||||
#include <esp_lcd_touch_xpt2046.h>
|
#include <esp_lcd_touch_xpt2046.h>
|
||||||
#include <esp_lvgl_port.h>
|
#include <esp_lvgl_port.h>
|
||||||
|
|
||||||
#define TAG "xpt2046_touch"
|
|
||||||
|
|
||||||
Xpt2046Touch* Xpt2046Touch::instance = nullptr;
|
Xpt2046Touch* Xpt2046Touch::instance = nullptr;
|
||||||
|
|
||||||
bool Xpt2046Touch::start(lv_display_t* display) {
|
bool Xpt2046Touch::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) {
|
||||||
const esp_lcd_panel_io_spi_config_t io_config = ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(configuration->spiPinCs);
|
const esp_lcd_panel_io_spi_config_t io_config = ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(configuration->spiPinCs);
|
||||||
|
return esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &outHandle) == ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &ioHandle) != ESP_OK) {
|
bool Xpt2046Touch::createTouchHandle(esp_lcd_panel_io_handle_t ioHandle, const esp_lcd_touch_config_t& config, esp_lcd_touch_handle_t& panelHandle) {
|
||||||
TT_LOG_E(TAG, "Touch IO SPI creation failed");
|
return esp_lcd_touch_new_spi_xpt2046(ioHandle, &config, &panelHandle) == ESP_OK;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
esp_lcd_touch_config_t config = {
|
esp_lcd_touch_config_t Xpt2046Touch::createEspLcdTouchConfig() {
|
||||||
|
return {
|
||||||
.x_max = configuration->xMax,
|
.x_max = configuration->xMax,
|
||||||
.y_max = configuration->yMax,
|
.y_max = configuration->yMax,
|
||||||
.rst_gpio_num = GPIO_NUM_NC,
|
.rst_gpio_num = GPIO_NUM_NC,
|
||||||
@ -38,61 +38,20 @@ bool Xpt2046Touch::start(lv_display_t* display) {
|
|||||||
.user_data = nullptr,
|
.user_data = nullptr,
|
||||||
.driver_data = nullptr
|
.driver_data = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_touch_new_spi_xpt2046(ioHandle, &config, &touchHandle) != ESP_OK) {
|
|
||||||
TT_LOG_E(TAG, "XPT2046 driver init failed");
|
|
||||||
cleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
|
||||||
.disp = display,
|
|
||||||
.handle = touchHandle,
|
|
||||||
};
|
|
||||||
|
|
||||||
TT_LOG_I(TAG, "Adding touch to LVGL");
|
|
||||||
deviceHandle = lvgl_port_add_touch(&touch_cfg);
|
|
||||||
if (deviceHandle == nullptr) {
|
|
||||||
TT_LOG_E(TAG, "Adding touch failed");
|
|
||||||
cleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
instance = this;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Xpt2046Touch::stop() {
|
|
||||||
instance = nullptr;
|
|
||||||
cleanup();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Xpt2046Touch::cleanup() {
|
|
||||||
if (deviceHandle != nullptr) {
|
|
||||||
lv_indev_delete(deviceHandle);
|
|
||||||
deviceHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touchHandle != nullptr) {
|
|
||||||
esp_lcd_touch_del(touchHandle);
|
|
||||||
touchHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioHandle != nullptr) {
|
|
||||||
esp_lcd_panel_io_del(ioHandle);
|
|
||||||
ioHandle = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Xpt2046Touch::getVBat(float& outputVbat) {
|
bool Xpt2046Touch::getVBat(float& outputVbat) {
|
||||||
if (touchHandle != nullptr) {
|
auto touch_handle = getTouchHandle();
|
||||||
|
if (touch_handle == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Shares the SPI bus with the display, so we have to sync/lock as this method might be called from anywhere
|
// Shares the SPI bus with the display, so we have to sync/lock as this method might be called from anywhere
|
||||||
if (tt::lvgl::lock(50 / portTICK_PERIOD_MS)) {
|
if (!tt::lvgl::lock(50 / portTICK_PERIOD_MS)) {
|
||||||
esp_lcd_touch_xpt2046_read_battery_level(touchHandle, &outputVbat);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_lcd_touch_xpt2046_read_battery_level(touch_handle, &outputVbat);
|
||||||
tt::lvgl::unlock();
|
tt::lvgl::unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Tactility/hal/touch/TouchDevice.h"
|
#include <Tactility/hal/touch/TouchDevice.h>
|
||||||
|
|
||||||
#include <Tactility/TactilityCore.h>
|
#include <EspLcdTouch.h>
|
||||||
|
|
||||||
#include <esp_lcd_panel_io_interface.h>
|
class Xpt2046Touch : public EspLcdTouch {
|
||||||
#include <esp_lcd_touch.h>
|
|
||||||
|
|
||||||
class Xpt2046Touch : public tt::hal::touch::TouchDevice {
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -45,11 +42,12 @@ private:
|
|||||||
static Xpt2046Touch* instance;
|
static Xpt2046Touch* instance;
|
||||||
|
|
||||||
std::unique_ptr<Configuration> configuration;
|
std::unique_ptr<Configuration> configuration;
|
||||||
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
|
|
||||||
esp_lcd_touch_handle_t _Nullable touchHandle = nullptr;
|
|
||||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
|
||||||
|
|
||||||
void cleanup();
|
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:
|
public:
|
||||||
|
|
||||||
@ -58,14 +56,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string getName() const final { return "XPT2046"; }
|
std::string getName() const final { return "XPT2046"; }
|
||||||
std::string getDescription() const final { return "I2C touch driver"; }
|
|
||||||
|
|
||||||
bool start(lv_display_t* display) override;
|
std::string getDescription() const final { return "XPT2046 I2C touch driver"; }
|
||||||
bool stop() override;
|
|
||||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
|
||||||
|
|
||||||
bool getVBat(float& outputVbat);
|
bool getVBat(float& outputVbat);
|
||||||
|
|
||||||
/** Used for accessing getVBat() in Power driver */
|
|
||||||
static Xpt2046Touch* getInstance() { return instance; }
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,7 +17,7 @@ platform_targets = ["esp32", "esp32s3"]
|
|||||||
platform_arguments = platform_targets.copy()
|
platform_arguments = platform_targets.copy()
|
||||||
platform_arguments.append("all")
|
platform_arguments.append("all")
|
||||||
ttbuild_path = ".tactility"
|
ttbuild_path = ".tactility"
|
||||||
ttbuild_version = "1.2.0"
|
ttbuild_version = "1.2.1"
|
||||||
ttbuild_properties_file = "tactility.properties"
|
ttbuild_properties_file = "tactility.properties"
|
||||||
ttbuild_cdn = "https://cdn.tactility.one"
|
ttbuild_cdn = "https://cdn.tactility.one"
|
||||||
ttbuild_sdk_json_validity = 3600 # seconds
|
ttbuild_sdk_json_validity = 3600 # seconds
|
||||||
@ -339,8 +339,6 @@ def read_sdk_json():
|
|||||||
def build_action(platform_arg):
|
def build_action(platform_arg):
|
||||||
# Environment validation
|
# Environment validation
|
||||||
validate_environment()
|
validate_environment()
|
||||||
# Environment setup
|
|
||||||
setup_environment()
|
|
||||||
platforms_to_build = platform_targets if platform_arg == "all" else [platform_arg]
|
platforms_to_build = platform_targets if platform_arg == "all" else [platform_arg]
|
||||||
if not is_valid_platform_name(platform_arg):
|
if not is_valid_platform_name(platform_arg):
|
||||||
print_help()
|
print_help()
|
||||||
@ -448,6 +446,8 @@ if __name__ == "__main__":
|
|||||||
verbose = "--verbose" in sys.argv
|
verbose = "--verbose" in sys.argv
|
||||||
skip_build = "--skip-build" in sys.argv
|
skip_build = "--skip-build" in sys.argv
|
||||||
use_local_sdk = "--local-sdk" in sys.argv
|
use_local_sdk = "--local-sdk" in sys.argv
|
||||||
|
# Environment setup
|
||||||
|
setup_environment()
|
||||||
# Update SDK cache (sdk.json)
|
# Update SDK cache (sdk.json)
|
||||||
if should_update_sdk_json() and not update_sdk_json():
|
if should_update_sdk_json() and not update_sdk_json():
|
||||||
exit_with_error("Failed to retrieve SDK info")
|
exit_with_error("Failed to retrieve SDK info")
|
||||||
|
|||||||
@ -17,7 +17,7 @@ platform_targets = ["esp32", "esp32s3"]
|
|||||||
platform_arguments = platform_targets.copy()
|
platform_arguments = platform_targets.copy()
|
||||||
platform_arguments.append("all")
|
platform_arguments.append("all")
|
||||||
ttbuild_path = ".tactility"
|
ttbuild_path = ".tactility"
|
||||||
ttbuild_version = "1.2.0"
|
ttbuild_version = "1.2.1"
|
||||||
ttbuild_properties_file = "tactility.properties"
|
ttbuild_properties_file = "tactility.properties"
|
||||||
ttbuild_cdn = "https://cdn.tactility.one"
|
ttbuild_cdn = "https://cdn.tactility.one"
|
||||||
ttbuild_sdk_json_validity = 3600 # seconds
|
ttbuild_sdk_json_validity = 3600 # seconds
|
||||||
@ -339,8 +339,6 @@ def read_sdk_json():
|
|||||||
def build_action(platform_arg):
|
def build_action(platform_arg):
|
||||||
# Environment validation
|
# Environment validation
|
||||||
validate_environment()
|
validate_environment()
|
||||||
# Environment setup
|
|
||||||
setup_environment()
|
|
||||||
platforms_to_build = platform_targets if platform_arg == "all" else [platform_arg]
|
platforms_to_build = platform_targets if platform_arg == "all" else [platform_arg]
|
||||||
if not is_valid_platform_name(platform_arg):
|
if not is_valid_platform_name(platform_arg):
|
||||||
print_help()
|
print_help()
|
||||||
@ -448,6 +446,8 @@ if __name__ == "__main__":
|
|||||||
verbose = "--verbose" in sys.argv
|
verbose = "--verbose" in sys.argv
|
||||||
skip_build = "--skip-build" in sys.argv
|
skip_build = "--skip-build" in sys.argv
|
||||||
use_local_sdk = "--local-sdk" in sys.argv
|
use_local_sdk = "--local-sdk" in sys.argv
|
||||||
|
# Environment setup
|
||||||
|
setup_environment()
|
||||||
# Update SDK cache (sdk.json)
|
# Update SDK cache (sdk.json)
|
||||||
if should_update_sdk_json() and not update_sdk_json():
|
if should_update_sdk_json() and not update_sdk_json():
|
||||||
exit_with_error("Failed to retrieve SDK info")
|
exit_with_error("Failed to retrieve SDK info")
|
||||||
|
|||||||
@ -8,10 +8,8 @@
|
|||||||
#include "Tactility/hal/uart/Uart.h"
|
#include "Tactility/hal/uart/Uart.h"
|
||||||
#include "Tactility/lvgl/LvglSync.h"
|
#include "Tactility/lvgl/LvglSync.h"
|
||||||
#include "Tactility/lvgl/Style.h"
|
#include "Tactility/lvgl/Style.h"
|
||||||
#include "Tactility/service/gui/Gui.h"
|
|
||||||
|
|
||||||
#include <Tactility/StringUtils.h>
|
#include <Tactility/StringUtils.h>
|
||||||
#include <array>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace tt::app::serialconsole {
|
namespace tt::app::serialconsole {
|
||||||
@ -117,7 +115,6 @@ public:
|
|||||||
lv_textarea_set_one_line(speedTextarea, true);
|
lv_textarea_set_one_line(speedTextarea, true);
|
||||||
lv_obj_set_width(speedTextarea, LV_PCT(50));
|
lv_obj_set_width(speedTextarea, LV_PCT(50));
|
||||||
lv_obj_align(speedTextarea, LV_ALIGN_TOP_RIGHT, 0, 40);
|
lv_obj_align(speedTextarea, LV_ALIGN_TOP_RIGHT, 0, 40);
|
||||||
service::gui::keyboardAddTextArea(speedTextarea);
|
|
||||||
|
|
||||||
auto* baud_rate_label = lv_label_create(wrapper);
|
auto* baud_rate_label = lv_label_create(wrapper);
|
||||||
lv_obj_align(baud_rate_label, LV_ALIGN_TOP_LEFT, 0, 50);
|
lv_obj_align(baud_rate_label, LV_ALIGN_TOP_LEFT, 0, 50);
|
||||||
@ -130,7 +127,7 @@ public:
|
|||||||
lv_obj_add_event_cb(connect_button, onConnectCallback, LV_EVENT_SHORT_CLICKED, this);
|
lv_obj_add_event_cb(connect_button, onConnectCallback, LV_EVENT_SHORT_CLICKED, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onStop() final {
|
void onStop() {
|
||||||
int speed = getSpeedInput();
|
int speed = getSpeedInput();
|
||||||
if (speed > 0) {
|
if (speed > 0) {
|
||||||
preferences.putInt32("speed", speed);
|
preferences.putInt32("speed", speed);
|
||||||
|
|||||||
@ -186,7 +186,6 @@ public:
|
|||||||
lv_obj_set_width(logTextarea, LV_PCT(100));
|
lv_obj_set_width(logTextarea, LV_PCT(100));
|
||||||
lv_obj_add_state(logTextarea, LV_STATE_DISABLED);
|
lv_obj_add_state(logTextarea, LV_STATE_DISABLED);
|
||||||
lv_obj_set_style_margin_ver(logTextarea, 0, 0);
|
lv_obj_set_style_margin_ver(logTextarea, 0, 0);
|
||||||
service::gui::keyboardAddTextArea(logTextarea);
|
|
||||||
|
|
||||||
auto* input_wrapper = lv_obj_create(parent);
|
auto* input_wrapper = lv_obj_create(parent);
|
||||||
lv_obj_set_size(input_wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
lv_obj_set_size(input_wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
||||||
@ -200,7 +199,6 @@ public:
|
|||||||
lv_textarea_set_placeholder_text(inputTextarea, "Text to send");
|
lv_textarea_set_placeholder_text(inputTextarea, "Text to send");
|
||||||
lv_obj_set_width(inputTextarea, LV_PCT(100));
|
lv_obj_set_width(inputTextarea, LV_PCT(100));
|
||||||
lv_obj_set_flex_grow(inputTextarea, 1);
|
lv_obj_set_flex_grow(inputTextarea, 1);
|
||||||
service::gui::keyboardAddTextArea(inputTextarea);
|
|
||||||
|
|
||||||
auto* terminator_dropdown = lv_dropdown_create(input_wrapper);
|
auto* terminator_dropdown = lv_dropdown_create(input_wrapper);
|
||||||
lv_dropdown_set_options(terminator_dropdown, "\\n\n\\r\\n");
|
lv_dropdown_set_options(terminator_dropdown, "\\n\n\\r\\n");
|
||||||
|
|||||||
@ -36,7 +36,7 @@ public:
|
|||||||
virtual ~Device() = default;
|
virtual ~Device() = default;
|
||||||
|
|
||||||
/** Unique identifier */
|
/** Unique identifier */
|
||||||
inline Id getId() const { return id; }
|
Id getId() const { return id; }
|
||||||
|
|
||||||
/** The type of device */
|
/** The type of device */
|
||||||
virtual Type getType() const = 0;
|
virtual Type getType() const = 0;
|
||||||
|
|||||||
@ -10,12 +10,15 @@ class TouchDevice;
|
|||||||
|
|
||||||
namespace tt::hal::display {
|
namespace tt::hal::display {
|
||||||
|
|
||||||
|
class DisplayDriver;
|
||||||
|
|
||||||
class DisplayDevice : public Device {
|
class DisplayDevice : public Device {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Type getType() const override { return Type::Display; }
|
Type getType() const override { return Type::Display; }
|
||||||
|
|
||||||
|
/** Starts the internal driver */
|
||||||
virtual bool start() = 0;
|
virtual bool start() = 0;
|
||||||
virtual bool stop() = 0;
|
virtual bool stop() = 0;
|
||||||
|
|
||||||
@ -23,7 +26,7 @@ public:
|
|||||||
virtual bool isPoweredOn() const { return true; }
|
virtual bool isPoweredOn() const { return true; }
|
||||||
virtual bool supportsPowerControl() const { return false; }
|
virtual bool supportsPowerControl() const { return false; }
|
||||||
|
|
||||||
virtual std::shared_ptr<touch::TouchDevice> _Nullable createTouch() = 0;
|
virtual std::shared_ptr<touch::TouchDevice> _Nullable getTouchDevice() = 0;
|
||||||
|
|
||||||
/** Set a value in the range [0, 255] */
|
/** Set a value in the range [0, 255] */
|
||||||
virtual void setBacklightDuty(uint8_t backlightDuty) { /* NO-OP */ }
|
virtual void setBacklightDuty(uint8_t backlightDuty) { /* NO-OP */ }
|
||||||
@ -33,8 +36,14 @@ public:
|
|||||||
virtual void setGammaCurve(uint8_t index) { /* NO-OP */ }
|
virtual void setGammaCurve(uint8_t index) { /* NO-OP */ }
|
||||||
virtual uint8_t getGammaCurveCount() const { return 0; };
|
virtual uint8_t getGammaCurveCount() const { return 0; };
|
||||||
|
|
||||||
/** After start() returns true, this should return a valid pointer until stop() is called and returns true */
|
virtual bool supportsLvgl() const { return false; }
|
||||||
|
virtual bool startLvgl() { return false; }
|
||||||
|
virtual bool stopLvgl() { return false; }
|
||||||
|
|
||||||
virtual lv_display_t* _Nullable getLvglDisplay() const = 0;
|
virtual lv_display_t* _Nullable getLvglDisplay() const = 0;
|
||||||
|
|
||||||
|
virtual bool supportsDisplayDriver() const { return false; }
|
||||||
|
virtual std::shared_ptr<DisplayDriver> _Nullable getDisplayDriver() { return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tt::hal::display
|
} // namespace tt::hal::display
|
||||||
|
|||||||
26
Tactility/Include/Tactility/hal/display/DisplayDriver.h
Normal file
26
Tactility/Include/Tactility/hal/display/DisplayDriver.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace tt::hal::display {
|
||||||
|
|
||||||
|
enum class ColorFormat {
|
||||||
|
Monochrome, // 1 bpp
|
||||||
|
BGR565,
|
||||||
|
RGB565,
|
||||||
|
RGB888
|
||||||
|
};
|
||||||
|
|
||||||
|
class DisplayDriver {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~DisplayDriver() = default;
|
||||||
|
|
||||||
|
virtual ColorFormat getColorFormat() const = 0;
|
||||||
|
virtual uint16_t getPixelWidth() const = 0;
|
||||||
|
virtual uint16_t getPixelHeight() const = 0;
|
||||||
|
virtual bool drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@ -14,8 +14,8 @@ public:
|
|||||||
|
|
||||||
Type getType() const override { return Type::Keyboard; }
|
Type getType() const override { return Type::Keyboard; }
|
||||||
|
|
||||||
virtual bool start(lv_display_t* display) = 0;
|
virtual bool startLvgl(lv_display_t* display) = 0;
|
||||||
virtual bool stop() = 0;
|
virtual bool stopLvgl() = 0;
|
||||||
virtual bool isAttached() const = 0;
|
virtual bool isAttached() const = 0;
|
||||||
|
|
||||||
virtual lv_indev_t* _Nullable getLvglIndev() = 0;
|
virtual lv_indev_t* _Nullable getLvglIndev() = 0;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../Device.h"
|
#include "../Device.h"
|
||||||
|
#include "TouchDriver.h"
|
||||||
|
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
|
||||||
@ -14,10 +15,18 @@ public:
|
|||||||
|
|
||||||
Type getType() const override { return Type::Touch; }
|
Type getType() const override { return Type::Touch; }
|
||||||
|
|
||||||
virtual bool start(lv_display_t* display) = 0;
|
virtual bool start() = 0;
|
||||||
virtual bool stop() = 0;
|
virtual bool stop() = 0;
|
||||||
|
|
||||||
|
virtual bool supportsLvgl() const = 0;
|
||||||
|
virtual bool startLvgl(lv_display_t* display) = 0;
|
||||||
|
virtual bool stopLvgl() = 0;
|
||||||
|
|
||||||
virtual lv_indev_t* _Nullable getLvglIndev() = 0;
|
virtual lv_indev_t* _Nullable getLvglIndev() = 0;
|
||||||
|
|
||||||
|
virtual bool supportsTouchDriver() = 0;
|
||||||
|
|
||||||
|
virtual std::shared_ptr<TouchDriver> _Nullable getTouchDriver() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
23
Tactility/Include/Tactility/hal/touch/TouchDriver.h
Normal file
23
Tactility/Include/Tactility/hal/touch/TouchDriver.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace tt::hal::touch {
|
||||||
|
|
||||||
|
class TouchDriver {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the coordinates for the currently touched points on the screen.
|
||||||
|
*
|
||||||
|
* @param[in] x array of X coordinates
|
||||||
|
* @param[in] y array of Y coordinates
|
||||||
|
* @param[in] strength optional array of strengths
|
||||||
|
* @param[in] pointCount the number of points currently touched on the screen
|
||||||
|
* @param[in] maxPointCount the maximum number of points that can be touched at once
|
||||||
|
*
|
||||||
|
* @return true when touched and coordinates are available
|
||||||
|
*/
|
||||||
|
virtual bool getTouchedPoints(uint16_t* x, uint16_t* y, uint16_t* _Nullable strength, uint8_t* pointCount, uint8_t maxPointCount) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@ -14,12 +14,14 @@ enum class SystemEvent {
|
|||||||
BootInitSpiEnd,
|
BootInitSpiEnd,
|
||||||
BootInitUartBegin,
|
BootInitUartBegin,
|
||||||
BootInitUartEnd,
|
BootInitUartEnd,
|
||||||
BootInitLvglBegin,
|
|
||||||
BootInitLvglEnd,
|
|
||||||
BootSplash,
|
BootSplash,
|
||||||
/** Gained IP address */
|
/** Gained IP address */
|
||||||
NetworkConnected,
|
NetworkConnected,
|
||||||
NetworkDisconnected,
|
NetworkDisconnected,
|
||||||
|
/** LVGL devices are initialized and usable */
|
||||||
|
LvglStarted,
|
||||||
|
/** LVGL devices were removed and not usable anymore */
|
||||||
|
LvglStopped,
|
||||||
/** An important system time-related event, such as NTP update or time-zone change */
|
/** An important system time-related event, such as NTP update or time-zone change */
|
||||||
Time,
|
Time,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -48,12 +48,4 @@ bool hardware_keyboard_is_available();
|
|||||||
*/
|
*/
|
||||||
void hardware_keyboard_set_indev(lv_indev_t* device);
|
void hardware_keyboard_set_indev(lv_indev_t* device);
|
||||||
|
|
||||||
/**
|
|
||||||
* Glue code for the on-screen keyboard and the hardware keyboard:
|
|
||||||
* - Attach automatic hide/show parameters for the on-screen keyboard.
|
|
||||||
* - Registers the textarea to the default lv_group_t for hardware keyboards.
|
|
||||||
* @param[in] textarea
|
|
||||||
*/
|
|
||||||
void keyboard_add_textarea(lv_obj_t* textarea);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,5 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <lvgl.h>
|
namespace tt::lvgl {
|
||||||
|
|
||||||
#include "./Colors.h"
|
bool isStarted();
|
||||||
|
|
||||||
|
void start();
|
||||||
|
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -4,6 +4,13 @@
|
|||||||
|
|
||||||
namespace tt::service {
|
namespace tt::service {
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
Starting,
|
||||||
|
Started,
|
||||||
|
Stopping,
|
||||||
|
Stopped
|
||||||
|
};
|
||||||
|
|
||||||
// Forward declaration
|
// Forward declaration
|
||||||
class ServiceContext;
|
class ServiceContext;
|
||||||
|
|
||||||
|
|||||||
@ -22,8 +22,8 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** @return a reference ot the service's manifest */
|
/** @return a reference to the service's manifest */
|
||||||
virtual const service::ServiceManifest& getManifest() const = 0;
|
virtual const ServiceManifest& getManifest() const = 0;
|
||||||
|
|
||||||
/** Retrieve the paths that are relevant to this service */
|
/** Retrieve the paths that are relevant to this service */
|
||||||
virtual std::unique_ptr<Paths> getPaths() const = 0;
|
virtual std::unique_ptr<Paths> getPaths() const = 0;
|
||||||
|
|||||||
@ -29,6 +29,13 @@ bool startService(const std::string& id);
|
|||||||
*/
|
*/
|
||||||
bool stopService(const std::string& id);
|
bool stopService(const std::string& id);
|
||||||
|
|
||||||
|
/** Get the state of a service.
|
||||||
|
* @warning If the service is not found, the returned result will be "Stopped" - even if the service id does not exist
|
||||||
|
* @param[in] the service id as defined in its manifest
|
||||||
|
* @return the service state
|
||||||
|
*/
|
||||||
|
State getState(const std::string& id);
|
||||||
|
|
||||||
/** Find a service manifest by its id.
|
/** Find a service manifest by its id.
|
||||||
* @param[in] id the id as defined in the manifest
|
* @param[in] id the id as defined in the manifest
|
||||||
* @return the matching manifest or nullptr when it wasn't found
|
* @return the matching manifest or nullptr when it wasn't found
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user