diff --git a/ExternalApps/GraphicsDemo/main/CMakeLists.txt b/ExternalApps/GraphicsDemo/main/CMakeLists.txt index 62c36897..759aed70 100644 --- a/ExternalApps/GraphicsDemo/main/CMakeLists.txt +++ b/ExternalApps/GraphicsDemo/main/CMakeLists.txt @@ -1,6 +1,7 @@ file(GLOB_RECURSE SOURCE_FILES Source/*.c*) idf_component_register( - SRCS ${SOURCE_FILES} + SRC_DIRS "Source" + INCLUDE_DIRS "Include" REQUIRES TactilitySDK ) diff --git a/ExternalApps/GraphicsDemo/main/Include/Application.h b/ExternalApps/GraphicsDemo/main/Include/Application.h new file mode 100644 index 00000000..6ab41058 --- /dev/null +++ b/ExternalApps/GraphicsDemo/main/Include/Application.h @@ -0,0 +1,6 @@ +#pragma once + +#include +#include + +void runApplication(DisplayDriverHandle display, TouchDriverHandle touch); diff --git a/ExternalApps/GraphicsDemo/main/Include/Drivers.h b/ExternalApps/GraphicsDemo/main/Include/Drivers.h new file mode 100644 index 00000000..4c49879f --- /dev/null +++ b/ExternalApps/GraphicsDemo/main/Include/Drivers.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +class Drivers { + + DeviceId displayId = 0; + DeviceId touchId = 0; + +public: + + DisplayDriverHandle display = nullptr; + TouchDriverHandle touch = nullptr; + + bool validateSupport(); + + bool start(); + + void stop(); +}; diff --git a/ExternalApps/GraphicsDemo/main/Source/main.cpp b/ExternalApps/GraphicsDemo/main/Source/Application.cpp similarity index 82% rename from ExternalApps/GraphicsDemo/main/Source/main.cpp rename to ExternalApps/GraphicsDemo/main/Source/Application.cpp index 0f505bf3..201df629 100644 --- a/ExternalApps/GraphicsDemo/main/Source/main.cpp +++ b/ExternalApps/GraphicsDemo/main/Source/Application.cpp @@ -1,14 +1,10 @@ -#include "esp_log.h" +#include "Application.h" -#include -#include -#include +#include +#include #include -#include -constexpr auto TAG = "GraphicsDemo"; - -const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t logo[] = { +const uint8_t logo[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xf4, 0x38, 0xf4, 0x78, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf4, 0x18, 0xf4, 0x18, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf4, 0x18, 0xf4, 0x18, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -35,49 +31,47 @@ const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t logo[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x06, 0xff, 0x05, 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; -static void onCreate(AppHandle appHandle, void* data) { - DeviceId deviceId = 0; - uint16_t count = 0; - if (!tt_hal_device_find(DEVICE_TYPE_DISPLAY, &deviceId, &count, 1)) { - ESP_LOGI(TAG, "No display device found"); - tt_app_stop(); - return; - } - - if (!tt_hal_display_driver_supported(deviceId)) { - ESP_LOGI(TAG, "Display doesn't support driver interface"); - tt_app_stop(); - return; - } - - tt_lvgl_stop(); - - auto* driver = tt_hal_display_driver_alloc(deviceId); - tt_hal_display_driver_draw_bitmap(driver, 0, 0, 24, 24, logo); - tt_hal_display_driver_free(driver); - - tt_kernel_delay_millis(2000); - - tt_app_stop(); +static void waitForTouch(TouchDriverHandle touch) { + // Wait for touch + uint16_t x, y, strength; + uint8_t pointCount = 0; + do { + tt_hal_touch_driver_get_touched_points(touch, &x, &y, &strength, &pointCount, 1); + tt_kernel_delay_millis(20); + } while (pointCount == 0); } -static void onDestroy(AppHandle appHandle, void* data) { - if (!tt_lvgl_is_started()) { - tt_lvgl_start(); +uint32_t getPixelSize(ColorFormat colorFormat) { + switch (colorFormat) { + case COLOR_FORMAT_MONOCHROME: + return 1; + case COLOR_FORMAT_BGR565: + return 2; + case COLOR_FORMAT_RGB565: + return 2; + case COLOR_FORMAT_RGB888: + return 3; + default: + return 0; } } -ExternalAppManifest manifest = { - .name = "Hello World", - .onCreate = onCreate, - .onDestroy = onDestroy -}; +void runApplication(DisplayDriverHandle display, TouchDriverHandle touch) { -extern "C" { + auto display_width = tt_hal_display_driver_get_pixel_width(display); + auto display_height = tt_hal_display_driver_get_pixel_height(display); + auto color_format = tt_hal_display_driver_get_colorformat(display); + auto buffer_height = display_height / 10; + auto buffer_size = display_width * buffer_height * getPixelSize(color_format); + void* buffer = malloc(buffer_size); + memset(buffer, 0, buffer_size); -int main(int argc, char* argv[]) { - tt_app_register(&manifest); - return 0; + for (int i = 0; i < 10; i++) { + tt_hal_display_driver_draw_bitmap(display, 0, i * buffer_height, display_width, (i + 1) * buffer_height, buffer); + } + + tt_hal_display_driver_draw_bitmap(display, 0, 0, 24, 24, logo); + + waitForTouch(touch); } -} diff --git a/ExternalApps/GraphicsDemo/main/Source/Drivers.cpp b/ExternalApps/GraphicsDemo/main/Source/Drivers.cpp new file mode 100644 index 00000000..886547b2 --- /dev/null +++ b/ExternalApps/GraphicsDemo/main/Source/Drivers.cpp @@ -0,0 +1,44 @@ +#include "Drivers.h" + +#include + +constexpr auto TAG = "Drivers"; + +bool Drivers::validateSupport() { + uint16_t display_count = 0; + if (!tt_hal_device_find(DEVICE_TYPE_DISPLAY, &displayId, &display_count, 1)) { + ESP_LOGI(TAG, "No display device found"); + return false; + } + + if (!tt_hal_display_driver_supported(displayId)) { + ESP_LOGI(TAG, "Display doesn't support driver interface"); + return false; + } + + uint16_t touch_count = 0; + if (!tt_hal_device_find(DEVICE_TYPE_TOUCH, &touchId, &touch_count, 1)) { + ESP_LOGI(TAG, "No touch device found"); + return false; + } + + if (!tt_hal_touch_driver_supported(touchId)) { + ESP_LOGI(TAG, "Touch doesn't support driver interface"); + return false; + } + + return true; +} + +bool Drivers::start() { + display = tt_hal_display_driver_alloc(displayId); + touch = tt_hal_touch_driver_alloc(touchId); + return true; +} + +void Drivers::stop() { + tt_hal_display_driver_free(display); + tt_hal_touch_driver_free(touch); + display = nullptr; + touch = nullptr; +} diff --git a/ExternalApps/GraphicsDemo/main/Source/Main.cpp b/ExternalApps/GraphicsDemo/main/Source/Main.cpp new file mode 100644 index 00000000..55fe7675 --- /dev/null +++ b/ExternalApps/GraphicsDemo/main/Source/Main.cpp @@ -0,0 +1,51 @@ +#include "Application.h" +#include "Drivers.h" + +#include +#include + +static void onCreate(AppHandle appHandle, void* data) { + Drivers drivers; + + // Find the hardware devices and verify support for the driver interface that we need + // Not all graphics and touch drivers support accessing them directly + if (!drivers.validateSupport()) { + tt_app_stop(); + return; + } + + // Stop LVGL first (because it's currently using the drivers we want to use) + tt_lvgl_stop(); + + // Start using the drivers + if (drivers.start()) { + // Run the main logic + runApplication(drivers.display, drivers.touch); + // Stop the drivers + drivers.stop(); + } + + tt_app_stop(); +} + +static void onDestroy(AppHandle appHandle, void* data) { + // Restart LVGL to resume rendering of regular apps + if (!tt_lvgl_is_started()) { + tt_lvgl_start(); + } +} + +ExternalAppManifest manifest = { + .name = "Hello World", + .onCreate = onCreate, + .onDestroy = onDestroy +}; + +extern "C" { + +int main(int argc, char* argv[]) { + tt_app_register(&manifest); + return 0; +} + +} diff --git a/TactilityC/Include/tt_hal_touch.h b/TactilityC/Include/tt_hal_touch.h new file mode 100644 index 00000000..9392b456 --- /dev/null +++ b/TactilityC/Include/tt_hal_touch.h @@ -0,0 +1,33 @@ +#pragma once + +#include "tt_hal_device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* TouchDriverHandle; + +bool tt_hal_touch_driver_supported(DeviceId id); + +TouchDriverHandle tt_hal_touch_driver_alloc(DeviceId id); + +void tt_hal_touch_driver_free(TouchDriverHandle handle); + +/** + * Get the coordinates for the currently touched points on the screen. + * + * @param[in] handle the touch driver handle + * @param[in] x array of X coordinates + * @param[in] y array of Y coordinates + * @param[in] strength array of strengths (with the minimum size of maxPointCount) or NULL + * @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 + */ +bool tt_hal_touch_driver_get_touched_points(TouchDriverHandle handle, uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* pointCount, uint8_t maxPointCount); + +#ifdef __cplusplus +} +#endif diff --git a/TactilityC/Source/tt_hal_touch.cpp b/TactilityC/Source/tt_hal_touch.cpp new file mode 100644 index 00000000..d28089f8 --- /dev/null +++ b/TactilityC/Source/tt_hal_touch.cpp @@ -0,0 +1,43 @@ +#include "tt_hal_touch.h" + +#include "Tactility/hal/Device.h" +#include "Tactility/hal/touch/TouchDevice.h" +#include "Tactility/hal/touch/TouchDriver.h" + +struct DriverWrapper { + std::shared_ptr driver; + DriverWrapper(std::shared_ptr driver) : driver(driver) {} +}; + +static std::shared_ptr findValidTouchDevice(tt::hal::Device::Id id) { + auto device = tt::hal::findDevice(id); + if (device == nullptr || device->getType() != tt::hal::Device::Type::Touch) { + return nullptr; + } + return std::reinterpret_pointer_cast(device); +} + +extern "C" { + +bool tt_hal_touch_driver_supported(DeviceId id) { + auto touch = findValidTouchDevice(id); + return touch != nullptr && touch->supportsTouchDriver(); +} + +TouchDriverHandle tt_hal_touch_driver_alloc(DeviceId id) { + auto touch = findValidTouchDevice(id); + assert(touch->supportsTouchDriver()); + return new DriverWrapper(touch->getTouchDriver()); +} + +void tt_hal_touch_driver_free(TouchDriverHandle handle) { + DriverWrapper* wrapper = static_cast(handle); + delete wrapper; +} + +bool tt_hal_touch_driver_get_touched_points(TouchDriverHandle handle, uint16_t* x, uint16_t* y, uint16_t* _Nullable strength, uint8_t* pointCount, uint8_t maxPointCount) { + DriverWrapper* wrapper = static_cast(handle); + return wrapper->driver->getTouchedPoints(x, y, strength, pointCount, maxPointCount); +} + +} diff --git a/TactilityC/Source/tt_init.cpp b/TactilityC/Source/tt_init.cpp index 0bf683f0..b7bf7f11 100644 --- a/TactilityC/Source/tt_init.cpp +++ b/TactilityC/Source/tt_init.cpp @@ -9,6 +9,7 @@ #include "tt_hal_device.h" #include "tt_hal_display.h" #include "tt_hal_i2c.h" +#include "tt_hal_touch.h" #include "tt_kernel.h" #include "tt_lvgl.h" #include "tt_lvgl_keyboard.h" @@ -147,6 +148,10 @@ const esp_elfsym elf_symbols[] { ESP_ELFSYM_EXPORT(tt_hal_i2c_master_has_device_at_address), ESP_ELFSYM_EXPORT(tt_hal_i2c_lock), ESP_ELFSYM_EXPORT(tt_hal_i2c_unlock), + ESP_ELFSYM_EXPORT(tt_hal_touch_driver_supported), + ESP_ELFSYM_EXPORT(tt_hal_touch_driver_alloc), + ESP_ELFSYM_EXPORT(tt_hal_touch_driver_free), + ESP_ELFSYM_EXPORT(tt_hal_touch_driver_get_touched_points), ESP_ELFSYM_EXPORT(tt_kernel_delay_millis), ESP_ELFSYM_EXPORT(tt_kernel_delay_micros), ESP_ELFSYM_EXPORT(tt_kernel_delay_ticks),