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:
Ken Van Hoeylandt
2025-08-16 20:22:49 +02:00
committed by GitHub
parent 15f4fbfdc6
commit d875ade8cb
127 changed files with 1907 additions and 1605 deletions
@@ -8,10 +8,8 @@
#include "Tactility/hal/uart/Uart.h"
#include "Tactility/lvgl/LvglSync.h"
#include "Tactility/lvgl/Style.h"
#include "Tactility/service/gui/Gui.h"
#include <Tactility/StringUtils.h>
#include <array>
#include <string>
namespace tt::app::serialconsole {
@@ -117,7 +115,6 @@ public:
lv_textarea_set_one_line(speedTextarea, true);
lv_obj_set_width(speedTextarea, LV_PCT(50));
lv_obj_align(speedTextarea, LV_ALIGN_TOP_RIGHT, 0, 40);
service::gui::keyboardAddTextArea(speedTextarea);
auto* baud_rate_label = lv_label_create(wrapper);
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);
}
void onStop() final {
void onStop() {
int speed = getSpeedInput();
if (speed > 0) {
preferences.putInt32("speed", speed);
@@ -186,7 +186,6 @@ public:
lv_obj_set_width(logTextarea, LV_PCT(100));
lv_obj_add_state(logTextarea, LV_STATE_DISABLED);
lv_obj_set_style_margin_ver(logTextarea, 0, 0);
service::gui::keyboardAddTextArea(logTextarea);
auto* input_wrapper = lv_obj_create(parent);
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_obj_set_width(inputTextarea, LV_PCT(100));
lv_obj_set_flex_grow(inputTextarea, 1);
service::gui::keyboardAddTextArea(inputTextarea);
auto* terminator_dropdown = lv_dropdown_create(input_wrapper);
lv_dropdown_set_options(terminator_dropdown, "\\n\n\\r\\n");
+1 -1
View File
@@ -36,7 +36,7 @@ public:
virtual ~Device() = default;
/** Unique identifier */
inline Id getId() const { return id; }
Id getId() const { return id; }
/** The type of device */
virtual Type getType() const = 0;
@@ -10,12 +10,15 @@ class TouchDevice;
namespace tt::hal::display {
class DisplayDriver;
class DisplayDevice : public Device {
public:
Type getType() const override { return Type::Display; }
/** Starts the internal driver */
virtual bool start() = 0;
virtual bool stop() = 0;
@@ -23,7 +26,7 @@ public:
virtual bool isPoweredOn() const { return true; }
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] */
virtual void setBacklightDuty(uint8_t backlightDuty) { /* NO-OP */ }
@@ -33,8 +36,14 @@ public:
virtual void setGammaCurve(uint8_t index) { /* NO-OP */ }
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 bool supportsDisplayDriver() const { return false; }
virtual std::shared_ptr<DisplayDriver> _Nullable getDisplayDriver() { return nullptr; }
};
} // namespace tt::hal::display
@@ -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; }
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;
@@ -1,6 +1,7 @@
#pragma once
#include "../Device.h"
#include "TouchDriver.h"
#include <lvgl.h>
@@ -14,10 +15,18 @@ 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 = 0;
virtual bool startLvgl(lv_display_t* display) = 0;
virtual bool stopLvgl() = 0;
virtual lv_indev_t* _Nullable getLvglIndev() = 0;
virtual bool supportsTouchDriver() = 0;
virtual std::shared_ptr<TouchDriver> _Nullable getTouchDriver() = 0;
};
}
@@ -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,
BootInitUartBegin,
BootInitUartEnd,
BootInitLvglBegin,
BootInitLvglEnd,
BootSplash,
/** Gained IP address */
NetworkConnected,
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 */
Time,
};
@@ -48,12 +48,4 @@ bool hardware_keyboard_is_available();
*/
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);
}
+8 -2
View File
@@ -1,5 +1,11 @@
#pragma once
#include <lvgl.h>
namespace tt::lvgl {
#include "./Colors.h"
bool isStarted();
void start();
void stop();
}
@@ -4,6 +4,13 @@
namespace tt::service {
enum class State {
Starting,
Started,
Stopping,
Stopped
};
// Forward declaration
class ServiceContext;
@@ -22,8 +22,8 @@ protected:
public:
/** @return a reference ot the service's manifest */
virtual const service::ServiceManifest& getManifest() const = 0;
/** @return a reference to the service's manifest */
virtual const ServiceManifest& getManifest() const = 0;
/** Retrieve the paths that are relevant to this service */
virtual std::unique_ptr<Paths> getPaths() const = 0;
@@ -29,6 +29,13 @@ bool startService(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.
* @param[in] id the id as defined in the manifest
* @return the matching manifest or nullptr when it wasn't found