mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-19 03:13:14 +00:00
Native touch driver
This commit is contained in:
parent
7de3b871c6
commit
4509e693da
@ -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);
|
||||
initEncoder();
|
||||
keypad->init(KB_ROWS, KB_COLS);
|
||||
@ -195,7 +195,7 @@ bool TpagerKeyboard::start(lv_display_t* display) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TpagerKeyboard::stop() {
|
||||
bool TpagerKeyboard::stopLvgl() {
|
||||
assert(inputTimer);
|
||||
inputTimer->stop();
|
||||
inputTimer = nullptr;
|
||||
|
||||
@ -41,8 +41,8 @@ public:
|
||||
std::string getName() const final { return "T-Lora Pager Keyboard"; }
|
||||
std::string getDescription() const final { return "I2C keyboard with encoder"; }
|
||||
|
||||
bool start(lv_display_t* display) override;
|
||||
bool stop() override;
|
||||
bool startLvgl(lv_display_t* display) override;
|
||||
bool stopLvgl() override;
|
||||
bool isAttached() const override;
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return kbHandle; }
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
#define TDECK_KEYBOARD_I2C_BUS_HANDLE I2C_NUM_0
|
||||
#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);
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ static void keyboard_read_callback(TT_UNUSED lv_indev_t* indev, lv_indev_data_t*
|
||||
last_buffer = read_buffer;
|
||||
}
|
||||
|
||||
bool TdeckKeyboard::start(lv_display_t* display) {
|
||||
bool TdeckKeyboard::startLvgl(lv_display_t* display) {
|
||||
deviceHandle = lv_indev_create();
|
||||
lv_indev_set_type(deviceHandle, LV_INDEV_TYPE_KEYPAD);
|
||||
lv_indev_set_read_cb(deviceHandle, &keyboard_read_callback);
|
||||
@ -52,7 +52,7 @@ bool TdeckKeyboard::start(lv_display_t* display) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TdeckKeyboard::stop() {
|
||||
bool TdeckKeyboard::stopLvgl() {
|
||||
lv_indev_delete(deviceHandle);
|
||||
deviceHandle = nullptr;
|
||||
return true;
|
||||
|
||||
@ -5,19 +5,17 @@
|
||||
#include <esp_lcd_panel_io_interface.h>
|
||||
#include <esp_lcd_touch.h>
|
||||
|
||||
class TdeckKeyboard : public tt::hal::keyboard::KeyboardDevice {
|
||||
|
||||
private:
|
||||
class TdeckKeyboard final : public tt::hal::keyboard::KeyboardDevice {
|
||||
|
||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
std::string getName() const final { return "T-Deck Keyboard"; }
|
||||
std::string getDescription() const final { return "I2C keyboard"; }
|
||||
std::string getName() const override { return "T-Deck Keyboard"; }
|
||||
std::string getDescription() const override { return "I2C keyboard"; }
|
||||
|
||||
bool start(lv_display_t* display) override;
|
||||
bool stop() override;
|
||||
bool startLvgl(lv_display_t* display) override;
|
||||
bool stopLvgl() override;
|
||||
bool isAttached() const override;
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||
};
|
||||
|
||||
@ -4,20 +4,20 @@
|
||||
#include <Tactility/TactilityCore.h>
|
||||
|
||||
class SdlKeyboard final : public tt::hal::keyboard::KeyboardDevice {
|
||||
private:
|
||||
|
||||
lv_indev_t* _Nullable handle = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
std::string getName() const final { return "SDL Keyboard"; }
|
||||
std::string getDescription() const final { return "SDL keyboard device"; }
|
||||
std::string getName() const override { return "SDL Keyboard"; }
|
||||
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();
|
||||
return handle != nullptr;
|
||||
}
|
||||
|
||||
bool stop() override { tt_crash("Not supported"); }
|
||||
bool stopLvgl() override { tt_crash("Not supported"); }
|
||||
|
||||
bool isAttached() const override { return true; }
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ bool EspLcdDisplay::startLvgl() {
|
||||
|
||||
auto touch_device = getTouchDevice();
|
||||
if (touch_device != nullptr) {
|
||||
touch_device->start(lvglDisplay);
|
||||
touch_device->startLvgl(lvglDisplay);
|
||||
}
|
||||
|
||||
return lvglDisplay != nullptr;
|
||||
@ -76,7 +76,7 @@ bool EspLcdDisplay::stopLvgl() {
|
||||
|
||||
auto touch_device = getTouchDevice();
|
||||
if (touch_device != nullptr) {
|
||||
touch_device->stop();
|
||||
touch_device->stopLvgl();
|
||||
}
|
||||
|
||||
lvgl_port_remove_disp(lvglDisplay);
|
||||
@ -84,10 +84,10 @@ bool EspLcdDisplay::stopLvgl() {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<tt::hal::display::NativeDisplay> EspLcdDisplay::getNativeDisplay() {
|
||||
std::shared_ptr<display::NativeDisplay> EspLcdDisplay::getNativeDisplay() {
|
||||
assert(lvglDisplay == nullptr); // Still attached to LVGL context. Call stopLvgl() first.
|
||||
if (nativeDisplay == nullptr) {
|
||||
nativeDisplay = std::make_shared<tt::hal::display::EspLcdNativeDisplay>(
|
||||
nativeDisplay = std::make_shared<EspLcdNativeDisplay>(
|
||||
panelHandle,
|
||||
lvglPortDisplayConfig
|
||||
);
|
||||
|
||||
@ -47,7 +47,7 @@ public:
|
||||
|
||||
// region NativedDisplay
|
||||
|
||||
/** @return a NativeDisplay if this device supports it */
|
||||
/** @return a NativeDisplay instance if this device supports it */
|
||||
std::shared_ptr<tt::hal::display::NativeDisplay> _Nullable getNativeDisplay() final;
|
||||
|
||||
// endregion
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
#include <esp_lcd_panel_ops.h>
|
||||
#include <esp_lvgl_port_disp.h>
|
||||
|
||||
namespace tt::hal::display {
|
||||
using namespace tt::hal;
|
||||
|
||||
class EspLcdNativeDisplay final : public NativeDisplay {
|
||||
class EspLcdNativeDisplay final : public display::NativeDisplay {
|
||||
|
||||
esp_lcd_panel_handle_t panelHandle;
|
||||
const lvgl_port_display_cfg_t& lvglPortDisplayConfig;
|
||||
@ -17,7 +17,8 @@ public:
|
||||
const lvgl_port_display_cfg_t& lvglPortDisplayConfig
|
||||
) : panelHandle(panelHandle), lvglPortDisplayConfig(lvglPortDisplayConfig) {}
|
||||
|
||||
ColorFormat getColorFormat() const override {
|
||||
display::ColorFormat getColorFormat() const override {
|
||||
using display::ColorFormat;
|
||||
switch (lvglPortDisplayConfig.color_format) {
|
||||
case LV_COLOR_FORMAT_I1:
|
||||
return ColorFormat::Monochrome;
|
||||
@ -39,5 +40,3 @@ public:
|
||||
uint16_t getPixelWidth() const override { return lvglPortDisplayConfig.hres; }
|
||||
uint16_t getPixelHeight() const override { return lvglPortDisplayConfig.vres; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
5
Drivers/EspLcdCompat/Source/EspLcdNativeTouch.cpp
Normal file
5
Drivers/EspLcdCompat/Source/EspLcdNativeTouch.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "EspLcdNativeTouch.h"
|
||||
|
||||
bool EspLcdNativeTouch::getTouchedPoints(uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* pointCount, uint8_t maxPointCount) {
|
||||
return esp_lcd_touch_get_coordinates(handle, x, y, strength, pointCount, maxPointCount) == ESP_OK;
|
||||
}
|
||||
15
Drivers/EspLcdCompat/Source/EspLcdNativeTouch.h
Normal file
15
Drivers/EspLcdCompat/Source/EspLcdNativeTouch.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <esp_lcd_touch.h>
|
||||
#include <Tactility/hal/touch/NativeTouch.h>
|
||||
|
||||
class EspLcdNativeTouch final : public tt::hal::touch::NativeTouch {
|
||||
|
||||
esp_lcd_touch_handle_t handle;
|
||||
|
||||
public:
|
||||
|
||||
EspLcdNativeTouch(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,11 +1,12 @@
|
||||
#include "EspLcdTouch.h"
|
||||
|
||||
#include <EspLcdNativeTouch.h>
|
||||
#include <esp_lvgl_port_touch.h>
|
||||
#include <Tactility/LogEsp.h>
|
||||
|
||||
constexpr char* TAG = "EspLcdTouch";
|
||||
|
||||
bool EspLcdTouch::start(lv_display_t* display) {
|
||||
bool EspLcdTouch::start() {
|
||||
if (!createIoHandle(ioHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Touch IO failed");
|
||||
return false;
|
||||
@ -15,10 +16,41 @@ bool EspLcdTouch::start(lv_display_t* display) {
|
||||
|
||||
if (!createTouchHandle(ioHandle, config, touchHandle)) {
|
||||
TT_LOG_E(TAG, "Driver init failed");
|
||||
cleanup();
|
||||
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 (nativeTouch != nullptr && nativeTouch.use_count() > 1) {
|
||||
TT_LOG_W(TAG, "NativeTouch is still in use.");
|
||||
}
|
||||
|
||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||
.disp = display,
|
||||
.handle = touchHandle,
|
||||
@ -28,28 +60,27 @@ bool EspLcdTouch::start(lv_display_t* display) {
|
||||
lvglDevice = lvgl_port_add_touch(&touch_cfg);
|
||||
if (lvglDevice == nullptr) {
|
||||
TT_LOG_E(TAG, "Adding touch failed");
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EspLcdTouch::stop() {
|
||||
cleanup();
|
||||
bool EspLcdTouch::stopLvgl() {
|
||||
if (lvglDevice == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lvgl_port_remove_touch(lvglDevice);
|
||||
lvglDevice = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EspLcdTouch::cleanup() {
|
||||
if (lvglDevice != nullptr) {
|
||||
lv_indev_delete(lvglDevice);
|
||||
lvglDevice = nullptr;
|
||||
// TODO: is this correct? We don't have to delete it manually?
|
||||
touchHandle = nullptr;
|
||||
}
|
||||
|
||||
if (ioHandle != nullptr) {
|
||||
esp_lcd_panel_io_del(ioHandle);
|
||||
ioHandle = nullptr;
|
||||
std::shared_ptr<tt::hal::touch::NativeTouch> _Nullable EspLcdTouch::getNativeTouch() {
|
||||
assert(lvglDevice == nullptr); // Still attached to LVGL context. Call stopLvgl() first.
|
||||
if (nativeTouch == nullptr) {
|
||||
nativeTouch = std::make_shared<EspLcdNativeTouch>(touchHandle);
|
||||
}
|
||||
return nativeTouch;
|
||||
}
|
||||
|
||||
@ -11,8 +11,7 @@ class EspLcdTouch : public tt::hal::touch::TouchDevice {
|
||||
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
|
||||
esp_lcd_touch_handle_t _Nullable touchHandle = nullptr;
|
||||
lv_indev_t* _Nullable lvglDevice = nullptr;
|
||||
|
||||
void cleanup();
|
||||
std::shared_ptr<tt::hal::touch::NativeTouch> nativeTouch;
|
||||
|
||||
protected:
|
||||
|
||||
@ -24,11 +23,17 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
bool start() final;
|
||||
|
||||
bool start(lv_display_t* display) override;
|
||||
bool stop() final;
|
||||
|
||||
bool stop() override;
|
||||
bool supportsLvgl() const final { return true; }
|
||||
|
||||
bool startLvgl(lv_display_t* display) final;
|
||||
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return lvglDevice; }
|
||||
bool stopLvgl() final;
|
||||
|
||||
lv_indev_t* _Nullable getLvglIndev() final { return lvglDevice; }
|
||||
|
||||
std::shared_ptr<tt::hal::touch::NativeTouch> _Nullable getNativeTouch() final;
|
||||
};
|
||||
|
||||
@ -67,5 +67,6 @@ public:
|
||||
}
|
||||
|
||||
std::string getName() const override { return "GT911"; }
|
||||
std::string getDescription() const override { return "I2C Touch Driver"; }
|
||||
|
||||
std::string getDescription() const override { return "GT911 I2C touch driver"; }
|
||||
};
|
||||
|
||||
@ -14,8 +14,8 @@ public:
|
||||
|
||||
Type getType() const override { return Type::Keyboard; }
|
||||
|
||||
virtual bool start(lv_display_t* display) = 0;
|
||||
virtual bool stop() = 0;
|
||||
virtual bool startLvgl(lv_display_t* display) = 0;
|
||||
virtual bool stopLvgl() = 0;
|
||||
virtual bool isAttached() const = 0;
|
||||
|
||||
virtual lv_indev_t* _Nullable getLvglIndev() = 0;
|
||||
|
||||
24
Tactility/Include/Tactility/hal/touch/NativeTouch.h
Normal file
24
Tactility/Include/Tactility/hal/touch/NativeTouch.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
namespace tt::hal::touch {
|
||||
|
||||
class NativeTouch {
|
||||
|
||||
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 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
|
||||
* - Returns true, when touched and coordinates readed. Otherwise returns false.
|
||||
*/
|
||||
virtual bool getTouchedPoints(uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* pointCount, uint8_t maxPointCount) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Device.h"
|
||||
#include "NativeTouch.h"
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
@ -14,10 +15,16 @@ public:
|
||||
|
||||
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 supportsLvgl() const { return false; }
|
||||
virtual bool startLvgl(lv_display_t* display) = 0;
|
||||
virtual bool stopLvgl() = 0;
|
||||
|
||||
virtual lv_indev_t* _Nullable getLvglIndev() = 0;
|
||||
|
||||
virtual std::shared_ptr<NativeTouch> _Nullable getNativeTouch() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -40,26 +40,6 @@ static std::shared_ptr<hal::display::DisplayDevice> createDisplay(const hal::Con
|
||||
return display;
|
||||
}
|
||||
|
||||
static bool startKeyboard(const std::shared_ptr<hal::display::DisplayDevice>& display, const std::shared_ptr<hal::keyboard::KeyboardDevice>& keyboard) {
|
||||
TT_LOG_I(TAG, "Keyboard init");
|
||||
assert(display);
|
||||
assert(keyboard);
|
||||
if (keyboard->isAttached()) {
|
||||
if (keyboard->start(display->getLvglDisplay())) {
|
||||
lv_indev_t* keyboard_indev = keyboard->getLvglIndev();
|
||||
hardware_keyboard_set_indev(keyboard_indev);
|
||||
TT_LOG_I(TAG, "Keyboard started");
|
||||
return true;
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Keyboard start failed");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Keyboard attach failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void init(const hal::Configuration& config) {
|
||||
TT_LOG_I(TAG, "Init started");
|
||||
|
||||
@ -77,6 +57,7 @@ void init(const hal::Configuration& config) {
|
||||
|
||||
auto touch = display->getTouchDevice();
|
||||
if (touch != nullptr) {
|
||||
touch->start();
|
||||
hal::registerDevice(touch);
|
||||
}
|
||||
|
||||
@ -119,6 +100,19 @@ void start() {
|
||||
}
|
||||
}
|
||||
|
||||
// Start touch
|
||||
|
||||
auto touch_devices = hal::findDevices<hal::touch::TouchDevice>(hal::Device::Type::Touch);
|
||||
for (auto touch_device : touch_devices) {
|
||||
if (displays.size() > 0) {
|
||||
// TODO: Consider implementing support for multiple displays
|
||||
auto display = displays[0];
|
||||
if (touch_device->supportsLvgl()) {
|
||||
touch_device->startLvgl(display->getLvglDisplay());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start keyboards
|
||||
|
||||
auto keyboards = hal::findDevices<hal::keyboard::KeyboardDevice>(hal::Device::Type::Keyboard);
|
||||
@ -126,7 +120,15 @@ void start() {
|
||||
if (displays.size() > 0) {
|
||||
// TODO: Consider implementing support for multiple displays
|
||||
auto display = displays[0];
|
||||
startKeyboard(display, keyboard);
|
||||
if (keyboard->isAttached()) {
|
||||
if (keyboard->startLvgl(display->getLvglDisplay())) {
|
||||
lv_indev_t* keyboard_indev = keyboard->getLvglIndev();
|
||||
hardware_keyboard_set_indev(keyboard_indev);
|
||||
TT_LOG_I(TAG, "Keyboard started");
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Keyboard start failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,7 +170,14 @@ void stop() {
|
||||
|
||||
auto keyboards = hal::findDevices<hal::keyboard::KeyboardDevice>(hal::Device::Type::Keyboard);
|
||||
for (auto keyboard : keyboards) {
|
||||
keyboard->stop();
|
||||
keyboard->stopLvgl();
|
||||
}
|
||||
|
||||
// Stop touch
|
||||
|
||||
auto touch_devices = hal::findDevices<hal::touch::TouchDevice>(hal::Device::Type::Touch);
|
||||
for (auto touch_device : touch_devices) {
|
||||
touch_device->stopLvgl();
|
||||
}
|
||||
|
||||
// Stop displays (and their touch devices)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user