First test
This commit is contained in:
commit
3eb49b31af
13
.devcontainer/Dockerfile
Normal file
13
.devcontainer/Dockerfile
Normal file
@ -0,0 +1,13 @@
|
||||
ARG DOCKER_TAG=latest
|
||||
FROM espressif/idf:${DOCKER_TAG}
|
||||
|
||||
ENV LC_ALL=C.UTF-8
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
RUN apt-get update -y && apt-get install udev -y
|
||||
|
||||
RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc
|
||||
|
||||
ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]
|
||||
|
||||
CMD ["/bin/bash", "-c"]
|
||||
19
.devcontainer/devcontainer.json
Normal file
19
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "ESP-IDF QEMU",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {
|
||||
"terminal.integrated.defaultProfile.linux": "bash",
|
||||
"idf.gitPath": "/usr/bin/git"
|
||||
},
|
||||
"extensions": [
|
||||
"espressif.esp-idf-extension",
|
||||
"espressif.esp-idf-web"
|
||||
]
|
||||
}
|
||||
},
|
||||
"runArgs": ["--privileged"]
|
||||
}
|
||||
78
.gitignore
vendored
Normal file
78
.gitignore
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
# macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Directory metadata
|
||||
.directory
|
||||
|
||||
# Temporary files
|
||||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
*.bak
|
||||
*.tmp
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
|
||||
# Build artifacts and directories
|
||||
**/build/
|
||||
build/
|
||||
*.o
|
||||
*.a
|
||||
*.out
|
||||
*.exe # For any host-side utilities compiled on Windows
|
||||
|
||||
# ESP-IDF specific build outputs
|
||||
*.bin
|
||||
*.elf
|
||||
*.map
|
||||
flasher_args.json # Generated in build directory
|
||||
sdkconfig.old
|
||||
sdkconfig
|
||||
|
||||
# ESP-IDF dependencies
|
||||
# For older versions or manual component management
|
||||
/components/.idf/
|
||||
**/components/.idf/
|
||||
# For modern ESP-IDF component manager
|
||||
managed_components/
|
||||
# If ESP-IDF tools are installed/referenced locally to the project
|
||||
.espressif/
|
||||
|
||||
# CMake generated files
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
CTestTestfile.cmake
|
||||
|
||||
# Python environment files
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
__pycache__/
|
||||
*.egg-info/
|
||||
dist/
|
||||
|
||||
# Virtual environment folders
|
||||
venv/
|
||||
.venv/
|
||||
env/
|
||||
|
||||
# Language Servers
|
||||
.clangd/
|
||||
.ccls-cache/
|
||||
compile_commands.json
|
||||
|
||||
# Windows specific
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
|
||||
# User-specific configuration files
|
||||
*.user
|
||||
*.workspace # General workspace files, can be from various tools
|
||||
*.suo # Visual Studio Solution User Options
|
||||
*.sln.docstates # Visual Studio
|
||||
19
.vscode/c_cpp_properties.json
vendored
Normal file
19
.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "ESP-IDF",
|
||||
"compilerPath": "/home/thomas/.espressif/tools/riscv32-esp-elf/esp-14.2.0_20251107/riscv32-esp-elf/bin/riscv32-esp-elf-gcc",
|
||||
"compileCommands": "${config:idf.buildPath}/compile_commands.json",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"browse": {
|
||||
"path": [
|
||||
"${workspaceFolder}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
15
.vscode/launch.json
vendored
Normal file
15
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "gdbtarget",
|
||||
"request": "attach",
|
||||
"name": "Eclipse CDT GDB Adapter"
|
||||
},
|
||||
{
|
||||
"type": "espidf",
|
||||
"name": "Launch",
|
||||
"request": "launch"
|
||||
}
|
||||
]
|
||||
}
|
||||
18
.vscode/settings.json
vendored
Normal file
18
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"C_Cpp.intelliSenseEngine": "default",
|
||||
"idf.openOcdConfigs": [
|
||||
"interface/ftdi/esp32_devkitj_v1.cfg",
|
||||
"target/esp32.cfg"
|
||||
],
|
||||
"idf.port": "/dev/ttyACM0",
|
||||
"idf.currentSetup": "/home/thomas/.espressif/v5.5.2/esp-idf",
|
||||
"idf.customExtraVars": {
|
||||
"IDF_TARGET": "esp32p4"
|
||||
},
|
||||
"clangd.path": "/home/thomas/.espressif/tools/esp-clang/esp-19.1.2_20250312/esp-clang/bin/clangd",
|
||||
"clangd.arguments": [
|
||||
"--background-index",
|
||||
"--query-driver=/home/thomas/.espressif/tools/riscv32-esp-elf/esp-14.2.0_20251107/riscv32-esp-elf/bin/riscv32-esp-elf-gcc",
|
||||
"--compile-commands-dir=/home/thomas/projekte/test1/display/build"
|
||||
]
|
||||
}
|
||||
8
CMakeLists.txt
Normal file
8
CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
# idf_build_set_property(MINIMAL_BUILD ON)
|
||||
project(knxdisplay)
|
||||
53
README.md
Normal file
53
README.md
Normal file
@ -0,0 +1,53 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | Linux |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | ----- |
|
||||
|
||||
# Hello World Example
|
||||
|
||||
Starts a FreeRTOS task to print "Hello World".
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
## How to use example
|
||||
|
||||
Follow detailed instructions provided specifically for this example.
|
||||
|
||||
Select the instructions depending on Espressif chip installed on your development board:
|
||||
|
||||
- [ESP32 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/index.html)
|
||||
- [ESP32-S2 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html)
|
||||
|
||||
|
||||
## Example folder contents
|
||||
|
||||
The project **hello_world** contains one source file in C language [hello_world_main.c](main/hello_world_main.c). The file is located in folder [main](main).
|
||||
|
||||
ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt` files that provide set of directives and instructions describing the project's source files and targets (executable, library, or both).
|
||||
|
||||
Below is short explanation of remaining files in the project folder.
|
||||
|
||||
```
|
||||
├── CMakeLists.txt
|
||||
├── pytest_hello_world.py Python script used for automated testing
|
||||
├── main
|
||||
│ ├── CMakeLists.txt
|
||||
│ └── hello_world_main.c
|
||||
└── README.md This is the file you are currently reading
|
||||
```
|
||||
|
||||
For more information on structure and contents of ESP-IDF projects, please refer to Section [Build System](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html) of the ESP-IDF Programming Guide.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* Program upload failure
|
||||
|
||||
* Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs.
|
||||
* The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again.
|
||||
|
||||
## Technical support and feedback
|
||||
|
||||
Please use the following feedback channels:
|
||||
|
||||
* For technical queries, go to the [esp32.com](https://esp32.com/) forum
|
||||
* For a feature request or bug report, create a [GitHub issue](https://github.com/espressif/esp-idf/issues)
|
||||
|
||||
We will get back to you as soon as possible.
|
||||
110
dependencies.lock
Normal file
110
dependencies.lock
Normal file
@ -0,0 +1,110 @@
|
||||
dependencies:
|
||||
espressif/cmake_utilities:
|
||||
component_hash:
|
||||
351350613ceafba240b761b4ea991e0f231ac7a9f59a9ee901f751bddc0bb18f
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.1'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 0.5.3
|
||||
espressif/esp_lcd_touch:
|
||||
component_hash:
|
||||
3f85a7d95af876f1a6ecca8eb90a81614890d0f03a038390804e5a77e2caf862
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.4.2'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 1.2.1
|
||||
espressif/esp_lcd_touch_gt911:
|
||||
component_hash:
|
||||
be02e243d18b9a661bc13b0d22c0a5cfa3f708cf04d6eb059772276c8c8a4d76
|
||||
dependencies:
|
||||
- name: espressif/esp_lcd_touch
|
||||
registry_url: https://components.espressif.com
|
||||
require: public
|
||||
version: ^1.2.0
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.4.2'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 1.2.0~1
|
||||
espressif/esp_lvgl_port:
|
||||
component_hash:
|
||||
f872401524cb645ee6ff1c9242d44fb4ddcfd4d37d7be8b9ed3f4e85a404efcd
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.1'
|
||||
- name: lvgl/lvgl
|
||||
registry_url: https://components.espressif.com
|
||||
require: public
|
||||
version: '>=8,<10'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 2.7.0
|
||||
espressif/i2c_bus:
|
||||
component_hash:
|
||||
4e990dc11734316186b489b362c61d41f23f79d58bc169795cec215e528cba14
|
||||
dependencies:
|
||||
- name: espressif/cmake_utilities
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '*'
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=4.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 1.5.0
|
||||
idf:
|
||||
source:
|
||||
type: idf
|
||||
version: 5.5.2
|
||||
lvgl/lvgl:
|
||||
component_hash:
|
||||
17e68bfd21f0edf4c3ee838e2273da840bf3930e5dbc3bfa6c1190c3aed41f9f
|
||||
dependencies: []
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 9.4.0
|
||||
waveshare/esp_lcd_jd9365_10_1:
|
||||
component_hash:
|
||||
6c1336b93a37df2b5be42c49c4c364d0bacdbf96f053a934f881349457fac679
|
||||
dependencies:
|
||||
- name: espressif/cmake_utilities
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: 0.*
|
||||
- name: espressif/i2c_bus
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: ^1.3.0
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
targets:
|
||||
- esp32p4
|
||||
version: 1.0.4
|
||||
direct_dependencies:
|
||||
- espressif/esp_lcd_touch_gt911
|
||||
- espressif/esp_lvgl_port
|
||||
- idf
|
||||
- lvgl/lvgl
|
||||
- waveshare/esp_lcd_jd9365_10_1
|
||||
manifest_hash: 1b3972520800645b8020e1ad5d7fcfe89a9006c17fff1fcaa83ae8df9e2314ff
|
||||
target: esp32p4
|
||||
version: 2.0.0
|
||||
4
main/CMakeLists.txt
Normal file
4
main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
idf_component_register(SRCS "hello_world_main.c"
|
||||
PRIV_REQUIRES spi_flash esp_lcd
|
||||
REQUIRES esp_timer lvgl
|
||||
INCLUDE_DIRS "")
|
||||
265
main/hello_world_main.c
Normal file
265
main/hello_world_main.c
Normal file
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 User
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/i2c_master.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lcd_panel_io.h"
|
||||
#include "esp_lcd_mipi_dsi.h"
|
||||
#include "esp_ldo_regulator.h"
|
||||
#include "esp_lcd_touch_gt911.h"
|
||||
#include "lvgl.h"
|
||||
#include "esp_lcd_jd9365_10_1.h"
|
||||
|
||||
#define TAG "JD9365_LVGL"
|
||||
|
||||
// Display config
|
||||
#define LCD_H_RES 800
|
||||
#define LCD_V_RES 1280
|
||||
#define LCD_BIT_PER_PIXEL 24
|
||||
#define LCD_RST_GPIO 27
|
||||
#define LCD_BK_GPIO 26
|
||||
#define LCD_BK_ON_LEVEL 1
|
||||
|
||||
// MIPI DSI config
|
||||
#define MIPI_DSI_LANE_NUM 2
|
||||
#define MIPI_DSI_PHY_LDO_CHAN 3
|
||||
#define MIPI_DSI_PHY_LDO_VOLTAGE_MV 2500
|
||||
|
||||
// Touch config (GT911)
|
||||
#define TOUCH_I2C_SDA 7
|
||||
#define TOUCH_I2C_SCL 8
|
||||
#define TOUCH_INT_GPIO 3
|
||||
#define TOUCH_RST_GPIO 2
|
||||
#define TOUCH_I2C_FREQ_HZ 400000
|
||||
|
||||
static esp_lcd_panel_handle_t panel_handle = NULL;
|
||||
static esp_lcd_touch_handle_t touch_handle = NULL;
|
||||
static esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
|
||||
static esp_lcd_panel_io_handle_t mipi_dbi_io = NULL;
|
||||
static SemaphoreHandle_t refresh_done_sem = NULL;
|
||||
|
||||
// ================= Color Transfer Done Callback ===================
|
||||
static bool on_color_trans_done(esp_lcd_panel_handle_t panel, esp_lcd_dpi_panel_event_data_t *event_data, void *user_ctx)
|
||||
{
|
||||
BaseType_t high_task_awoken = pdFALSE;
|
||||
if (refresh_done_sem) {
|
||||
xSemaphoreGiveFromISR(refresh_done_sem, &high_task_awoken);
|
||||
}
|
||||
return high_task_awoken == pdTRUE;
|
||||
}
|
||||
|
||||
|
||||
// ================= Flush Callback ===================
|
||||
static void lvgl_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *color_p)
|
||||
{
|
||||
xSemaphoreTake(refresh_done_sem, portMAX_DELAY);
|
||||
|
||||
esp_lcd_panel_draw_bitmap(panel_handle, area->x1, area->y1,
|
||||
area->x2 + 1, area->y2 + 1, color_p);
|
||||
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
// ================= MIPI DSI / JD9365 init ===================
|
||||
static void lcd_init(void)
|
||||
{
|
||||
// Backlight GPIO
|
||||
gpio_config_t bk_gpio = {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = 1ULL << LCD_BK_GPIO
|
||||
};
|
||||
gpio_config(&bk_gpio);
|
||||
gpio_set_level(LCD_BK_GPIO, LCD_BK_ON_LEVEL);
|
||||
|
||||
// LDO für MIPI PHY
|
||||
esp_ldo_channel_handle_t ldo_mipi = NULL;
|
||||
esp_ldo_channel_config_t ldo_cfg = {
|
||||
.chan_id = MIPI_DSI_PHY_LDO_CHAN,
|
||||
.voltage_mv = MIPI_DSI_PHY_LDO_VOLTAGE_MV
|
||||
};
|
||||
esp_ldo_acquire_channel(&ldo_cfg, &ldo_mipi);
|
||||
|
||||
// MIPI DSI Bus
|
||||
esp_lcd_dsi_bus_config_t bus_cfg = JD9365_PANEL_BUS_DSI_2CH_CONFIG();
|
||||
esp_lcd_new_dsi_bus(&bus_cfg, &mipi_dsi_bus);
|
||||
|
||||
// Panel IO
|
||||
esp_lcd_dbi_io_config_t io_cfg = JD9365_PANEL_IO_DBI_CONFIG();
|
||||
esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &io_cfg, &mipi_dbi_io);
|
||||
|
||||
// Panel Driver
|
||||
esp_lcd_dpi_panel_config_t dpi_cfg = JD9365_800_1280_PANEL_60HZ_DPI_CONFIG(LCD_COLOR_PIXEL_FORMAT_RGB888);
|
||||
jd9365_vendor_config_t vendor_cfg = {
|
||||
.flags = { .use_mipi_interface = 1 },
|
||||
.mipi_config = { .dsi_bus = mipi_dsi_bus, .dpi_config = &dpi_cfg, .lane_num = MIPI_DSI_LANE_NUM }
|
||||
};
|
||||
esp_lcd_panel_dev_config_t panel_cfg = {
|
||||
.reset_gpio_num = LCD_RST_GPIO,
|
||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
|
||||
.bits_per_pixel = LCD_BIT_PER_PIXEL,
|
||||
.vendor_config = &vendor_cfg
|
||||
};
|
||||
esp_lcd_new_panel_jd9365(mipi_dbi_io, &panel_cfg, &panel_handle);
|
||||
|
||||
// Initialize panel first
|
||||
esp_lcd_panel_reset(panel_handle);
|
||||
esp_lcd_panel_init(panel_handle);
|
||||
esp_lcd_panel_disp_on_off(panel_handle, true);
|
||||
|
||||
// Now set up synchronization after panel is ready
|
||||
refresh_done_sem = xSemaphoreCreateBinary();
|
||||
xSemaphoreGive(refresh_done_sem); // Allow first draw to proceed
|
||||
|
||||
// Register color transfer done callback (signals when draw_bitmap completes)
|
||||
esp_lcd_dpi_panel_event_callbacks_t cbs = {
|
||||
.on_color_trans_done = on_color_trans_done,
|
||||
};
|
||||
esp_lcd_dpi_panel_register_event_callbacks(panel_handle, &cbs, NULL);
|
||||
}
|
||||
|
||||
// ================= Touch init ===================
|
||||
static void touch_init(void)
|
||||
{
|
||||
// I2C Bus initialisieren
|
||||
i2c_master_bus_config_t i2c_bus_cfg = {
|
||||
.i2c_port = I2C_NUM_0,
|
||||
.sda_io_num = TOUCH_I2C_SDA,
|
||||
.scl_io_num = TOUCH_I2C_SCL,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.glitch_ignore_cnt = 7,
|
||||
.flags.enable_internal_pullup = true, // Board hat externe Pullups
|
||||
};
|
||||
i2c_master_bus_handle_t i2c_bus = NULL;
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &i2c_bus));
|
||||
|
||||
// Touch Panel IO
|
||||
esp_lcd_panel_io_handle_t touch_io = NULL;
|
||||
esp_lcd_panel_io_i2c_config_t touch_io_cfg = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
|
||||
touch_io_cfg.scl_speed_hz = TOUCH_I2C_FREQ_HZ;
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(i2c_bus, &touch_io_cfg, &touch_io));
|
||||
|
||||
// GT911 Touch Controller
|
||||
esp_lcd_touch_config_t touch_cfg = {
|
||||
.x_max = LCD_H_RES,
|
||||
.y_max = LCD_V_RES,
|
||||
.rst_gpio_num = TOUCH_RST_GPIO,
|
||||
.int_gpio_num = TOUCH_INT_GPIO,
|
||||
.levels = {
|
||||
.reset = 0,
|
||||
.interrupt = 0,
|
||||
},
|
||||
.flags = {
|
||||
.swap_xy = 0,
|
||||
.mirror_x = 0,
|
||||
.mirror_y = 0,
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(touch_io, &touch_cfg, &touch_handle));
|
||||
ESP_LOGI(TAG, "Touch GT911 initialized");
|
||||
}
|
||||
|
||||
// ================= LVGL Touch Callback ===================
|
||||
static void lvgl_touch_cb(lv_indev_t *indev, lv_indev_data_t *data)
|
||||
{
|
||||
uint16_t x[1];
|
||||
uint16_t y[1];
|
||||
uint8_t touch_cnt = 0;
|
||||
|
||||
esp_lcd_touch_read_data(touch_handle);
|
||||
bool touched = esp_lcd_touch_get_coordinates(touch_handle, x, y, NULL, &touch_cnt, 1);
|
||||
|
||||
if (touched && touch_cnt > 0) {
|
||||
data->point.x = x[0];
|
||||
data->point.y = y[0];
|
||||
data->state = LV_INDEV_STATE_PRESSED;
|
||||
} else {
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
}
|
||||
|
||||
// ================= LVGL init ===================
|
||||
static void lvgl_init(void)
|
||||
{
|
||||
lv_init();
|
||||
|
||||
// Display erstellen
|
||||
lv_display_t* display1 = lv_display_create(LCD_H_RES, LCD_V_RES);
|
||||
|
||||
// Set color format to match panel (RGB888 = 24-bit)
|
||||
lv_display_set_color_format(display1, LV_COLOR_FORMAT_RGB888);
|
||||
|
||||
// Allocate buffers in PSRAM with proper alignment for DMA
|
||||
size_t buf_size = LCD_H_RES * 100 * 3; // 100 lines at a time, RGB888
|
||||
uint8_t *buf1 = heap_caps_aligned_alloc(64, buf_size,
|
||||
MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA);
|
||||
uint8_t *buf2 = heap_caps_aligned_alloc(64, buf_size,
|
||||
MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA);
|
||||
|
||||
if (!buf1 || !buf2) {
|
||||
ESP_LOGE(TAG, "Failed to allocate display buffers!");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_display_set_buffers(display1, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
|
||||
// Flush-Callback setzen
|
||||
lv_display_set_flush_cb(display1, lvgl_flush_cb);
|
||||
|
||||
// Touch Input Device registrieren
|
||||
lv_indev_t *indev = lv_indev_create();
|
||||
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
|
||||
lv_indev_set_read_cb(indev, lvgl_touch_cb);
|
||||
lv_indev_set_display(indev, display1);
|
||||
|
||||
lv_display_set_default(display1);
|
||||
}
|
||||
|
||||
// ================= Button Callback ===================
|
||||
static void btn_event_cb(lv_event_t *e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
if (code == LV_EVENT_CLICKED) {
|
||||
ESP_LOGI(TAG, "Button clicked!");
|
||||
}
|
||||
}
|
||||
|
||||
// ================= UI erstellen ===================
|
||||
static void create_ui(void)
|
||||
{
|
||||
// Button erstellen
|
||||
lv_obj_t *btn = lv_button_create(lv_screen_active());
|
||||
lv_obj_set_size(btn, 200, 80);
|
||||
lv_obj_center(btn);
|
||||
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
// Label auf dem Button
|
||||
lv_obj_t *label = lv_label_create(btn);
|
||||
lv_label_set_text(label, "Klick mich!");
|
||||
lv_obj_center(label);
|
||||
}
|
||||
|
||||
// ================= Main ===================
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Starting JD9365 + LVGL 9");
|
||||
|
||||
lcd_init();
|
||||
touch_init();
|
||||
lvgl_init();
|
||||
create_ui();
|
||||
|
||||
while (1) {
|
||||
lv_tick_inc(10);
|
||||
lv_task_handler();
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
}
|
||||
20
main/idf_component.yml
Normal file
20
main/idf_component.yml
Normal file
@ -0,0 +1,20 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: '>=4.1.0'
|
||||
# # Put list of dependencies here
|
||||
# # For components maintained by Espressif:
|
||||
# component: "~1.0.0"
|
||||
# # For 3rd party components:
|
||||
# username/component: ">=1.0.0,<2.0.0"
|
||||
# username2/component2:
|
||||
# version: "~1.0.0"
|
||||
# # For transient dependencies `public` flag can be set.
|
||||
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||
# # All dependencies of `main` are public by default.
|
||||
# public: true
|
||||
waveshare/esp_lcd_jd9365_10_1: '*'
|
||||
lvgl/lvgl: ^9.4.0
|
||||
espressif/esp_lvgl_port: ^2.3.0
|
||||
espressif/esp_lcd_touch_gt911: '*'
|
||||
55
pytest_hello_world.py
Normal file
55
pytest_hello_world.py
Normal file
@ -0,0 +1,55 @@
|
||||
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import hashlib
|
||||
import logging
|
||||
from typing import Callable
|
||||
|
||||
import pytest
|
||||
from pytest_embedded_idf.dut import IdfDut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
from pytest_embedded_qemu.app import QemuApp
|
||||
from pytest_embedded_qemu.dut import QemuDut
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['supported_targets', 'preview_targets'], indirect=['target'])
|
||||
def test_hello_world(dut: IdfDut, log_minimum_free_heap_size: Callable[..., None]) -> None:
|
||||
dut.expect('Hello world!')
|
||||
log_minimum_free_heap_size()
|
||||
|
||||
|
||||
@pytest.mark.host_test
|
||||
@idf_parametrize('target', ['linux'], indirect=['target'])
|
||||
def test_hello_world_linux(dut: IdfDut) -> None:
|
||||
dut.expect('Hello world!')
|
||||
|
||||
|
||||
@pytest.mark.host_test
|
||||
@pytest.mark.macos_shell
|
||||
@idf_parametrize('target', ['linux'], indirect=['target'])
|
||||
def test_hello_world_macos(dut: IdfDut) -> None:
|
||||
dut.expect('Hello world!')
|
||||
|
||||
|
||||
def verify_elf_sha256_embedding(app: QemuApp, sha256_reported: str) -> None:
|
||||
sha256 = hashlib.sha256()
|
||||
with open(app.elf_file, 'rb') as f:
|
||||
sha256.update(f.read())
|
||||
sha256_expected = sha256.hexdigest()
|
||||
|
||||
logging.info(f'ELF file SHA256: {sha256_expected}')
|
||||
logging.info(f'ELF file SHA256 (reported by the app): {sha256_reported}')
|
||||
|
||||
# the app reports only the first several hex characters of the SHA256, check that they match
|
||||
if not sha256_expected.startswith(sha256_reported):
|
||||
raise ValueError('ELF file SHA256 mismatch')
|
||||
|
||||
|
||||
@pytest.mark.host_test
|
||||
@pytest.mark.qemu
|
||||
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
|
||||
def test_hello_world_host(app: QemuApp, dut: QemuDut) -> None:
|
||||
sha256_reported = dut.expect(r'ELF file SHA256:\s+([a-f0-9]+)').group(1).decode('utf-8')
|
||||
verify_elf_sha256_embedding(app, sha256_reported)
|
||||
|
||||
dut.expect('Hello world!')
|
||||
0
sdkconfig.ci
Normal file
0
sdkconfig.ci
Normal file
Loading…
Reference in New Issue
Block a user