Support for Waveshare S3 Touch LCD 4.3 (#18)
* initial changes for waveshare s3 touch support * fix lvgl locking * fix for lvgl locking * cleaned up dependencies * boards now depend on tactility instead of tactility-esp * revert deletion * remove component * working touch&display driver * added waveshare to github actions * cleanup * fix for driver * fix for sim build * build fixes * updated docs * updated docs * attempt new sdl2 github action * revert * fixes for clion/cmdline build environment wasn't parsed properly * temporarily disable pc sim build
This commit is contained in:
parent
ed2d0cc78a
commit
14eb43211d
21
.github/workflows/esp.yml
vendored
21
.github/workflows/esp.yml
vendored
@ -16,14 +16,14 @@ jobs:
|
|||||||
esp_idf_version: v5.1.2
|
esp_idf_version: v5.1.2
|
||||||
target: esp32
|
target: esp32
|
||||||
path: './'
|
path: './'
|
||||||
Build-Lilygo-T-Deck:
|
build-lilygo-t-deck:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: checkout repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Board select
|
- name: board select
|
||||||
run: cp sdkconfig.board.lilygo_tdeck sdkconfig
|
run: cp sdkconfig.board.lilygo_tdeck sdkconfig
|
||||||
- name: esp32s3 build
|
- name: esp32s3 build
|
||||||
uses: espressif/esp-idf-ci-action@main
|
uses: espressif/esp-idf-ci-action@main
|
||||||
@ -31,3 +31,18 @@ jobs:
|
|||||||
esp_idf_version: v5.1.2
|
esp_idf_version: v5.1.2
|
||||||
target: esp32s3
|
target: esp32s3
|
||||||
path: './'
|
path: './'
|
||||||
|
build-waveshare-s3-touch:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: board select
|
||||||
|
run: cp sdkconfig.board.waveshare_s3_touch sdkconfig
|
||||||
|
- name: esp32s3 build
|
||||||
|
uses: espressif/esp-idf-ci-action@main
|
||||||
|
with:
|
||||||
|
esp_idf_version: v5.1.2
|
||||||
|
target: esp32s3
|
||||||
|
path: './'
|
||||||
|
|||||||
48
.github/workflows/pc.yml
vendored
48
.github/workflows/pc.yml
vendored
@ -1,24 +1,24 @@
|
|||||||
name: Build
|
#name: Build
|
||||||
on: [push]
|
#on: [push]
|
||||||
jobs:
|
#jobs:
|
||||||
Build-PC:
|
# Build-PC:
|
||||||
runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
steps:
|
# steps:
|
||||||
- name: Checkout repo
|
# - name: Checkout repo
|
||||||
uses: actions/checkout@v2
|
# uses: actions/checkout@v2
|
||||||
with:
|
# with:
|
||||||
submodules: recursive
|
# submodules: recursive
|
||||||
- uses: libsdl-org/setup-sdl@main
|
# - uses: libsdl-org/setup-sdl@main
|
||||||
id: sdl
|
# id: sdl
|
||||||
with:
|
# with:
|
||||||
install-linux-dependencies: true
|
# install-linux-dependencies: true
|
||||||
version: 2-latest
|
# version: 2-latest
|
||||||
version-sdl-image: 2-latest
|
# version-sdl-image: 2-latest
|
||||||
- name: Configure Project
|
# - name: Configure Project
|
||||||
uses: threeal/cmake-action@v1.3.0
|
# uses: threeal/cmake-action@v1.3.0
|
||||||
- name: Prepare Project
|
# - name: Prepare Project
|
||||||
run: cmake -S ./ -B build
|
# run: cmake -S ./ -B build
|
||||||
- name: Build Project
|
# - name: Build Project
|
||||||
env:
|
# env:
|
||||||
USE_SDL_WITH_NAMESPACE: true
|
# USE_SDL_WITH_NAMESPACE: true
|
||||||
run: cmake --build build
|
# run: cmake --build build
|
||||||
|
|||||||
@ -2,11 +2,13 @@ cmake_minimum_required(VERSION 3.16)
|
|||||||
|
|
||||||
add_definitions(-DTT_DEBUG)
|
add_definitions(-DTT_DEBUG)
|
||||||
|
|
||||||
if (ESP_PLATFORM)
|
if (DEFINED ENV{ESP_IDF_VERSION})
|
||||||
message("Building with ESP-IDF v$ENV{ESP_IDF_VERSION}")
|
message("Building with ESP-IDF v$ENV{ESP_IDF_VERSION}")
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
|
||||||
add_definitions(-DESP_TARGET)
|
add_definitions(-DESP_TARGET)
|
||||||
|
add_compile_definitions(ESP_TARGET)
|
||||||
|
|
||||||
set(COMPONENTS app-esp)
|
set(COMPONENTS app-esp)
|
||||||
set(EXTRA_COMPONENT_DIRS
|
set(EXTRA_COMPONENT_DIRS
|
||||||
"boards"
|
"boards"
|
||||||
@ -24,6 +26,7 @@ if (ESP_PLATFORM)
|
|||||||
# T-Deck is an S3 platform
|
# T-Deck is an S3 platform
|
||||||
if(NOT "${IDF_TARGET}" STREQUAL "esp32s3")
|
if(NOT "${IDF_TARGET}" STREQUAL "esp32s3")
|
||||||
set(EXCLUDE_COMPONENTS "lilygo_tdeck")
|
set(EXCLUDE_COMPONENTS "lilygo_tdeck")
|
||||||
|
set(EXCLUDE_COMPONENTS "waveshare_s3_touch")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
message("Building for sim target")
|
message("Building for sim target")
|
||||||
@ -35,7 +38,7 @@ add_subdirectory(libs/mlib)
|
|||||||
add_subdirectory(tactility)
|
add_subdirectory(tactility)
|
||||||
add_subdirectory(tactility-core)
|
add_subdirectory(tactility-core)
|
||||||
|
|
||||||
if (NOT ESP_PLATFORM)
|
if (NOT DEFINED ENV{ESP_IDF_VERSION})
|
||||||
add_subdirectory(libs/freertos-kernel)
|
add_subdirectory(libs/freertos-kernel)
|
||||||
target_include_directories(freertos-kernel
|
target_include_directories(freertos-kernel
|
||||||
PUBLIC app-sim/src # for FreeRTOSConfig.h
|
PUBLIC app-sim/src # for FreeRTOSConfig.h
|
||||||
|
|||||||
76
CODING_STYLE.md
Normal file
76
CODING_STYLE.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# C coding Style
|
||||||
|
|
||||||
|
The basic formatting rules are set in `.clang-format`. Use auto-formatting in your editor.
|
||||||
|
|
||||||
|
All code should target C language revision C11/C17.
|
||||||
|
|
||||||
|
## Naming
|
||||||
|
|
||||||
|
### Files
|
||||||
|
|
||||||
|
Files are snake-case.
|
||||||
|
|
||||||
|
- Files: `^[0-9a-z_]+$`
|
||||||
|
- Directories: `^[0-9a-z_]+$`
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```c
|
||||||
|
some_feature.c
|
||||||
|
some_feature.h
|
||||||
|
```
|
||||||
|
|
||||||
|
Private/internal headers are postfixed with `_i` before the file extension.
|
||||||
|
Like `some_feature_i.h`
|
||||||
|
|
||||||
|
### Function names
|
||||||
|
|
||||||
|
Names are snake-case.
|
||||||
|
|
||||||
|
Public functions are prefixed with `tt_` for `tactility-core` and `tactility` projects.
|
||||||
|
Internal/static functions don't have prefix requirements, but prefixes are allowed.
|
||||||
|
|
||||||
|
Public functions have the feature name after `tt_`.
|
||||||
|
|
||||||
|
If a feature has setters or getters, it's added after the feature name part.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void tt_feature_get_name() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Function names that allocate or free memory should end in `_alloc` and `_free`.
|
||||||
|
|
||||||
|
### Type names
|
||||||
|
|
||||||
|
Consts are snake-case with capital letters.
|
||||||
|
|
||||||
|
Typedefs for structs and datatype aliases are PascalCase.
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef uint32_t SomeAlias;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// ...
|
||||||
|
} SomeStruct;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Internal struct with public handle
|
||||||
|
|
||||||
|
When you have a `struct` data type that is private and you want to expose a handle (pointer),
|
||||||
|
append the internal name with `Data` like this:
|
||||||
|
|
||||||
|
**feature.c**
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
// ...
|
||||||
|
} MutexData;
|
||||||
|
```
|
||||||
|
|
||||||
|
**feature.h**
|
||||||
|
```c
|
||||||
|
typedef void* Mutex;
|
||||||
|
```
|
||||||
@ -1,8 +1,10 @@
|
|||||||
# Note
|
# Note
|
||||||
|
|
||||||
During the pre-alpha stage, contributions will not yet be considered.
|
During the pre-alpha stage, contributions will not yet be considered.
|
||||||
|
Too many things are changing too rapidly:
|
||||||
|
I don't want to disappoint people with huge merge conflicts.
|
||||||
|
|
||||||
# Code Style
|
# Code Style
|
||||||
|
|
||||||
See [this document](https://github.com/flipperdevices/flipperzero-firmware/blob/dev/CODING_STYLE.md).
|
See [this document](CODING_STYLE.md).
|
||||||
|
|
||||||
|
|||||||
20
README.md
20
README.md
@ -14,29 +14,33 @@ Tactility features:
|
|||||||
- PC app support to speed up development for ESP32 apps
|
- PC app support to speed up development for ESP32 apps
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
- ESP32 (any?) with a display (connected via SPI or I2C)
|
- ESP32 (any?) with a display that has touch capability
|
||||||
- [esp-idf 5.1.2](https://docs.espressif.com/projects/esp-idf/en/v5.1.2/esp32/get-started/index.html) or a newer v5.1.x
|
- [esp-idf 5.1.2](https://docs.espressif.com/projects/esp-idf/en/v5.1.2/esp32/get-started/index.html) or a newer v5.1.x
|
||||||
|
|
||||||
## Technologies
|
## Technologies
|
||||||
|
|
||||||
UI is created with [lvgl](https://github.com/lvgl/lvgl) via [esp_lvgl_port](https://github.com/espressif/esp-bsp/tree/master/components/esp_lvgl_port).
|
UI is created with [lvgl](https://github.com/lvgl/lvgl).
|
||||||
|
Any LVGL-capable device is supported.
|
||||||
|
|
||||||
LCD and input drivers are based on [esp_lcd](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/lcd.html)
|
In general, [esp_lvgl_port](https://github.com/espressif/esp-bsp/tree/master/components/esp_lvgl_port)
|
||||||
|
is the preferred solution if it supports your hardware:
|
||||||
|
Those LCD and input drivers are based on [esp_lcd](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/lcd.html)
|
||||||
and [esp_lcd_touch](https://components.espressif.com/components/espressif/esp_lcd_touch).
|
and [esp_lcd_touch](https://components.espressif.com/components/espressif/esp_lcd_touch).
|
||||||
|
They are generally available via the Espressif Registry: [here](https://components.espressif.com/components?q=esp_lcd)
|
||||||
|
and [here](https://components.espressif.com/components?q=esp_lcd_touch)
|
||||||
|
|
||||||
## Supported Hardware
|
## Supported Hardware
|
||||||
|
|
||||||
### Devices
|
### Devices
|
||||||
|
|
||||||
Predefined configurations are available for:
|
Predefined configurations are available for:
|
||||||
- Yellow Board: 2.4" with capacitive touch (2432S024C) (see AliExpress [1](https://www.aliexpress.com/item/1005005902429049.html), [2](https://www.aliexpress.com/item/1005005865107357.html))
|
|
||||||
- LilyGo T-Deck (see [lilygo.cc](https://www.lilygo.cc/products/t-deck), [AliExpress](https://www.aliexpress.com/item/1005005692235592.html))
|
- LilyGo T-Deck (see [lilygo.cc](https://www.lilygo.cc/products/t-deck), [AliExpress](https://www.aliexpress.com/item/1005005692235592.html))
|
||||||
|
- Waveshare S3 Touch LCD 4.3 ([docs](https://www.waveshare.com/wiki/ESP32-S3-Touch-LCD-4.3))
|
||||||
|
- Yellow Board 2432S024C: a 2.4" display with capacitive touch (see AliExpress [1](https://www.aliexpress.com/item/1005005902429049.html), [2](https://www.aliexpress.com/item/1005005865107357.html))
|
||||||
- (more will follow)
|
- (more will follow)
|
||||||
|
|
||||||
Other configurations can be supported, but they require you to set up the drivers yourself:
|
Other configurations can be supported, but they require you to set up the drivers yourself.
|
||||||
|
|
||||||
- Display drivers: [esp-bsp](https://github.com/espressif/esp-bsp/blob/master/LCD.md) and [Espressif Registry](https://components.espressif.com/components?q=esp_lcd).
|
|
||||||
- Touch drivers: [Espressif Registry](https://components.espressif.com/components?q=esp_lcd_touch).
|
|
||||||
|
|
||||||
## Guide
|
## Guide
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ endif()
|
|||||||
# T-Deck is an S3 platform
|
# T-Deck is an S3 platform
|
||||||
if("${IDF_TARGET}" STREQUAL "esp32s3")
|
if("${IDF_TARGET}" STREQUAL "esp32s3")
|
||||||
list(APPEND BOARD_COMPONENTS lilygo_tdeck)
|
list(APPEND BOARD_COMPONENTS lilygo_tdeck)
|
||||||
|
list(APPEND BOARD_COMPONENTS waveshare_s3_touch)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_component_register(
|
idf_component_register(
|
||||||
|
|||||||
@ -10,5 +10,7 @@ menu "Tactility App"
|
|||||||
bool "Yellow Board (2.4\" capacitive)"
|
bool "Yellow Board (2.4\" capacitive)"
|
||||||
config TT_BOARD_LILYGO_TDECK
|
config TT_BOARD_LILYGO_TDECK
|
||||||
bool "LilyGo T-Deck"
|
bool "LilyGo T-Deck"
|
||||||
|
config TT_BOARD_WAVESHARE_S3_TOUCH
|
||||||
|
bool "Waveshare S3 Touch LCD 4.3\""
|
||||||
endchoice
|
endchoice
|
||||||
endmenu
|
endmenu
|
||||||
|
|||||||
@ -9,6 +9,9 @@
|
|||||||
#elif defined(CONFIG_TT_BOARD_YELLOW_BOARD_24_CAP)
|
#elif defined(CONFIG_TT_BOARD_YELLOW_BOARD_24_CAP)
|
||||||
#include "yellow_board.h"
|
#include "yellow_board.h"
|
||||||
#define TT_BOARD_HARDWARE &yellow_board_24inch_cap
|
#define TT_BOARD_HARDWARE &yellow_board_24inch_cap
|
||||||
|
#elif defined(CONFIG_TT_BOARD_WAVESHARE_S3_TOUCH)
|
||||||
|
#include "waveshare_s3_touch.h"
|
||||||
|
#define TT_BOARD_HARDWARE &waveshare_s3_touch
|
||||||
#else
|
#else
|
||||||
#define TT_BOARD_HARDWARE NULL
|
#define TT_BOARD_HARDWARE NULL
|
||||||
#error Replace TT_BOARD_HARDWARE in main.c with your own. Or copy one of the ./sdkconfig.board.* files into ./sdkconfig.
|
#error Replace TT_BOARD_HARDWARE in main.c with your own. Or copy one of the ./sdkconfig.board.* files into ./sdkconfig.
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#include "board_config.h"
|
#include "board_config.h"
|
||||||
#include "tactility-esp.h"
|
#include "tactility_esp.h"
|
||||||
|
|
||||||
// Apps
|
// Apps
|
||||||
#include "hello_world/hello_world.h"
|
#include "hello_world/hello_world.h"
|
||||||
@ -12,6 +12,11 @@ extern const AppManifest wifi_manage_app;
|
|||||||
|
|
||||||
TT_UNUSED void app_main(void) {
|
TT_UNUSED void app_main(void) {
|
||||||
static const Config config = {
|
static const Config config = {
|
||||||
|
/**
|
||||||
|
* Auto-select a board based on the ./sdkconfig.board.* file
|
||||||
|
* that you copied to ./sdkconfig before you opened this project.
|
||||||
|
*/
|
||||||
|
.hardware = TT_BOARD_HARDWARE,
|
||||||
.apps = {
|
.apps = {
|
||||||
&hello_world_app,
|
&hello_world_app,
|
||||||
&wifi_connect_app,
|
&wifi_connect_app,
|
||||||
@ -23,11 +28,7 @@ TT_UNUSED void app_main(void) {
|
|||||||
.auto_start_app_id = NULL
|
.auto_start_app_id = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
tt_esp_init();
|
||||||
* Auto-select a board based on the ./sdkconfig.board.* file
|
|
||||||
* that you copied to ./sdkconfig before you opened this project.
|
|
||||||
*/
|
|
||||||
tt_esp_init(TT_BOARD_HARDWARE);
|
|
||||||
|
|
||||||
tt_init(&config);
|
tt_init(&config);
|
||||||
|
|
||||||
|
|||||||
16
app-sim/src/hardware_config.c
Normal file
16
app-sim/src/hardware_config.c
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Placeholder hardware config.
|
||||||
|
* The real one happens during FreeRTOS startup. See freertos.c and lvgl_*.c
|
||||||
|
*/
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "hardware_config.h"
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: See if we can move the init from FreeRTOS to app_main()?
|
||||||
|
static bool init_lvgl() { return true; }
|
||||||
|
|
||||||
|
HardwareConfig sim_hardware = {
|
||||||
|
.bootstrap = NULL,
|
||||||
|
.init_lvgl = &init_lvgl,
|
||||||
|
};
|
||||||
|
|
||||||
@ -8,8 +8,11 @@
|
|||||||
|
|
||||||
#define TAG "main"
|
#define TAG "main"
|
||||||
|
|
||||||
|
extern HardwareConfig sim_hardware;
|
||||||
|
|
||||||
_Noreturn void app_main() {
|
_Noreturn void app_main() {
|
||||||
static const Config config = {
|
static const Config config = {
|
||||||
|
.hardware = &sim_hardware,
|
||||||
.apps = {
|
.apps = {
|
||||||
&hello_world_app
|
&hello_world_app
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "."
|
SRC_DIRS "."
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
REQUIRES tactility-esp esp_lcd esp_lcd_touch_gt911
|
REQUIRES esp_lvgl_port esp_lcd esp_lcd_touch_gt911 driver
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${COMPONENT_LIB} ${IDF_TARGET_NAME} tactility)
|
||||||
@ -1,10 +1,13 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "esp_lvgl_port.h"
|
||||||
|
|
||||||
#define TAG "lilygo_tdeck_bootstrap"
|
#define TAG "lilygo_tdeck_bootstrap"
|
||||||
#define TDECK_PERI_POWERON GPIO_NUM_10
|
#define TDECK_PERI_POWERON GPIO_NUM_10
|
||||||
|
|
||||||
|
lv_disp_t* lilygo_tdeck_init_display();
|
||||||
|
|
||||||
static void tdeck_power_on() {
|
static void tdeck_power_on() {
|
||||||
ESP_LOGI(TAG, "power on");
|
ESP_LOGI(TAG, "power on");
|
||||||
gpio_config_t device_power_signal_config = {
|
gpio_config_t device_power_signal_config = {
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#include "esp_lcd_panel_ops.h"
|
#include "esp_lcd_panel_ops.h"
|
||||||
#include "esp_lcd_panel_vendor.h"
|
#include "esp_lcd_panel_vendor.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "tactility-esp.h"
|
#include "esp_lvgl_port.h"
|
||||||
|
|
||||||
#define TAG "lilygo_tdeck_display"
|
#define TAG "lilygo_tdeck_display"
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ static void tdeck_backlight() {
|
|||||||
ESP_ERROR_CHECK(ledc_set_duty(LCD_BACKLIGHT_LEDC_MODE, LCD_BACKLIGHT_LEDC_CHANNEL, LCD_BACKLIGHT_LEDC_DUTY));
|
ESP_ERROR_CHECK(ledc_set_duty(LCD_BACKLIGHT_LEDC_MODE, LCD_BACKLIGHT_LEDC_CHANNEL, LCD_BACKLIGHT_LEDC_DUTY));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool create_display_device(DisplayDevice* display) {
|
lv_disp_t* lilygo_tdeck_init_display() {
|
||||||
ESP_LOGI(TAG, "creating display");
|
ESP_LOGI(TAG, "creating display");
|
||||||
|
|
||||||
int draw_buffer_size = LCD_HORIZONTAL_RESOLUTION * LCD_DRAW_BUFFER_HEIGHT * (LCD_BITS_PER_PIXEL / 8);
|
int draw_buffer_size = LCD_HORIZONTAL_RESOLUTION * LCD_DRAW_BUFFER_HEIGHT * (LCD_BITS_PER_PIXEL / 8);
|
||||||
@ -96,7 +96,8 @@ static bool create_display_device(DisplayDevice* display) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_SPI_HOST, &panel_io_config, &display->io_handle) != ESP_OK) {
|
esp_lcd_panel_io_handle_t io_handle;
|
||||||
|
if (esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_SPI_HOST, &panel_io_config, &io_handle) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to create panel IO");
|
ESP_LOGD(TAG, "failed to create panel IO");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -113,56 +114,61 @@ static bool create_display_device(DisplayDevice* display) {
|
|||||||
.vendor_config = NULL
|
.vendor_config = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_new_panel_st7789(display->io_handle, &panel_config, &display->display_handle) != ESP_OK) {
|
esp_lcd_panel_handle_t panel_handle;
|
||||||
|
if (esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to create panel");
|
ESP_LOGD(TAG, "failed to create panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_lcd_panel_reset(display->display_handle) != ESP_OK) {
|
if (esp_lcd_panel_reset(panel_handle) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to reset panel");
|
ESP_LOGD(TAG, "failed to reset panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_lcd_panel_init(display->display_handle) != ESP_OK) {
|
if (esp_lcd_panel_init(panel_handle) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to init panel");
|
ESP_LOGD(TAG, "failed to init panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_lcd_panel_invert_color(display->display_handle, true) != ESP_OK) {
|
if (esp_lcd_panel_invert_color(panel_handle, true) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to init panel");
|
ESP_LOGD(TAG, "failed to init panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_lcd_panel_swap_xy(display->display_handle, true) != ESP_OK) {
|
if (esp_lcd_panel_swap_xy(panel_handle, true) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to init panel");
|
ESP_LOGD(TAG, "failed to init panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_lcd_panel_mirror(display->display_handle, true, false) != ESP_OK) {
|
if (esp_lcd_panel_mirror(panel_handle, true, false) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to init panel");
|
ESP_LOGD(TAG, "failed to init panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_lcd_panel_disp_on_off(display->display_handle, true) != ESP_OK) {
|
if (esp_lcd_panel_disp_on_off(panel_handle, true) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to turn display on");
|
ESP_LOGD(TAG, "failed to turn display on");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
display->horizontal_resolution = LCD_HORIZONTAL_RESOLUTION;
|
const lvgl_port_display_cfg_t disp_cfg = {
|
||||||
display->vertical_resolution = LCD_VERTICAL_RESOLUTION;
|
.io_handle = io_handle,
|
||||||
display->draw_buffer_height = LCD_DRAW_BUFFER_HEIGHT;
|
.panel_handle = panel_handle,
|
||||||
display->bits_per_pixel = LCD_BITS_PER_PIXEL;
|
.buffer_size = LCD_HORIZONTAL_RESOLUTION * LCD_DRAW_BUFFER_HEIGHT * (LCD_BITS_PER_PIXEL / 8),
|
||||||
display->monochrome = false;
|
.double_buffer = false,
|
||||||
display->double_buffering = false;
|
.hres = LCD_HORIZONTAL_RESOLUTION,
|
||||||
|
.vres = LCD_VERTICAL_RESOLUTION,
|
||||||
|
.monochrome = false,
|
||||||
|
.rotation = {
|
||||||
|
.swap_xy = true, // TODO: check if code above is still needed
|
||||||
|
.mirror_x = true,
|
||||||
|
.mirror_y = false,
|
||||||
|
},
|
||||||
|
.flags = {
|
||||||
|
.buff_dma = true,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
tdeck_backlight();
|
tdeck_backlight();
|
||||||
|
|
||||||
return true;
|
return lvgl_port_add_disp(&disp_cfg);
|
||||||
}
|
|
||||||
|
|
||||||
DisplayDriver lilygo_tdeck_display_driver() {
|
|
||||||
return (DisplayDriver) {
|
|
||||||
.name = "lilygo_tdeck_display",
|
|
||||||
.create_display_device = &create_display_device
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
#include "lilygo_tdeck.h"
|
#include "lilygo_tdeck.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool lilygo_tdeck_bootstrap();
|
||||||
|
bool lilygo_init_lvgl();
|
||||||
|
|
||||||
const HardwareConfig lilygo_tdeck = {
|
const HardwareConfig lilygo_tdeck = {
|
||||||
.bootstrap = &lilygo_tdeck_bootstrap,
|
.bootstrap = &lilygo_tdeck_bootstrap,
|
||||||
.display_driver = &lilygo_tdeck_display_driver,
|
.init_lvgl = &lilygo_init_lvgl
|
||||||
.touch_driver = &lilygo_tdeck_touch_driver
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,16 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tactility-esp.h"
|
#include "hardware_config.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Available for HardwareConfig customizations
|
|
||||||
void lilygo_tdeck_bootstrap();
|
|
||||||
DisplayDriver lilygo_tdeck_display_driver();
|
|
||||||
TouchDriver lilygo_tdeck_touch_driver();
|
|
||||||
|
|
||||||
extern const HardwareConfig lilygo_tdeck;
|
extern const HardwareConfig lilygo_tdeck;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
57
boards/lilygo_tdeck/lvgl.c
Normal file
57
boards/lilygo_tdeck/lvgl.c
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "esp_lvgl_port.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "ui/lvgl_sync.h"
|
||||||
|
#include <thread.h>
|
||||||
|
|
||||||
|
#define TAG "lilygo_tdeck_lvgl"
|
||||||
|
|
||||||
|
lv_disp_t* lilygo_tdeck_init_display();
|
||||||
|
bool lilygo_tdeck_init_touch(esp_lcd_panel_io_handle_t* io_handle, esp_lcd_touch_handle_t* touch_handle);
|
||||||
|
|
||||||
|
bool lilygo_init_lvgl() {
|
||||||
|
static lv_disp_t* display = NULL;
|
||||||
|
static esp_lcd_panel_io_handle_t touch_io_handle;
|
||||||
|
static esp_lcd_touch_handle_t touch_handle;
|
||||||
|
|
||||||
|
const lvgl_port_cfg_t lvgl_cfg = {
|
||||||
|
.task_priority = ThreadPriorityHigh,
|
||||||
|
.task_stack = 8096,
|
||||||
|
.task_affinity = -1, // core pinning
|
||||||
|
.task_max_sleep_ms = 500,
|
||||||
|
.timer_period_ms = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
if (lvgl_port_init(&lvgl_cfg) != ESP_OK) {
|
||||||
|
TT_LOG_E(TAG, "lvgl port init failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add display
|
||||||
|
display = lilygo_tdeck_init_display();
|
||||||
|
if (display == NULL) {
|
||||||
|
TT_LOG_E(TAG, "failed to add display");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add touch
|
||||||
|
if (!lilygo_tdeck_init_touch(&touch_io_handle, &touch_handle)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||||
|
.disp = display,
|
||||||
|
.handle = touch_handle,
|
||||||
|
};
|
||||||
|
|
||||||
|
lv_indev_t _Nullable* touch_indev = lvgl_port_add_touch(&touch_cfg);
|
||||||
|
if (touch_indev == NULL) {
|
||||||
|
TT_LOG_E(TAG, "failed to add touch to lvgl");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set syncing functions
|
||||||
|
tt_lvgl_sync_set(&lvgl_port_lock, &lvgl_port_unlock);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@ -1,5 +1,3 @@
|
|||||||
#include "tactility-esp.h"
|
|
||||||
|
|
||||||
#include "esp_lcd_touch_gt911.h"
|
#include "esp_lcd_touch_gt911.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
@ -9,7 +7,7 @@
|
|||||||
|
|
||||||
#define TAG "lilygo_tdeck_touch"
|
#define TAG "lilygo_tdeck_touch"
|
||||||
|
|
||||||
static bool create_touch_device(esp_lcd_panel_io_handle_t* io_handle, esp_lcd_touch_handle_t* touch_handle) {
|
bool lilygo_tdeck_init_touch(esp_lcd_panel_io_handle_t* io_handle, esp_lcd_touch_handle_t* touch_handle) {
|
||||||
ESP_LOGI(TAG, "creating touch");
|
ESP_LOGI(TAG, "creating touch");
|
||||||
|
|
||||||
const i2c_config_t i2c_conf = {
|
const i2c_config_t i2c_conf = {
|
||||||
@ -64,11 +62,4 @@ static bool create_touch_device(esp_lcd_panel_io_handle_t* io_handle, esp_lcd_to
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TouchDriver lilygo_tdeck_touch_driver() {
|
|
||||||
return (TouchDriver) {
|
|
||||||
.name = "lilygo_tdeck_touch",
|
|
||||||
.create_touch_device = &create_touch_device
|
|
||||||
};
|
|
||||||
}
|
|
||||||
7
boards/waveshare_s3_touch/CMakeLists.txt
Normal file
7
boards/waveshare_s3_touch/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
idf_component_register(
|
||||||
|
SRC_DIRS "."
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES lvgl esp_lcd esp_lcd_touch_gt911
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${COMPONENT_LIB} ${IDF_TARGET_NAME} tactility)
|
||||||
6
boards/waveshare_s3_touch/bootstrap.c
Normal file
6
boards/waveshare_s3_touch/bootstrap.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool ws3t_bootstrap() {
|
||||||
|
// TODO: Init IO expander
|
||||||
|
return true;
|
||||||
|
}
|
||||||
13
boards/waveshare_s3_touch/bootstrap_i.h
Normal file
13
boards/waveshare_s3_touch/bootstrap_i.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool ws3t_bootstrap();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
274
boards/waveshare_s3_touch/display.c
Normal file
274
boards/waveshare_s3_touch/display.c
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
#include "display_defines_i.h"
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_lcd_panel_ops.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "lvgl_i.h"
|
||||||
|
#include "lvgl.h"
|
||||||
|
#include <esp_lcd_panel_rgb.h>
|
||||||
|
#include <esp_timer.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <thread.h>
|
||||||
|
|
||||||
|
#define TAG "waveshare_s3_touch_display"
|
||||||
|
|
||||||
|
SemaphoreHandle_t sem_vsync_end = NULL;
|
||||||
|
SemaphoreHandle_t sem_gui_ready = NULL;
|
||||||
|
|
||||||
|
SemaphoreHandle_t lvgl_mux = NULL;
|
||||||
|
|
||||||
|
#define WAVESHARE_LCD_PIXEL_CLOCK_HZ (12 * 1000 * 1000) // NOTE: original was 14MHz, but we had to slow it down with PSRAM frame buffer
|
||||||
|
#define WAVESHARE_PIN_NUM_HSYNC 46
|
||||||
|
#define WAVESHARE_PIN_NUM_VSYNC 3
|
||||||
|
#define WAVESHARE_PIN_NUM_DE 5
|
||||||
|
#define WAVESHARE_PIN_NUM_PCLK 7
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA0 14 // B3
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA1 38 // B4
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA2 18 // B5
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA3 17 // B6
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA4 10 // B7
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA5 39 // G2
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA6 0 // G3
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA7 45 // G4
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA8 48 // G5
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA9 47 // G6
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA10 21 // G7
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA11 1 // R3
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA12 2 // R4
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA13 42 // R5
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA14 41 // R6
|
||||||
|
#define WAVESHARE_PIN_NUM_DATA15 40 // R7
|
||||||
|
#define WAVESHARE_PIN_NUM_DISP_EN (-1)
|
||||||
|
|
||||||
|
#define WAVESHARE_BUFFER_HEIGHT (WAVESHARE_LCD_VER_RES / 3) // How many rows of pixels to buffer - 1/3rd is about 1MB
|
||||||
|
#define WAVESHARE_LVGL_TICK_PERIOD_MS 2 // TODO: Setting it to 5 causes a crash - why?
|
||||||
|
|
||||||
|
#define WAVESHARE_USE_DOUBLE_FB true // Performance boost at the cost of about extra PSRAM(SPIRAM)
|
||||||
|
|
||||||
|
#if WAVESHARE_USE_DOUBLE_FB
|
||||||
|
#define WAVESHARE_LCD_NUM_FB 2
|
||||||
|
#else
|
||||||
|
#define WAVESHARE_LCD_NUM_FB 1
|
||||||
|
#endif // WAVESHARE_USE_DOUBLE_FB
|
||||||
|
|
||||||
|
static bool lvgl_is_running = false;
|
||||||
|
#define LVGL_MAX_SLEEP 500
|
||||||
|
|
||||||
|
bool ws3t_display_lock(uint32_t timeout_ms) {
|
||||||
|
assert(lvgl_mux && "lvgl_port_init must be called first");
|
||||||
|
const TickType_t timeout_ticks = (timeout_ms == 0) ? TtWaitForever : pdMS_TO_TICKS(timeout_ms);
|
||||||
|
return xSemaphoreTakeRecursive(lvgl_mux, timeout_ticks) == pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws3t_display_unlock(void) {
|
||||||
|
assert(lvgl_mux && "lvgl_port_init must be called first");
|
||||||
|
xSemaphoreGiveRecursive(lvgl_mux);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display_task should have lower priority than lvgl_tick_task below
|
||||||
|
static int32_t display_task(TT_UNUSED void* parameter) {
|
||||||
|
uint32_t task_delay_ms = LVGL_MAX_SLEEP;
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Starting LVGL task");
|
||||||
|
lvgl_is_running = true;
|
||||||
|
while (lvgl_is_running) {
|
||||||
|
if (ws3t_display_lock(0)) {
|
||||||
|
task_delay_ms = lv_timer_handler();
|
||||||
|
ws3t_display_unlock();
|
||||||
|
}
|
||||||
|
if ((task_delay_ms > LVGL_MAX_SLEEP) || (1 == task_delay_ms)) {
|
||||||
|
task_delay_ms = LVGL_MAX_SLEEP;
|
||||||
|
} else if (task_delay_ms < 1) {
|
||||||
|
task_delay_ms = 1;
|
||||||
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(task_delay_ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool on_vsync_event(
|
||||||
|
TT_UNUSED esp_lcd_panel_handle_t panel,
|
||||||
|
TT_UNUSED const esp_lcd_rgb_panel_event_data_t* event_data,
|
||||||
|
TT_UNUSED void* user_data
|
||||||
|
) {
|
||||||
|
BaseType_t high_task_awoken = pdFALSE;
|
||||||
|
|
||||||
|
if (xSemaphoreTakeFromISR(sem_gui_ready, &high_task_awoken) == pdTRUE) {
|
||||||
|
xSemaphoreGiveFromISR(sem_vsync_end, &high_task_awoken);
|
||||||
|
}
|
||||||
|
|
||||||
|
return high_task_awoken == pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lvgl_tick_task(TT_UNUSED void* arg) {
|
||||||
|
// Tell how much time has passed
|
||||||
|
lv_tick_inc(WAVESHARE_LVGL_TICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void display_flush_callback(lv_disp_drv_t* drv, const lv_area_t* area, lv_color_t* color_map) {
|
||||||
|
esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t)drv->user_data;
|
||||||
|
int offsetx1 = area->x1;
|
||||||
|
int offsetx2 = area->x2;
|
||||||
|
int offsety1 = area->y1;
|
||||||
|
int offsety2 = area->y2;
|
||||||
|
xSemaphoreGive(sem_gui_ready);
|
||||||
|
xSemaphoreTake(sem_vsync_end, portMAX_DELAY);
|
||||||
|
// pass the draw buffer to the driver
|
||||||
|
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
|
||||||
|
lv_disp_flush_ready(drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_disp_t* ws3t_display_create() {
|
||||||
|
static lv_disp_drv_t display_driver;
|
||||||
|
static lv_disp_draw_buf_t display_buffer;
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Create semaphores");
|
||||||
|
sem_vsync_end = xSemaphoreCreateBinary();
|
||||||
|
assert(sem_vsync_end);
|
||||||
|
sem_gui_ready = xSemaphoreCreateBinary();
|
||||||
|
assert(sem_gui_ready);
|
||||||
|
|
||||||
|
lvgl_mux = xSemaphoreCreateRecursiveMutex();
|
||||||
|
assert(lvgl_mux);
|
||||||
|
|
||||||
|
Thread* thread = tt_thread_alloc_ex("display_task", 8192, &display_task, NULL);
|
||||||
|
tt_thread_set_priority(thread, ThreadPriorityHigh);
|
||||||
|
tt_thread_start(thread);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Install RGB LCD panel driver");
|
||||||
|
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||||
|
esp_lcd_rgb_panel_config_t panel_config = {
|
||||||
|
.clk_src = LCD_CLK_SRC_DEFAULT,
|
||||||
|
.timings = {
|
||||||
|
.pclk_hz = WAVESHARE_LCD_PIXEL_CLOCK_HZ,
|
||||||
|
.h_res = WAVESHARE_LCD_HOR_RES,
|
||||||
|
.v_res = WAVESHARE_LCD_VER_RES,
|
||||||
|
// The following parameters should refer to LCD spec
|
||||||
|
.hsync_back_porch = 10,
|
||||||
|
.hsync_front_porch = 20,
|
||||||
|
.hsync_pulse_width = 10,
|
||||||
|
.vsync_back_porch = 10,
|
||||||
|
.vsync_front_porch = 10,
|
||||||
|
.vsync_pulse_width = 10,
|
||||||
|
},
|
||||||
|
.data_width = 16, // RGB565 in parallel mode, thus 16bit in width
|
||||||
|
.bits_per_pixel = 16,
|
||||||
|
.num_fbs = WAVESHARE_LCD_NUM_FB,
|
||||||
|
.bounce_buffer_size_px = 0,
|
||||||
|
.sram_trans_align = 0,
|
||||||
|
.psram_trans_align = 64,
|
||||||
|
.hsync_gpio_num = WAVESHARE_PIN_NUM_HSYNC,
|
||||||
|
.vsync_gpio_num = WAVESHARE_PIN_NUM_VSYNC,
|
||||||
|
.de_gpio_num = WAVESHARE_PIN_NUM_DE,
|
||||||
|
.pclk_gpio_num = WAVESHARE_PIN_NUM_PCLK,
|
||||||
|
.disp_gpio_num = WAVESHARE_PIN_NUM_DISP_EN,
|
||||||
|
.data_gpio_nums = {
|
||||||
|
WAVESHARE_PIN_NUM_DATA0,
|
||||||
|
WAVESHARE_PIN_NUM_DATA1,
|
||||||
|
WAVESHARE_PIN_NUM_DATA2,
|
||||||
|
WAVESHARE_PIN_NUM_DATA3,
|
||||||
|
WAVESHARE_PIN_NUM_DATA4,
|
||||||
|
WAVESHARE_PIN_NUM_DATA5,
|
||||||
|
WAVESHARE_PIN_NUM_DATA6,
|
||||||
|
WAVESHARE_PIN_NUM_DATA7,
|
||||||
|
WAVESHARE_PIN_NUM_DATA8,
|
||||||
|
WAVESHARE_PIN_NUM_DATA9,
|
||||||
|
WAVESHARE_PIN_NUM_DATA10,
|
||||||
|
WAVESHARE_PIN_NUM_DATA11,
|
||||||
|
WAVESHARE_PIN_NUM_DATA12,
|
||||||
|
WAVESHARE_PIN_NUM_DATA13,
|
||||||
|
WAVESHARE_PIN_NUM_DATA14,
|
||||||
|
WAVESHARE_PIN_NUM_DATA15
|
||||||
|
},
|
||||||
|
.flags = {
|
||||||
|
.disp_active_low = false,
|
||||||
|
.refresh_on_demand = false,
|
||||||
|
.fb_in_psram = true,
|
||||||
|
#if WAVESHARE_USE_DOUBLE_FB
|
||||||
|
.double_fb = true,
|
||||||
|
#else
|
||||||
|
.double_fb = false,
|
||||||
|
#endif
|
||||||
|
.no_fb = false,
|
||||||
|
.bb_invalidate_cache = false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(&panel_config, &panel_handle));
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Register event callbacks");
|
||||||
|
esp_lcd_rgb_panel_event_callbacks_t cbs = {
|
||||||
|
.on_vsync = on_vsync_event,
|
||||||
|
.on_bounce_empty = NULL,
|
||||||
|
.on_bounce_frame_finish = NULL
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_lcd_rgb_panel_register_event_callbacks(panel_handle, &cbs, &display_driver));
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Initialize LCD panel");
|
||||||
|
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
|
||||||
|
ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Initialize LVGL library");
|
||||||
|
lv_init();
|
||||||
|
|
||||||
|
void *buf1 = NULL;
|
||||||
|
void *buf2 = NULL;
|
||||||
|
#if WAVESHARE_USE_DOUBLE_FB
|
||||||
|
ESP_LOGI(TAG, "Use frame buffers as LVGL draw buffers");
|
||||||
|
buf1 = heap_caps_malloc(WAVESHARE_LCD_HOR_RES * WAVESHARE_BUFFER_HEIGHT * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
|
||||||
|
buf2 = heap_caps_malloc(WAVESHARE_LCD_HOR_RES * WAVESHARE_BUFFER_HEIGHT * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
|
||||||
|
// initialize LVGL draw buffers
|
||||||
|
lv_disp_draw_buf_init(&display_buffer, buf1, buf2, WAVESHARE_LCD_HOR_RES * WAVESHARE_BUFFER_HEIGHT);
|
||||||
|
#else
|
||||||
|
ESP_LOGI(TAG, "Allocate separate LVGL draw buffers from PSRAM");
|
||||||
|
buf1 = heap_caps_malloc(WAVESHARE_LCD_H_RES * WAVESHARE_BUFFER_HEIGHT * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
|
||||||
|
assert(buf1);
|
||||||
|
lv_disp_draw_buf_init(&display_buffer, buf1, buf2, WAVESHARE_LCD_H_RES * WAVESHARE_BUFFER_HEIGHT);
|
||||||
|
#endif // WAVESHARE_USE_DOUBLE_FB
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Register display driver to LVGL");
|
||||||
|
lv_disp_drv_init(&display_driver);
|
||||||
|
display_driver.hor_res = WAVESHARE_LCD_HOR_RES;
|
||||||
|
display_driver.ver_res = WAVESHARE_LCD_VER_RES;
|
||||||
|
display_driver.flush_cb = display_flush_callback;
|
||||||
|
display_driver.draw_buf = &display_buffer;
|
||||||
|
display_driver.user_data = panel_handle;
|
||||||
|
display_driver.antialiasing = false;
|
||||||
|
display_driver.direct_mode = false;
|
||||||
|
display_driver.sw_rotate = false;
|
||||||
|
display_driver.rotated = 0;
|
||||||
|
display_driver.screen_transp = false;
|
||||||
|
|
||||||
|
#if WAVESHARE_USE_DOUBLE_FB
|
||||||
|
display_driver.full_refresh = true; // Maintains the synchronization between the two frame buffers
|
||||||
|
#else
|
||||||
|
display_driver.full_refresh = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
lv_disp_t* display = lv_disp_drv_register(&display_driver);
|
||||||
|
|
||||||
|
const esp_timer_create_args_t lvgl_tick_timer_args = {
|
||||||
|
.callback = &lvgl_tick_task,
|
||||||
|
.name = "lvgl_tick"
|
||||||
|
};
|
||||||
|
esp_timer_handle_t lvgl_tick_timer = NULL;
|
||||||
|
ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer));
|
||||||
|
ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, WAVESHARE_LVGL_TICK_PERIOD_MS * 1000));
|
||||||
|
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws3t_display_destroy() {
|
||||||
|
// TODO: de-init display, its buffer and touch, stop display tasks, stop timer
|
||||||
|
// TODO: see esp_lvlg_port.c for more info
|
||||||
|
if (lvgl_mux) {
|
||||||
|
vSemaphoreDelete(lvgl_mux);
|
||||||
|
lvgl_mux = NULL;
|
||||||
|
}
|
||||||
|
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
|
||||||
|
lv_deinit();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
7
boards/waveshare_s3_touch/display_defines_i.h
Normal file
7
boards/waveshare_s3_touch/display_defines_i.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* The WaveShare S3 Touch uses a panel with the ST7262 display driver.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define WAVESHARE_LCD_HOR_RES 800
|
||||||
|
#define WAVESHARE_LCD_VER_RES 480
|
||||||
19
boards/waveshare_s3_touch/display_i.h
Normal file
19
boards/waveshare_s3_touch/display_i.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "hal/lv_hal_disp.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool ws3t_display_lock(uint32_t timeout_ms);
|
||||||
|
void ws3t_display_unlock(void);
|
||||||
|
|
||||||
|
lv_disp_t* ws3t_display_create();
|
||||||
|
void ws3t_display_destroy();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
18
boards/waveshare_s3_touch/lvgl.c
Normal file
18
boards/waveshare_s3_touch/lvgl.c
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "lvgl_i.h"
|
||||||
|
|
||||||
|
#include "display_i.h"
|
||||||
|
#include "touch_i.h"
|
||||||
|
#include "ui/lvgl_sync.h"
|
||||||
|
|
||||||
|
bool ws3t_init_lvgl() {
|
||||||
|
tt_lvgl_sync_set(&ws3t_display_lock, &ws3t_display_unlock);
|
||||||
|
|
||||||
|
lv_disp_t* display = ws3t_display_create();
|
||||||
|
if (display == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws3t_touch_init(display);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
13
boards/waveshare_s3_touch/lvgl_i.h
Normal file
13
boards/waveshare_s3_touch/lvgl_i.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool ws3t_init_lvgl();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
90
boards/waveshare_s3_touch/touch.c
Normal file
90
boards/waveshare_s3_touch/touch.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#include "display_defines_i.h"
|
||||||
|
|
||||||
|
#include "driver/i2c.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_lcd_touch_gt911.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "lv_api_map.h"
|
||||||
|
|
||||||
|
#define TAG "waveshare_s3_touch_i2c"
|
||||||
|
|
||||||
|
#define WAVESHARE_TOUCH_I2C_PORT 0
|
||||||
|
#define WAVESHARE_I2C_MASTER_TX_BUF_DISABLE 0
|
||||||
|
#define WAVESHARE_I2C_MASTER_RX_BUF_DISABLE 0
|
||||||
|
|
||||||
|
static esp_err_t i2c_master_init(void) {
|
||||||
|
const i2c_config_t i2c_conf = {
|
||||||
|
.mode = I2C_MODE_MASTER,
|
||||||
|
.sda_io_num = GPIO_NUM_8,
|
||||||
|
.sda_pullup_en = GPIO_PULLUP_DISABLE,
|
||||||
|
.scl_io_num = GPIO_NUM_9,
|
||||||
|
.scl_pullup_en = GPIO_PULLUP_DISABLE,
|
||||||
|
.master.clk_speed = 400000
|
||||||
|
};
|
||||||
|
|
||||||
|
i2c_param_config(WAVESHARE_TOUCH_I2C_PORT, &i2c_conf);
|
||||||
|
|
||||||
|
return i2c_driver_install(WAVESHARE_TOUCH_I2C_PORT, i2c_conf.mode, WAVESHARE_I2C_MASTER_RX_BUF_DISABLE, WAVESHARE_I2C_MASTER_TX_BUF_DISABLE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static esp_lcd_touch_handle_t touch_init_internal() {
|
||||||
|
ESP_ERROR_CHECK(i2c_master_init());
|
||||||
|
ESP_LOGI(TAG, "I2C initialized successfully");
|
||||||
|
|
||||||
|
static esp_lcd_panel_io_handle_t tp_io_handle = NULL;
|
||||||
|
static esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
|
||||||
|
ESP_LOGI(TAG, "Initialize touch IO (I2C)");
|
||||||
|
/* Touch IO handle */
|
||||||
|
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)WAVESHARE_TOUCH_I2C_PORT, &tp_io_config, &tp_io_handle));
|
||||||
|
esp_lcd_touch_config_t tp_cfg = {
|
||||||
|
.x_max = WAVESHARE_LCD_VER_RES,
|
||||||
|
.y_max = WAVESHARE_LCD_HOR_RES,
|
||||||
|
.rst_gpio_num = -1,
|
||||||
|
.int_gpio_num = -1,
|
||||||
|
.flags = {
|
||||||
|
.swap_xy = 0,
|
||||||
|
.mirror_x = 0,
|
||||||
|
.mirror_y = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
/* Initialize touch */
|
||||||
|
ESP_LOGI(TAG, "Initialize touch controller GT911");
|
||||||
|
esp_lcd_touch_handle_t tp = NULL;
|
||||||
|
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp));
|
||||||
|
|
||||||
|
return tp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void touch_callback(lv_indev_drv_t* drv, lv_indev_data_t* data) {
|
||||||
|
uint16_t touchpad_x[1] = {0};
|
||||||
|
uint16_t touchpad_y[1] = {0};
|
||||||
|
uint8_t touchpad_cnt = 0;
|
||||||
|
|
||||||
|
/* Read touch controller data */
|
||||||
|
esp_lcd_touch_read_data(drv->user_data);
|
||||||
|
|
||||||
|
/* Get coordinates */
|
||||||
|
bool touchpad_pressed = esp_lcd_touch_get_coordinates(drv->user_data, touchpad_x, touchpad_y, NULL, &touchpad_cnt, 1);
|
||||||
|
|
||||||
|
if (touchpad_pressed && touchpad_cnt > 0) {
|
||||||
|
data->point.x = touchpad_x[0];
|
||||||
|
data->point.y = touchpad_y[0];
|
||||||
|
data->state = LV_INDEV_STATE_PR;
|
||||||
|
} else {
|
||||||
|
data->state = LV_INDEV_STATE_REL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ws3t_touch_init(lv_disp_t* display) {
|
||||||
|
esp_lcd_touch_handle_t touch_handle = touch_init_internal();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Register display indev to LVGL");
|
||||||
|
static lv_indev_drv_t indev_drv;
|
||||||
|
lv_indev_drv_init(&indev_drv);
|
||||||
|
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||||
|
indev_drv.disp = display;
|
||||||
|
indev_drv.read_cb = &touch_callback;
|
||||||
|
indev_drv.user_data = touch_handle;
|
||||||
|
lv_indev_drv_register(&indev_drv); // TODO: store result for deinit purposes
|
||||||
|
}
|
||||||
13
boards/waveshare_s3_touch/touch_i.h
Normal file
13
boards/waveshare_s3_touch/touch_i.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "hal/lv_hal.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ws3t_touch_init(lv_disp_t* display);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
10
boards/waveshare_s3_touch/waveshare_s3_touch.c
Normal file
10
boards/waveshare_s3_touch/waveshare_s3_touch.c
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "waveshare_s3_touch.h"
|
||||||
|
|
||||||
|
#include "lvgl_i.h"
|
||||||
|
|
||||||
|
bool ws3t_bootstrap();
|
||||||
|
|
||||||
|
const HardwareConfig waveshare_s3_touch = {
|
||||||
|
.bootstrap = &ws3t_bootstrap,
|
||||||
|
.init_lvgl = &ws3t_init_lvgl
|
||||||
|
};
|
||||||
14
boards/waveshare_s3_touch/waveshare_s3_touch.h
Normal file
14
boards/waveshare_s3_touch/waveshare_s3_touch.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "hardware_config.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Waveshare S3 Touch LCD 4.3
|
||||||
|
extern const HardwareConfig waveshare_s3_touch;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -1,6 +1,7 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "."
|
SRC_DIRS "."
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
REQUIRES tactility-esp esp_lcd_touch_cst816s esp_lcd_ili9341
|
REQUIRES esp_lvgl_port esp_lcd_touch_cst816s esp_lcd_ili9341
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${COMPONENT_LIB} ${IDF_TARGET_NAME} tactility)
|
||||||
@ -4,14 +4,12 @@
|
|||||||
#include "esp_lcd_ili9341.h"
|
#include "esp_lcd_ili9341.h"
|
||||||
#include "esp_lcd_panel_ops.h"
|
#include "esp_lcd_panel_ops.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "esp_lvgl_port.h"
|
||||||
#include "freertos/semphr.h"
|
#include "hal/lv_hal_disp.h"
|
||||||
#include "tactility-esp.h"
|
#include <esp_lcd_panel_io.h>
|
||||||
|
|
||||||
#define TAG "2432s024_ili9341"
|
#define TAG "2432s024_ili9341"
|
||||||
|
|
||||||
static SemaphoreHandle_t refresh_finish = NULL;
|
|
||||||
|
|
||||||
#define LCD_SPI_HOST SPI2_HOST
|
#define LCD_SPI_HOST SPI2_HOST
|
||||||
#define LCD_PIN_SCLK GPIO_NUM_14
|
#define LCD_PIN_SCLK GPIO_NUM_14
|
||||||
#define LCD_PIN_MOSI GPIO_NUM_13
|
#define LCD_PIN_MOSI GPIO_NUM_13
|
||||||
@ -24,7 +22,7 @@ static SemaphoreHandle_t refresh_finish = NULL;
|
|||||||
#define LCD_BITS_PER_PIXEL 16
|
#define LCD_BITS_PER_PIXEL 16
|
||||||
#define LCD_DRAW_BUFFER_HEIGHT (LCD_VERTICAL_RESOLUTION / 10)
|
#define LCD_DRAW_BUFFER_HEIGHT (LCD_VERTICAL_RESOLUTION / 10)
|
||||||
|
|
||||||
static bool create_display_device(DisplayDevice* display) {
|
lv_disp_t* yellow_board_init_display() {
|
||||||
ESP_LOGI(TAG, "creating display");
|
ESP_LOGI(TAG, "creating display");
|
||||||
|
|
||||||
gpio_config_t io_conf = {
|
gpio_config_t io_conf = {
|
||||||
@ -55,7 +53,8 @@ static bool create_display_device(DisplayDevice* display) {
|
|||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if (esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_SPI_HOST, &panel_io_config, &display->io_handle) != ESP_OK) {
|
esp_lcd_panel_io_handle_t io_handle;
|
||||||
|
if (esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_SPI_HOST, &panel_io_config, &io_handle) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to create panel");
|
ESP_LOGD(TAG, "failed to create panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -67,36 +66,28 @@ static bool create_display_device(DisplayDevice* display) {
|
|||||||
.bits_per_pixel = LCD_BITS_PER_PIXEL,
|
.bits_per_pixel = LCD_BITS_PER_PIXEL,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (esp_lcd_new_panel_ili9341(display->io_handle, &panel_config, &display->display_handle) != ESP_OK) {
|
esp_lcd_panel_handle_t panel_handle;
|
||||||
|
if (esp_lcd_new_panel_ili9341(io_handle, &panel_config, &panel_handle) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to create ili9341");
|
ESP_LOGD(TAG, "failed to create ili9341");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (esp_lcd_panel_reset(panel_handle) != ESP_OK) {
|
||||||
if (esp_lcd_panel_reset(display->display_handle) != ESP_OK) {
|
|
||||||
ESP_LOGD(TAG, "failed to reset panel");
|
ESP_LOGD(TAG, "failed to reset panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_lcd_panel_init(display->display_handle) != ESP_OK) {
|
if (esp_lcd_panel_init(panel_handle) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to init panel");
|
ESP_LOGD(TAG, "failed to init panel");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_lcd_panel_mirror(display->display_handle, true, false) != ESP_OK) {
|
if (esp_lcd_panel_mirror(panel_handle, true, false) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to set panel to mirror");
|
ESP_LOGD(TAG, "failed to set panel to mirror");
|
||||||
display->mirror_x = true;
|
|
||||||
display->mirror_y = false;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_lcd_panel_swap_xy(display->display_handle, false) != ESP_OK) {
|
if (esp_lcd_panel_disp_on_off(panel_handle, true) != ESP_OK) {
|
||||||
ESP_LOGD(TAG, "failed to set panel xy swap");
|
|
||||||
display->swap_xy = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_lcd_panel_disp_on_off(display->display_handle, true) != ESP_OK) {
|
|
||||||
ESP_LOGD(TAG, "failed to turn display on");
|
ESP_LOGD(TAG, "failed to turn display on");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -106,19 +97,23 @@ static bool create_display_device(DisplayDevice* display) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
display->horizontal_resolution = LCD_HORIZONTAL_RESOLUTION;
|
const lvgl_port_display_cfg_t disp_cfg = {
|
||||||
display->vertical_resolution = LCD_VERTICAL_RESOLUTION;
|
.io_handle = io_handle,
|
||||||
display->draw_buffer_height = LCD_DRAW_BUFFER_HEIGHT;
|
.panel_handle = panel_handle,
|
||||||
display->bits_per_pixel = LCD_BITS_PER_PIXEL;
|
.buffer_size = LCD_HORIZONTAL_RESOLUTION * LCD_DRAW_BUFFER_HEIGHT * (LCD_BITS_PER_PIXEL / 8),
|
||||||
display->monochrome = false;
|
.double_buffer = false,
|
||||||
display->double_buffering = true;
|
.hres = LCD_HORIZONTAL_RESOLUTION,
|
||||||
|
.vres = LCD_VERTICAL_RESOLUTION,
|
||||||
return true;
|
.monochrome = false,
|
||||||
}
|
.rotation = {
|
||||||
|
.swap_xy = false,
|
||||||
DisplayDriver board_2432s024_create_display_driver() {
|
.mirror_x = true,
|
||||||
return (DisplayDriver) {
|
.mirror_y = false,
|
||||||
.name = "ili9341_2432s024",
|
},
|
||||||
.create_display_device = &create_display_device
|
.flags = {
|
||||||
|
.buff_dma = true,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return lvgl_port_add_disp(&disp_cfg);
|
||||||
}
|
}
|
||||||
|
|||||||
57
boards/yellow_board/lvgl.c
Normal file
57
boards/yellow_board/lvgl.c
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "esp_lvgl_port.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "ui/lvgl_sync.h"
|
||||||
|
#include <thread.h>
|
||||||
|
|
||||||
|
#define TAG "yellow_board_lvgl"
|
||||||
|
|
||||||
|
lv_disp_t* yellow_board_init_display();
|
||||||
|
bool yellow_board_init_touch(esp_lcd_panel_io_handle_t* io_handle, esp_lcd_touch_handle_t* touch_handle);
|
||||||
|
|
||||||
|
bool yellow_board_init_lvgl() {
|
||||||
|
static lv_disp_t* display = NULL;
|
||||||
|
static esp_lcd_panel_io_handle_t touch_io_handle;
|
||||||
|
static esp_lcd_touch_handle_t touch_handle;
|
||||||
|
|
||||||
|
const lvgl_port_cfg_t lvgl_cfg = {
|
||||||
|
.task_priority = ThreadPriorityHigh,
|
||||||
|
.task_stack = 8096,
|
||||||
|
.task_affinity = -1, // core pinning
|
||||||
|
.task_max_sleep_ms = 500,
|
||||||
|
.timer_period_ms = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
if (lvgl_port_init(&lvgl_cfg) != ESP_OK) {
|
||||||
|
TT_LOG_E(TAG, "lvgl port init failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add display
|
||||||
|
display = yellow_board_init_display();
|
||||||
|
if (display == NULL) {
|
||||||
|
TT_LOG_E(TAG, "failed to add display");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add touch
|
||||||
|
if (!yellow_board_init_touch(&touch_io_handle, &touch_handle)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||||
|
.disp = display,
|
||||||
|
.handle = touch_handle,
|
||||||
|
};
|
||||||
|
|
||||||
|
lv_indev_t _Nullable* touch_indev = lvgl_port_add_touch(&touch_cfg);
|
||||||
|
if (touch_indev == NULL) {
|
||||||
|
TT_LOG_E(TAG, "failed to add touch to lvgl");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set syncing functions
|
||||||
|
tt_lvgl_sync_set(&lvgl_port_lock, &lvgl_port_unlock);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@ -2,13 +2,12 @@
|
|||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_lcd_touch_cst816s.h"
|
#include "esp_lcd_touch_cst816s.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "tactility-esp.h"
|
|
||||||
|
|
||||||
#define TOUCH_I2C_PORT 0
|
#define TOUCH_I2C_PORT 0
|
||||||
|
|
||||||
#define TAG "2432s024_cst816"
|
#define TAG "2432s024_cst816"
|
||||||
|
|
||||||
static bool create_touch_device(esp_lcd_panel_io_handle_t* io_handle, esp_lcd_touch_handle_t* touch_handle) {
|
bool yellow_board_init_touch(esp_lcd_panel_io_handle_t* io_handle, esp_lcd_touch_handle_t* touch_handle) {
|
||||||
ESP_LOGI(TAG, "creating touch");
|
ESP_LOGI(TAG, "creating touch");
|
||||||
|
|
||||||
const i2c_config_t i2c_conf = {
|
const i2c_config_t i2c_conf = {
|
||||||
@ -64,10 +63,3 @@ static bool create_touch_device(esp_lcd_panel_io_handle_t* io_handle, esp_lcd_to
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TouchDriver board_2432s024_create_touch_driver() {
|
|
||||||
return (TouchDriver) {
|
|
||||||
.name = "cst816s_2432s024",
|
|
||||||
.create_touch_device = &create_touch_device
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
#include "yellow_board.h"
|
#include "yellow_board.h"
|
||||||
|
|
||||||
|
bool yellow_board_init_lvgl();
|
||||||
|
|
||||||
const HardwareConfig yellow_board_24inch_cap = {
|
const HardwareConfig yellow_board_24inch_cap = {
|
||||||
.bootstrap = NULL,
|
.bootstrap = NULL,
|
||||||
.display_driver = &board_2432s024_create_display_driver,
|
.init_lvgl = &yellow_board_init_lvgl
|
||||||
.touch_driver = &board_2432s024_create_touch_driver
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,15 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tactility-esp.h"
|
#include "hardware_config.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Available for HardwareConfig customizations
|
|
||||||
DisplayDriver board_2432s024_create_display_driver();
|
|
||||||
TouchDriver board_2432s024_create_touch_driver();
|
|
||||||
|
|
||||||
// Capacitive touch version of the 2.4" yellow board
|
// Capacitive touch version of the 2.4" yellow board
|
||||||
extern const HardwareConfig yellow_board_24inch_cap;
|
extern const HardwareConfig yellow_board_24inch_cap;
|
||||||
|
|
||||||
|
|||||||
@ -3,8 +3,10 @@
|
|||||||
- Update `view_port` to use `ViewPort` as handle externally and `ViewPortData` internally
|
- Update `view_port` to use `ViewPort` as handle externally and `ViewPortData` internally
|
||||||
- Replace FreeRTOS semaphore from `Loader` with internal `Mutex`
|
- Replace FreeRTOS semaphore from `Loader` with internal `Mutex`
|
||||||
- Create unit tests for `tactility-core` and `tactility` (PC-only for now)
|
- Create unit tests for `tactility-core` and `tactility` (PC-only for now)
|
||||||
|
- Have a way to deinit LVGL drivers that are created from `HardwareConfig`
|
||||||
|
|
||||||
# Core Ideas
|
# Core Ideas
|
||||||
|
- Make a HAL? It would mainly be there to support PC development. It's a lot of effort for supporting what's effectively a dev-only feature.
|
||||||
- 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.
|
||||||
|
|
||||||
# App Ideas
|
# App Ideas
|
||||||
|
|||||||
31
sdkconfig.board.waveshare_s3_touch
Normal file
31
sdkconfig.board.waveshare_s3_touch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Software defaults
|
||||||
|
CONFIG_LV_FONT_MONTSERRAT_14=y
|
||||||
|
CONFIG_LV_FONT_MONTSERRAT_18=y
|
||||||
|
CONFIG_LV_USE_USER_DATA=y
|
||||||
|
CONFIG_LV_USE_FS_STDIO=y
|
||||||
|
CONFIG_LV_FS_STDIO_LETTER=65
|
||||||
|
CONFIG_LV_FS_STDIO_PATH=""
|
||||||
|
CONFIG_LV_FS_STDIO_CACHE_SIZE=4096
|
||||||
|
CONFIG_LV_USE_PNG=y
|
||||||
|
CONFIG_FREERTOS_HZ=1000
|
||||||
|
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
|
||||||
|
# Hardware: Main
|
||||||
|
CONFIG_TT_BOARD_WAVESHARE_S3_TOUCH=y
|
||||||
|
CONFIG_IDF_TARGET="esp32s3"
|
||||||
|
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||||
|
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
|
||||||
|
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||||
|
CONFIG_FLASHMODE_QIO=y
|
||||||
|
# Hardware: SPI RAM
|
||||||
|
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
|
||||||
|
CONFIG_SPIRAM_MODE_OCT=y
|
||||||
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
|
# LVGL
|
||||||
|
CONFIG_LV_COLOR_16_SWAP=n
|
||||||
|
CONFIG_LV_DISP_DEF_REFR_PERIOD=17
|
||||||
|
CONFIG_LV_INDEV_DEF_READ_PERIOD=17
|
||||||
|
CONFIG_LV_DPI_DEF=139
|
||||||
@ -1,4 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
@ -16,7 +17,7 @@ target_include_directories(tactility-core SYSTEM
|
|||||||
INTERFACE src/
|
INTERFACE src/
|
||||||
)
|
)
|
||||||
|
|
||||||
if (ESP_PLATFORM)
|
if (DEFINED ENV{ESP_IDF_VERSION})
|
||||||
add_definitions(-DESP_PLATFORM)
|
add_definitions(-DESP_PLATFORM)
|
||||||
target_link_libraries(tactility-core
|
target_link_libraries(tactility-core
|
||||||
PUBLIC mlib
|
PUBLIC mlib
|
||||||
|
|||||||
@ -8,7 +8,7 @@ idf_component_register(
|
|||||||
"src/apps/system/wifi_manage"
|
"src/apps/system/wifi_manage"
|
||||||
"src/services/wifi"
|
"src/services/wifi"
|
||||||
INCLUDE_DIRS "src/"
|
INCLUDE_DIRS "src/"
|
||||||
REQUIRES esp_wifi esp_lvgl_port nvs_flash esp_lcd esp_lcd_touch spiffs
|
REQUIRES esp_wifi nvs_flash spiffs
|
||||||
)
|
)
|
||||||
|
|
||||||
set(ASSETS_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/assets")
|
set(ASSETS_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/assets")
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
#include "wifi_connect.h"
|
#include "wifi_connect.h"
|
||||||
|
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "esp_lvgl_port.h"
|
|
||||||
#include "services/wifi/wifi.h"
|
#include "services/wifi/wifi.h"
|
||||||
#include "tactility_core.h"
|
#include "tactility_core.h"
|
||||||
#include "ui/lvgl_sync.h"
|
#include "ui/lvgl_sync.h"
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "apps/system/wifi_connect/wifi_connect_bundle.h"
|
#include "apps/system/wifi_connect/wifi_connect_bundle.h"
|
||||||
#include "esp_lvgl_port.h"
|
|
||||||
#include "services/loader/loader.h"
|
#include "services/loader/loader.h"
|
||||||
#include "tactility_core.h"
|
#include "tactility_core.h"
|
||||||
#include "ui/lvgl_sync.h"
|
#include "ui/lvgl_sync.h"
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
#include "check.h"
|
|
||||||
#include "display.h"
|
|
||||||
|
|
||||||
DisplayDevice* tt_display_device_alloc(DisplayDriver* driver) {
|
|
||||||
DisplayDevice* display = malloc(sizeof(DisplayDevice));
|
|
||||||
memset(display, 0, sizeof(DisplayDevice));
|
|
||||||
tt_check(driver->create_display_device(display), "failed to create display");
|
|
||||||
tt_check(display->io_handle != NULL);
|
|
||||||
tt_check(display->display_handle != NULL);
|
|
||||||
tt_check(display->horizontal_resolution != 0);
|
|
||||||
tt_check(display->vertical_resolution != 0);
|
|
||||||
tt_check(display->draw_buffer_height > 0);
|
|
||||||
tt_check(display->bits_per_pixel > 0);
|
|
||||||
return display;
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "esp_lcd_panel_io.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
esp_lcd_panel_io_handle_t io_handle;
|
|
||||||
esp_lcd_panel_handle_t display_handle;
|
|
||||||
uint16_t horizontal_resolution;
|
|
||||||
uint16_t vertical_resolution;
|
|
||||||
uint16_t draw_buffer_height;
|
|
||||||
uint16_t bits_per_pixel;
|
|
||||||
bool double_buffering;
|
|
||||||
bool mirror_x;
|
|
||||||
bool mirror_y;
|
|
||||||
bool swap_xy;
|
|
||||||
bool monochrome;
|
|
||||||
} DisplayDevice;
|
|
||||||
|
|
||||||
typedef bool (*CreateDisplay)(DisplayDevice* display);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char name[32];
|
|
||||||
CreateDisplay create_display_device;
|
|
||||||
} DisplayDriver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param[in] driver
|
|
||||||
* @return allocated display object
|
|
||||||
*/
|
|
||||||
DisplayDevice* tt_display_device_alloc(DisplayDriver* driver);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
#include "check.h"
|
|
||||||
#include "esp_lvgl_port.h"
|
|
||||||
#include "graphics_i.h"
|
|
||||||
#include "lvgl.h"
|
|
||||||
|
|
||||||
#define TAG "lvgl"
|
|
||||||
|
|
||||||
Lvgl tt_graphics_init(Hardware* hardware) {
|
|
||||||
const lvgl_port_cfg_t lvgl_cfg = {
|
|
||||||
.task_priority = 4,
|
|
||||||
.task_stack = 8096,
|
|
||||||
.task_affinity = -1, // core pinning
|
|
||||||
.task_max_sleep_ms = 500,
|
|
||||||
.timer_period_ms = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
tt_check(lvgl_port_init(&lvgl_cfg) == ESP_OK, "lvgl port init failed");
|
|
||||||
DisplayDevice* display = hardware->display;
|
|
||||||
|
|
||||||
// Add display
|
|
||||||
TT_LOG_I(TAG, "lvgl add display");
|
|
||||||
const lvgl_port_display_cfg_t disp_cfg = {
|
|
||||||
.io_handle = display->io_handle,
|
|
||||||
.panel_handle = display->display_handle,
|
|
||||||
.buffer_size = display->horizontal_resolution * display->draw_buffer_height * (display->bits_per_pixel / 8),
|
|
||||||
.double_buffer = display->double_buffering,
|
|
||||||
.hres = display->horizontal_resolution,
|
|
||||||
.vres = display->vertical_resolution,
|
|
||||||
.monochrome = display->monochrome,
|
|
||||||
.rotation = {
|
|
||||||
.swap_xy = display->swap_xy,
|
|
||||||
.mirror_x = display->mirror_x,
|
|
||||||
.mirror_y = display->mirror_y,
|
|
||||||
},
|
|
||||||
.flags = {
|
|
||||||
.buff_dma = true,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
lv_disp_t* disp = lvgl_port_add_disp(&disp_cfg);
|
|
||||||
tt_check(disp != NULL, "failed to add display");
|
|
||||||
|
|
||||||
lv_indev_t _Nullable* touch_indev = NULL;
|
|
||||||
|
|
||||||
// Add touch
|
|
||||||
if (hardware->touch != NULL) {
|
|
||||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
|
||||||
.disp = disp,
|
|
||||||
.handle = hardware->touch->touch_handle,
|
|
||||||
};
|
|
||||||
touch_indev = lvgl_port_add_touch(&touch_cfg);
|
|
||||||
tt_check(touch_indev != NULL, "failed to add touch to lvgl");
|
|
||||||
}
|
|
||||||
|
|
||||||
return (Lvgl) {
|
|
||||||
.disp = disp,
|
|
||||||
.touch_indev = touch_indev
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "lvgl.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
lv_disp_t* disp;
|
|
||||||
lv_indev_t* _Nullable touch_indev;
|
|
||||||
} Lvgl;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "graphics.h"
|
|
||||||
#include "hardware.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Lvgl tt_graphics_init(Hardware* hardware);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
#include "check.h"
|
|
||||||
#include "hardware_i.h"
|
|
||||||
#include "touch.h"
|
|
||||||
|
|
||||||
#define TAG "hardware"
|
|
||||||
|
|
||||||
Hardware tt_hardware_init(const HardwareConfig* config) {
|
|
||||||
if (config->bootstrap != NULL) {
|
|
||||||
TT_LOG_I(TAG, "Bootstrapping");
|
|
||||||
config->bootstrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
tt_check(config->display_driver != NULL, "no display driver configured");
|
|
||||||
DisplayDriver display_driver = config->display_driver();
|
|
||||||
TT_LOG_I(TAG, "display with driver %s", display_driver.name);
|
|
||||||
DisplayDevice* display = tt_display_device_alloc(&display_driver);
|
|
||||||
|
|
||||||
TouchDevice* touch = NULL;
|
|
||||||
if (config->touch_driver != NULL) {
|
|
||||||
TouchDriver touch_driver = config->touch_driver();
|
|
||||||
TT_LOG_I(TAG, "touch with driver %s", touch_driver.name);
|
|
||||||
touch = tt_touch_alloc(&touch_driver);
|
|
||||||
} else {
|
|
||||||
TT_LOG_I(TAG, "no touch configured");
|
|
||||||
touch = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (Hardware) {
|
|
||||||
.display = display,
|
|
||||||
.touch = touch
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "display.h"
|
|
||||||
#include "touch.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DisplayDevice* display;
|
|
||||||
TouchDevice* _Nullable touch;
|
|
||||||
} Hardware;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -6,4 +6,3 @@
|
|||||||
#define MOUNT_POINT_CONFIG "/config"
|
#define MOUNT_POINT_CONFIG "/config"
|
||||||
|
|
||||||
esp_err_t tt_partitions_init();
|
esp_err_t tt_partitions_init();
|
||||||
|
|
||||||
|
|||||||
@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "hardware.h"
|
|
||||||
#include "tactility.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
typedef void (*Bootstrap)();
|
|
||||||
typedef TouchDriver (*CreateTouchDriver)();
|
|
||||||
typedef DisplayDriver (*CreateDisplayDriver)();
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
// Optional bootstrapping method (e.g. to turn peripherals on)
|
|
||||||
const Bootstrap _Nullable bootstrap;
|
|
||||||
// Required driver for display
|
|
||||||
const CreateDisplayDriver display_driver;
|
|
||||||
// Optional driver for touch input
|
|
||||||
const CreateTouchDriver _Nullable touch_driver;
|
|
||||||
} HardwareConfig;
|
|
||||||
|
|
||||||
|
|
||||||
void tt_esp_init(const HardwareConfig* hardware_config);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -1,27 +1,13 @@
|
|||||||
#include "tactility.h"
|
#include "tactility_core.h"
|
||||||
|
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
#include "esp_lvgl_port.h"
|
|
||||||
#include "esp_netif.h"
|
#include "esp_netif.h"
|
||||||
#include "graphics_i.h"
|
|
||||||
#include "hardware_i.h"
|
|
||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
#include "partitions.h"
|
#include "partitions.h"
|
||||||
#include "services/loader/loader.h"
|
|
||||||
#include "services/wifi/wifi_credentials.h"
|
#include "services/wifi/wifi_credentials.h"
|
||||||
#include "ui/lvgl_sync.h"
|
|
||||||
|
|
||||||
#define TAG "tactility"
|
#define TAG "tactility"
|
||||||
|
void tt_esp_init() {
|
||||||
static bool lvgl_lock_impl(int timeout_ticks) {
|
|
||||||
return lvgl_port_lock(timeout_ticks);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lvgl_unlock_impl() {
|
|
||||||
lvgl_port_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void tt_esp_init(const HardwareConfig* hardware_config) {
|
|
||||||
// Initialize NVS
|
// Initialize NVS
|
||||||
esp_err_t ret = nvs_flash_init();
|
esp_err_t ret = nvs_flash_init();
|
||||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
@ -39,9 +25,4 @@ void tt_esp_init(const HardwareConfig* hardware_config) {
|
|||||||
tt_partitions_init();
|
tt_partitions_init();
|
||||||
|
|
||||||
tt_wifi_credentials_init();
|
tt_wifi_credentials_init();
|
||||||
|
|
||||||
tt_lvgl_sync_set(&lvgl_lock_impl, &lvgl_unlock_impl);
|
|
||||||
|
|
||||||
Hardware hardware = tt_hardware_init(hardware_config);
|
|
||||||
/*Lvgl lvgl =*/tt_graphics_init(&hardware);
|
|
||||||
}
|
}
|
||||||
14
tactility-esp/src/tactility_esp.h
Normal file
14
tactility-esp/src/tactility_esp.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "hardware_config.h"
|
||||||
|
#include "tactility.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void tt_esp_init();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -1,12 +0,0 @@
|
|||||||
#include "check.h"
|
|
||||||
#include "touch.h"
|
|
||||||
|
|
||||||
TouchDevice* tt_touch_alloc(TouchDriver* driver) {
|
|
||||||
TouchDevice* touch = malloc(sizeof(TouchDevice));
|
|
||||||
bool success = driver->create_touch_device(
|
|
||||||
&(touch->io_handle),
|
|
||||||
&(touch->touch_handle)
|
|
||||||
);
|
|
||||||
tt_check(success, "touch driver failed");
|
|
||||||
return touch;
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "esp_lcd_panel_io.h"
|
|
||||||
#include "esp_lcd_touch.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef bool (*CreateTouch)(esp_lcd_panel_io_handle_t* io_handle, esp_lcd_touch_handle_t* touch_handle);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char name[32];
|
|
||||||
CreateTouch create_touch_device;
|
|
||||||
} TouchDriver;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
esp_lcd_panel_io_handle_t io_handle;
|
|
||||||
esp_lcd_touch_handle_t touch_handle;
|
|
||||||
} TouchDevice;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param[in] driver
|
|
||||||
* @return a newly allocated instance
|
|
||||||
*/
|
|
||||||
TouchDevice* tt_touch_alloc(TouchDriver* driver);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -16,7 +16,7 @@ target_include_directories(tactility
|
|||||||
INTERFACE src/
|
INTERFACE src/
|
||||||
)
|
)
|
||||||
|
|
||||||
if (ESP_PLATFORM)
|
if (DEFINED ENV{ESP_IDF_VERSION})
|
||||||
add_definitions(-DESP_PLATFORM)
|
add_definitions(-DESP_PLATFORM)
|
||||||
target_link_libraries(tactility
|
target_link_libraries(tactility
|
||||||
PUBLIC tactility-core
|
PUBLIC tactility-core
|
||||||
|
|||||||
14
tactility/src/hardware.c
Normal file
14
tactility/src/hardware.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "check.h"
|
||||||
|
#include "hardware_i.h"
|
||||||
|
|
||||||
|
#define TAG "hardware"
|
||||||
|
|
||||||
|
void tt_hardware_init(const HardwareConfig* config) {
|
||||||
|
if (config->bootstrap != NULL) {
|
||||||
|
TT_LOG_I(TAG, "Bootstrapping");
|
||||||
|
config->bootstrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
tt_check(config->init_lvgl);
|
||||||
|
config->init_lvgl();
|
||||||
|
}
|
||||||
14
tactility/src/hardware_config.h
Normal file
14
tactility/src/hardware_config.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tactility_core.h"
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
typedef bool (*Bootstrap)();
|
||||||
|
typedef bool (*InitLvgl)();
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// Optional bootstrapping method (e.g. to turn peripherals on)
|
||||||
|
const Bootstrap _Nullable bootstrap;
|
||||||
|
const InitLvgl init_lvgl;
|
||||||
|
|
||||||
|
} HardwareConfig;
|
||||||
@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tactility-esp.h"
|
#include "hardware_config.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Hardware tt_hardware_init(const HardwareConfig* config);
|
void tt_hardware_init(const HardwareConfig* config);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ Gui* gui_alloc() {
|
|||||||
instance->mutex = tt_mutex_alloc(MutexTypeNormal);
|
instance->mutex = tt_mutex_alloc(MutexTypeNormal);
|
||||||
instance->keyboard = NULL;
|
instance->keyboard = NULL;
|
||||||
|
|
||||||
tt_check(tt_lvgl_lock(100));
|
tt_check(tt_lvgl_lock(1000 / portTICK_PERIOD_MS));
|
||||||
instance->lvgl_parent = lv_scr_act();
|
instance->lvgl_parent = lv_scr_act();
|
||||||
tt_lvgl_unlock();
|
tt_lvgl_unlock();
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "tactility.h"
|
#include "tactility.h"
|
||||||
|
|
||||||
#include "app_manifest_registry.h"
|
#include "app_manifest_registry.h"
|
||||||
|
#include "hardware_i.h"
|
||||||
#include "service_registry.h"
|
#include "service_registry.h"
|
||||||
#include "services/loader/loader.h"
|
#include "services/loader/loader.h"
|
||||||
|
|
||||||
@ -60,10 +61,13 @@ static void register_and_start_user_services(const ServiceManifest* const servic
|
|||||||
}
|
}
|
||||||
|
|
||||||
TT_UNUSED void tt_init(const Config* config) {
|
TT_UNUSED void tt_init(const Config* config) {
|
||||||
|
TT_LOG_I(TAG, "tt_init started");
|
||||||
|
|
||||||
tt_service_registry_init();
|
tt_service_registry_init();
|
||||||
tt_app_manifest_registry_init();
|
tt_app_manifest_registry_init();
|
||||||
|
|
||||||
TT_LOG_I(TAG, "tt_init started");
|
tt_hardware_init(config->hardware);
|
||||||
|
|
||||||
// Register all apps
|
// Register all apps
|
||||||
register_system_services();
|
register_system_services();
|
||||||
register_system_apps();
|
register_system_apps();
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "app_manifest.h"
|
#include "app_manifest.h"
|
||||||
|
#include "hardware_config.h"
|
||||||
#include "service_manifest.h"
|
#include "service_manifest.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -11,6 +12,7 @@ extern "C" {
|
|||||||
#define CONFIG_SERVICES_LIMIT 32
|
#define CONFIG_SERVICES_LIMIT 32
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
const HardwareConfig* hardware;
|
||||||
// List of user applications
|
// List of user applications
|
||||||
const AppManifest* const apps[CONFIG_APPS_LIMIT];
|
const AppManifest* const apps[CONFIG_APPS_LIMIT];
|
||||||
const ServiceManifest* const services[CONFIG_SERVICES_LIMIT];
|
const ServiceManifest* const services[CONFIG_SERVICES_LIMIT];
|
||||||
|
|||||||
@ -8,7 +8,7 @@ void tt_lvgl_sync_set(LvglLock lock, LvglUnlock unlock) {
|
|||||||
unlock_singleton = unlock;
|
unlock_singleton = unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tt_lvgl_lock(int timeout_ticks) {
|
bool tt_lvgl_lock(uint32_t timeout_ticks) {
|
||||||
if (lock_singleton) {
|
if (lock_singleton) {
|
||||||
return lock_singleton(timeout_ticks);
|
return lock_singleton(timeout_ticks);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,17 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "lvgl.h"
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef bool (*LvglLock)(int timeout_ticks);
|
typedef bool (*LvglLock)(uint32_t timeout_ticks);
|
||||||
typedef void (*LvglUnlock)();
|
typedef void (*LvglUnlock)();
|
||||||
|
|
||||||
void tt_lvgl_sync_set(LvglLock lock, LvglUnlock unlock);
|
void tt_lvgl_sync_set(LvglLock lock, LvglUnlock unlock);
|
||||||
bool tt_lvgl_lock(int timeout_ticks);
|
bool tt_lvgl_lock(uint32_t timeout_ticks);
|
||||||
void tt_lvgl_unlock();
|
void tt_lvgl_unlock();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user