Compare commits
118 commits
master
...
feat/displ
Author | SHA1 | Date | |
---|---|---|---|
d9d7f87e1a | |||
9b64c063df | |||
bb83ea90cb | |||
fc81c6da5a | |||
28d663f6b6 | |||
463721e291 | |||
8dda9ded4f | |||
9b4eedd00f | |||
6418f805bb | |||
11f9c2b93f | |||
6af2ab1f1c | |||
62704efd08 | |||
ff055b629e | |||
17eb416ef8 | |||
bb0e3a1f27 | |||
dcff9a7f11 | |||
f669a09b19 | |||
d0376e705c | |||
35d2d3a5af | |||
9ee177b684 | |||
31399e012a | |||
79d8989b2a | |||
1a8a610b05 | |||
26272b08f0 | |||
fbb4ebe409 | |||
a2a13f1a5f | |||
b9377200a6 | |||
c78e9fe169 | |||
d0eca96cd7 | |||
385421fe06 | |||
c7607e93d8 | |||
2dad083264 | |||
ac6cde35c9 | |||
919d644dc8 | |||
3625deb36d | |||
86e3f259ba | |||
ec944af90f | |||
ea37784f08 | |||
a0e915eebc | |||
9c886307b2 | |||
1ededabf99 | |||
6b6b756da3 | |||
18569b6c17 | |||
5d55edc37c | |||
4a9cfeb6fb | |||
83875cc6bd | |||
94244ad432 | |||
44b552758e | |||
b9c381a07d | |||
e51f475263 | |||
e1c18c13b9 | |||
83d5486207 | |||
1a8d0d91e2 | |||
81abc17904 | |||
ef0946a6cc | |||
f1e1f0d9fd | |||
12cf92da81 | |||
d116dfd87d | |||
6a76078ba8 | |||
5fbce2a3bf | |||
0b8d488867 | |||
364349dbf8 | |||
4b01564076 | |||
f7b34f8a3e | |||
3d775fadd1 | |||
0a924fc1b6 | |||
4255e3005b | |||
52f89b10e1 | |||
3b33c04585 | |||
152582e9f8 | |||
f7164ff22a | |||
f6999a52fe | |||
d627884887 | |||
e5b7ef9de2 | |||
3c5a4061d9 | |||
2006d5e449 | |||
cd999e34cd | |||
85f70cb688 | |||
3980e51f07 | |||
9d9fadf450 | |||
359dcb92ba | |||
20438187b1 | |||
0e29128b3b | |||
ffae578a39 | |||
9b1e3d1198 | |||
2134cdcfb5 | |||
b6e1f91ed1 | |||
2a3157b8fc | |||
d79b68bdf6 | |||
dfe54e8573 | |||
83c08f6a2a | |||
f6307afabc | |||
c797562321 | |||
aa8a78f72a | |||
64832c4136 | |||
e314c7563b | |||
0c6975954f | |||
0ae3f76097 | |||
37da744873 | |||
0f1a6d490e | |||
413721182c | |||
7cebfdd671 | |||
2629b6d86a | |||
6122d139de | |||
49a3ba84b4 | |||
0b09769dcc | |||
31f340d864 | |||
7c956f1442 | |||
e3347e3cb5 | |||
56208791b2 | |||
7d9527b6e1 | |||
568dce244a | |||
40ec379b2d | |||
72a5d3da79 | |||
4e0355ec30 | |||
280bebf52e | |||
01dc1259f8 | |||
803c58774c |
29
.github/workflows/build_examples.yml
vendored
Normal file
29
.github/workflows/build_examples.yml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
name: 'build'
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
idf_ver: ["v4.1", "v4.2", "v4.3"]
|
||||||
|
idf_target: ["esp32"]
|
||||||
|
include:
|
||||||
|
- idf_ver: "v4.2"
|
||||||
|
idf_target: esp32s2
|
||||||
|
- idf_ver: "v4.3"
|
||||||
|
idf_target: esp32c3
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container: espressif/idf:release-${{ matrix.idf_ver }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Build ESP examples
|
||||||
|
env:
|
||||||
|
IDF_TARGET: ${{ matrix.idf_target }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd examples/wemos_lolin_oled/hello_world
|
||||||
|
. ${IDF_PATH}/export.sh
|
||||||
|
idf.py build
|
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -56,3 +56,10 @@ dkms.conf
|
||||||
|
|
||||||
# ESP-IDF build dir
|
# ESP-IDF build dir
|
||||||
build
|
build
|
||||||
|
|
||||||
|
# Kconfig files
|
||||||
|
sdkconfig
|
||||||
|
sdkconfig.old
|
||||||
|
|
||||||
|
# pre-commit configuration file
|
||||||
|
.pre-commit-config.yaml
|
||||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "examples/common_components/lvgl"]
|
||||||
|
path = examples/common_components/lvgl
|
||||||
|
url = https://github.com/lvgl/lvgl.git
|
|
@ -3,53 +3,38 @@ if(ESP_PLATFORM)
|
||||||
file(GLOB SOURCES *.c)
|
file(GLOB SOURCES *.c)
|
||||||
set(LVGL_INCLUDE_DIRS . lvgl_tft)
|
set(LVGL_INCLUDE_DIRS . lvgl_tft)
|
||||||
list(APPEND SOURCES "lvgl_tft/disp_driver.c")
|
list(APPEND SOURCES "lvgl_tft/disp_driver.c")
|
||||||
list(APPEND SOURCES "lvgl_tft/esp_lcd_backlight.c")
|
list(APPEND SOURCES "lv_port/esp_lcd_backlight.c")
|
||||||
|
|
||||||
# Include only the source file of the selected
|
# This are the source files used for mcu abstraction
|
||||||
# display controller.
|
set(LV_PORT_PATH "lv_port")
|
||||||
if(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341)
|
|
||||||
|
list(APPEND SOURCES "${LV_PORT_PATH}/lv_port_display_espressif.c")
|
||||||
|
|
||||||
|
#@todo add SimleInclude macro here
|
||||||
|
|
||||||
|
# Build all display drivers
|
||||||
list(APPEND SOURCES "lvgl_tft/ili9341.c")
|
list(APPEND SOURCES "lvgl_tft/ili9341.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/ili9481.c")
|
list(APPEND SOURCES "lvgl_tft/ili9481.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/ili9486.c")
|
list(APPEND SOURCES "lvgl_tft/ili9486.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/ili9488.c")
|
list(APPEND SOURCES "lvgl_tft/ili9488.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/st7789.c")
|
list(APPEND SOURCES "lvgl_tft/st7789.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/st7735s.c")
|
list(APPEND SOURCES "lvgl_tft/st7735s.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/st7796s.c")
|
list(APPEND SOURCES "lvgl_tft/st7796s.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/hx8357.c")
|
list(APPEND SOURCES "lvgl_tft/hx8357.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/sh1107.c")
|
list(APPEND SOURCES "lvgl_tft/sh1107.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/ssd1306.c")
|
list(APPEND SOURCES "lvgl_tft/ssd1306.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/EVE_commands.c")
|
list(APPEND SOURCES "lvgl_tft/EVE_commands.c")
|
||||||
list(APPEND SOURCES "lvgl_tft/FT81x.c")
|
list(APPEND SOURCES "lvgl_tft/FT81x.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/il3820.c")
|
list(APPEND SOURCES "lvgl_tft/il3820.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/jd79653a.c")
|
list(APPEND SOURCES "lvgl_tft/jd79653a.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/uc8151d.c")
|
list(APPEND SOURCES "lvgl_tft/uc8151d.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/ra8875.c")
|
list(APPEND SOURCES "lvgl_tft/ra8875.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_GC9A01)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/GC9A01.c")
|
list(APPEND SOURCES "lvgl_tft/GC9A01.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/ili9163c.c")
|
list(APPEND SOURCES "lvgl_tft/ili9163c.c")
|
||||||
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544)
|
|
||||||
list(APPEND SOURCES "lvgl_tft/pcd8544.c")
|
list(APPEND SOURCES "lvgl_tft/pcd8544.c")
|
||||||
else()
|
|
||||||
message(WARNING "LVGL ESP32 drivers: Display controller not defined.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI)
|
if(CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI)
|
||||||
list(APPEND SOURCES "lvgl_tft/disp_spi.c")
|
list(APPEND SOURCES "lv_port/disp_spi.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Add touch driver to compilation only if it is selected in menuconfig
|
# Add touch driver to compilation only if it is selected in menuconfig
|
||||||
|
@ -76,7 +61,7 @@ if(CONFIG_LV_TOUCH_CONTROLLER)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
|
if(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
|
||||||
list(APPEND SOURCES "lvgl_touch/tp_spi.c")
|
list(APPEND SOURCES "lv_port/tp_spi.c")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -84,6 +69,8 @@ if(CONFIG_LV_I2C)
|
||||||
list(APPEND SOURCES "lvgl_i2c/i2c_manager.c")
|
list(APPEND SOURCES "lvgl_i2c/i2c_manager.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
list(APPEND LVGL_INCLUDE_DIRS lv_port)
|
||||||
|
|
||||||
idf_component_register(SRCS ${SOURCES}
|
idf_component_register(SRCS ${SOURCES}
|
||||||
INCLUDE_DIRS ${LVGL_INCLUDE_DIRS}
|
INCLUDE_DIRS ${LVGL_INCLUDE_DIRS}
|
||||||
REQUIRES lvgl)
|
REQUIRES lvgl)
|
||||||
|
|
|
@ -12,6 +12,11 @@ For a ready to use ESP32 project take look at the [lv_port_esp32](https://github
|
||||||
**NOTE:** You need to set the display horizontal and vertical size, color depth and
|
**NOTE:** You need to set the display horizontal and vertical size, color depth and
|
||||||
swap of RGB565 color on the LVGL configuration menuconfig (it's not handled automatically).
|
swap of RGB565 color on the LVGL configuration menuconfig (it's not handled automatically).
|
||||||
|
|
||||||
|
## MCU Configuration
|
||||||
|
|
||||||
|
Example of SPI/I2C configuration peripherals is done with `lvgl_interface_init`.
|
||||||
|
Example of display gpios configuration, such as the DC, RST, Backlight is done with `lvgl_display_gpios_init`
|
||||||
|
|
||||||
|
|
||||||
## Supported display controllers
|
## Supported display controllers
|
||||||
|
|
||||||
|
|
43
display_config.h
Normal file
43
display_config.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef DISPLAY_CONFIG_H_
|
||||||
|
#define DISPLAY_CONFIG_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
/* Configuration options for ST7789 display controllers */
|
||||||
|
#if defined CONFIG_LV_DISP_USE_RST
|
||||||
|
#if defined CONFIG_LV_DISP_ST7789_SOFT_RESET
|
||||||
|
#define ST7789_SOFT_RST
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define ST7789_SOFT_RST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (CONFIG_LV_INVERT_COLORS)
|
||||||
|
#define ST7789_INVERT_COLORS 1U
|
||||||
|
#define ILI9341_INVERT_COLORS 1U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ST7789_INITIAL_ORIENTATION CONFIG_LV_DISPLAY_ORIENTATION
|
||||||
|
|
||||||
|
#if CONFIG_LV_DISP_USE_RST
|
||||||
|
#define ILI9341_USE_RST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ILI9341_INITIAL_ORIENTATION CONFIG_LV_DISPLAY_ORIENTATION
|
||||||
|
|
||||||
|
/* ILI9488 Configuration */
|
||||||
|
#if CONFIG_LV_DISP_USE_RST
|
||||||
|
#define ILI9488_USE_RST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ILI9488_INITIAL_ORIENTATION CONFIG_LV_DISPLAY_ORIENTATION
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* DISPLAY_CONFIG_H_ */
|
1
examples/common_components/lvgl
Submodule
1
examples/common_components/lvgl
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 2e942060f077de19667ec200afcfd2b32352064b
|
9
examples/wemos_lolin_oled/hello_world/CMakeLists.txt
Normal file
9
examples/wemos_lolin_oled/hello_world/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# For more information about build system see
|
||||||
|
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
|
||||||
|
# The following five 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.5)
|
||||||
|
|
||||||
|
set(EXTRA_COMPONENT_DIRS ../../common_components ../../..)
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(hello_world)
|
|
@ -0,0 +1,2 @@
|
||||||
|
idf_component_register(SRCS "hello_world.c"
|
||||||
|
INCLUDE_DIRS ".")
|
110
examples/wemos_lolin_oled/hello_world/main/hello_world.c
Normal file
110
examples/wemos_lolin_oled/hello_world/main/hello_world.c
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/* Hello world on Wemos Lolin32 board
|
||||||
|
*
|
||||||
|
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, this
|
||||||
|
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
* CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "esp_freertos_hooks.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
/* Littlevgl specific */
|
||||||
|
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "lvgl_helpers.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
#define LV_TICK_PERIOD_MS 1
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
static void lvgl_tick_inc(void *arg);
|
||||||
|
static void guiTask(void *pvParameter);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* APPLICATION MAIN
|
||||||
|
**********************/
|
||||||
|
void app_main()
|
||||||
|
{
|
||||||
|
xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 0, NULL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void guiTask(void *pvParameter)
|
||||||
|
{
|
||||||
|
(void) pvParameter;
|
||||||
|
lv_init();
|
||||||
|
|
||||||
|
/* Initialize the needed peripherals */
|
||||||
|
lvgl_interface_init();
|
||||||
|
/* Initialize needed GPIOs, e.g. backlight, reset GPIOs */
|
||||||
|
lvgl_display_gpios_init();
|
||||||
|
|
||||||
|
/* ToDo Initialize used display driver passing registered lv_disp_drv_t as parameter */
|
||||||
|
|
||||||
|
size_t display_buffer_size = lvgl_get_display_buffer_size();
|
||||||
|
lv_color_t* buf1 = heap_caps_malloc(display_buffer_size * sizeof(lv_color_t), MALLOC_CAP_DMA);
|
||||||
|
assert(buf1 != NULL);
|
||||||
|
|
||||||
|
static lv_disp_draw_buf_t disp_buf;
|
||||||
|
lv_disp_draw_buf_init(&disp_buf, buf1, NULL, display_buffer_size * 8);
|
||||||
|
|
||||||
|
lv_disp_drv_t disp_drv;
|
||||||
|
lv_disp_drv_init(&disp_drv);
|
||||||
|
disp_drv.flush_cb = disp_driver_flush;
|
||||||
|
disp_drv.rounder_cb = disp_driver_rounder;
|
||||||
|
disp_drv.set_px_cb = disp_driver_set_px;
|
||||||
|
disp_drv.draw_buf = &disp_buf;
|
||||||
|
/* LVGL v8: Set display horizontal and vertical resolution (in pixels), it's no longer done with lv_conf.h */
|
||||||
|
disp_drv.hor_res = 128u;
|
||||||
|
disp_drv.ver_res = 64u;
|
||||||
|
lv_disp_drv_register(&disp_drv);
|
||||||
|
|
||||||
|
/* Create and start a periodic timer interrupt to call lv_tick_inc */
|
||||||
|
const esp_timer_create_args_t periodic_timer_args = {
|
||||||
|
.callback = &lvgl_tick_inc,
|
||||||
|
.name = "lvgl_tick"
|
||||||
|
};
|
||||||
|
esp_timer_handle_t periodic_timer;
|
||||||
|
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
|
||||||
|
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000));
|
||||||
|
|
||||||
|
/* Create a Hellow World label on the currently active screen */
|
||||||
|
lv_obj_t *scr = lv_disp_get_scr_act(NULL);
|
||||||
|
|
||||||
|
/* LVGL v8 lv_label_create no longer takes 2 parameters */
|
||||||
|
lv_obj_t *label1 = lv_label_create(scr);
|
||||||
|
lv_label_set_text(label1, "Hello\nworld");
|
||||||
|
|
||||||
|
/* Align the Label to the center
|
||||||
|
* NULL means align on parent (which is the screen now)
|
||||||
|
* 0, 0 at the end means an x, y offset after alignment*/
|
||||||
|
lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
lv_task_handler();
|
||||||
|
}
|
||||||
|
free(buf1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lvgl_tick_inc(void *arg) {
|
||||||
|
(void) arg;
|
||||||
|
lv_tick_inc(LV_TICK_PERIOD_MS);
|
||||||
|
}
|
11
examples/wemos_lolin_oled/hello_world/sdkconfig.defaults
Normal file
11
examples/wemos_lolin_oled/hello_world/sdkconfig.defaults
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
CONFIG_LV_HOR_RES_MAX=128
|
||||||
|
CONFIG_LV_VER_RES_MAX=64
|
||||||
|
CONFIG_LV_COLOR_DEPTH_1=y
|
||||||
|
CONFIG_LV_THEME_MONO=y
|
||||||
|
|
||||||
|
CONFIG_LV_PREDEFINED_DISPLAY_WEMOS_LOLIN=y
|
||||||
|
|
||||||
|
CONFIG_I2C_MANAGER_0_ENABLED=y
|
||||||
|
CONFIG_I2C_MANAGER_0_SDA=5
|
||||||
|
CONFIG_I2C_MANAGER_0_SCL=4
|
||||||
|
CONFIG_I2C_MANAGER_0_FREQ_HZ=100000
|
161
lv_port/lv_port_display_espressif.c
Normal file
161
lv_port/lv_port_display_espressif.c
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
#include "display_port.h"
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
#include "disp_spi.h"
|
||||||
|
#include "lvgl_i2c/i2c_manager.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/* NOTE: Needed by the I2C Manager */
|
||||||
|
#define OLED_I2C_PORT (CONFIG_LV_I2C_DISPLAY_PORT)
|
||||||
|
/* FIXME: Be able to get display driver I2C address from Kconfig */
|
||||||
|
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306)
|
||||||
|
#define OLED_I2C_ADDRESS 0x3C
|
||||||
|
#else
|
||||||
|
#define OLED_I2C_ADDRESS 0x00
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Control byte
|
||||||
|
#define OLED_CONTROL_BYTE_CMD_SINGLE 0x80
|
||||||
|
#define OLED_CONTROL_BYTE_CMD_STREAM 0x00
|
||||||
|
#define OLED_CONTROL_BYTE_DATA_STREAM 0x40
|
||||||
|
|
||||||
|
#define LV_DISPLAY_DC_CMD_MODE 0
|
||||||
|
#define LV_DISPLAY_DC_DATA_MODE 1
|
||||||
|
|
||||||
|
/* Helper functions to get display communication interface kind, this can be
|
||||||
|
* implemented as users see fit, we're using the symbols created by Kconfig
|
||||||
|
* because is what we have available.
|
||||||
|
* Other ways to implement it is using the user_data poiter in lv_disp_drv_t */
|
||||||
|
static inline bool display_interface_is_spi(lv_disp_drv_t * drv);
|
||||||
|
static inline bool display_interface_is_i2c(lv_disp_drv_t * drv);
|
||||||
|
|
||||||
|
void display_port_delay(lv_disp_drv_t *drv, uint32_t delay_ms)
|
||||||
|
{
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(delay_ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_port_backlight(lv_disp_drv_t *drv, uint8_t state)
|
||||||
|
{
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
#ifdef CONFIG_LV_DISP_PIN_BCKL
|
||||||
|
gpio_set_level(CONFIG_LV_DISP_PIN_BCKL, state);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_port_gpio_dc(lv_disp_drv_t *drv, uint8_t state)
|
||||||
|
{
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
#ifdef CONFIG_LV_DISPLAY_USE_DC
|
||||||
|
gpio_set_level(CONFIG_LV_DISP_PIN_DC, state);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_port_gpio_rst(lv_disp_drv_t *drv, uint8_t state)
|
||||||
|
{
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
#ifdef CONFIG_LV_DISP_USE_RST
|
||||||
|
gpio_set_level(CONFIG_LV_DISP_PIN_RST, state);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool display_port_gpio_is_busy(lv_disp_drv_t *drv)
|
||||||
|
{
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
bool device_busy = false;
|
||||||
|
|
||||||
|
#ifdef CONFIG_LV_DISP_PIN_BUSY
|
||||||
|
/* FIXME Assuming the busy signal in logic 1 means the device is busy */
|
||||||
|
if (gpio_get_level(CONFIG_LV_DISP_PIN_BUSY) == 1) {
|
||||||
|
device_busy = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return device_busy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_interface_send_cmd(lv_disp_drv_t *drv, uint32_t cmd, cmd_width_t cmd_width, void *args, size_t args_len)
|
||||||
|
{
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
if (display_interface_is_spi(drv)) {
|
||||||
|
disp_wait_for_pending_transactions();
|
||||||
|
display_port_gpio_dc(drv, LV_DISPLAY_DC_CMD_MODE);
|
||||||
|
|
||||||
|
if (CMD_WIDTH_8BITS == cmd_width) {
|
||||||
|
uint8_t cmd_8bits = (uint8_t) cmd & 0xFFU;
|
||||||
|
disp_spi_send_data(&cmd_8bits, 1);
|
||||||
|
}
|
||||||
|
else if (CMD_WIDTH_16BITS == cmd_width) {
|
||||||
|
/* Send 16bits cmd */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Invalid cmd size */
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args != CMD_WITHOUT_ARGS) {
|
||||||
|
display_port_gpio_dc(drv, LV_DISPLAY_DC_DATA_MODE);
|
||||||
|
disp_spi_send_data(args, args_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display_interface_is_i2c(drv)) {
|
||||||
|
uint8_t *data = (uint8_t *) args;
|
||||||
|
lvgl_i2c_write(OLED_I2C_PORT, OLED_I2C_ADDRESS, cmd, data, args_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void display_interface_send_data(lv_disp_drv_t *drv, void *data, size_t len)
|
||||||
|
{
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
if (display_interface_is_spi(drv)) {
|
||||||
|
disp_wait_for_pending_transactions();
|
||||||
|
display_port_gpio_dc(drv, LV_DISPLAY_DC_DATA_MODE);
|
||||||
|
disp_spi_send_colors(data, len);
|
||||||
|
/* lv_disp_flush_ready is called in the SPI xfer done callback */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display_interface_is_i2c(drv)) {
|
||||||
|
lvgl_i2c_write(OLED_I2C_PORT, OLED_I2C_ADDRESS, OLED_CONTROL_BYTE_DATA_STREAM, data, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool display_interface_is_spi(lv_disp_drv_t * drv)
|
||||||
|
{
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI)
|
||||||
|
retval = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool display_interface_is_i2c(lv_disp_drv_t * drv)
|
||||||
|
{
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_I2C)
|
||||||
|
retval = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
290
lvgl_helpers.c
290
lvgl_helpers.c
|
@ -6,12 +6,16 @@
|
||||||
/*********************
|
/*********************
|
||||||
* INCLUDES
|
* INCLUDES
|
||||||
*********************/
|
*********************/
|
||||||
#include "sdkconfig.h"
|
|
||||||
#include "lvgl_helpers.h"
|
#include "lvgl_helpers.h"
|
||||||
#include "esp_log.h"
|
|
||||||
|
|
||||||
#include "lvgl_tft/disp_spi.h"
|
#include "sdkconfig.h"
|
||||||
#include "lvgl_touch/tp_spi.h"
|
|
||||||
|
#include "driver/spi_common.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_idf_version.h"
|
||||||
|
|
||||||
|
#include "disp_spi.h"
|
||||||
|
#include "tp_spi.h"
|
||||||
|
|
||||||
#include "lvgl_spi_conf.h"
|
#include "lvgl_spi_conf.h"
|
||||||
|
|
||||||
|
@ -29,6 +33,8 @@
|
||||||
|
|
||||||
#define TAG "lvgl_helpers"
|
#define TAG "lvgl_helpers"
|
||||||
|
|
||||||
|
#define GPIO_NOT_USED (-1)
|
||||||
|
#define DMA_DEFAULT_TRANSFER_SIZE (0u)
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -37,6 +43,20 @@
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the SPI max transfer size based on the display buffer size
|
||||||
|
*
|
||||||
|
* @return SPI max transfer size in bytes
|
||||||
|
*/
|
||||||
|
static int calculate_spi_max_transfer_size(const int display_buffer_size);
|
||||||
|
|
||||||
|
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
|
||||||
|
/**
|
||||||
|
* Handle FT81X initialization as it's a particular case
|
||||||
|
*/
|
||||||
|
static void init_ft81x(int dma_channel);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -49,8 +69,8 @@
|
||||||
* GLOBAL FUNCTIONS
|
* GLOBAL FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
/* Interface and driver initialization */
|
/* Interface (SPI, I2C) initialization */
|
||||||
void lvgl_driver_init(void)
|
void lvgl_interface_init(void)
|
||||||
{
|
{
|
||||||
/* Since LVGL v8 LV_HOR_RES_MAX and LV_VER_RES_MAX are not defined, so
|
/* Since LVGL v8 LV_HOR_RES_MAX and LV_VER_RES_MAX are not defined, so
|
||||||
* print it only if they are defined. */
|
* print it only if they are defined. */
|
||||||
|
@ -58,57 +78,49 @@ void lvgl_driver_init(void)
|
||||||
ESP_LOGI(TAG, "Display hor size: %d, ver size: %d", LV_HOR_RES_MAX, LV_VER_RES_MAX);
|
ESP_LOGI(TAG, "Display hor size: %d, ver size: %d", LV_HOR_RES_MAX, LV_VER_RES_MAX);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Display buffer size: %d", DISP_BUF_SIZE);
|
size_t display_buffer_size = lvgl_get_display_buffer_size();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Display buffer size: %d", display_buffer_size);
|
||||||
|
|
||||||
|
/* SPI DMA Channel selection
|
||||||
|
* SPI_DMA_CH1 is only defined for ESP32, so let the driver choose which
|
||||||
|
* channel to use, and use the proven channel 1 on esp32 targets */
|
||||||
|
int dma_channel = 3;
|
||||||
|
#if defined (CONFIG_IDF_TARGET_ESP32)
|
||||||
|
dma_channel = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
|
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
|
||||||
ESP_LOGI(TAG, "Initializing SPI master for FT81X");
|
init_ft81x(dma_channel);
|
||||||
|
|
||||||
lvgl_spi_driver_init(TFT_SPI_HOST,
|
|
||||||
DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
|
|
||||||
SPI_BUS_MAX_TRANSFER_SZ, 1,
|
|
||||||
DISP_SPI_IO2, DISP_SPI_IO3);
|
|
||||||
|
|
||||||
disp_spi_add_device(TFT_SPI_HOST);
|
|
||||||
disp_driver_init();
|
|
||||||
|
|
||||||
#if defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
|
|
||||||
touch_driver_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (SHARED_SPI_BUS)
|
|
||||||
ESP_LOGI(TAG, "Initializing shared SPI master");
|
|
||||||
|
|
||||||
lvgl_spi_driver_init(TFT_SPI_HOST,
|
|
||||||
TP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
|
|
||||||
SPI_BUS_MAX_TRANSFER_SZ, 1,
|
|
||||||
-1, -1);
|
|
||||||
|
|
||||||
disp_spi_add_device(TFT_SPI_HOST);
|
|
||||||
tp_spi_add_device(TOUCH_SPI_HOST);
|
|
||||||
|
|
||||||
disp_driver_init();
|
|
||||||
touch_driver_init();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Display controller initialization */
|
/* Display controller initialization */
|
||||||
#if defined CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI
|
#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI) || defined (SHARED_SPI_BUS)
|
||||||
ESP_LOGI(TAG, "Initializing SPI master for display");
|
ESP_LOGI(TAG, "Initializing SPI master");
|
||||||
|
|
||||||
lvgl_spi_driver_init(TFT_SPI_HOST,
|
int miso = DISP_SPI_MISO;
|
||||||
DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
|
int spi_max_transfer_size = calculate_spi_max_transfer_size(display_buffer_size);
|
||||||
SPI_BUS_MAX_TRANSFER_SZ, 1,
|
|
||||||
DISP_SPI_IO2, DISP_SPI_IO3);
|
/* Set the miso signal to be the selected for the touch driver */
|
||||||
|
#if defined (SHARED_SPI_BUS)
|
||||||
|
miso = TP_SPI_MISO;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
lvgl_spi_driver_init(TFT_SPI_HOST, miso, DISP_SPI_MOSI, DISP_SPI_CLK,
|
||||||
|
spi_max_transfer_size, dma_channel, DISP_SPI_IO2, DISP_SPI_IO3);
|
||||||
|
|
||||||
disp_spi_add_device(TFT_SPI_HOST);
|
disp_spi_add_device(TFT_SPI_HOST);
|
||||||
|
|
||||||
disp_driver_init();
|
/* Add device for touch driver */
|
||||||
|
#if defined (SHARED_SPI_BUS)
|
||||||
|
tp_spi_add_device(TOUCH_SPI_HOST);
|
||||||
|
touch_driver_init();
|
||||||
|
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif defined (CONFIG_LV_I2C_DISPLAY)
|
#elif defined (CONFIG_LV_I2C_DISPLAY)
|
||||||
disp_driver_init();
|
|
||||||
#else
|
#else
|
||||||
#error "No protocol defined for display controller"
|
#error "No protocol defined for display controller"
|
||||||
#endif
|
#endif
|
||||||
|
@ -118,10 +130,12 @@ void lvgl_driver_init(void)
|
||||||
#if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
|
#if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
|
||||||
ESP_LOGI(TAG, "Initializing SPI master for touch");
|
ESP_LOGI(TAG, "Initializing SPI master for touch");
|
||||||
|
|
||||||
lvgl_spi_driver_init(TOUCH_SPI_HOST,
|
#if defined (CONFIG_IDF_TARGET_ESP32)
|
||||||
TP_SPI_MISO, TP_SPI_MOSI, TP_SPI_CLK,
|
dma_channel = 2;
|
||||||
0 /* Defaults to 4094 */, 2,
|
#endif
|
||||||
-1, -1);
|
|
||||||
|
lvgl_spi_driver_init(TOUCH_SPI_HOST, TP_SPI_MISO, TP_SPI_MOSI, TP_SPI_CLK,
|
||||||
|
DMA_DEFAULT_TRANSFER_SIZE, dma_channel, GPIO_NOT_USED, GPIO_NOT_USED);
|
||||||
|
|
||||||
tp_spi_add_device(TOUCH_SPI_HOST);
|
tp_spi_add_device(TOUCH_SPI_HOST);
|
||||||
|
|
||||||
|
@ -139,6 +153,105 @@ void lvgl_driver_init(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lvgl_display_gpios_init(void)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
gpio_config_t io_conf = {
|
||||||
|
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||||
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_LV_DISPLAY_USE_DC
|
||||||
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||||
|
io_conf.pin_bit_mask = (1ULL << CONFIG_LV_DISP_PIN_DC);
|
||||||
|
err = gpio_config(&io_conf);
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LV_DISP_USE_RST
|
||||||
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||||
|
io_conf.pin_bit_mask = (1ULL << CONFIG_LV_DISP_PIN_RST);
|
||||||
|
err = gpio_config(&io_conf);
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CONFIG_LV_DISP_BACKLIGHT_OFF) && defined(CONFIG_LV_DISP_PIN_BCKL) && \
|
||||||
|
(CONFIG_LV_DISP_PIN_BCKL > 0)
|
||||||
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||||
|
io_conf.pin_bit_mask = (1ULL << CONFIG_LV_DISP_PIN_BCKL);
|
||||||
|
err = gpio_config(&io_conf);
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LV_DISP_USE_BUSY
|
||||||
|
io_conf.mode = GPIO_MODE_INPUT;
|
||||||
|
io_conf.pin_bit_mask = (1ULL << CONFIG_LV_DISP_PIN_BUSY);
|
||||||
|
err = gpio_config(&io_conf);
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DISP_BUF_SIZE value doesn't have an special meaning, but it's the size
|
||||||
|
* of the buffer(s) passed to LVGL as display buffers. The default values used
|
||||||
|
* were the values working for the contributor of the display controller.
|
||||||
|
*
|
||||||
|
* As LVGL supports partial display updates the DISP_BUF_SIZE doesn't
|
||||||
|
* necessarily need to be equal to the display size.
|
||||||
|
*
|
||||||
|
* When using RGB displays the display buffer size will also depends on the
|
||||||
|
* color format being used, for RGB565 each pixel needs 2 bytes.
|
||||||
|
* When using the mono theme, the display pixels can be represented in one bit,
|
||||||
|
* so the buffer size can be divided by 8, e.g. see SSD1306 display size. */
|
||||||
|
size_t lvgl_get_display_buffer_size(void)
|
||||||
|
{
|
||||||
|
size_t disp_buffer_size = 0;
|
||||||
|
|
||||||
|
#if LVGL_VERSION_MAJOR < 8
|
||||||
|
#if defined (CONFIG_CUSTOM_DISPLAY_BUFFER_SIZE)
|
||||||
|
disp_buffer_size = CONFIG_CUSTOM_DISPLAY_BUFFER_BYTES;
|
||||||
|
#else
|
||||||
|
/* Calculate total of 40 lines of display horizontal size */
|
||||||
|
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_GC9A01) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C)
|
||||||
|
disp_buffer_size = LV_HOR_RES_MAX * 40;
|
||||||
|
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107
|
||||||
|
disp_buffer_size = LV_HOR_RES_MAX * LV_VER_RES_MAX;
|
||||||
|
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306
|
||||||
|
#if defined (CONFIG_LV_THEME_MONO)
|
||||||
|
disp_buffer_size = LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8);
|
||||||
|
#else
|
||||||
|
disp_buffer_size = LV_HOR_RES_MAX * LV_VER_RES_MAX);
|
||||||
|
#endif
|
||||||
|
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820)
|
||||||
|
disp_buffer_size = LV_VER_RES_MAX * IL3820_COLUMNS;
|
||||||
|
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A)
|
||||||
|
disp_buffer_size = ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8); // 5KB
|
||||||
|
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D)
|
||||||
|
disp_buffer_size = ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8); // 2888 bytes
|
||||||
|
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544)
|
||||||
|
disp_buffer_size = (LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8));
|
||||||
|
#else
|
||||||
|
#error "No display controller selected"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* LVGL v8 */
|
||||||
|
/* ToDo: Implement display buffer size calculation with configuration values from the display driver */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return disp_buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize spi bus master
|
/* Initialize spi bus master
|
||||||
*
|
*
|
||||||
|
@ -154,34 +267,17 @@ bool lvgl_spi_driver_init(int host,
|
||||||
int dma_channel,
|
int dma_channel,
|
||||||
int quadwp_pin, int quadhd_pin)
|
int quadwp_pin, int quadhd_pin)
|
||||||
{
|
{
|
||||||
int dma_chan = 0 /* SPI_DMA_DISABLED */;
|
#if defined (SPI_HOST_MAX)
|
||||||
|
assert((SPI1_HOST <= host) && (SPI_HOST_MAX > host));
|
||||||
|
#else
|
||||||
|
assert((SPI1_HOST <= host) && ((SPI3_HOST + 1) > host));
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined (CONFIG_IDF_TARGET_ESP32)
|
|
||||||
assert((SPI_HOST <= host) && (VSPI_HOST >= host));
|
|
||||||
const char *spi_names[] = {
|
|
||||||
"SPI_HOST", "HSPI_HOST", "VSPI_HOST"
|
|
||||||
};
|
|
||||||
|
|
||||||
dma_chan = dma_channel;
|
|
||||||
#elif defined (CONFIG_IDF_TARGET_ESP32S2)
|
|
||||||
assert((SPI_HOST <= host) && (HSPI_HOST >= host));
|
|
||||||
const char *spi_names[] = {
|
|
||||||
"SPI_HOST", "", ""
|
|
||||||
};
|
|
||||||
|
|
||||||
dma_chan = dma_channel;
|
|
||||||
#elif defined (CONFIG_IDF_TARGET_ESP32C3)
|
|
||||||
assert((SPI1_HOST <= host) && (SPI3_HOST >= host));
|
|
||||||
const char *spi_names[] = {
|
const char *spi_names[] = {
|
||||||
"SPI1_HOST", "SPI2_HOST", "SPI3_HOST"
|
"SPI1_HOST", "SPI2_HOST", "SPI3_HOST"
|
||||||
};
|
};
|
||||||
|
|
||||||
dma_chan = 3 /* SPI_DMA_CH_AUTO */;
|
ESP_LOGI(TAG, "Configuring SPI host %s", spi_names[host]);
|
||||||
#else
|
|
||||||
#error "Target chip not selected"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Configuring SPI host %s (%d)", spi_names[host], host);
|
|
||||||
ESP_LOGI(TAG, "MISO pin: %d, MOSI pin: %d, SCLK pin: %d, IO2/WP pin: %d, IO3/HD pin: %d",
|
ESP_LOGI(TAG, "MISO pin: %d, MOSI pin: %d, SCLK pin: %d, IO2/WP pin: %d, IO3/HD pin: %d",
|
||||||
miso_pin, mosi_pin, sclk_pin, quadwp_pin, quadhd_pin);
|
miso_pin, mosi_pin, sclk_pin, quadwp_pin, quadhd_pin);
|
||||||
|
|
||||||
|
@ -197,9 +293,55 @@ bool lvgl_spi_driver_init(int host,
|
||||||
};
|
};
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Initializing SPI bus...");
|
ESP_LOGI(TAG, "Initializing SPI bus...");
|
||||||
esp_err_t ret = spi_bus_initialize(host, &buscfg, dma_chan);
|
|
||||||
|
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0)
|
||||||
|
esp_err_t ret = spi_bus_initialize((spi_host_device_t) host, &buscfg, (spi_dma_chan_t)dma_channel);
|
||||||
|
#else
|
||||||
|
esp_err_t ret = spi_bus_initialize(host, &buscfg, dma_channel);
|
||||||
|
#endif
|
||||||
|
|
||||||
assert(ret == ESP_OK);
|
assert(ret == ESP_OK);
|
||||||
|
|
||||||
return ESP_OK != ret;
|
return ESP_OK != ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int calculate_spi_max_transfer_size(const int display_buffer_size)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488)
|
||||||
|
retval = display_buffer_size * 3;
|
||||||
|
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A) || \
|
||||||
|
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C)
|
||||||
|
retval = display_buffer_size * 2;
|
||||||
|
#else
|
||||||
|
retval = display_buffer_size * 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
|
||||||
|
static void init_ft81x(int dma_channel)
|
||||||
|
{
|
||||||
|
size_t display_buffer_size = lvgl_get_display_buffer_size();
|
||||||
|
int spi_max_transfer_size = calculate_spi_max_transfer_size(display_buffer_size);
|
||||||
|
|
||||||
|
lvgl_spi_driver_init(TFT_SPI_HOST, DISP_SPI_MISO, DISP_SPI_MOSI, DISP_SPI_CLK,
|
||||||
|
spi_max_transfer_size, dma_channel, DISP_SPI_IO2, DISP_SPI_IO3);
|
||||||
|
|
||||||
|
disp_spi_add_device(TFT_SPI_HOST);
|
||||||
|
|
||||||
|
#if defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
|
||||||
|
touch_driver_init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -23,66 +23,6 @@ extern "C" {
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
|
|
||||||
/* DISP_BUF_SIZE value doesn't have an special meaning, but it's the size
|
|
||||||
* of the buffer(s) passed to LVGL as display buffers. The default values used
|
|
||||||
* were the values working for the contributor of the display controller.
|
|
||||||
*
|
|
||||||
* As LVGL supports partial display updates the DISP_BUF_SIZE doesn't
|
|
||||||
* necessarily need to be equal to the display size.
|
|
||||||
*
|
|
||||||
* When using RGB displays the display buffer size will also depends on the
|
|
||||||
* color format being used, for RGB565 each pixel needs 2 bytes.
|
|
||||||
* When using the mono theme, the display pixels can be represented in one bit,
|
|
||||||
* so the buffer size can be divided by 8, e.g. see SSD1306 display size. */
|
|
||||||
#if defined (CONFIG_CUSTOM_DISPLAY_BUFFER_SIZE)
|
|
||||||
#define DISP_BUF_SIZE CONFIG_CUSTOM_DISPLAY_BUFFER_BYTES
|
|
||||||
#else
|
|
||||||
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789)
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX)
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306
|
|
||||||
#if defined (CONFIG_LV_THEME_MONO)
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8))
|
|
||||||
#else
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX)
|
|
||||||
#endif
|
|
||||||
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
|
|
||||||
#define DISP_BUF_LINES 40
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * DISP_BUF_LINES)
|
|
||||||
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820)
|
|
||||||
#define DISP_BUF_SIZE (LV_VER_RES_MAX * IL3820_COLUMNS)
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_GC9A01)
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A)
|
|
||||||
#define DISP_BUF_SIZE ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8) // 5KB
|
|
||||||
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D)
|
|
||||||
#define DISP_BUF_SIZE ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8) // 2888 bytes
|
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
|
|
||||||
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544)
|
|
||||||
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * (LV_VER_RES_MAX / 8))
|
|
||||||
#else
|
|
||||||
#error "No display controller selected"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -94,12 +34,18 @@ extern "C" {
|
||||||
void lvgl_i2c_locking(void* leader);
|
void lvgl_i2c_locking(void* leader);
|
||||||
|
|
||||||
/* Initialize detected SPI and I2C bus and devices */
|
/* Initialize detected SPI and I2C bus and devices */
|
||||||
void lvgl_driver_init(void);
|
void lvgl_interface_init(void);
|
||||||
|
|
||||||
/* Initialize SPI master */
|
/* Initialize SPI master */
|
||||||
bool lvgl_spi_driver_init(int host, int miso_pin, int mosi_pin, int sclk_pin,
|
bool lvgl_spi_driver_init(int host, int miso_pin, int mosi_pin, int sclk_pin,
|
||||||
int max_transfer_sz, int dma_channel, int quadwp_pin, int quadhd_pin);
|
int max_transfer_sz, int dma_channel, int quadwp_pin, int quadhd_pin);
|
||||||
|
|
||||||
|
/* Initialize display GPIOs, e.g. DC and RST pins */
|
||||||
|
void lvgl_display_gpios_init(void);
|
||||||
|
|
||||||
|
/* Get display buffer size */
|
||||||
|
size_t lvgl_get_display_buffer_size(void);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#ifndef LVGL_SPI_CONF_H
|
#ifndef LVGL_SPI_CONF_H
|
||||||
#define LVGL_SPI_CONF_H
|
#define LVGL_SPI_CONF_H
|
||||||
|
|
||||||
|
#include <sdkconfig.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,25 +20,32 @@ extern "C" {
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
// DISPLAY PINS
|
// DISPLAY PINS
|
||||||
|
|
||||||
|
/* Mandatory pins are MOSI and CLK */
|
||||||
#define DISP_SPI_MOSI CONFIG_LV_DISP_SPI_MOSI
|
#define DISP_SPI_MOSI CONFIG_LV_DISP_SPI_MOSI
|
||||||
|
#define DISP_SPI_CLK CONFIG_LV_DISP_SPI_CLK
|
||||||
|
|
||||||
|
/* Optional pins */
|
||||||
#if defined (CONFIG_LV_DISPLAY_USE_SPI_MISO)
|
#if defined (CONFIG_LV_DISPLAY_USE_SPI_MISO)
|
||||||
#define DISP_SPI_MISO CONFIG_LV_DISP_SPI_MISO
|
#define DISP_SPI_MISO CONFIG_LV_DISP_SPI_MISO
|
||||||
#define DISP_SPI_INPUT_DELAY_NS CONFIG_LV_DISP_SPI_INPUT_DELAY_NS
|
#define DISP_SPI_INPUT_DELAY_NS CONFIG_LV_DISP_SPI_INPUT_DELAY_NS
|
||||||
#else
|
#else
|
||||||
#define DISP_SPI_MISO (-1)
|
#define DISP_SPI_MISO (-1)
|
||||||
#define DISP_SPI_INPUT_DELAY_NS (0)
|
#define DISP_SPI_INPUT_DELAY_NS (0U)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_LV_DISP_SPI_IO2)
|
#if defined(CONFIG_LV_DISP_SPI_IO2)
|
||||||
#define DISP_SPI_IO2 CONFIG_LV_DISP_SPI_IO2
|
#define DISP_SPI_IO2 CONFIG_LV_DISP_SPI_IO2
|
||||||
#else
|
#else
|
||||||
#define DISP_SPI_IO2 (-1)
|
#define DISP_SPI_IO2 (-1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_LV_DISP_SPI_IO3)
|
#if defined(CONFIG_LV_DISP_SPI_IO3)
|
||||||
#define DISP_SPI_IO3 CONFIG_LV_DISP_SPI_IO3
|
#define DISP_SPI_IO3 CONFIG_LV_DISP_SPI_IO3
|
||||||
#else
|
#else
|
||||||
#define DISP_SPI_IO3 (-1)
|
#define DISP_SPI_IO3 (-1)
|
||||||
#endif
|
#endif
|
||||||
#define DISP_SPI_CLK CONFIG_LV_DISP_SPI_CLK
|
|
||||||
#if defined (CONFIG_LV_DISPLAY_USE_SPI_CS)
|
#if defined (CONFIG_LV_DISPLAY_USE_SPI_CS)
|
||||||
#define DISP_SPI_CS CONFIG_LV_DISP_SPI_CS
|
#define DISP_SPI_CS CONFIG_LV_DISP_SPI_CS
|
||||||
#else
|
#else
|
||||||
|
@ -50,6 +59,8 @@ extern "C" {
|
||||||
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) && \
|
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) && \
|
||||||
defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
|
defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
|
||||||
|
|
||||||
|
#define SHARED_SPI_BUS
|
||||||
|
|
||||||
#define TP_SPI_MOSI CONFIG_LV_DISP_SPI_MOSI
|
#define TP_SPI_MOSI CONFIG_LV_DISP_SPI_MOSI
|
||||||
#define TP_SPI_MISO CONFIG_LV_DISP_SPI_MISO
|
#define TP_SPI_MISO CONFIG_LV_DISP_SPI_MISO
|
||||||
#define TP_SPI_CLK CONFIG_LV_DISP_SPI_CLK
|
#define TP_SPI_CLK CONFIG_LV_DISP_SPI_CLK
|
||||||
|
@ -64,12 +75,22 @@ extern "C" {
|
||||||
|
|
||||||
#define ENABLE_TOUCH_INPUT CONFIG_LV_ENABLE_TOUCH
|
#define ENABLE_TOUCH_INPUT CONFIG_LV_ENABLE_TOUCH
|
||||||
|
|
||||||
#if defined (CONFIG_LV_TFT_DISPLAY_SPI1_HOST)
|
#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI)
|
||||||
#define TFT_SPI_HOST SPI1_HOST
|
/* Display controller SPI host configuration */
|
||||||
#elif defined (CONFIG_LV_TFT_DISPLAY_SPI2_HOST)
|
#if defined (CONFIG_LV_TFT_DISPLAY_SPI2_HOST)
|
||||||
#define TFT_SPI_HOST SPI2_HOST
|
#define TFT_SPI_HOST SPI2_HOST
|
||||||
#elif defined (CONFIG_LV_TFT_DISPLAY_SPI3_HOST)
|
#elif defined (CONFIG_LV_TFT_DISPLAY_SPI3_HOST)
|
||||||
#define TFT_SPI_HOST SPI3_HOST
|
#define TFT_SPI_HOST SPI3_HOST
|
||||||
|
#else
|
||||||
|
#error SPI host not defined
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Touch controller SPI host configuration */
|
||||||
|
#if defined (CONFIG_LV_TOUCH_CONTROLLER_SPI2_HOST)
|
||||||
|
#define TOUCH_SPI_HOST SPI2_HOST
|
||||||
|
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_SPI3_HOST)
|
||||||
|
#define TOUCH_SPI_HOST SPI3_HOST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (CONFIG_LV_TFT_DISPLAY_SPI_HALF_DUPLEX)
|
#if defined (CONFIG_LV_TFT_DISPLAY_SPI_HALF_DUPLEX)
|
||||||
|
@ -86,59 +107,30 @@ extern "C" {
|
||||||
#define DISP_SPI_TRANS_MODE_SIO
|
#define DISP_SPI_TRANS_MODE_SIO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (CONFIG_LV_TOUCH_CONTROLLER_SPI_HSPI)
|
/* Detect usage of shared SPI bus between display and indev controllers
|
||||||
#define TOUCH_SPI_HOST HSPI_HOST
|
*
|
||||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_SPI_VSPI)
|
* If the user sets the same MOSI and CLK pins for both display and indev
|
||||||
#define TOUCH_SPI_HOST VSPI_HOST
|
* controllers then we can assume the user is using the same SPI bus
|
||||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_SPI_FSPI)
|
* If so verify the user specified the same SPI bus for both */
|
||||||
#define TOUCH_SPI_HOST FSPI_HOST
|
#if !defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Handle the FT81X Special case */
|
#if defined (CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI) && \
|
||||||
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X)
|
(CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI == 1) && \
|
||||||
|
defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI) && \
|
||||||
|
(TP_SPI_MOSI == DISP_SPI_MOSI) && (TP_SPI_CLK == DISP_SPI_CLK)
|
||||||
|
|
||||||
#if defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
|
|
||||||
#define SHARED_SPI_BUS
|
|
||||||
#else
|
|
||||||
/* Empty */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
// Detect the use of a shared SPI Bus and verify the user specified the same SPI bus for both touch and tft
|
|
||||||
#if defined (CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI) && TP_SPI_MOSI == DISP_SPI_MOSI && TP_SPI_CLK == DISP_SPI_CLK
|
|
||||||
#if TFT_SPI_HOST != TOUCH_SPI_HOST
|
#if TFT_SPI_HOST != TOUCH_SPI_HOST
|
||||||
#error You must specify the same SPI host (HSPI, VSPI or FSPI) for both display and touch driver
|
#error You must specify the same SPI host (SPIx_HOST) for both display and touch driver
|
||||||
#endif
|
#else
|
||||||
|
|
||||||
#define SHARED_SPI_BUS
|
#define SHARED_SPI_BUS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481) || \
|
|
||||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488)
|
|
||||||
|
|
||||||
#define SPI_BUS_MAX_TRANSFER_SZ (DISP_BUF_SIZE * 3)
|
|
||||||
|
|
||||||
#elif defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341) || \
|
|
||||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789) || \
|
|
||||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S) || \
|
|
||||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357) || \
|
|
||||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107) || \
|
|
||||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_FT81X) || \
|
|
||||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820) || \
|
|
||||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A) || \
|
|
||||||
defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C)
|
|
||||||
|
|
||||||
#define SPI_BUS_MAX_TRANSFER_SZ (DISP_BUF_SIZE * 2)
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define SPI_BUS_MAX_TRANSFER_SZ (DISP_BUF_SIZE * 2)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (CONFIG_LV_TFT_USE_CUSTOM_SPI_CLK_DIVIDER)
|
#if defined (CONFIG_LV_TFT_USE_CUSTOM_SPI_CLK_DIVIDER)
|
||||||
#define SPI_TFT_CLOCK_SPEED_HZ ((80 * 1000 * 1000) / CONFIG_LV_TFT_CUSTOM_SPI_CLK_DIVIDER)
|
#define SPI_TFT_CLOCK_SPEED_HZ ((80 * 1000 * 1000) / CONFIG_LV_TFT_CUSTOM_SPI_CLK_DIVIDER)
|
||||||
#else
|
#else
|
||||||
|
@ -168,22 +160,21 @@ extern "C" {
|
||||||
#define SPI_TFT_CLOCK_SPEED_HZ (40*1000*1000)
|
#define SPI_TFT_CLOCK_SPEED_HZ (40*1000*1000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif /* CONFIG_LV_TFT_USE_CUSTOM_SPI_CLK_DIVIDER */
|
||||||
|
|
||||||
|
|
||||||
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789)
|
#if defined (CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789)
|
||||||
#define SPI_TFT_SPI_MODE (2)
|
#define SPI_TFT_SPI_MODE (2U)
|
||||||
#else
|
#else
|
||||||
#define SPI_TFT_SPI_MODE (0)
|
#define SPI_TFT_SPI_MODE (0U)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Touch driver */
|
/* Touch driver */
|
||||||
#if (CONFIG_LV_TOUCH_CONTROLLER == TOUCH_CONTROLLER_STMPE610)
|
#if (CONFIG_LV_TOUCH_CONTROLLER == TOUCH_CONTROLLER_STMPE610)
|
||||||
#define SPI_TOUCH_CLOCK_SPEED_HZ (1*1000*1000)
|
#define SPI_TOUCH_CLOCK_SPEED_HZ (1*1000*1000)
|
||||||
#define SPI_TOUCH_SPI_MODE (1)
|
#define SPI_TOUCH_SPI_MODE (1U)
|
||||||
#else
|
#else
|
||||||
#define SPI_TOUCH_CLOCK_SPEED_HZ (2*1000*1000)
|
#define SPI_TOUCH_CLOCK_SPEED_HZ (2*1000*1000)
|
||||||
#define SPI_TOUCH_SPI_MODE (0)
|
#define SPI_TOUCH_SPI_MODE (0U)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
|
|
@ -41,6 +41,11 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined (BT81X_ENABLE)
|
||||||
|
#include <stdarg.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "EVE.h"
|
#include "EVE.h"
|
||||||
#include "EVE_commands.h"
|
#include "EVE_commands.h"
|
||||||
|
@ -50,19 +55,8 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "soc/soc_memory_layout.h"
|
#include "soc/soc_memory_layout.h"
|
||||||
|
|
||||||
#include "esp_log.h"
|
|
||||||
|
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#if defined (BT81X_ENABLE)
|
|
||||||
#include <stdarg.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TAG_LOG "FT81X"
|
|
||||||
|
|
||||||
/* data structure for SPI reading that has (optional) space for inserted dummy byte */
|
/* data structure for SPI reading that has (optional) space for inserted dummy byte */
|
||||||
typedef struct _spi_read_data {
|
typedef struct _spi_read_data {
|
||||||
#if defined(DISP_SPI_FULL_DUPLEX)
|
#if defined(DISP_SPI_FULL_DUPLEX)
|
||||||
|
@ -273,7 +267,13 @@ void EVE_memWrite_buffer(uint32_t ftAddress, const uint8_t *data, uint32_t len,
|
||||||
uint32_t bytes_left = len;
|
uint32_t bytes_left = len;
|
||||||
while(bytes_left > 0)
|
while(bytes_left > 0)
|
||||||
{
|
{
|
||||||
uint32_t block_len = (bytes_left > SPI_TRANSER_SIZE ? SPI_TRANSER_SIZE : bytes_left);
|
uint32_t block_len = 0;
|
||||||
|
|
||||||
|
#if defined (SPI_TRANSFER_SIZE)
|
||||||
|
block_len = (bytes_left > SPI_TRANSER_SIZE ? SPI_TRANSER_SIZE : bytes_left);
|
||||||
|
#else
|
||||||
|
/* ToDo Update SPI_TRANSFER_SIZE calculation, it's based on the DISP_BUF_SIZE */
|
||||||
|
#endif
|
||||||
|
|
||||||
// only send flush on last chunk
|
// only send flush on last chunk
|
||||||
disp_spi_send_flag_t flush_flag = 0;
|
disp_spi_send_flag_t flush_flag = 0;
|
||||||
|
@ -334,7 +334,6 @@ uint8_t EVE_busy(void)
|
||||||
|
|
||||||
cmdOffset += 8;
|
cmdOffset += 8;
|
||||||
|
|
||||||
BUFFER_SPI_BYTE
|
|
||||||
BUFFER_SPI_BYTE(MEM_WRITE | 0x30); /* send Memory Write plus high address byte of REG_CMD_WRITE for EVE81x */
|
BUFFER_SPI_BYTE(MEM_WRITE | 0x30); /* send Memory Write plus high address byte of REG_CMD_WRITE for EVE81x */
|
||||||
BUFFER_SPI_BYTE(0x20); /* send middle address byte of REG_CMD_WRITE for EVE81x */
|
BUFFER_SPI_BYTE(0x20); /* send middle address byte of REG_CMD_WRITE for EVE81x */
|
||||||
BUFFER_SPI_BYTE(0xfc); /* send low address byte of REG_CMD_WRITE for EVE81x */
|
BUFFER_SPI_BYTE(0xfc); /* send low address byte of REG_CMD_WRITE for EVE81x */
|
||||||
|
@ -875,13 +874,13 @@ uint8_t EVE_init(void)
|
||||||
|
|
||||||
/* The most reliable DIO/QIO switching point is after EVE start up but before reading the ChipID. */
|
/* The most reliable DIO/QIO switching point is after EVE start up but before reading the ChipID. */
|
||||||
#if defined(DISP_SPI_TRANS_MODE_DIO)
|
#if defined(DISP_SPI_TRANS_MODE_DIO)
|
||||||
ESP_LOGI(TAG_LOG, "Switching to DIO mode");
|
LV_LOG_INFO("Switching to DIO mode");
|
||||||
DELAY_MS(20); /* different boards may take a different delay but this generally seems to work */
|
DELAY_MS(20); /* different boards may take a different delay but this generally seems to work */
|
||||||
EVE_memWrite16(REG_SPI_WIDTH, SPI_WIDTH_DIO);
|
EVE_memWrite16(REG_SPI_WIDTH, SPI_WIDTH_DIO);
|
||||||
SPIInherentSendFlags = DISP_SPI_MODE_DIO | DISP_SPI_MODE_DIOQIO_ADDR;
|
SPIInherentSendFlags = DISP_SPI_MODE_DIO | DISP_SPI_MODE_DIOQIO_ADDR;
|
||||||
SPIDummyReadBits = 4; /* Esp32 DMA SPI transaction dummy_bits works more like clock cycles, so in DIO 4 dummy_bits == 8 total bits */
|
SPIDummyReadBits = 4; /* Esp32 DMA SPI transaction dummy_bits works more like clock cycles, so in DIO 4 dummy_bits == 8 total bits */
|
||||||
#elif defined(DISP_SPI_TRANS_MODE_QIO)
|
#elif defined(DISP_SPI_TRANS_MODE_QIO)
|
||||||
ESP_LOGI(TAG_LOG, "Switching to QIO mode");
|
LV_LOG_INFO("Switching to QIO mode");
|
||||||
DELAY_MS(20); /* different boards may take a different delay but this generally seems to work */
|
DELAY_MS(20); /* different boards may take a different delay but this generally seems to work */
|
||||||
EVE_memWrite16(REG_SPI_WIDTH, SPI_WIDTH_QIO);
|
EVE_memWrite16(REG_SPI_WIDTH, SPI_WIDTH_QIO);
|
||||||
SPIInherentSendFlags = DISP_SPI_MODE_QIO | DISP_SPI_MODE_DIOQIO_ADDR;
|
SPIInherentSendFlags = DISP_SPI_MODE_QIO | DISP_SPI_MODE_DIOQIO_ADDR;
|
||||||
|
@ -897,7 +896,7 @@ uint8_t EVE_init(void)
|
||||||
timeout++;
|
timeout++;
|
||||||
if(timeout > 400)
|
if(timeout > 400)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG_LOG, "Failed to read ChipID...aborting initialization.");
|
LV_LOG_WARN("Failed to read ChipID...aborting initialization.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -909,7 +908,7 @@ uint8_t EVE_init(void)
|
||||||
timeout++;
|
timeout++;
|
||||||
if(timeout > 50) /* experimental, 10 was the lowest value to get the BT815 started with, the touch-controller was the last to get out of reset */
|
if(timeout > 50) /* experimental, 10 was the lowest value to get the BT815 started with, the touch-controller was the last to get out of reset */
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG_LOG, "Failed to read CPU status...aborting initialization.");
|
LV_LOG_WARN("Failed to read CPU status...aborting initialization.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,11 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
#define EVE_PDN CONFIG_LV_DISP_PIN_RST // grey
|
#define EVE_PDN CONFIG_LV_DISP_PIN_RST // grey
|
||||||
#define EVE_USE_PDN CONFIG_LV_DISP_USE_RST
|
#define EVE_USE_PDN CONFIG_LV_DISP_USE_RST
|
||||||
|
|
||||||
|
#if defined (DISP_BUF_SIZE)
|
||||||
#define SPI_TRANSER_SIZE (DISP_BUF_SIZE * (LV_COLOR_DEPTH / 8))
|
#define SPI_TRANSER_SIZE (DISP_BUF_SIZE * (LV_COLOR_DEPTH / 8))
|
||||||
|
#else
|
||||||
|
/* ToDo Update using new API */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BYTES_PER_PIXEL (LV_COLOR_DEPTH / 8) // bytes per pixel for (16 for RGB565)
|
#define BYTES_PER_PIXEL (LV_COLOR_DEPTH / 8) // bytes per pixel for (16 for RGB565)
|
||||||
#define BYTES_PER_LINE (EVE_HSIZE * BYTES_PER_PIXEL)
|
#define BYTES_PER_LINE (EVE_HSIZE * BYTES_PER_PIXEL)
|
||||||
|
@ -208,6 +212,8 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
#define EVE_SUNFLOWER
|
#define EVE_SUNFLOWER
|
||||||
#elif defined(CONFIG_LV_FT81X_CONFIG_EVE_CONNECTEVE)
|
#elif defined(CONFIG_LV_FT81X_CONFIG_EVE_CONNECTEVE)
|
||||||
#define EVE_CONNECTEVE
|
#define EVE_CONNECTEVE
|
||||||
|
#else
|
||||||
|
#define EVE_EVE2_35 // Define something if there is no Kconfig option selected
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* display timing parameters below */
|
/* display timing parameters below */
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "GC9A01"
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
|
@ -37,6 +36,7 @@ static void GC9A01_set_orientation(uint8_t orientation);
|
||||||
static void GC9A01_send_cmd(uint8_t cmd);
|
static void GC9A01_send_cmd(uint8_t cmd);
|
||||||
static void GC9A01_send_data(void * data, uint16_t length);
|
static void GC9A01_send_data(void * data, uint16_t length);
|
||||||
static void GC9A01_send_color(void * data, uint16_t length);
|
static void GC9A01_send_color(void * data, uint16_t length);
|
||||||
|
static void GC9A01_reset(void);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
|
@ -111,22 +111,9 @@ void GC9A01_init(void)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Initialize non-SPI GPIOs
|
GC9A01_reset();
|
||||||
gpio_pad_select_gpio(GC9A01_DC);
|
|
||||||
gpio_set_direction(GC9A01_DC, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
#if GC9A01_USE_RST
|
LV_LOG_INFO("Initialization.");
|
||||||
gpio_pad_select_gpio(GC9A01_RST);
|
|
||||||
gpio_set_direction(GC9A01_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
gpio_set_level(GC9A01_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(GC9A01_RST, 1);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Initialization.");
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
|
@ -220,24 +207,36 @@ static void GC9A01_send_color(void * data, uint16_t length)
|
||||||
|
|
||||||
static void GC9A01_set_orientation(uint8_t orientation)
|
static void GC9A01_set_orientation(uint8_t orientation)
|
||||||
{
|
{
|
||||||
// ESP_ASSERT(orientation < 4);
|
assert(orientation < 4);
|
||||||
|
|
||||||
|
#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK
|
||||||
|
const uint8_t data[] = {0x68, 0x68, 0x08, 0x08};
|
||||||
|
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_WROVER4)
|
||||||
|
const uint8_t data[] = {0x4C, 0x88, 0x28, 0xE8};
|
||||||
|
#else
|
||||||
|
const uint8_t data[] = {0x08, 0xC8, 0x68, 0xA8};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (LV_USE_LOG == 1)
|
||||||
const char *orientation_str[] = {
|
const char *orientation_str[] = {
|
||||||
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
||||||
};
|
};
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]);
|
LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]);
|
||||||
|
LV_LOG_INFO("0x36 command value: 0x%02X", data[orientation]);
|
||||||
#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK
|
|
||||||
uint8_t data[] = {0x68, 0x68, 0x08, 0x08}; ///
|
|
||||||
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_WROVER4)
|
|
||||||
uint8_t data[] = {0x4C, 0x88, 0x28, 0xE8}; ///
|
|
||||||
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE)
|
|
||||||
uint8_t data[] = {0x08, 0xC8, 0x68, 0xA8}; ///ggggg
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]);
|
|
||||||
|
|
||||||
GC9A01_send_cmd(0x36);
|
GC9A01_send_cmd(0x36);
|
||||||
GC9A01_send_data((void *) &data[orientation], 1);
|
GC9A01_send_data((void *) &data[orientation], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GC9A01_reset(void)
|
||||||
|
{
|
||||||
|
#if GC9A01_USE_RST
|
||||||
|
//Reset the display
|
||||||
|
gpio_set_level(GC9A01_RST, 0);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
gpio_set_level(GC9A01_RST, 1);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -226,15 +226,15 @@ menu "LVGL TFT Display controller"
|
||||||
config LV_TFT_DISPLAY_X_OFFSET
|
config LV_TFT_DISPLAY_X_OFFSET
|
||||||
depends on LV_TFT_DISPLAY_OFFSETS
|
depends on LV_TFT_DISPLAY_OFFSETS
|
||||||
int "X offset"
|
int "X offset"
|
||||||
default 40 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
|
default 40 if LV_PREDEFINED_DISPLAY_TTGO && (DISPLAY_ORIENTATION_LANDSCAPE || DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
|
||||||
default 53 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
default 53 if LV_PREDEFINED_DISPLAY_TTGO && (DISPLAY_ORIENTATION_PORTRAIT || DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
||||||
default 0
|
default 0
|
||||||
|
|
||||||
config LV_TFT_DISPLAY_Y_OFFSET
|
config LV_TFT_DISPLAY_Y_OFFSET
|
||||||
depends on LV_TFT_DISPLAY_OFFSETS
|
depends on LV_TFT_DISPLAY_OFFSETS
|
||||||
int "Y offset"
|
int "Y offset"
|
||||||
default 53 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
|
default 53 if LV_PREDEFINED_DISPLAY_TTGO && (DISPLAY_ORIENTATION_LANDSCAPE || DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
|
||||||
default 40 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
default 40 if LV_PREDEFINED_DISPLAY_TTGO && (DISPLAY_ORIENTATION_PORTRAIT || DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
||||||
default 0
|
default 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -469,17 +469,15 @@ menu "LVGL TFT Display controller"
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "TFT SPI Bus." if LV_TFT_DISPLAY_PROTOCOL_SPI
|
prompt "TFT SPI Bus." if LV_TFT_DISPLAY_PROTOCOL_SPI
|
||||||
default LV_TFT_DISPLAY_SPI3_HOST if LV_PREDEFINED_DISPLAY_TTGO && \
|
default LV_TFT_DISPLAY_SPI2_HOST if LV_PREDEFINED_DISPLAY_TTGO
|
||||||
!IDF_TARGET_ESP32S2
|
default LV_TFT_DISPLAY_SPI3_HOST if !LV_PREDEFINED_DISPLAY_TTGO
|
||||||
help
|
|
||||||
Select the SPI Bus the TFT Display is attached to.
|
|
||||||
|
|
||||||
config LV_TFT_DISPLAY_SPI1_HOST
|
|
||||||
bool "SPI1_HOST"
|
|
||||||
config LV_TFT_DISPLAY_SPI2_HOST
|
config LV_TFT_DISPLAY_SPI2_HOST
|
||||||
bool "SPI2_HOST"
|
bool "SPI2_HOST"
|
||||||
config LV_TFT_DISPLAY_SPI3_HOST
|
config LV_TFT_DISPLAY_SPI3_HOST
|
||||||
bool "SPI3_HOST"
|
bool "SPI3_HOST" if !IDF_TARGET_ESP32C3
|
||||||
|
help
|
||||||
|
Select the SPI Bus the TFT Display is attached to.
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
choice
|
choice
|
||||||
|
@ -909,6 +907,13 @@ menu "LVGL TFT Display controller"
|
||||||
help
|
help
|
||||||
Configure the display Reset pin here.
|
Configure the display Reset pin here.
|
||||||
|
|
||||||
|
config LV_DISP_USE_BUSY
|
||||||
|
bool "Use a GPIO for busy signal" if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
||||||
|
default y if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Use a GPIO for busy signal available in e-ink display controllers.
|
||||||
|
|
||||||
config LV_DISP_PIN_BUSY
|
config LV_DISP_PIN_BUSY
|
||||||
int "GPIO for Busy" if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
int "GPIO for Busy" if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
||||||
default 35 if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
default 35 if LV_TFT_DISPLAY_CONTROLLER_IL3820 || LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D
|
||||||
|
@ -1011,6 +1016,3 @@ menu "LVGL TFT Display controller"
|
||||||
default 0
|
default 0
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,16 @@
|
||||||
#include "esp_lcd_backlight.h"
|
#include "esp_lcd_backlight.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
void *disp_driver_init(void)
|
void *disp_driver_init(lv_disp_drv_t *drv)
|
||||||
{
|
{
|
||||||
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341
|
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341
|
||||||
ili9341_init();
|
ili9341_init(drv);
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481
|
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481
|
||||||
ili9481_init();
|
ili9481_init();
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
|
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
|
||||||
ili9488_init();
|
ili9488_init(drv);
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789
|
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7789
|
||||||
st7789_init();
|
st7789_init(drv);
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S
|
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7796S
|
||||||
st7796s_init();
|
st7796s_init();
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S
|
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ST7735S
|
||||||
|
@ -44,9 +44,14 @@ void *disp_driver_init(void)
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C
|
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9163C
|
||||||
ili9163c_init();
|
ili9163c_init();
|
||||||
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544
|
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_PCD8544
|
||||||
pcd8544_init();
|
pcd8544_init(drv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return disp_backlight_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void *disp_backlight_init(void)
|
||||||
|
{
|
||||||
// We still use menuconfig for these settings
|
// We still use menuconfig for these settings
|
||||||
// It will be set up during runtime in the future
|
// It will be set up during runtime in the future
|
||||||
#if (defined(CONFIG_LV_DISP_BACKLIGHT_SWITCH) || defined(CONFIG_LV_DISP_BACKLIGHT_PWM))
|
#if (defined(CONFIG_LV_DISP_BACKLIGHT_SWITCH) || defined(CONFIG_LV_DISP_BACKLIGHT_PWM))
|
||||||
|
|
|
@ -69,7 +69,7 @@ extern "C" {
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
/* Initialize display */
|
/* Initialize display */
|
||||||
void *disp_driver_init(void);
|
void *disp_driver_init(lv_disp_drv_t *drv);
|
||||||
|
|
||||||
/* Display flush callback */
|
/* Display flush callback */
|
||||||
void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
||||||
|
@ -81,6 +81,8 @@ void disp_driver_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area);
|
||||||
void disp_driver_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
void disp_driver_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||||
lv_color_t color, lv_opa_t opa);
|
lv_color_t color, lv_opa_t opa);
|
||||||
|
|
||||||
|
/* Display backlight configuration */
|
||||||
|
void *disp_backlight_init(void);
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
95
lvgl_tft/display_port.h
Normal file
95
lvgl_tft/display_port.h
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
#ifndef DISPLAY_PORT_H_
|
||||||
|
#define DISPLAY_PORT_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
|
#include "lvgl.h"
|
||||||
|
#else
|
||||||
|
#include "lvgl/lvgl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define CMD_WITHOUT_ARGS NULL
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CMD_WIDTH_8BITS,
|
||||||
|
CMD_WIDTH_16BITS,
|
||||||
|
CMD_WIDTH_INVALID,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef uint8_t cmd_width_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Busy wait delay port
|
||||||
|
*
|
||||||
|
* @param drv Pointer to driver See @ref lv_disp_drv_t
|
||||||
|
* @param delay_ms Delay duration in milliseconds
|
||||||
|
*/
|
||||||
|
void display_port_delay(lv_disp_drv_t *drv, uint32_t delay_ms);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backlight control port
|
||||||
|
*
|
||||||
|
* @param drv Pointer to driver See @ref lv_disp_drv_t
|
||||||
|
* @param state State of the backlight signal
|
||||||
|
*/
|
||||||
|
void display_port_backlight(lv_disp_drv_t *drv, uint8_t state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DC signal control port
|
||||||
|
*
|
||||||
|
* @param drv Pointer to driver See @ref lv_disp_drv_t
|
||||||
|
* @param state State of the DC signal, 1 for logic high, 0 for logic low
|
||||||
|
*/
|
||||||
|
void display_port_gpio_dc(lv_disp_drv_t *drv, uint8_t state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hardware reset control port
|
||||||
|
*
|
||||||
|
* @param drv Pointer to driver See @ref lv_disp_drv_t
|
||||||
|
* @param state State of the reset signal, 1 for logic high, 0 for logic low
|
||||||
|
*/
|
||||||
|
void display_port_gpio_rst(lv_disp_drv_t *drv, uint8_t state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display is busy port
|
||||||
|
*
|
||||||
|
* @param drv Pointer to driver See @ref lv_disp_drv_t
|
||||||
|
*
|
||||||
|
* @retval Returns false when display is not busy, true otherwise.
|
||||||
|
*/
|
||||||
|
bool display_port_gpio_is_busy(lv_disp_drv_t *drv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send cmd to display
|
||||||
|
*
|
||||||
|
* @param drv Pointer to driver
|
||||||
|
* @param cmd Command to send
|
||||||
|
* @param cmd_width Width of the command (in bits) to be sent, see @ref cmd_width_t
|
||||||
|
* @param args Pointer to arguments, use CMD_WITHOUT_ARGS to send command without arguments
|
||||||
|
* @param args_len Arguments length (in bytes) to be sent
|
||||||
|
*/
|
||||||
|
void display_interface_send_cmd(lv_disp_drv_t *drv, uint32_t cmd, cmd_width_t cmd_width, void *args, size_t args_len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send (image) data to display
|
||||||
|
*
|
||||||
|
* User must call lv_disp_flush after the image is sent
|
||||||
|
*
|
||||||
|
* @param drv Pointer to driver
|
||||||
|
* @param data Pointer to data to be sent
|
||||||
|
* @param len Data length (in bytes) to be sent
|
||||||
|
*/
|
||||||
|
void display_interface_send_data(lv_disp_drv_t *drv, void *data, size_t len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -18,15 +18,12 @@
|
||||||
#include "hx8357.h"
|
#include "hx8357.h"
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include <esp_log.h>
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "HX8357"
|
|
||||||
|
|
||||||
#define MADCTL_MY 0x80 ///< Bottom to top
|
#define MADCTL_MY 0x80 ///< Bottom to top
|
||||||
#define MADCTL_MX 0x40 ///< Right to left
|
#define MADCTL_MX 0x40 ///< Right to left
|
||||||
#define MADCTL_MV 0x20 ///< Reverse Mode
|
#define MADCTL_MV 0x20 ///< Reverse Mode
|
||||||
|
@ -52,7 +49,7 @@ typedef struct {
|
||||||
static void hx8357_send_cmd(uint8_t cmd);
|
static void hx8357_send_cmd(uint8_t cmd);
|
||||||
static void hx8357_send_data(void * data, uint16_t length);
|
static void hx8357_send_data(void * data, uint16_t length);
|
||||||
static void hx8357_send_color(void * data, uint16_t length);
|
static void hx8357_send_color(void * data, uint16_t length);
|
||||||
|
static void hx8357_reset(void);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* INITIALIZATION ARRAYS
|
* INITIALIZATION ARRAYS
|
||||||
|
@ -159,22 +156,9 @@ static uint8_t displayType = HX8357D;
|
||||||
|
|
||||||
void hx8357_init(void)
|
void hx8357_init(void)
|
||||||
{
|
{
|
||||||
//Initialize non-SPI GPIOs
|
hx8357_reset();
|
||||||
gpio_pad_select_gpio(HX8357_DC);
|
|
||||||
gpio_set_direction(HX8357_DC, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
#if HX8357_USE_RST
|
LV_LOG_INFO("Initialization.");
|
||||||
gpio_pad_select_gpio(HX8357_RST);
|
|
||||||
gpio_set_direction(HX8357_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
gpio_set_level(HX8357_RST, 0);
|
|
||||||
vTaskDelay(10 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(HX8357_RST, 1);
|
|
||||||
vTaskDelay(120 / portTICK_RATE_MS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Initialization.");
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
const uint8_t *addr = (displayType == HX8357B) ? initb : initd;
|
const uint8_t *addr = (displayType == HX8357B) ? initb : initd;
|
||||||
|
@ -289,3 +273,13 @@ static void hx8357_send_color(void * data, uint16_t length)
|
||||||
gpio_set_level(HX8357_DC, 1); /*Data mode*/
|
gpio_set_level(HX8357_DC, 1); /*Data mode*/
|
||||||
disp_spi_send_colors(data, length);
|
disp_spi_send_colors(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hx8357_reset(void)
|
||||||
|
{
|
||||||
|
#if HX8357_USE_RST
|
||||||
|
gpio_set_level(HX8357_RST, 0);
|
||||||
|
vTaskDelay(10 / portTICK_RATE_MS);
|
||||||
|
gpio_set_level(HX8357_RST, 1);
|
||||||
|
vTaskDelay(120 / portTICK_RATE_MS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
*********************/
|
*********************/
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
@ -39,7 +38,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "IL3820"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SSD1673, SSD1608 compatible EPD controller driver.
|
* SSD1673, SSD1608 compatible EPD controller driver.
|
||||||
|
@ -102,6 +100,7 @@ static inline void il3820_set_window( uint16_t sx, uint16_t ex, uint16_t ys, uin
|
||||||
static inline void il3820_set_cursor(uint16_t sx, uint16_t ys);
|
static inline void il3820_set_cursor(uint16_t sx, uint16_t ys);
|
||||||
static void il3820_update_display(void);
|
static void il3820_update_display(void);
|
||||||
static void il3820_clear_cntlr_mem(uint8_t ram_cmd, bool update);
|
static void il3820_clear_cntlr_mem(uint8_t ram_cmd, bool update);
|
||||||
|
static void il3820_reset(void);
|
||||||
|
|
||||||
/* Required by LVGL */
|
/* Required by LVGL */
|
||||||
void il3820_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
|
void il3820_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
|
||||||
|
@ -180,7 +179,9 @@ void il3820_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t* buf,
|
||||||
BIT_CLEAR(buf[byte_index], 7 - bit_index);
|
BIT_CLEAR(buf[byte_index], 7 - bit_index);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#error "Unsupported orientation used"
|
(void)byte_index;
|
||||||
|
(void)bit_index;
|
||||||
|
assert(false); // Unsupported orientation configured. Crash if we get here, but allow compilation for CI
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,26 +196,7 @@ void il3820_init(void)
|
||||||
{
|
{
|
||||||
uint8_t tmp[3] = {0};
|
uint8_t tmp[3] = {0};
|
||||||
|
|
||||||
/* Initialize non-SPI GPIOs */
|
il3820_reset();
|
||||||
gpio_pad_select_gpio(IL3820_DC_PIN);
|
|
||||||
gpio_set_direction(IL3820_DC_PIN, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
gpio_pad_select_gpio(IL3820_BUSY_PIN);
|
|
||||||
gpio_set_direction(IL3820_BUSY_PIN, GPIO_MODE_INPUT);
|
|
||||||
|
|
||||||
#if IL3820_USE_RST
|
|
||||||
gpio_pad_select_gpio(IL3820_RST_PIN);
|
|
||||||
gpio_set_direction(IL3820_RST_PIN, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
/* Harware reset */
|
|
||||||
gpio_set_level( IL3820_RST_PIN, 0);
|
|
||||||
vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS);
|
|
||||||
gpio_set_level( IL3820_RST_PIN, 1);
|
|
||||||
vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Software reset */
|
|
||||||
il3820_write_cmd(IL3820_CMD_SW_RESET, NULL, 0);
|
|
||||||
|
|
||||||
/* Busy wait for the BUSY signal to go low */
|
/* Busy wait for the BUSY signal to go low */
|
||||||
il3820_waitbusy(IL3820_WAIT);
|
il3820_waitbusy(IL3820_WAIT);
|
||||||
|
@ -277,7 +259,7 @@ static void il3820_waitbusy(int wait_ms)
|
||||||
vTaskDelay(10 / portTICK_RATE_MS);
|
vTaskDelay(10 / portTICK_RATE_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGE( TAG, "busy exceeded %dms", i*10 );
|
LV_LOG_ERROR("Busy exceeded %dms", i*10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set DC signal to command mode */
|
/* Set DC signal to command mode */
|
||||||
|
@ -416,3 +398,17 @@ static void il3820_clear_cntlr_mem(uint8_t ram_cmd, bool update)
|
||||||
il3820_update_display();
|
il3820_update_display();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void il3820_reset(void)
|
||||||
|
{
|
||||||
|
#if IL3820_USE_RST
|
||||||
|
/* Harware reset */
|
||||||
|
gpio_set_level( IL3820_RST_PIN, 0);
|
||||||
|
vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS);
|
||||||
|
gpio_set_level( IL3820_RST_PIN, 1);
|
||||||
|
vTaskDelay(IL3820_RESET_DELAY / portTICK_RATE_MS);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Software reset */
|
||||||
|
il3820_write_cmd(IL3820_CMD_SW_RESET, NULL, 0);
|
||||||
|
}
|
||||||
|
|
|
@ -20,8 +20,19 @@ extern "C"
|
||||||
|
|
||||||
/* Values for Waveshare 2.9inch e-Paper Module, this values shouldn't be
|
/* Values for Waveshare 2.9inch e-Paper Module, this values shouldn't be
|
||||||
* swapped to change display orientation */
|
* swapped to change display orientation */
|
||||||
|
#if defined (LV_HOR_RES_MAX)
|
||||||
#define EPD_PANEL_WIDTH LV_HOR_RES_MAX /* 128 */
|
#define EPD_PANEL_WIDTH LV_HOR_RES_MAX /* 128 */
|
||||||
|
#else
|
||||||
|
/* Fallback to default value */
|
||||||
|
#define EPD_PANEL_WIDTH 128u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (LV_VER_RES_MAX)
|
||||||
#define EPD_PANEL_HEIGHT LV_VER_RES_MAX /* 296 */
|
#define EPD_PANEL_HEIGHT LV_VER_RES_MAX /* 296 */
|
||||||
|
#else
|
||||||
|
/* Fallback to default value */
|
||||||
|
#define EPD_PANEL_HEIGHT 296u
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 128 = panel width */
|
/* 128 = panel width */
|
||||||
#define IL3820_COLUMNS (EPD_PANEL_WIDTH / 8)
|
#define IL3820_COLUMNS (EPD_PANEL_WIDTH / 8)
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "ili9163c.h"
|
#include "ili9163c.h"
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
@ -17,8 +16,6 @@
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "ILI9163C"
|
|
||||||
|
|
||||||
// ILI9163C specific commands used in init
|
// ILI9163C specific commands used in init
|
||||||
#define ILI9163C_NOP 0x00
|
#define ILI9163C_NOP 0x00
|
||||||
#define ILI9163C_SWRESET 0x01
|
#define ILI9163C_SWRESET 0x01
|
||||||
|
@ -69,7 +66,7 @@
|
||||||
|
|
||||||
#define ST77XX_MADCTL_MY 0x80
|
#define ST77XX_MADCTL_MY 0x80
|
||||||
#define ST77XX_MADCTL_MX 0x40
|
#define ST77XX_MADCTL_MX 0x40
|
||||||
#define ST77XX_MADCTL_MV 0x20 #define
|
#define ST77XX_MADCTL_MV 0x20
|
||||||
#define ST77XX_MADCTL_ML 0x10
|
#define ST77XX_MADCTL_ML 0x10
|
||||||
#define ST77XX_MADCTL_RGB 0x00
|
#define ST77XX_MADCTL_RGB 0x00
|
||||||
#define ST77XX_MADCTL_BGR 0x08
|
#define ST77XX_MADCTL_BGR 0x08
|
||||||
|
@ -94,7 +91,7 @@ static void ili9163c_set_orientation(uint8_t orientation);
|
||||||
static void ili9163c_send_cmd(uint8_t cmd);
|
static void ili9163c_send_cmd(uint8_t cmd);
|
||||||
static void ili9163c_send_data(void *data, uint16_t length);
|
static void ili9163c_send_data(void *data, uint16_t length);
|
||||||
static void ili9163c_send_color(void *data, uint16_t length);
|
static void ili9163c_send_color(void *data, uint16_t length);
|
||||||
|
static void ili9163c_reset(void);
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -109,7 +106,7 @@ static void ili9163c_send_color(void *data, uint16_t length);
|
||||||
|
|
||||||
void ili9163c_init(void)
|
void ili9163c_init(void)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "Init");
|
LV_LOG_INFO("Init");
|
||||||
|
|
||||||
lcd_init_cmd_t ili_init_cmds[] = {
|
lcd_init_cmd_t ili_init_cmds[] = {
|
||||||
{ILI9163C_SWRESET, {0}, 0x80}, // Software reset, 0 args, w/delay 120ms
|
{ILI9163C_SWRESET, {0}, 0x80}, // Software reset, 0 args, w/delay 120ms
|
||||||
|
@ -137,17 +134,7 @@ void ili9163c_init(void)
|
||||||
{0, {0}, 0xff}
|
{0, {0}, 0xff}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Initialize non-SPI GPIOs
|
ili9163c_reset();
|
||||||
gpio_pad_select_gpio(ILI9163C_DC);
|
|
||||||
gpio_set_direction(ILI9163C_DC, GPIO_MODE_OUTPUT);
|
|
||||||
gpio_pad_select_gpio(ILI9163C_RST);
|
|
||||||
gpio_set_direction(ILI9163C_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
gpio_set_level(ILI9163C_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(ILI9163C_RST, 1);
|
|
||||||
vTaskDelay(150 / portTICK_RATE_MS);
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
|
@ -236,13 +223,25 @@ static void ili9163c_set_orientation(uint8_t orientation)
|
||||||
{
|
{
|
||||||
assert(orientation < 4);
|
assert(orientation < 4);
|
||||||
|
|
||||||
|
#if (LV_USE_LOG == 1)
|
||||||
const char *orientation_str[] = {
|
const char *orientation_str[] = {
|
||||||
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"};
|
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"};
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Display orientation: %s", orientation_str[orientation]);
|
LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]);
|
||||||
|
#endif
|
||||||
uint8_t data[] = {0x48, 0x88, 0xA8, 0x68};
|
uint8_t data[] = {0x48, 0x88, 0xA8, 0x68};
|
||||||
|
|
||||||
ili9163c_send_cmd(ILI9163C_MADCTL);
|
ili9163c_send_cmd(ILI9163C_MADCTL);
|
||||||
ili9163c_send_data((void *)&data[orientation], 1);
|
ili9163c_send_data((void *)&data[orientation], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ili9163c_reset(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_LV_DISP_USE_RST
|
||||||
|
gpio_set_level(ILI9163C_RST, 0);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
gpio_set_level(ILI9163C_RST, 1);
|
||||||
|
vTaskDelay(150 / portTICK_RATE_MS);
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -7,22 +7,24 @@
|
||||||
* INCLUDES
|
* INCLUDES
|
||||||
*********************/
|
*********************/
|
||||||
#include "ili9341.h"
|
#include "ili9341.h"
|
||||||
|
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "driver/gpio.h"
|
#include "display_port.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "ILI9341"
|
#define END_OF_CMD_MARKER 0xFFU
|
||||||
|
|
||||||
|
#define MEMORY_ACCESS_CONTROL_REG 0x36U
|
||||||
|
#define SOFTWARE_RESET_REG 0x01U
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
/*The LCD needs a bunch of command/argument values to be initialized. They are stored in this struct. */
|
/*The LCD needs a bunch of command/argument values to be initialized. They are stored in this struct. */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
uint8_t data[16];
|
uint8_t data[16];
|
||||||
|
@ -32,12 +34,13 @@ typedef struct {
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
static void ili9341_set_orientation(uint8_t orientation);
|
static void ili9341_set_orientation(lv_disp_drv_t * drv, uint8_t orientation);
|
||||||
|
|
||||||
static void ili9341_send_cmd(uint8_t cmd);
|
static void ili9341_send_cmd(lv_disp_drv_t * drv, uint8_t cmd);
|
||||||
static void ili9341_send_data(void * data, uint16_t length);
|
static void ili9341_send_data(lv_disp_drv_t * drv, void * data, uint16_t length);
|
||||||
static void ili9341_send_color(void * data, uint16_t length);
|
static void ili9341_send_color(lv_disp_drv_t * drv, void * data, uint16_t length);
|
||||||
|
|
||||||
|
static void ili9341_reset(lv_disp_drv_t * drv);
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -50,7 +53,7 @@ static void ili9341_send_color(void * data, uint16_t length);
|
||||||
* GLOBAL FUNCTIONS
|
* GLOBAL FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
void ili9341_init(void)
|
void ili9341_init(lv_disp_drv_t * drv)
|
||||||
{
|
{
|
||||||
lcd_init_cmd_t ili_init_cmds[] = {
|
lcd_init_cmd_t ili_init_cmds[] = {
|
||||||
{0xCF, {0x00, 0x83, 0X30}, 3},
|
{0xCF, {0x00, 0x83, 0X30}, 3},
|
||||||
|
@ -59,12 +62,18 @@ void ili9341_init(void)
|
||||||
{0xCB, {0x39, 0x2C, 0x00, 0x34, 0x02}, 5},
|
{0xCB, {0x39, 0x2C, 0x00, 0x34, 0x02}, 5},
|
||||||
{0xF7, {0x20}, 1},
|
{0xF7, {0x20}, 1},
|
||||||
{0xEA, {0x00, 0x00}, 2},
|
{0xEA, {0x00, 0x00}, 2},
|
||||||
{0xC0, {0x26}, 1}, /*Power control*/
|
/* Power control */
|
||||||
{0xC1, {0x11}, 1}, /*Power control */
|
{0xC0, {0x26}, 1},
|
||||||
{0xC5, {0x35, 0x3E}, 2}, /*VCOM control*/
|
/* Power control */
|
||||||
{0xC7, {0xBE}, 1}, /*VCOM control*/
|
{0xC1, {0x11}, 1},
|
||||||
{0x36, {0x28}, 1}, /*Memory Access Control*/
|
/* VCOM control */
|
||||||
{0x3A, {0x55}, 1}, /*Pixel Format Set*/
|
{0xC5, {0x35, 0x3E}, 2},
|
||||||
|
/* VCOM control */
|
||||||
|
{0xC7, {0xBE}, 1},
|
||||||
|
/* Memory Access Control */
|
||||||
|
{0x36, {0x28}, 1},
|
||||||
|
/* Pixel Format Set */
|
||||||
|
{0x3A, {0x55}, 1},
|
||||||
{0xB1, {0x00, 0x1B}, 2},
|
{0xB1, {0x00, 0x1B}, 2},
|
||||||
{0xF2, {0x08}, 1},
|
{0xF2, {0x08}, 1},
|
||||||
{0x26, {0x01}, 1},
|
{0x26, {0x01}, 1},
|
||||||
|
@ -77,135 +86,139 @@ void ili9341_init(void)
|
||||||
{0xB6, {0x0A, 0x82, 0x27, 0x00}, 4},
|
{0xB6, {0x0A, 0x82, 0x27, 0x00}, 4},
|
||||||
{0x11, {0}, 0x80},
|
{0x11, {0}, 0x80},
|
||||||
{0x29, {0}, 0x80},
|
{0x29, {0}, 0x80},
|
||||||
{0, {0}, 0xff},
|
{0, {0}, END_OF_CMD_MARKER},
|
||||||
};
|
};
|
||||||
|
|
||||||
//Initialize non-SPI GPIOs
|
ili9341_reset(drv);
|
||||||
gpio_pad_select_gpio(ILI9341_DC);
|
|
||||||
gpio_set_direction(ILI9341_DC, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
#if ILI9341_USE_RST
|
|
||||||
gpio_pad_select_gpio(ILI9341_RST);
|
|
||||||
gpio_set_direction(ILI9341_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
gpio_set_level(ILI9341_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(ILI9341_RST, 1);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Initialization.");
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
while (ili_init_cmds[cmd].databytes!=0xff) {
|
while (ili_init_cmds[cmd].databytes != END_OF_CMD_MARKER) {
|
||||||
ili9341_send_cmd(ili_init_cmds[cmd].cmd);
|
ili9341_send_cmd(drv, ili_init_cmds[cmd].cmd);
|
||||||
ili9341_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F);
|
ili9341_send_data(drv, ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes & 0x1F);
|
||||||
|
|
||||||
if (ili_init_cmds[cmd].databytes & 0x80) {
|
if (ili_init_cmds[cmd].databytes & 0x80) {
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
display_port_delay(drv, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd++;
|
cmd++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ili9341_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
|
ili9341_set_orientation(drv, ILI9341_INITIAL_ORIENTATION);
|
||||||
|
|
||||||
#if ILI9341_INVERT_COLORS == 1
|
#if ILI9341_INVERT_COLORS == 1U
|
||||||
ili9341_send_cmd(0x21);
|
ili9341_send_cmd(drv, 0x21);
|
||||||
#else
|
#else
|
||||||
ili9341_send_cmd(0x20);
|
ili9341_send_cmd(drv, 0x20);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
||||||
{
|
{
|
||||||
uint8_t data[4];
|
uint8_t data[4] = {0};
|
||||||
|
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
|
||||||
|
|
||||||
/*Column addresses*/
|
/*Column addresses*/
|
||||||
ili9341_send_cmd(0x2A);
|
|
||||||
data[0] = (area->x1 >> 8) & 0xFF;
|
data[0] = (area->x1 >> 8) & 0xFF;
|
||||||
data[1] = area->x1 & 0xFF;
|
data[1] = area->x1 & 0xFF;
|
||||||
data[2] = (area->x2 >> 8) & 0xFF;
|
data[2] = (area->x2 >> 8) & 0xFF;
|
||||||
data[3] = area->x2 & 0xFF;
|
data[3] = area->x2 & 0xFF;
|
||||||
ili9341_send_data(data, 4);
|
|
||||||
|
ili9341_send_cmd(drv, 0x2A);
|
||||||
|
ili9341_send_data(drv, data, 4);
|
||||||
|
|
||||||
/* Page addresses */
|
/* Page addresses */
|
||||||
ili9341_send_cmd(0x2B);
|
|
||||||
data[0] = (area->y1 >> 8) & 0xFF;
|
data[0] = (area->y1 >> 8) & 0xFF;
|
||||||
data[1] = area->y1 & 0xFF;
|
data[1] = area->y1 & 0xFF;
|
||||||
data[2] = (area->y2 >> 8) & 0xFF;
|
data[2] = (area->y2 >> 8) & 0xFF;
|
||||||
data[3] = area->y2 & 0xFF;
|
data[3] = area->y2 & 0xFF;
|
||||||
ili9341_send_data(data, 4);
|
|
||||||
|
ili9341_send_cmd(drv, 0x2B);
|
||||||
|
ili9341_send_data(drv, data, 4);
|
||||||
|
|
||||||
/* Memory write */
|
/* Memory write */
|
||||||
ili9341_send_cmd(0x2C);
|
ili9341_send_cmd(drv, 0x2C);
|
||||||
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
|
ili9341_send_color(drv, (void*)color_map, size * 2);
|
||||||
ili9341_send_color((void*)color_map, size * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ili9341_sleep_in()
|
void ili9341_sleep_in(lv_disp_drv_t * drv)
|
||||||
{
|
{
|
||||||
uint8_t data[] = {0x08};
|
uint8_t data[] = {0x08};
|
||||||
ili9341_send_cmd(0x10);
|
ili9341_send_cmd(drv, 0x10);
|
||||||
ili9341_send_data(&data, 1);
|
ili9341_send_data(drv, data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ili9341_sleep_out()
|
void ili9341_sleep_out(lv_disp_drv_t * drv)
|
||||||
{
|
{
|
||||||
uint8_t data[] = {0x08};
|
uint8_t data[] = {0x08};
|
||||||
ili9341_send_cmd(0x11);
|
ili9341_send_cmd(drv, 0x11);
|
||||||
ili9341_send_data(&data, 1);
|
ili9341_send_data(drv, data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
static inline void set_cmd_mode(lv_disp_drv_t * drv)
|
||||||
|
{
|
||||||
|
display_port_gpio_dc(drv, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void ili9341_send_cmd(uint8_t cmd)
|
static inline void set_data_mode(lv_disp_drv_t * drv)
|
||||||
|
{
|
||||||
|
display_port_gpio_dc(drv, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ili9341_send_cmd(lv_disp_drv_t * drv, uint8_t cmd)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(ILI9341_DC, 0); /*Command mode*/
|
set_cmd_mode(drv);
|
||||||
disp_spi_send_data(&cmd, 1);
|
disp_spi_send_data(&cmd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ili9341_send_data(void * data, uint16_t length)
|
static void ili9341_send_data(lv_disp_drv_t *drv, void * data, uint16_t length)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(ILI9341_DC, 1); /*Data mode*/
|
set_data_mode(drv);
|
||||||
disp_spi_send_data(data, length);
|
disp_spi_send_data(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ili9341_send_color(void * data, uint16_t length)
|
static void ili9341_send_color(lv_disp_drv_t *drv, void * data, uint16_t length)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(ILI9341_DC, 1); /*Data mode*/
|
set_data_mode(drv);
|
||||||
disp_spi_send_colors(data, length);
|
disp_spi_send_colors(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ili9341_set_orientation(uint8_t orientation)
|
static void ili9341_set_orientation(lv_disp_drv_t *drv, uint8_t orientation)
|
||||||
{
|
{
|
||||||
// ESP_ASSERT(orientation < 4);
|
assert(orientation < 4);
|
||||||
|
|
||||||
const char *orientation_str[] = {
|
|
||||||
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
|
||||||
};
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]);
|
|
||||||
|
|
||||||
#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK
|
#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK
|
||||||
uint8_t data[] = {0x68, 0x68, 0x08, 0x08};
|
const uint8_t data[] = {0x68, 0x68, 0x08, 0x08};
|
||||||
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_M5CORE2)
|
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_M5CORE2)
|
||||||
uint8_t data[] = {0x08, 0x88, 0x28, 0xE8};
|
const uint8_t data[] = {0x08, 0x88, 0x28, 0xE8};
|
||||||
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_WROVER4)
|
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_WROVER4)
|
||||||
uint8_t data[] = {0x6C, 0xEC, 0xCC, 0x4C};
|
const uint8_t data[] = {0x6C, 0xEC, 0xCC, 0x4C};
|
||||||
#elif defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE)
|
#else
|
||||||
uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};
|
const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]);
|
ili9341_send_cmd(drv, MEMORY_ACCESS_CONTROL_REG);
|
||||||
|
ili9341_send_data(drv, (void *) &data[orientation], 1);
|
||||||
ili9341_send_cmd(0x36);
|
}
|
||||||
ili9341_send_data((void *) &data[orientation], 1);
|
|
||||||
|
/* Reset the display, if we don't have a reset pin we use software reset */
|
||||||
|
static void ili9341_reset(lv_disp_drv_t *drv)
|
||||||
|
{
|
||||||
|
#if defined(ILI9341_USE_RST)
|
||||||
|
display_port_gpio_rst(drv, 0);
|
||||||
|
display_port_delay(drv, 100);
|
||||||
|
display_port_gpio_rst(drv, 1);
|
||||||
|
display_port_delay(drv, 100);
|
||||||
|
#else
|
||||||
|
ili9341_send_cmd(drv, SOFTWARE_RESET_REG);
|
||||||
|
display_port_delay(drv, 5);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,23 +13,17 @@ extern "C" {
|
||||||
/*********************
|
/*********************
|
||||||
* INCLUDES
|
* INCLUDES
|
||||||
*********************/
|
*********************/
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "display_config.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define ILI9341_DC CONFIG_LV_DISP_PIN_DC
|
|
||||||
#define ILI9341_USE_RST CONFIG_LV_DISP_USE_RST
|
|
||||||
#define ILI9341_RST CONFIG_LV_DISP_PIN_RST
|
|
||||||
#define ILI9341_INVERT_COLORS CONFIG_LV_INVERT_COLORS
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
|
@ -39,10 +33,10 @@ extern "C" {
|
||||||
* GLOBAL PROTOTYPES
|
* GLOBAL PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
void ili9341_init(void);
|
void ili9341_init(lv_disp_drv_t * drv);
|
||||||
void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
void ili9341_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
||||||
void ili9341_sleep_in(void);
|
void ili9341_sleep_in(lv_disp_drv_t * drv);
|
||||||
void ili9341_sleep_out(void);
|
void ili9341_sleep_out(lv_disp_drv_t *drv);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
|
|
|
@ -8,16 +8,13 @@
|
||||||
#include "ili9481.h"
|
#include "ili9481.h"
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "ILI9481"
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
|
@ -38,6 +35,7 @@ static void ili9481_set_orientation(uint8_t orientation);
|
||||||
static void ili9481_send_cmd(uint8_t cmd);
|
static void ili9481_send_cmd(uint8_t cmd);
|
||||||
static void ili9481_send_data(void * data, uint16_t length);
|
static void ili9481_send_data(void * data, uint16_t length);
|
||||||
static void ili9481_send_color(void * data, uint16_t length);
|
static void ili9481_send_color(void * data, uint16_t length);
|
||||||
|
static void ili9481_reset(void);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
|
@ -73,26 +71,9 @@ void ili9481_init(void)
|
||||||
{0, {0}, 0xff},
|
{0, {0}, 0xff},
|
||||||
};
|
};
|
||||||
|
|
||||||
//Initialize non-SPI GPIOs
|
ili9481_reset();
|
||||||
gpio_pad_select_gpio(ILI9481_DC);
|
|
||||||
gpio_set_direction(ILI9481_DC, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
#if ILI9481_USE_RST
|
LV_LOG_INFO("Initialization.");
|
||||||
gpio_pad_select_gpio(ILI9481_RST);
|
|
||||||
gpio_set_direction(ILI9481_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
gpio_set_level(ILI9481_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(ILI9481_RST, 1);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "ILI9481 initialization.");
|
|
||||||
|
|
||||||
// Exit sleep
|
|
||||||
ili9481_send_cmd(0x01); /* Software reset */
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
|
@ -111,13 +92,16 @@ void ili9481_init(void)
|
||||||
// Flush function based on mvturnho repo
|
// Flush function based on mvturnho repo
|
||||||
void ili9481_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
void ili9481_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
||||||
{
|
{
|
||||||
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
|
/* 3 is number of bytes in lv_color_t */
|
||||||
|
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 3;
|
||||||
|
|
||||||
lv_color16_t *buffer_16bit = (lv_color16_t *) color_map;
|
lv_color16_t *buffer_16bit = (lv_color16_t *) color_map;
|
||||||
uint8_t *mybuf;
|
uint8_t *mybuf;
|
||||||
do {
|
do {
|
||||||
mybuf = (uint8_t *) heap_caps_malloc(3 * size * sizeof(uint8_t), MALLOC_CAP_DMA);
|
mybuf = (uint8_t *) heap_caps_malloc(3 * size * sizeof(uint8_t), MALLOC_CAP_DMA);
|
||||||
if (mybuf == NULL) ESP_LOGW(TAG, "Could not allocate enough DMA memory!");
|
if (mybuf == NULL) {
|
||||||
|
LV_LOG_WARN("Could not allocate enough DMA memory!");
|
||||||
|
}
|
||||||
} while (mybuf == NULL);
|
} while (mybuf == NULL);
|
||||||
|
|
||||||
uint32_t LD = 0;
|
uint32_t LD = 0;
|
||||||
|
@ -160,7 +144,9 @@ void ili9481_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
|
||||||
/*Memory write*/
|
/*Memory write*/
|
||||||
ili9481_send_cmd(ILI9481_CMD_MEMORY_WRITE);
|
ili9481_send_cmd(ILI9481_CMD_MEMORY_WRITE);
|
||||||
|
|
||||||
ili9481_send_color((void *) mybuf, size * 3);
|
ili9481_send_color((void *) mybuf, size);
|
||||||
|
|
||||||
|
/* FIXME: Can we free the memory even when it's being transferred? */
|
||||||
heap_caps_free(mybuf);
|
heap_caps_free(mybuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,13 +178,29 @@ static void ili9481_send_color(void * data, uint16_t length)
|
||||||
|
|
||||||
static void ili9481_set_orientation(uint8_t orientation)
|
static void ili9481_set_orientation(uint8_t orientation)
|
||||||
{
|
{
|
||||||
|
#if (LV_USE_LOG == 1)
|
||||||
const char *orientation_str[] = {
|
const char *orientation_str[] = {
|
||||||
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
||||||
};
|
};
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]);
|
LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]);
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8_t data[] = {0x48, 0x4B, 0x28, 0x2B};
|
uint8_t data[] = {0x48, 0x4B, 0x28, 0x2B};
|
||||||
ili9481_send_cmd(ILI9481_CMD_MEMORY_ACCESS_CONTROL);
|
ili9481_send_cmd(ILI9481_CMD_MEMORY_ACCESS_CONTROL);
|
||||||
ili9481_send_data((void *) &data[orientation], 1);
|
ili9481_send_data((void *) &data[orientation], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ili9481_reset(void)
|
||||||
|
{
|
||||||
|
#if ILI9481_USE_RST
|
||||||
|
gpio_set_level(ILI9481_RST, 0);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
gpio_set_level(ILI9481_RST, 1);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
#else
|
||||||
|
// Exit sleep, software reset
|
||||||
|
ili9481_send_cmd(0x01);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -9,14 +9,12 @@
|
||||||
#include "ili9486.h"
|
#include "ili9486.h"
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "ILI9486"
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
|
@ -37,7 +35,7 @@ static void ili9486_set_orientation(uint8_t orientation);
|
||||||
static void ili9486_send_cmd(uint8_t cmd);
|
static void ili9486_send_cmd(uint8_t cmd);
|
||||||
static void ili9486_send_data(void * data, uint16_t length);
|
static void ili9486_send_data(void * data, uint16_t length);
|
||||||
static void ili9486_send_color(void * data, uint16_t length);
|
static void ili9486_send_color(void * data, uint16_t length);
|
||||||
|
static void ili9486_reset(void);
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -65,22 +63,9 @@ void ili9486_init(void)
|
||||||
{0x00, {0}, 0xff},
|
{0x00, {0}, 0xff},
|
||||||
};
|
};
|
||||||
|
|
||||||
//Initialize non-SPI GPIOs
|
ili9486_reset();
|
||||||
gpio_pad_select_gpio(ILI9486_DC);
|
|
||||||
gpio_set_direction(ILI9486_DC, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
#if ILI9486_USE_RST
|
LV_LOG_INFO("ILI9486 Initialization.");
|
||||||
gpio_pad_select_gpio(ILI9486_RST);
|
|
||||||
gpio_set_direction(ILI9486_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
gpio_set_level(ILI9486_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(ILI9486_RST, 1);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "ILI9486 Initialization.");
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
|
@ -99,7 +84,8 @@ void ili9486_init(void)
|
||||||
void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
||||||
{
|
{
|
||||||
uint8_t data[4] = {0};
|
uint8_t data[4] = {0};
|
||||||
uint32_t size = 0;
|
/* 2 is the number of bytes in color depth */
|
||||||
|
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 2;
|
||||||
|
|
||||||
/*Column addresses*/
|
/*Column addresses*/
|
||||||
ili9486_send_cmd(0x2A);
|
ili9486_send_cmd(0x2A);
|
||||||
|
@ -119,10 +105,7 @@ void ili9486_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
|
||||||
|
|
||||||
/*Memory write*/
|
/*Memory write*/
|
||||||
ili9486_send_cmd(0x2C);
|
ili9486_send_cmd(0x2C);
|
||||||
|
ili9486_send_color((void*) color_map, size);
|
||||||
size = lv_area_get_width(area) * lv_area_get_height(area);
|
|
||||||
|
|
||||||
ili9486_send_color((void*) color_map, size * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
@ -165,20 +148,29 @@ static void ili9486_send_color(void * data, uint16_t length)
|
||||||
|
|
||||||
static void ili9486_set_orientation(uint8_t orientation)
|
static void ili9486_set_orientation(uint8_t orientation)
|
||||||
{
|
{
|
||||||
// ESP_ASSERT(orientation < 4);
|
assert(orientation < 4);
|
||||||
|
|
||||||
|
const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};
|
||||||
|
|
||||||
|
#if (LV_USE_LOG == 1)
|
||||||
const char *orientation_str[] = {
|
const char *orientation_str[] = {
|
||||||
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
||||||
};
|
};
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]);
|
LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]);
|
||||||
|
LV_LOG_INFO("0x36 command value: 0x%02X", data[orientation]);
|
||||||
#if defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE)
|
|
||||||
uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]);
|
|
||||||
|
|
||||||
ili9486_send_cmd(0x36);
|
ili9486_send_cmd(0x36);
|
||||||
ili9486_send_data((void *) &data[orientation], 1);
|
ili9486_send_data((void *) &data[orientation], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ili9486_reset(void)
|
||||||
|
{
|
||||||
|
#if ILI9486_USE_RST
|
||||||
|
gpio_set_level(ILI9486_RST, 0);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
gpio_set_level(ILI9486_RST, 1);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -6,18 +6,14 @@
|
||||||
* INCLUDES
|
* INCLUDES
|
||||||
*********************/
|
*********************/
|
||||||
#include "ili9488.h"
|
#include "ili9488.h"
|
||||||
#include "disp_spi.h"
|
|
||||||
#include "driver/gpio.h"
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_heap_caps.h"
|
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "disp_spi.h"
|
||||||
#include "freertos/task.h"
|
#include "display_port.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "ILI9488"
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
|
@ -33,11 +29,12 @@ typedef struct {
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
static void ili9488_set_orientation(uint8_t orientation);
|
static void ili9488_set_orientation(lv_disp_drv_t * drv, uint8_t orientation);
|
||||||
|
|
||||||
static void ili9488_send_cmd(uint8_t cmd);
|
static void ili9488_send_cmd(lv_disp_drv_t * drv, uint8_t cmd);
|
||||||
static void ili9488_send_data(void * data, uint16_t length);
|
static void ili9488_send_data(lv_disp_drv_t * drv, void * data, uint16_t length);
|
||||||
static void ili9488_send_color(void * data, uint16_t length);
|
static void ili9488_send_color(lv_disp_drv_t * drv, void * data, uint16_t length);
|
||||||
|
static void ili9488_reset(lv_disp_drv_t * drv);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
|
@ -52,7 +49,7 @@ static void ili9488_send_color(void * data, uint16_t length);
|
||||||
**********************/
|
**********************/
|
||||||
// From github.com/jeremyjh/ESP32_TFT_library
|
// From github.com/jeremyjh/ESP32_TFT_library
|
||||||
// From github.com/mvturnho/ILI9488-lvgl-ESP32-WROVER-B
|
// From github.com/mvturnho/ILI9488-lvgl-ESP32-WROVER-B
|
||||||
void ili9488_init(void)
|
void ili9488_init(lv_disp_drv_t * drv)
|
||||||
{
|
{
|
||||||
lcd_init_cmd_t ili_init_cmds[]={
|
lcd_init_cmd_t ili_init_cmds[]={
|
||||||
{ILI9488_CMD_SLEEP_OUT, {0x00}, 0x80},
|
{ILI9488_CMD_SLEEP_OUT, {0x00}, 0x80},
|
||||||
|
@ -75,39 +72,24 @@ void ili9488_init(void)
|
||||||
{0, {0}, 0xff},
|
{0, {0}, 0xff},
|
||||||
};
|
};
|
||||||
|
|
||||||
//Initialize non-SPI GPIOs
|
ili9488_reset(drv);
|
||||||
gpio_pad_select_gpio(ILI9488_DC);
|
|
||||||
gpio_set_direction(ILI9488_DC, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
#if ILI9488_USE_RST
|
LV_LOG_INFO("ILI9488 initialization.");
|
||||||
gpio_pad_select_gpio(ILI9488_RST);
|
|
||||||
gpio_set_direction(ILI9488_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
gpio_set_level(ILI9488_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(ILI9488_RST, 1);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "ILI9488 initialization.");
|
|
||||||
|
|
||||||
// Exit sleep
|
|
||||||
ili9488_send_cmd(0x01); /* Software reset */
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
while (ili_init_cmds[cmd].databytes!=0xff) {
|
while (ili_init_cmds[cmd].databytes!=0xff) {
|
||||||
ili9488_send_cmd(ili_init_cmds[cmd].cmd);
|
ili9488_send_cmd(drv, ili_init_cmds[cmd].cmd);
|
||||||
ili9488_send_data(ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F);
|
ili9488_send_data(drv, ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F);
|
||||||
|
|
||||||
if (ili_init_cmds[cmd].databytes & 0x80) {
|
if (ili_init_cmds[cmd].databytes & 0x80) {
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
display_port_delay(drv, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd++;
|
cmd++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ili9488_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
|
ili9488_set_orientation(drv, ILI9488_INITIAL_ORIENTATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush function based on mvturnho repo
|
// Flush function based on mvturnho repo
|
||||||
|
@ -119,7 +101,9 @@ void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
|
||||||
uint8_t *mybuf;
|
uint8_t *mybuf;
|
||||||
do {
|
do {
|
||||||
mybuf = (uint8_t *) heap_caps_malloc(3 * size * sizeof(uint8_t), MALLOC_CAP_DMA);
|
mybuf = (uint8_t *) heap_caps_malloc(3 * size * sizeof(uint8_t), MALLOC_CAP_DMA);
|
||||||
if (mybuf == NULL) ESP_LOGW(TAG, "Could not allocate enough DMA memory!");
|
if (mybuf == NULL) {
|
||||||
|
LV_LOG_WARN("Could not allocate enough DMA memory!");
|
||||||
|
}
|
||||||
} while (mybuf == NULL);
|
} while (mybuf == NULL);
|
||||||
|
|
||||||
uint32_t LD = 0;
|
uint32_t LD = 0;
|
||||||
|
@ -152,17 +136,17 @@ void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
|
||||||
};
|
};
|
||||||
|
|
||||||
/*Column addresses*/
|
/*Column addresses*/
|
||||||
ili9488_send_cmd(ILI9488_CMD_COLUMN_ADDRESS_SET);
|
ili9488_send_cmd(drv, ILI9488_CMD_COLUMN_ADDRESS_SET);
|
||||||
ili9488_send_data(xb, 4);
|
ili9488_send_data(drv, xb, 4);
|
||||||
|
|
||||||
/*Page addresses*/
|
/*Page addresses*/
|
||||||
ili9488_send_cmd(ILI9488_CMD_PAGE_ADDRESS_SET);
|
ili9488_send_cmd(drv, ILI9488_CMD_PAGE_ADDRESS_SET);
|
||||||
ili9488_send_data(yb, 4);
|
ili9488_send_data(drv, yb, 4);
|
||||||
|
|
||||||
/*Memory write*/
|
/*Memory write*/
|
||||||
ili9488_send_cmd(ILI9488_CMD_MEMORY_WRITE);
|
ili9488_send_cmd(drv, ILI9488_CMD_MEMORY_WRITE);
|
||||||
|
|
||||||
ili9488_send_color((void *) mybuf, size * 3);
|
ili9488_send_color(drv, (void *) mybuf, size * 3);
|
||||||
heap_caps_free(mybuf);
|
heap_caps_free(mybuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,44 +154,65 @@ void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
static inline void set_cmd_mode(lv_disp_drv_t * drv)
|
||||||
|
{
|
||||||
|
display_port_gpio_dc(drv, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void ili9488_send_cmd(uint8_t cmd)
|
static inline void set_data_mode(lv_disp_drv_t * drv)
|
||||||
|
{
|
||||||
|
display_port_gpio_dc(drv, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ili9488_send_cmd(lv_disp_drv_t * drv, uint8_t cmd)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(ILI9488_DC, 0); /*Command mode*/
|
set_cmd_mode(drv);
|
||||||
disp_spi_send_data(&cmd, 1);
|
disp_spi_send_data(&cmd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ili9488_send_data(void * data, uint16_t length)
|
static void ili9488_send_data(lv_disp_drv_t * drv, void * data, uint16_t length)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(ILI9488_DC, 1); /*Data mode*/
|
set_data_mode(drv);
|
||||||
disp_spi_send_data(data, length);
|
disp_spi_send_data(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ili9488_send_color(void * data, uint16_t length)
|
static void ili9488_send_color(lv_disp_drv_t * drv, void * data, uint16_t length)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(ILI9488_DC, 1); /*Data mode*/
|
set_data_mode(drv);
|
||||||
disp_spi_send_colors(data, length);
|
disp_spi_send_colors(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ili9488_set_orientation(uint8_t orientation)
|
static void ili9488_set_orientation(lv_disp_drv_t * drv, uint8_t orientation)
|
||||||
{
|
{
|
||||||
// ESP_ASSERT(orientation < 4);
|
assert(orientation < 4);
|
||||||
|
const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};
|
||||||
|
|
||||||
|
#if (LV_USE_LOG == 1)
|
||||||
const char *orientation_str[] = {
|
const char *orientation_str[] = {
|
||||||
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
||||||
};
|
};
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]);
|
LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]);
|
||||||
|
LV_LOG_INFO("0x36 command value: 0x%02X", data[orientation]);
|
||||||
#if defined (CONFIG_LV_PREDEFINED_DISPLAY_NONE)
|
|
||||||
uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]);
|
ili9488_send_cmd(drv, 0x36);
|
||||||
|
ili9488_send_data(drv, (void *) &data[orientation], 1);
|
||||||
ili9488_send_cmd(0x36);
|
}
|
||||||
ili9488_send_data((void *) &data[orientation], 1);
|
|
||||||
|
/* Reset the display, if we don't have a reset pin we use software reset */
|
||||||
|
static void ili9488_reset(lv_disp_drv_t *drv)
|
||||||
|
{
|
||||||
|
#if defined(ILI9488_USE_RST)
|
||||||
|
display_port_gpio_rst(drv, 0);
|
||||||
|
display_port_delay(drv, 100);
|
||||||
|
display_port_gpio_rst(drv, 1);
|
||||||
|
display_port_delay(drv, 100);
|
||||||
|
#else
|
||||||
|
ili9488_send_cmd(drv, 0x01);
|
||||||
|
display_port_delay(drv, 5);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,13 @@ extern "C" {
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../lvgl_helpers.h"
|
#include "../lvgl_helpers.h"
|
||||||
|
#include "display_config.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define ILI9488_DC CONFIG_LV_DISP_PIN_DC
|
|
||||||
#define ILI9488_RST CONFIG_LV_DISP_PIN_RST
|
|
||||||
#define ILI9488_USE_RST CONFIG_LV_DISP_USE_RSTS
|
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
* ILI9488 REGS
|
* ILI9488 REGS
|
||||||
|
@ -144,7 +143,7 @@ typedef struct {
|
||||||
* GLOBAL PROTOTYPES
|
* GLOBAL PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
void ili9488_init(void);
|
void ili9488_init(lv_disp_drv_t * drv);
|
||||||
void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
void ili9488_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
|
|
@ -29,23 +29,39 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
|
||||||
#include <freertos/task.h>
|
#include <freertos/task.h>
|
||||||
#include <freertos/event_groups.h>
|
#include <freertos/event_groups.h>
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <esp_log.h>
|
|
||||||
|
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "jd79653a.h"
|
#include "jd79653a.h"
|
||||||
|
|
||||||
#define TAG "lv_jd79653a"
|
|
||||||
|
|
||||||
#define PIN_DC CONFIG_LV_DISP_PIN_DC
|
#define PIN_DC CONFIG_LV_DISP_PIN_DC
|
||||||
#define PIN_DC_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_DC)))
|
#define PIN_DC_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_DC)))
|
||||||
|
|
||||||
|
#if defined CONFIG_LV_DISP_PIN_RST
|
||||||
#define PIN_RST CONFIG_LV_DISP_PIN_RST
|
#define PIN_RST CONFIG_LV_DISP_PIN_RST
|
||||||
#define PIN_RST_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_RST)))
|
#define PIN_RST_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_RST)))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PIN_BUSY CONFIG_LV_DISP_PIN_BUSY
|
#define PIN_BUSY CONFIG_LV_DISP_PIN_BUSY
|
||||||
#define PIN_BUSY_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_BUSY)))
|
#define PIN_BUSY_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_BUSY)))
|
||||||
#define EVT_BUSY (1UL << 0UL)
|
#define EVT_BUSY (1UL << 0UL)
|
||||||
|
|
||||||
|
#if defined (LV_HOR_RES_MAX)
|
||||||
#define EPD_WIDTH LV_HOR_RES_MAX
|
#define EPD_WIDTH LV_HOR_RES_MAX
|
||||||
|
#else
|
||||||
|
/* ToDo Remove magic number */
|
||||||
|
#define EPD_WIDTH 256u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (LV_VER_RES_MAX)
|
||||||
#define EPD_HEIGHT LV_VER_RES_MAX
|
#define EPD_HEIGHT LV_VER_RES_MAX
|
||||||
|
#else
|
||||||
|
/* ToDo Remove magic number */
|
||||||
|
#define EPD_HEIGHT 128u
|
||||||
|
#endif
|
||||||
|
|
||||||
#define EPD_ROW_LEN (EPD_HEIGHT / 8u)
|
#define EPD_ROW_LEN (EPD_HEIGHT / 8u)
|
||||||
|
|
||||||
|
/* ToDo Remove semicolon */
|
||||||
#define EPD_PARTIAL_CNT 5;
|
#define EPD_PARTIAL_CNT 5;
|
||||||
|
|
||||||
#define BIT_SET(a, b) ((a) |= (1U << (b)))
|
#define BIT_SET(a, b) ((a) |= (1U << (b)))
|
||||||
|
@ -123,10 +139,9 @@ static const uint8_t lut_bb1[] = {
|
||||||
static const jd79653a_seq_t init_seq[] = {
|
static const jd79653a_seq_t init_seq[] = {
|
||||||
#if defined (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
#if defined (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
||||||
{0x00, {0xd3, 0x0e}, 2}, // Panel settings
|
{0x00, {0xd3, 0x0e}, 2}, // Panel settings
|
||||||
#elif defined(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
//#elif defined(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
||||||
{0x00, {0xdf, 0x0e}, 2}, // Panel settings
|
|
||||||
#else
|
#else
|
||||||
#error "Unsupported orientation - only portrait modes are supported for now"
|
{0x00, {0xdf, 0x0e}, 2}, // Panel settings
|
||||||
#endif
|
#endif
|
||||||
{0x4d, {0x55}, 1}, // Undocumented secret from demo code
|
{0x4d, {0x55}, 1}, // Undocumented secret from demo code
|
||||||
{0xaa, {0x0f}, 1}, // Undocumented secret from demo code
|
{0xaa, {0x0f}, 1}, // Undocumented secret from demo code
|
||||||
|
@ -176,16 +191,9 @@ static void jd79653a_spi_send_data(uint8_t *data, size_t len)
|
||||||
disp_spi_send_data(data, len);
|
disp_spi_send_data(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jd79653a_spi_send_fb(uint8_t *data, size_t len)
|
|
||||||
{
|
|
||||||
disp_wait_for_pending_transactions();
|
|
||||||
gpio_set_level(PIN_DC, 1); // DC = 1 for data
|
|
||||||
disp_spi_send_colors(data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void jd79653a_spi_send_seq(const jd79653a_seq_t *seq, size_t len)
|
static void jd79653a_spi_send_seq(const jd79653a_seq_t *seq, size_t len)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "Writing cmd/data sequence, count %u", len);
|
LV_LOG_INFO("Writing cmd/data sequence, count %u", len);
|
||||||
|
|
||||||
if (!seq || len < 1) return;
|
if (!seq || len < 1) return;
|
||||||
for (size_t cmd_idx = 0; cmd_idx < len; cmd_idx++) {
|
for (size_t cmd_idx = 0; cmd_idx < len; cmd_idx++) {
|
||||||
|
@ -207,21 +215,21 @@ static esp_err_t jd79653a_wait_busy(uint32_t timeout_ms)
|
||||||
return ((bits & EVT_BUSY) != 0) ? ESP_OK : ESP_ERR_TIMEOUT;
|
return ((bits & EVT_BUSY) != 0) ? ESP_OK : ESP_ERR_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jd79653a_power_on()
|
static void jd79653a_power_on(void)
|
||||||
{
|
{
|
||||||
jd79653a_spi_send_seq(power_on_seq, EPD_SEQ_LEN(power_on_seq));
|
jd79653a_spi_send_seq(power_on_seq, EPD_SEQ_LEN(power_on_seq));
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
jd79653a_wait_busy(0);
|
jd79653a_wait_busy(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jd79653a_power_off()
|
static void jd79653a_power_off(void)
|
||||||
{
|
{
|
||||||
jd79653a_spi_send_seq(power_off_seq, EPD_SEQ_LEN(power_off_seq));
|
jd79653a_spi_send_seq(power_off_seq, EPD_SEQ_LEN(power_off_seq));
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
jd79653a_wait_busy(0);
|
jd79653a_wait_busy(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jd79653a_load_partial_lut()
|
static void jd79653a_load_partial_lut(void)
|
||||||
{
|
{
|
||||||
jd79653a_spi_send_cmd(0x20); // LUT VCOM register
|
jd79653a_spi_send_cmd(0x20); // LUT VCOM register
|
||||||
jd79653a_spi_send_data((uint8_t *)lut_vcom_dc1, sizeof(lut_vcom_dc1));
|
jd79653a_spi_send_data((uint8_t *)lut_vcom_dc1, sizeof(lut_vcom_dc1));
|
||||||
|
@ -239,9 +247,9 @@ static void jd79653a_load_partial_lut()
|
||||||
jd79653a_spi_send_data((uint8_t *)lut_bb1, sizeof(lut_bb1));
|
jd79653a_spi_send_data((uint8_t *)lut_bb1, sizeof(lut_bb1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jd79653a_partial_in()
|
static void jd79653a_partial_in(void)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "Partial in!");
|
LV_LOG_INFO("Partial in!");
|
||||||
|
|
||||||
// Panel setting: accept LUT from registers instead of OTP
|
// Panel setting: accept LUT from registers instead of OTP
|
||||||
#if defined (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
#if defined (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
||||||
|
@ -249,7 +257,8 @@ static void jd79653a_partial_in()
|
||||||
#elif defined(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
#elif defined(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
||||||
uint8_t pst_use_reg_lut[] = { 0xff, 0x0e };
|
uint8_t pst_use_reg_lut[] = { 0xff, 0x0e };
|
||||||
#else
|
#else
|
||||||
#error "Unsupported orientation - only portrait modes are supported for now"
|
assert(false); // Unsupported orientation configured. Crash if we get here, but allow compilation for CI
|
||||||
|
uint8_t pst_use_reg_lut[] = { 0,0 };
|
||||||
#endif
|
#endif
|
||||||
jd79653a_spi_send_cmd(0x00);
|
jd79653a_spi_send_cmd(0x00);
|
||||||
jd79653a_spi_send_data(pst_use_reg_lut, sizeof(pst_use_reg_lut));
|
jd79653a_spi_send_data(pst_use_reg_lut, sizeof(pst_use_reg_lut));
|
||||||
|
@ -266,9 +275,9 @@ static void jd79653a_partial_in()
|
||||||
jd79653a_spi_send_cmd(0x91);
|
jd79653a_spi_send_cmd(0x91);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jd79653a_partial_out()
|
static void jd79653a_partial_out(void)
|
||||||
{
|
{
|
||||||
ESP_LOGD(TAG, "Partial out!");
|
LV_LOG_INFO("Partial out!");
|
||||||
|
|
||||||
// Panel setting: use LUT from OTP
|
// Panel setting: use LUT from OTP
|
||||||
#if defined (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
#if defined (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
||||||
|
@ -276,7 +285,8 @@ static void jd79653a_partial_out()
|
||||||
#elif defined(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
#elif defined(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
||||||
uint8_t pst_use_otp_lut[] = { 0xdf, 0x0e };
|
uint8_t pst_use_otp_lut[] = { 0xdf, 0x0e };
|
||||||
#else
|
#else
|
||||||
#error "Unsupported orientation - only portrait modes are supported for now"
|
assert(false); // Unsupported orientation configured. Crash if we get here, but allow compilation for CI
|
||||||
|
uint8_t pst_use_otp_lut[] = { 0,0 };
|
||||||
#endif
|
#endif
|
||||||
jd79653a_spi_send_cmd(0x00);
|
jd79653a_spi_send_cmd(0x00);
|
||||||
jd79653a_spi_send_data(pst_use_otp_lut, sizeof(pst_use_otp_lut));
|
jd79653a_spi_send_data(pst_use_otp_lut, sizeof(pst_use_otp_lut));
|
||||||
|
@ -294,10 +304,10 @@ static void jd79653a_update_partial(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t
|
||||||
{
|
{
|
||||||
jd79653a_power_on();
|
jd79653a_power_on();
|
||||||
jd79653a_partial_in();
|
jd79653a_partial_in();
|
||||||
ESP_LOGD(TAG, "x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", x1, x2, y1, y2);
|
LV_LOG_INFO("x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", x1, x2, y1, y2);
|
||||||
|
|
||||||
size_t len = ((x2 - x1 + 1) * (y2 - y1 + 1)) / 8;
|
size_t len = ((x2 - x1 + 1) * (y2 - y1 + 1)) / 8;
|
||||||
ESP_LOGD(TAG, "Writing PARTIAL LVGL fb with len: %u", len);
|
LV_LOG_INFO("Writing PARTIAL LVGL fb with len: %u", len);
|
||||||
|
|
||||||
// Set partial window
|
// Set partial window
|
||||||
uint8_t ptl_setting[7] = { x1, x2, 0, y1, 0, y2, 0x01 };
|
uint8_t ptl_setting[7] = { x1, x2, 0, y1, 0, y2, 0x01 };
|
||||||
|
@ -313,16 +323,18 @@ static void jd79653a_update_partial(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t
|
||||||
len -= EPD_ROW_LEN;
|
len -= EPD_ROW_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Partial wait start");
|
LV_LOG_INFO("Partial wait start");
|
||||||
|
|
||||||
jd79653a_spi_send_cmd(0x12);
|
jd79653a_spi_send_cmd(0x12);
|
||||||
jd79653a_wait_busy(0);
|
jd79653a_wait_busy(0);
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Partial updated");
|
LV_LOG_INFO("Partial updated");
|
||||||
jd79653a_partial_out();
|
jd79653a_partial_out();
|
||||||
jd79653a_power_off();
|
jd79653a_power_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void jd79653a_reset(void);
|
||||||
|
|
||||||
void jd79653a_fb_set_full_color(uint8_t color)
|
void jd79653a_fb_set_full_color(uint8_t color)
|
||||||
{
|
{
|
||||||
jd79653a_power_on();
|
jd79653a_power_on();
|
||||||
|
@ -353,7 +365,7 @@ void jd79653a_fb_set_full_color(uint8_t color)
|
||||||
void jd79653a_fb_full_update(uint8_t *data, size_t len)
|
void jd79653a_fb_full_update(uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
jd79653a_power_on();
|
jd79653a_power_on();
|
||||||
ESP_LOGD(TAG, "Performing full update, len: %u", len);
|
LV_LOG_INFO("Performing full update, len: %u", len);
|
||||||
|
|
||||||
uint8_t *data_ptr = data;
|
uint8_t *data_ptr = data;
|
||||||
|
|
||||||
|
@ -372,7 +384,7 @@ void jd79653a_fb_full_update(uint8_t *data, size_t len)
|
||||||
len -= EPD_ROW_LEN;
|
len -= EPD_ROW_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Rest len: %u", len);
|
LV_LOG_INFO("Rest len: %u", len);
|
||||||
|
|
||||||
jd79653a_spi_send_cmd(0x12); // Issue refresh command
|
jd79653a_spi_send_cmd(0x12); // Issue refresh command
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
|
@ -381,7 +393,7 @@ void jd79653a_fb_full_update(uint8_t *data, size_t len)
|
||||||
jd79653a_power_off();
|
jd79653a_power_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
void jd79653a_lv_set_fb_cb(struct _disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
void jd79653a_lv_set_fb_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||||
lv_color_t color, lv_opa_t opa)
|
lv_color_t color, lv_opa_t opa)
|
||||||
{
|
{
|
||||||
uint16_t byte_index = (x >> 3u) + (y * EPD_ROW_LEN);
|
uint16_t byte_index = (x >> 3u) + (y * EPD_ROW_LEN);
|
||||||
|
@ -394,7 +406,7 @@ void jd79653a_lv_set_fb_cb(struct _disp_drv_t *disp_drv, uint8_t *buf, lv_coord_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void jd79653a_lv_rounder_cb(struct _disp_drv_t *disp_drv, lv_area_t *area)
|
void jd79653a_lv_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area)
|
||||||
{
|
{
|
||||||
// Always send full framebuffer if it's not in partial mode
|
// Always send full framebuffer if it's not in partial mode
|
||||||
area->x1 = 0;
|
area->x1 = 0;
|
||||||
|
@ -405,15 +417,16 @@ void jd79653a_lv_rounder_cb(struct _disp_drv_t *disp_drv, lv_area_t *area)
|
||||||
|
|
||||||
void jd79653a_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
|
void jd79653a_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
|
||||||
{
|
{
|
||||||
|
#if LV_USE_LOG
|
||||||
size_t len = ((area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1)) / 8;
|
size_t len = ((area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1)) / 8;
|
||||||
|
LV_LOG_INFO("x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", area->x1, area->x2, area->y1, area->y2);
|
||||||
ESP_LOGD(TAG, "x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", area->x1, area->x2, area->y1, area->y2);
|
LV_LOG_INFO("Writing LVGL fb with len: %u, partial counter: %u", len, partial_counter);
|
||||||
ESP_LOGD(TAG, "Writing LVGL fb with len: %u, partial counter: %u", len, partial_counter);
|
#endif
|
||||||
|
|
||||||
uint8_t *buf = (uint8_t *) color_map;
|
uint8_t *buf = (uint8_t *) color_map;
|
||||||
|
|
||||||
if (partial_counter == 0) {
|
if (partial_counter == 0) {
|
||||||
ESP_LOGD(TAG, "Refreshing in FULL");
|
LV_LOG_INFO("Refreshing in FULL");
|
||||||
jd79653a_fb_full_update(buf, ((EPD_HEIGHT * EPD_WIDTH) / 8));
|
jd79653a_fb_full_update(buf, ((EPD_HEIGHT * EPD_WIDTH) / 8));
|
||||||
partial_counter = EPD_PARTIAL_CNT; // Reset partial counter here
|
partial_counter = EPD_PARTIAL_CNT; // Reset partial counter here
|
||||||
} else {
|
} else {
|
||||||
|
@ -424,7 +437,7 @@ void jd79653a_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t
|
||||||
lv_disp_flush_ready(drv);
|
lv_disp_flush_ready(drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void jd79653a_deep_sleep()
|
void jd79653a_deep_sleep(void)
|
||||||
{
|
{
|
||||||
jd79653a_spi_send_seq(power_off_seq, EPD_SEQ_LEN(power_off_seq));
|
jd79653a_spi_send_seq(power_off_seq, EPD_SEQ_LEN(power_off_seq));
|
||||||
jd79653a_wait_busy(1000);
|
jd79653a_wait_busy(1000);
|
||||||
|
@ -434,25 +447,15 @@ void jd79653a_deep_sleep()
|
||||||
jd79653a_spi_send_data(&check_code, sizeof(check_code));
|
jd79653a_spi_send_data(&check_code, sizeof(check_code));
|
||||||
}
|
}
|
||||||
|
|
||||||
void jd79653a_init()
|
void jd79653a_init(void)
|
||||||
{
|
{
|
||||||
// Initialise event group
|
// Initialise event group
|
||||||
jd79653a_evts = xEventGroupCreate();
|
jd79653a_evts = xEventGroupCreate();
|
||||||
if (!jd79653a_evts) {
|
if (!jd79653a_evts) {
|
||||||
ESP_LOGE(TAG, "Failed when initialising event group!");
|
LV_LOG_ERROR("Failed when initialising event group!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup output pins, output (PP)
|
|
||||||
gpio_config_t out_io_conf = {
|
|
||||||
.intr_type = GPIO_INTR_DISABLE,
|
|
||||||
.mode = GPIO_MODE_OUTPUT,
|
|
||||||
.pin_bit_mask = PIN_DC_BIT | PIN_RST_BIT,
|
|
||||||
.pull_down_en = 0,
|
|
||||||
.pull_up_en = 0,
|
|
||||||
};
|
|
||||||
ESP_ERROR_CHECK(gpio_config(&out_io_conf));
|
|
||||||
|
|
||||||
// Setup input pin, pull-up, input
|
// Setup input pin, pull-up, input
|
||||||
gpio_config_t in_io_conf = {
|
gpio_config_t in_io_conf = {
|
||||||
.intr_type = GPIO_INTR_POSEDGE,
|
.intr_type = GPIO_INTR_POSEDGE,
|
||||||
|
@ -465,18 +468,25 @@ void jd79653a_init()
|
||||||
gpio_install_isr_service(0);
|
gpio_install_isr_service(0);
|
||||||
gpio_isr_handler_add(PIN_BUSY, jd79653a_busy_intr, (void *) PIN_BUSY);
|
gpio_isr_handler_add(PIN_BUSY, jd79653a_busy_intr, (void *) PIN_BUSY);
|
||||||
|
|
||||||
// Hardware reset
|
jd79653a_reset();
|
||||||
gpio_set_level(PIN_RST, 0);
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(15)); // At least 10ms, leave 15ms for now just in case...
|
|
||||||
gpio_set_level(PIN_RST, 1);
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(120));
|
|
||||||
|
|
||||||
// Dump in initialise sequence
|
// Dump in initialise sequence
|
||||||
jd79653a_spi_send_seq(init_seq, EPD_SEQ_LEN(init_seq));
|
jd79653a_spi_send_seq(init_seq, EPD_SEQ_LEN(init_seq));
|
||||||
ESP_LOGI(TAG, "Panel init sequence sent");
|
LV_LOG_INFO("Panel init sequence sent");
|
||||||
|
|
||||||
// Check BUSY status here
|
// Check BUSY status here
|
||||||
jd79653a_wait_busy(0);
|
jd79653a_wait_busy(0);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Panel is up!");
|
LV_LOG_INFO("Panel is up!");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void jd79653a_reset(void)
|
||||||
|
{
|
||||||
|
#if defined CONFIG_LV_DISP_PIN_RST
|
||||||
|
gpio_set_level(PIN_RST, 0);
|
||||||
|
// At least 10ms, leave 15ms for now just in case...
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(15));
|
||||||
|
gpio_set_level(PIN_RST, 1);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(120));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,12 @@ extern "C"
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void jd79653a_init();
|
void jd79653a_init(void);
|
||||||
void jd79653a_deep_sleep();
|
void jd79653a_deep_sleep(void);
|
||||||
|
|
||||||
void jd79653a_lv_set_fb_cb(struct _disp_drv_t * disp_drv, uint8_t* buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
void jd79653a_lv_set_fb_cb(lv_disp_drv_t * disp_drv, uint8_t* buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||||
lv_color_t color, lv_opa_t opa);
|
lv_color_t color, lv_opa_t opa);
|
||||||
void jd79653a_lv_rounder_cb(struct _disp_drv_t * disp_drv, lv_area_t *area);
|
void jd79653a_lv_rounder_cb(lv_disp_drv_t * disp_drv, lv_area_t *area);
|
||||||
void jd79653a_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
|
void jd79653a_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
|
||||||
|
|
||||||
void jd79653a_fb_set_full_color(uint8_t color);
|
void jd79653a_fb_set_full_color(uint8_t color);
|
||||||
|
|
|
@ -6,15 +6,11 @@
|
||||||
* https://github.com/olikraus/u8g2
|
* https://github.com/olikraus/u8g2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "disp_spi.h"
|
|
||||||
#include "driver/gpio.h"
|
|
||||||
|
|
||||||
#include <esp_log.h>
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
|
|
||||||
#include "pcd8544.h"
|
#include "pcd8544.h"
|
||||||
|
|
||||||
|
#include "disp_spi.h"
|
||||||
|
#include "display_port.h"
|
||||||
|
|
||||||
#define TAG "lv_pcd8544"
|
#define TAG "lv_pcd8544"
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
@ -27,24 +23,33 @@
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
static inline void set_cmd_mode(lv_disp_drv_t * drv)
|
||||||
|
{
|
||||||
|
display_port_gpio_dc(drv, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void pcd8544_send_cmd(uint8_t cmd)
|
static inline void set_data_mode(lv_disp_drv_t * drv)
|
||||||
|
{
|
||||||
|
display_port_gpio_dc(drv, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pcd8544_send_cmd(lv_disp_drv_t *drv, uint8_t cmd)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(PCD8544_DC, 0); /*Command mode*/
|
set_cmd_mode(drv);
|
||||||
disp_spi_send_data(&cmd, 1);
|
disp_spi_send_data(&cmd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcd8544_send_data(void * data, uint16_t length)
|
static void pcd8544_send_data(lv_disp_drv_t *drv, void * data, uint16_t length)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(PCD8544_DC, 1); /*Data mode*/
|
set_data_mode(drv);
|
||||||
disp_spi_send_data(data, length);
|
disp_spi_send_data(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcd8544_send_colors(void * data, uint16_t length)
|
static void pcd8544_send_colors(lv_disp_drv_t *drv, void * data, uint16_t length)
|
||||||
{
|
{
|
||||||
gpio_set_level(PCD8544_DC, 1); /*Data mode*/
|
set_data_mode(drv);
|
||||||
disp_spi_send_colors(data, length);
|
disp_spi_send_colors(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,37 +57,38 @@ static void pcd8544_send_colors(void * data, uint16_t length)
|
||||||
* GLOBAL FUNCTIONS
|
* GLOBAL FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
void pcd8544_init(void){
|
void pcd8544_reset(lv_disp_drv_t *drv)
|
||||||
|
{
|
||||||
// TODO: orientation
|
display_port_gpio_rst(drv, 0);
|
||||||
|
display_port_delay(drv, 100);
|
||||||
// Initialize non-SPI GPIOs
|
display_port_gpio_rst(drv, 1);
|
||||||
gpio_pad_select_gpio(PCD8544_DC);
|
display_port_delay(drv, 100);
|
||||||
gpio_set_direction(PCD8544_DC, GPIO_MODE_OUTPUT);
|
|
||||||
gpio_pad_select_gpio(PCD8544_RST);
|
|
||||||
gpio_set_direction(PCD8544_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
// Reset the display
|
|
||||||
gpio_set_level(PCD8544_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(PCD8544_RST, 1);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
|
|
||||||
pcd8544_send_cmd(0x21); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */
|
|
||||||
pcd8544_send_cmd(0x06); /* temp. control: b10 = 2 */
|
|
||||||
pcd8544_send_cmd(0x13); /* bias system 1:48 */
|
|
||||||
pcd8544_send_cmd(0xc0); /* medium Vop = Contrast 0x40 = 64 */
|
|
||||||
|
|
||||||
pcd8544_send_cmd(0x20); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=0) */
|
|
||||||
pcd8544_send_cmd(0x0c); /* display mode normal */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcd8544_set_contrast (uint8_t contrast){
|
void pcd8544_init(lv_disp_drv_t *drv)
|
||||||
|
{
|
||||||
|
// TODO: orientation
|
||||||
|
|
||||||
|
// Reset the display
|
||||||
|
pcd8544_reset(drv);
|
||||||
|
|
||||||
|
pcd8544_send_cmd(drv, 0x21); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */
|
||||||
|
pcd8544_send_cmd(drv, 0x06); /* temp. control: b10 = 2 */
|
||||||
|
pcd8544_send_cmd(drv, 0x13); /* bias system 1:48 */
|
||||||
|
pcd8544_send_cmd(drv, 0xc0); /* medium Vop = Contrast 0x40 = 64 */
|
||||||
|
|
||||||
|
pcd8544_send_cmd(drv, 0x20); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=0) */
|
||||||
|
pcd8544_send_cmd(drv, 0x0c); /* display mode normal */
|
||||||
|
}
|
||||||
|
|
||||||
|
void pcd8544_set_contrast(lv_disp_drv_t *drv, uint8_t contrast)
|
||||||
|
{
|
||||||
if (contrast > 0x7f){
|
if (contrast > 0x7f){
|
||||||
contrast = 0x7f;
|
contrast = 0x7f;
|
||||||
}
|
}
|
||||||
pcd8544_send_cmd(0x21); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */
|
|
||||||
pcd8544_send_cmd(0x80 | contrast); /* medium Vop = Contrast */
|
pcd8544_send_cmd(drv, 0x21); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */
|
||||||
|
pcd8544_send_cmd(drv, 0x80 | contrast); /* medium Vop = Contrast */
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcd8544_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area){
|
void pcd8544_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area){
|
||||||
|
@ -112,7 +118,7 @@ void pcd8544_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w
|
||||||
|
|
||||||
void pcd8544_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_map){
|
void pcd8544_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_map){
|
||||||
|
|
||||||
pcd8544_send_cmd(0x20); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=0) */
|
pcd8544_send_cmd(disp_drv, 0x20); /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=0) */
|
||||||
|
|
||||||
uint8_t * buf = (uint8_t *) color_map;
|
uint8_t * buf = (uint8_t *) color_map;
|
||||||
|
|
||||||
|
@ -123,9 +129,9 @@ void pcd8544_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t
|
||||||
// send complete frame buffer at once.
|
// send complete frame buffer at once.
|
||||||
// NOTE: disp_spi_send_colors triggers lv_disp_flush_ready
|
// NOTE: disp_spi_send_colors triggers lv_disp_flush_ready
|
||||||
|
|
||||||
pcd8544_send_cmd(0x40); /* set Y address */
|
pcd8544_send_cmd(disp_drv, 0x40); /* set Y address */
|
||||||
pcd8544_send_cmd(0x80); /* set X address */
|
pcd8544_send_cmd(disp_drv, 0x80); /* set X address */
|
||||||
pcd8544_send_colors(buf, disp_drv->hor_res * disp_drv->ver_res / 8);
|
pcd8544_send_colors(disp_drv, buf, disp_drv->hor_res * disp_drv->ver_res / 8);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -137,10 +143,10 @@ void pcd8544_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t
|
||||||
uint16_t bank;
|
uint16_t bank;
|
||||||
uint16_t cols_to_update = area->x2 - area->x1 + 1;
|
uint16_t cols_to_update = area->x2 - area->x1 + 1;
|
||||||
for (bank = bank_start ; bank <= bank_end ; bank++){
|
for (bank = bank_start ; bank <= bank_end ; bank++){
|
||||||
pcd8544_send_cmd(0x40 | bank ); /* set Y address */
|
pcd8544_send_cmd(disp_drv, 0x40 | bank); /* set Y address */
|
||||||
pcd8544_send_cmd(0x80 | area->x1 ); /* set X address */
|
pcd8544_send_cmd(disp_drv, 0x80 | area->x1); /* set X address */
|
||||||
uint16_t offset = bank * disp_drv->hor_res + area->x1;
|
uint16_t offset = bank * disp_drv->hor_res + area->x1;
|
||||||
pcd8544_send_data(&buf[offset], cols_to_update);
|
pcd8544_send_data(disp_drv, &buf[offset], cols_to_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_disp_flush_ready(disp_drv);
|
lv_disp_flush_ready(disp_drv);
|
||||||
|
|
|
@ -26,10 +26,6 @@ extern "C" {
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
|
|
||||||
#define PCD8544_DC CONFIG_LV_DISP_PIN_DC
|
|
||||||
#define PCD8544_RST CONFIG_LV_DISP_PIN_RST
|
|
||||||
#define PCD8544_BCKL CONFIG_LV_DISP_PIN_BCKL
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -38,12 +34,12 @@ extern "C" {
|
||||||
* GLOBAL PROTOTYPES
|
* GLOBAL PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
void pcd8544_init(void);
|
void pcd8544_init(lv_disp_drv_t *drv);
|
||||||
void pcd8544_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
void pcd8544_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
||||||
void pcd8544_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area);
|
void pcd8544_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area);
|
||||||
void pcd8544_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
void pcd8544_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||||
lv_color_t color, lv_opa_t opa);
|
lv_color_t color, lv_opa_t opa);
|
||||||
void pcd8544_set_contrast(uint8_t contrast);
|
void pcd8544_set_contrast(lv_disp_drv_t *drv, uint8_t contrast);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
|
|
|
@ -9,16 +9,12 @@
|
||||||
#include "ra8875.h"
|
#include "ra8875.h"
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define DEBUG false
|
|
||||||
#define TAG "RA8875"
|
|
||||||
|
|
||||||
#define DIV_ROUND_UP(n, d) (((n)+(d)-1)/(d))
|
#define DIV_ROUND_UP(n, d) (((n)+(d)-1)/(d))
|
||||||
|
|
||||||
#define SPI_CLOCK_SPEED_SLOW_HZ 1000000
|
#define SPI_CLOCK_SPEED_SLOW_HZ 1000000
|
||||||
|
@ -28,6 +24,45 @@
|
||||||
#define RA8875_MODE_CMD_WRITE (0x80)
|
#define RA8875_MODE_CMD_WRITE (0x80)
|
||||||
#define RA8875_MODE_STATUS_READ (0xC0)
|
#define RA8875_MODE_STATUS_READ (0xC0)
|
||||||
|
|
||||||
|
#define BYTES_PER_PIXEL (LV_COLOR_DEPTH / 8)
|
||||||
|
|
||||||
|
#if defined (LV_HOR_RES_MAX)
|
||||||
|
#define HDWR_VAL (LV_HOR_RES_MAX/8 - 1)
|
||||||
|
#else
|
||||||
|
/* ToDo Remove magic number 256u */
|
||||||
|
#define HDWR_VAL (256u/8u - 1u)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (LV_VER_RES_MAX)
|
||||||
|
#define VDHR_VAL (LV_VER_RES_MAX - 1)
|
||||||
|
#else
|
||||||
|
/* ToDo Remove magic number 128u */
|
||||||
|
#define VDHR_VAL (128u - 1u)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VDIR_MASK (1 << 2)
|
||||||
|
#define HDIR_MASK (1 << 3)
|
||||||
|
|
||||||
|
#ifndef CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875
|
||||||
|
// Use this settings if there is no Kconfig settings defined
|
||||||
|
#define SYSR_VAL (0x00)
|
||||||
|
#define DPCR_VAL (0x00)
|
||||||
|
#define PCSR_VAL (0x00)
|
||||||
|
#define HNDR_VAL (0x00)
|
||||||
|
#define HNDFTR_VAL (0x00)
|
||||||
|
#define HSTR_VAL (0x00)
|
||||||
|
#define HPW (0x00)
|
||||||
|
#define HPWR_VAL (0x00)
|
||||||
|
#define VNDR_VAL (0x00)
|
||||||
|
#define VSTR_VAL (0x00)
|
||||||
|
#define VPW (0x00)
|
||||||
|
#define VPWR_VAL (0x00)
|
||||||
|
#define CONFIG_LV_DISP_RA8875_PLLDIVM (0x00)
|
||||||
|
#define CONFIG_LV_DISP_RA8875_PLLDIVN (0x00)
|
||||||
|
#define CONFIG_LV_DISP_RA8875_PLLDIVK (0x00)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#if (LV_COLOR_DEPTH == 8)
|
#if (LV_COLOR_DEPTH == 8)
|
||||||
#define SYSR_VAL (0x00)
|
#define SYSR_VAL (0x00)
|
||||||
#elif (LV_COLOR_DEPTH == 16)
|
#elif (LV_COLOR_DEPTH == 16)
|
||||||
|
@ -35,13 +70,6 @@
|
||||||
#else
|
#else
|
||||||
#error "Unsupported color depth (LV_COLOR_DEPTH)"
|
#error "Unsupported color depth (LV_COLOR_DEPTH)"
|
||||||
#endif
|
#endif
|
||||||
#define BYTES_PER_PIXEL (LV_COLOR_DEPTH / 8)
|
|
||||||
|
|
||||||
#define HDWR_VAL (LV_HOR_RES_MAX/8 - 1)
|
|
||||||
#define VDHR_VAL (LV_VER_RES_MAX - 1)
|
|
||||||
|
|
||||||
#define VDIR_MASK (1 << 2)
|
|
||||||
#define HDIR_MASK (1 << 3)
|
|
||||||
|
|
||||||
#if ( CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED || CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED )
|
#if ( CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED || CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED )
|
||||||
#if CONFIG_LV_INVERT_DISPLAY
|
#if CONFIG_LV_INVERT_DISPLAY
|
||||||
|
@ -92,6 +120,7 @@
|
||||||
#else
|
#else
|
||||||
#define VPWR_VAL (VPW)
|
#define VPWR_VAL (VPW)
|
||||||
#endif
|
#endif
|
||||||
|
#endif // CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
|
@ -104,7 +133,7 @@ static void ra8875_configure_clocks(bool high_speed);
|
||||||
static void ra8875_set_memory_write_cursor(unsigned int x, unsigned int y);
|
static void ra8875_set_memory_write_cursor(unsigned int x, unsigned int y);
|
||||||
static void ra8875_set_window(unsigned int xs, unsigned int xe, unsigned int ys, unsigned int ye);
|
static void ra8875_set_window(unsigned int xs, unsigned int xe, unsigned int ys, unsigned int ye);
|
||||||
static void ra8875_send_buffer(uint8_t * data, size_t length, bool signal_flush);
|
static void ra8875_send_buffer(uint8_t * data, size_t length, bool signal_flush);
|
||||||
|
static void ra8875_reset(void);
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -119,6 +148,9 @@ static void ra8875_send_buffer(uint8_t * data, size_t length, bool signal_flush)
|
||||||
|
|
||||||
void ra8875_init(void)
|
void ra8875_init(void)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875
|
||||||
|
assert(false); // This driver is not properly configured
|
||||||
|
#endif
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -146,20 +178,9 @@ void ra8875_init(void)
|
||||||
};
|
};
|
||||||
#define INIT_CMDS_SIZE (sizeof(init_cmds)/sizeof(init_cmds[0]))
|
#define INIT_CMDS_SIZE (sizeof(init_cmds)/sizeof(init_cmds[0]))
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Initializing RA8875...");
|
LV_LOG_INFO("Initializing RA8875...");
|
||||||
|
|
||||||
// Initialize non-SPI GPIOs
|
ra8875_reset();
|
||||||
|
|
||||||
#if RA8875_USE_RST
|
|
||||||
gpio_pad_select_gpio(RA8875_RST);
|
|
||||||
gpio_set_direction(RA8875_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
// Reset the RA8875
|
|
||||||
gpio_set_level(RA8875_RST, 0);
|
|
||||||
vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS));
|
|
||||||
gpio_set_level(RA8875_RST, 1);
|
|
||||||
vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Initalize RA8875 clocks (SPI must be decelerated before initializing clocks)
|
// Initalize RA8875 clocks (SPI must be decelerated before initializing clocks)
|
||||||
disp_spi_change_device_speed(SPI_CLOCK_SPEED_SLOW_HZ);
|
disp_spi_change_device_speed(SPI_CLOCK_SPEED_SLOW_HZ);
|
||||||
|
@ -180,7 +201,7 @@ void ra8875_init(void)
|
||||||
vTaskDelay(1);
|
vTaskDelay(1);
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
ESP_LOGW(TAG, "WARNING: Memory clear timed out; RA8875 may be unresponsive.");
|
LV_LOG_WARN("WARNING: Memory clear timed out; RA8875 may be unresponsive.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable the display
|
// Enable the display
|
||||||
|
@ -189,7 +210,7 @@ void ra8875_init(void)
|
||||||
|
|
||||||
void ra8875_enable_display(bool enable)
|
void ra8875_enable_display(bool enable)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "%s display.", enable ? "Enabling" : "Disabling");
|
LV_LOG_INFO("%s display.", enable ? "Enabling" : "Disabling");
|
||||||
uint8_t val = enable ? (0x80) : (0x00);
|
uint8_t val = enable ? (0x80) : (0x00);
|
||||||
ra8875_write_cmd(RA8875_REG_PWRR, val); // Power and Display Control Register (PWRR)
|
ra8875_write_cmd(RA8875_REG_PWRR, val); // Power and Display Control Register (PWRR)
|
||||||
}
|
}
|
||||||
|
@ -205,35 +226,47 @@ void ra8875_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
|
||||||
size_t linelen = (area->x2 - area->x1 + 1);
|
size_t linelen = (area->x2 - area->x1 + 1);
|
||||||
uint8_t * buffer = (uint8_t*)color_map;
|
uint8_t * buffer = (uint8_t*)color_map;
|
||||||
|
|
||||||
#if DEBUG
|
LV_LOG_INFO("flush: %d,%d at %d,%d", area->x1, area->x2, area->y1, area->y2 );
|
||||||
ESP_LOGI(TAG, "flush: %d,%d at %d,%d", area->x1, area->x2, area->y1, area->y2 );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
disp_spi_acquire();
|
disp_spi_acquire();
|
||||||
|
|
||||||
// Set window if needed
|
// Set window if needed
|
||||||
if ((x1 != area->x1) || (x2 != area->x2)) {
|
if ((x1 != area->x1) || (x2 != area->x2)) {
|
||||||
#if DEBUG
|
LV_LOG_INFO("flush: set window (x1,x2): %d,%d -> %d,%d", x1, x2, area->x1, area->x2);
|
||||||
ESP_LOGI(TAG, "flush: set window (x1,x2): %d,%d -> %d,%d", x1, x2, area->x1, area->x2);
|
unsigned int ye = 0;
|
||||||
|
|
||||||
|
#if LVGL_VERSION_MAJOR < 8
|
||||||
|
ye = LV_VER_RES_MAX - 1;
|
||||||
|
#else
|
||||||
|
/* ToDo Get y end from driver information */
|
||||||
#endif
|
#endif
|
||||||
ra8875_set_window(area->x1, area->x2, 0, LV_VER_RES_MAX-1);
|
|
||||||
|
ra8875_set_window(area->x1, area->x2, 0, ye);
|
||||||
|
|
||||||
x1 = area->x1;
|
x1 = area->x1;
|
||||||
x2 = area->x2;
|
x2 = area->x2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set cursor if needed
|
// Set cursor if needed
|
||||||
if ((x != area->x1) || (y != area->y1)) {
|
if ((x != area->x1) || (y != area->y1)) {
|
||||||
#if DEBUG
|
LV_LOG_INFO("flush: set cursor (x,y): %d,%d -> %d,%d", x, y, area->x1, area->y1);
|
||||||
ESP_LOGI(TAG, "flush: set cursor (x,y): %d,%d -> %d,%d", x, y, area->x1, area->y1);
|
|
||||||
#endif
|
|
||||||
ra8875_set_memory_write_cursor(area->x1, area->y1);
|
ra8875_set_memory_write_cursor(area->x1, area->y1);
|
||||||
x = area->x1;
|
x = area->x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update to future cursor location
|
// Update to future cursor location
|
||||||
y = area->y2 + 1;
|
y = area->y2 + 1;
|
||||||
if (y >= LV_VER_RES_MAX) {
|
lv_coord_t ver_max = 0;
|
||||||
|
|
||||||
|
#if LVGL_VERSION_MAJOR < 8
|
||||||
|
ver_max = LV_VER_RES_MAX;
|
||||||
|
#else
|
||||||
|
/* ToDo Get vertical max from driver information */
|
||||||
|
ver_max = lv_disp_get_ver_res((lv_disp_t *) drv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (y >= ver_max) {
|
||||||
y = 0;
|
y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,3 +365,13 @@ static void ra8875_send_buffer(uint8_t * data, size_t length, bool signal_flush)
|
||||||
| (RA8875_MODE_DATA_WRITE); // Data write mode
|
| (RA8875_MODE_DATA_WRITE); // Data write mode
|
||||||
disp_spi_transaction(data, length, flags, NULL, prefix, 0);
|
disp_spi_transaction(data, length, flags, NULL, prefix, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ra8875_reset(void)
|
||||||
|
{
|
||||||
|
#if RA8875_USE_RST
|
||||||
|
gpio_set_level(RA8875_RST, 0);
|
||||||
|
vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS));
|
||||||
|
gpio_set_level(RA8875_RST, 1);
|
||||||
|
vTaskDelay(DIV_ROUND_UP(100, portTICK_RATE_MS));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "SH1107"
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
|
@ -35,6 +34,10 @@ typedef struct {
|
||||||
static void sh1107_send_cmd(uint8_t cmd);
|
static void sh1107_send_cmd(uint8_t cmd);
|
||||||
static void sh1107_send_data(void * data, uint16_t length);
|
static void sh1107_send_data(void * data, uint16_t length);
|
||||||
static void sh1107_send_color(void * data, uint16_t length);
|
static void sh1107_send_color(void * data, uint16_t length);
|
||||||
|
static void sh1107_reset(void);
|
||||||
|
|
||||||
|
static lv_coord_t get_display_ver_res(lv_disp_drv_t *disp_drv);
|
||||||
|
static lv_coord_t get_display_hor_res(lv_disp_drv_t *disp_drv);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
|
@ -91,20 +94,7 @@ void sh1107_init(void)
|
||||||
{0, {0}, 0xff},
|
{0, {0}, 0xff},
|
||||||
};
|
};
|
||||||
|
|
||||||
//Initialize non-SPI GPIOs
|
sh1107_reset();
|
||||||
gpio_pad_select_gpio(SH1107_DC);
|
|
||||||
gpio_set_direction(SH1107_DC, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
#if SH1107_USE_RST
|
|
||||||
gpio_pad_select_gpio(SH1107_RST);
|
|
||||||
gpio_set_direction(SH1107_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
gpio_set_level(SH1107_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(SH1107_RST, 1);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
|
@ -118,7 +108,7 @@ void sh1107_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sh1107_set_px_cb(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
void sh1107_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||||
lv_color_t color, lv_opa_t opa)
|
lv_color_t color, lv_opa_t opa)
|
||||||
{
|
{
|
||||||
/* buf_w will be ignored, the configured CONFIG_LV_DISPLAY_HEIGHT and _WIDTH,
|
/* buf_w will be ignored, the configured CONFIG_LV_DISPLAY_HEIGHT and _WIDTH,
|
||||||
|
@ -127,10 +117,10 @@ void sh1107_set_px_cb(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t b
|
||||||
uint8_t bit_index = 0;
|
uint8_t bit_index = 0;
|
||||||
|
|
||||||
#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
|
#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
|
||||||
byte_index = y + (( x>>3 ) * LV_VER_RES_MAX);
|
byte_index = y + (( x>>3 ) * get_display_ver_res(disp_drv));
|
||||||
bit_index = x & 0x7;
|
bit_index = x & 0x7;
|
||||||
#elif defined CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT
|
#elif defined CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT
|
||||||
byte_index = x + (( y>>3 ) * LV_HOR_RES_MAX);
|
byte_index = x + (( y>>3 ) * get_display_hor_res(disp_drv));
|
||||||
bit_index = y & 0x7;
|
bit_index = y & 0x7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -162,9 +152,9 @@ void sh1107_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
|
||||||
sh1107_send_cmd(0xB0 | i); // Set Page Start Address for Page Addressing Mode
|
sh1107_send_cmd(0xB0 | i); // Set Page Start Address for Page Addressing Mode
|
||||||
size = area->y2 - area->y1 + 1;
|
size = area->y2 - area->y1 + 1;
|
||||||
#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
|
#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
|
||||||
ptr = color_map + i * LV_VER_RES_MAX;
|
ptr = color_map + i * get_display_ver_res(drv);
|
||||||
#else
|
#else
|
||||||
ptr = color_map + i * LV_HOR_RES_MAX;
|
ptr = color_map + i * get_display_hor_res(drv);
|
||||||
#endif
|
#endif
|
||||||
if(i != row2){
|
if(i != row2){
|
||||||
sh1107_send_data( (void *) ptr, size);
|
sh1107_send_data( (void *) ptr, size);
|
||||||
|
@ -175,21 +165,21 @@ void sh1107_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sh1107_rounder(struct _disp_drv_t * disp_drv, lv_area_t *area)
|
void sh1107_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area)
|
||||||
{
|
{
|
||||||
// workaround: always send complete size display buffer
|
// workaround: always send complete size display buffer
|
||||||
area->x1 = 0;
|
area->x1 = 0;
|
||||||
area->y1 = 0;
|
area->y1 = 0;
|
||||||
area->x2 = LV_HOR_RES_MAX-1;
|
area->x2 = get_display_hor_res(disp_drv) - 1;
|
||||||
area->y2 = LV_VER_RES_MAX-1;
|
area->y2 = get_display_ver_res(disp_drv) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sh1107_sleep_in()
|
void sh1107_sleep_in(void)
|
||||||
{
|
{
|
||||||
sh1107_send_cmd(0xAE);
|
sh1107_send_cmd(0xAE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sh1107_sleep_out()
|
void sh1107_sleep_out(void)
|
||||||
{
|
{
|
||||||
sh1107_send_cmd(0xAF);
|
sh1107_send_cmd(0xAF);
|
||||||
}
|
}
|
||||||
|
@ -219,3 +209,49 @@ static void sh1107_send_color(void * data, uint16_t length)
|
||||||
gpio_set_level(SH1107_DC, 1); /*Data mode*/
|
gpio_set_level(SH1107_DC, 1); /*Data mode*/
|
||||||
disp_spi_send_colors(data, length);
|
disp_spi_send_colors(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static lv_coord_t get_display_ver_res(lv_disp_drv_t *disp_drv)
|
||||||
|
{
|
||||||
|
lv_coord_t val = 0;
|
||||||
|
|
||||||
|
#if LVGL_VERSION_MAJOR < 8
|
||||||
|
#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
|
||||||
|
val = LV_VER_RES_MAX;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* ToDo Use display rotation API to get vertical size */
|
||||||
|
#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
|
||||||
|
val = lv_disp_get_ver_res((lv_disp_t *) disp_drv);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static lv_coord_t get_display_hor_res(lv_disp_drv_t *disp_drv)
|
||||||
|
{
|
||||||
|
lv_coord_t val = 0;
|
||||||
|
|
||||||
|
#if LVGL_VERSION_MAJOR < 8
|
||||||
|
#if defined CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT
|
||||||
|
val = LV_HOR_RES_MAX;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* ToDo Use display rotation API to get horizontal size */
|
||||||
|
#if defined CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT
|
||||||
|
val = lv_disp_get_hor_res((lv_disp_t *) disp_drv);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sh1107_reset(void)
|
||||||
|
{
|
||||||
|
#if SH1107_USE_RST
|
||||||
|
gpio_set_level(SH1107_RST, 0);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
gpio_set_level(SH1107_RST, 1);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -39,8 +39,8 @@ extern "C" {
|
||||||
|
|
||||||
void sh1107_init(void);
|
void sh1107_init(void);
|
||||||
void sh1107_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
void sh1107_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
|
||||||
void sh1107_rounder(struct _disp_drv_t * disp_drv, lv_area_t *area);
|
void sh1107_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area);
|
||||||
void sh1107_set_px_cb(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
void sh1107_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||||
lv_color_t color, lv_opa_t opa);
|
lv_color_t color, lv_opa_t opa);
|
||||||
void sh1107_sleep_in(void);
|
void sh1107_sleep_in(void);
|
||||||
void sh1107_sleep_out(void);
|
void sh1107_sleep_out(void);
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "SSD1306"
|
|
||||||
|
|
||||||
#define OLED_I2C_PORT (CONFIG_LV_I2C_DISPLAY_PORT)
|
#define OLED_I2C_PORT (CONFIG_LV_I2C_DISPLAY_PORT)
|
||||||
// SLA (0x3C) + WRITE_MODE (0x00) = 0x78 (0b01111000)
|
// SLA (0x3C) + WRITE_MODE (0x00) = 0x78 (0b01111000)
|
||||||
#define OLED_I2C_ADDRESS 0x3C
|
#define OLED_I2C_ADDRESS 0x3C
|
||||||
|
@ -106,7 +104,7 @@ void ssd1306_init(void)
|
||||||
orientation_1 = 0xA0;
|
orientation_1 = 0xA0;
|
||||||
orientation_2 = OLED_CMD_SET_COM_SCAN_MODE_NORMAL;
|
orientation_2 = OLED_CMD_SET_COM_SCAN_MODE_NORMAL;
|
||||||
#else
|
#else
|
||||||
#error "Unsupported orientation"
|
assert(false); // Invalid configuration of SSD1306 driver
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t display_mode = 0;
|
uint8_t display_mode = 0;
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "st7735s.h"
|
#include "st7735s.h"
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
@ -20,7 +19,6 @@
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "ST7735S"
|
|
||||||
#define AXP192_I2C_ADDRESS 0x34
|
#define AXP192_I2C_ADDRESS 0x34
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
@ -41,10 +39,14 @@ static void st7735s_send_cmd(uint8_t cmd);
|
||||||
static void st7735s_send_data(void * data, uint16_t length);
|
static void st7735s_send_data(void * data, uint16_t length);
|
||||||
static void st7735s_send_color(void * data, uint16_t length);
|
static void st7735s_send_color(void * data, uint16_t length);
|
||||||
static void st7735s_set_orientation(uint8_t orientation);
|
static void st7735s_set_orientation(uint8_t orientation);
|
||||||
|
static void st7735s_reset(void);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192
|
||||||
static void axp192_write_byte(uint8_t addr, uint8_t data);
|
static void axp192_write_byte(uint8_t addr, uint8_t data);
|
||||||
static void axp192_init();
|
static void axp192_init();
|
||||||
static void axp192_sleep_in();
|
static void axp192_sleep_in();
|
||||||
static void axp192_sleep_out();
|
static void axp192_sleep_out();
|
||||||
|
#endif
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
|
@ -97,22 +99,9 @@ void st7735s_init(void)
|
||||||
{0, {0}, 0xff}
|
{0, {0}, 0xff}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Initialize non-SPI GPIOs
|
st7735s_reset();
|
||||||
gpio_pad_select_gpio(ST7735S_DC);
|
|
||||||
gpio_set_direction(ST7735S_DC, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
#if ST7735S_USE_RST
|
LV_LOG_INFO("ST7735S initialization.");
|
||||||
gpio_pad_select_gpio(ST7735S_RST);
|
|
||||||
gpio_set_direction(ST7735S_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
gpio_set_level(ST7735S_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(ST7735S_RST, 1);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "ST7735S initialization.");
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
|
@ -136,7 +125,7 @@ void st7735s_init(void)
|
||||||
|
|
||||||
void st7735s_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
void st7735s_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
||||||
{
|
{
|
||||||
uint8_t data[4];
|
uint8_t data[4] = {0};
|
||||||
|
|
||||||
/*Column addresses*/
|
/*Column addresses*/
|
||||||
st7735s_send_cmd(0x2A);
|
st7735s_send_cmd(0x2A);
|
||||||
|
@ -157,8 +146,8 @@ void st7735s_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * col
|
||||||
/*Memory write*/
|
/*Memory write*/
|
||||||
st7735s_send_cmd(0x2C);
|
st7735s_send_cmd(0x2C);
|
||||||
|
|
||||||
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
|
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area) * 2;
|
||||||
st7735s_send_color((void*)color_map, size * 2);
|
st7735s_send_color((void*)color_map, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void st7735s_sleep_in()
|
void st7735s_sleep_in()
|
||||||
|
@ -204,11 +193,7 @@ static void st7735s_send_color(void * data, uint16_t length)
|
||||||
|
|
||||||
static void st7735s_set_orientation(uint8_t orientation)
|
static void st7735s_set_orientation(uint8_t orientation)
|
||||||
{
|
{
|
||||||
const char *orientation_str[] = {
|
assert(orientation < 4);
|
||||||
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
|
||||||
};
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Display orientation: %s", orientation_str[orientation]);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Portrait: 0xC8 = ST77XX_MADCTL_MX | ST77XX_MADCTL_MY | ST77XX_MADCTL_BGR
|
Portrait: 0xC8 = ST77XX_MADCTL_MX | ST77XX_MADCTL_MY | ST77XX_MADCTL_BGR
|
||||||
|
@ -217,19 +202,36 @@ static void st7735s_set_orientation(uint8_t orientation)
|
||||||
*/
|
*/
|
||||||
uint8_t data[] = {0xC8, 0xC8, 0xA8, 0xA8};
|
uint8_t data[] = {0xC8, 0xC8, 0xA8, 0xA8};
|
||||||
|
|
||||||
ESP_LOGD(TAG, "0x36 command value: 0x%02X", data[orientation]);
|
#if (LV_USE_LOG == 1)
|
||||||
|
const char *orientation_str[] = {
|
||||||
|
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
||||||
|
};
|
||||||
|
|
||||||
|
LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]);
|
||||||
|
LV_LOG_INFO("0x36 command value: 0x%02X", data[orientation]);
|
||||||
|
#endif
|
||||||
|
|
||||||
st7735s_send_cmd(ST7735_MADCTL);
|
st7735s_send_cmd(ST7735_MADCTL);
|
||||||
st7735s_send_data((void *) &data[orientation], 1);
|
st7735s_send_data((void *) &data[orientation], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void st7735s_reset(void)
|
||||||
|
{
|
||||||
|
#if ST7735S_USE_RST
|
||||||
|
gpio_set_level(ST7735S_RST, 0);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
gpio_set_level(ST7735S_RST, 1);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192
|
#ifdef CONFIG_LV_M5STICKC_HANDLE_AXP192
|
||||||
|
|
||||||
static void axp192_write_byte(uint8_t addr, uint8_t data)
|
static void axp192_write_byte(uint8_t addr, uint8_t data)
|
||||||
{
|
{
|
||||||
err = lvgl_i2c_write(CONFIG_LV_I2C_DISPLAY_PORT, AXP192_I2C_ADDRESS, addr, &data, 1);
|
err = lvgl_i2c_write(CONFIG_LV_I2C_DISPLAY_PORT, AXP192_I2C_ADDRESS, addr, &data, 1);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "AXP192 send failed. code: 0x%.2X", ret);
|
LV_LOG_ERROR("AXP192 send failed. code: 0x%.2X", ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +243,7 @@ static void st7735s_set_orientation(uint8_t orientation)
|
||||||
axp192_write_byte(0x10, 0xFF); // OLED_VPP Enable
|
axp192_write_byte(0x10, 0xFF); // OLED_VPP Enable
|
||||||
axp192_write_byte(0x28, 0xCC); // Enable LDO2&LDO3, LED&TFT 3.0V
|
axp192_write_byte(0x28, 0xCC); // Enable LDO2&LDO3, LED&TFT 3.0V
|
||||||
axp192_sleep_out();
|
axp192_sleep_out();
|
||||||
ESP_LOGI(TAG, "AXP192 initialized, power enabled for LDO2 and LDO3");
|
LV_LOG_INFO("AXP192 initialized, power enabled for LDO2 and LDO3");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void axp192_sleep_in()
|
static void axp192_sleep_in()
|
||||||
|
|
|
@ -4,21 +4,15 @@
|
||||||
* Mostly taken from lbthomsen/esp-idf-littlevgl github.
|
* Mostly taken from lbthomsen/esp-idf-littlevgl github.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
|
|
||||||
#include "esp_log.h"
|
|
||||||
|
|
||||||
#include "st7789.h"
|
#include "st7789.h"
|
||||||
|
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "driver/gpio.h"
|
#include "display_port.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "st7789"
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
@ -33,13 +27,18 @@ typedef struct {
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
static void st7789_set_orientation(uint8_t orientation);
|
static void st7789_set_orientation(lv_disp_drv_t *drv, uint8_t orientation);
|
||||||
|
static void st7789_send_cmd(lv_disp_drv_t * drv, uint8_t cmd);
|
||||||
static void st7789_send_color(void *data, size_t length);
|
static void st7789_send_data(lv_disp_drv_t * drv, void *data, uint16_t length);
|
||||||
|
static void st7789_send_color(lv_disp_drv_t * drv, void *data, uint16_t length);
|
||||||
|
static void st7789_reset(lv_disp_drv_t * drv);
|
||||||
|
|
||||||
|
static void setup_initial_offsets(void);
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
|
static uint16_t user_x_offset = 0u;
|
||||||
|
static uint16_t user_y_offset = 0u;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
|
@ -48,8 +47,10 @@ static void st7789_send_color(void *data, size_t length);
|
||||||
/**********************
|
/**********************
|
||||||
* GLOBAL FUNCTIONS
|
* GLOBAL FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
void st7789_init(void)
|
void st7789_init(lv_disp_drv_t *drv)
|
||||||
{
|
{
|
||||||
|
setup_initial_offsets();
|
||||||
|
|
||||||
lcd_init_cmd_t st7789_init_cmds[] = {
|
lcd_init_cmd_t st7789_init_cmds[] = {
|
||||||
{0xCF, {0x00, 0x83, 0X30}, 3},
|
{0xCF, {0x00, 0x83, 0X30}, 3},
|
||||||
{0xED, {0x64, 0x03, 0X12, 0X81}, 4},
|
{0xED, {0x64, 0x03, 0X12, 0X81}, 4},
|
||||||
|
@ -85,44 +86,26 @@ void st7789_init(void)
|
||||||
{0, {0}, 0xff},
|
{0, {0}, 0xff},
|
||||||
};
|
};
|
||||||
|
|
||||||
//Initialize non-SPI GPIOs
|
st7789_reset(drv);
|
||||||
gpio_pad_select_gpio(ST7789_DC);
|
|
||||||
gpio_set_direction(ST7789_DC, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
#if !defined(ST7789_SOFT_RST)
|
|
||||||
gpio_pad_select_gpio(ST7789_RST);
|
|
||||||
gpio_set_direction(ST7789_RST, GPIO_MODE_OUTPUT);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
#if !defined(ST7789_SOFT_RST)
|
|
||||||
gpio_set_level(ST7789_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(ST7789_RST, 1);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
#else
|
|
||||||
st7789_send_cmd(ST7789_SWRESET);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
printf("ST7789 initialization.\n");
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
while (st7789_init_cmds[cmd].databytes!=0xff) {
|
while (st7789_init_cmds[cmd].databytes!=0xff) {
|
||||||
st7789_send_cmd(st7789_init_cmds[cmd].cmd);
|
st7789_send_cmd(drv, st7789_init_cmds[cmd].cmd);
|
||||||
st7789_send_data(st7789_init_cmds[cmd].data, st7789_init_cmds[cmd].databytes&0x1F);
|
st7789_send_data(drv, st7789_init_cmds[cmd].data, st7789_init_cmds[cmd].databytes&0x1F);
|
||||||
if (st7789_init_cmds[cmd].databytes & 0x80) {
|
if (st7789_init_cmds[cmd].databytes & 0x80) {
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
display_port_delay(drv, 100);
|
||||||
}
|
}
|
||||||
cmd++;
|
cmd++;
|
||||||
}
|
}
|
||||||
|
|
||||||
st7789_set_orientation(CONFIG_LV_DISPLAY_ORIENTATION);
|
/* FIXME We're setting up the initial orientation in the cmd array */
|
||||||
|
st7789_set_orientation(drv, ST7789_INITIAL_ORIENTATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The ST7789 display controller can drive 320*240 displays, when using a 240*240
|
/* The ST7789 display controller can drive up to 320*240 displays, when using a 240*240 or 240*135
|
||||||
* display there's a gap of 80px, we need to edit the coordinates to take into
|
* displays there's a gap of 80px or 40/52/53px respectively. 52px or 53x offset depends on display orientation.
|
||||||
* account that gap, this is not necessary in all orientations. */
|
* We need to edit the coordinates to take into account those gaps, this is not necessary in all orientations. */
|
||||||
void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map)
|
||||||
{
|
{
|
||||||
uint8_t data[4] = {0};
|
uint8_t data[4] = {0};
|
||||||
|
@ -131,82 +114,94 @@ void st7789_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
|
||||||
uint16_t offsetx2 = area->x2;
|
uint16_t offsetx2 = area->x2;
|
||||||
uint16_t offsety1 = area->y1;
|
uint16_t offsety1 = area->y1;
|
||||||
uint16_t offsety2 = area->y2;
|
uint16_t offsety2 = area->y2;
|
||||||
|
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
|
||||||
|
|
||||||
#if (CONFIG_LV_TFT_DISPLAY_OFFSETS)
|
offsetx1 += st7789_x_offset();
|
||||||
offsetx1 += CONFIG_LV_TFT_DISPLAY_X_OFFSET;
|
offsetx2 += st7789_x_offset();
|
||||||
offsetx2 += CONFIG_LV_TFT_DISPLAY_X_OFFSET;
|
offsety1 += st7789_y_offset();
|
||||||
offsety1 += CONFIG_LV_TFT_DISPLAY_Y_OFFSET;
|
offsety2 += st7789_y_offset();
|
||||||
offsety2 += CONFIG_LV_TFT_DISPLAY_Y_OFFSET;
|
|
||||||
|
|
||||||
#elif (LV_HOR_RES_MAX == 240) && (LV_VER_RES_MAX == 240)
|
|
||||||
#if (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
|
||||||
offsetx1 += 80;
|
|
||||||
offsetx2 += 80;
|
|
||||||
#elif (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
|
|
||||||
offsety1 += 80;
|
|
||||||
offsety2 += 80;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*Column addresses*/
|
/*Column addresses*/
|
||||||
st7789_send_cmd(ST7789_CASET);
|
st7789_send_cmd(drv, ST7789_CASET);
|
||||||
data[0] = (offsetx1 >> 8) & 0xFF;
|
data[0] = (offsetx1 >> 8) & 0xFF;
|
||||||
data[1] = offsetx1 & 0xFF;
|
data[1] = offsetx1 & 0xFF;
|
||||||
data[2] = (offsetx2 >> 8) & 0xFF;
|
data[2] = (offsetx2 >> 8) & 0xFF;
|
||||||
data[3] = offsetx2 & 0xFF;
|
data[3] = offsetx2 & 0xFF;
|
||||||
st7789_send_data(data, 4);
|
st7789_send_data(drv, data, 4);
|
||||||
|
|
||||||
/*Page addresses*/
|
/*Page addresses*/
|
||||||
st7789_send_cmd(ST7789_RASET);
|
st7789_send_cmd(drv, ST7789_RASET);
|
||||||
data[0] = (offsety1 >> 8) & 0xFF;
|
data[0] = (offsety1 >> 8) & 0xFF;
|
||||||
data[1] = offsety1 & 0xFF;
|
data[1] = offsety1 & 0xFF;
|
||||||
data[2] = (offsety2 >> 8) & 0xFF;
|
data[2] = (offsety2 >> 8) & 0xFF;
|
||||||
data[3] = offsety2 & 0xFF;
|
data[3] = offsety2 & 0xFF;
|
||||||
st7789_send_data(data, 4);
|
st7789_send_data(drv, data, 4);
|
||||||
|
|
||||||
/*Memory write*/
|
/*Memory write*/
|
||||||
st7789_send_cmd(ST7789_RAMWR);
|
st7789_send_cmd(drv, ST7789_RAMWR);
|
||||||
|
st7789_send_color(drv, (void*) color_map, size * 2);
|
||||||
|
}
|
||||||
|
|
||||||
size_t size = (size_t)lv_area_get_width(area) * (size_t)lv_area_get_height(area);
|
void st7789_set_x_offset(const uint16_t offset)
|
||||||
|
{
|
||||||
|
user_x_offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
st7789_send_color((void*)color_map, size * 2);
|
void st7789_set_y_offset(const uint16_t offset)
|
||||||
|
{
|
||||||
|
user_y_offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t st7789_x_offset(void)
|
||||||
|
{
|
||||||
|
return user_x_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t st7789_y_offset(void)
|
||||||
|
{
|
||||||
|
return user_y_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
void st7789_send_cmd(uint8_t cmd)
|
static void st7789_send_cmd(lv_disp_drv_t *drv, uint8_t cmd)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(ST7789_DC, 0);
|
display_port_gpio_dc(drv, 0);
|
||||||
disp_spi_send_data(&cmd, 1);
|
disp_spi_send_data(&cmd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void st7789_send_data(void * data, uint16_t length)
|
static void st7789_send_data(lv_disp_drv_t *drv, void * data, uint16_t length)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(ST7789_DC, 1);
|
display_port_gpio_dc(drv, 1);
|
||||||
disp_spi_send_data(data, length);
|
disp_spi_send_data(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void st7789_send_color(void * data, size_t length)
|
static void st7789_send_color(lv_disp_drv_t *drv, void * data, uint16_t length)
|
||||||
{
|
{
|
||||||
disp_wait_for_pending_transactions();
|
disp_wait_for_pending_transactions();
|
||||||
gpio_set_level(ST7789_DC, 1);
|
display_port_gpio_dc(drv, 1);
|
||||||
disp_spi_send_colors(data, length);
|
disp_spi_send_colors(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void st7789_set_orientation(uint8_t orientation)
|
/* Reset the display, if we don't have a reset pin we use software reset */
|
||||||
|
static void st7789_reset(lv_disp_drv_t *drv)
|
||||||
{
|
{
|
||||||
// ESP_ASSERT(orientation < 4);
|
#if !defined(ST7789_SOFT_RST)
|
||||||
|
display_port_gpio_rst(drv, 0);
|
||||||
const char *orientation_str[] = {
|
display_port_delay(drv, 100);
|
||||||
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"
|
display_port_gpio_rst(drv, 1);
|
||||||
};
|
display_port_delay(drv, 100);
|
||||||
|
#else
|
||||||
ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]);
|
st7789_send_cmd(drv, ST7789_SWRESET);
|
||||||
|
display_port_delay(drv, 5);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st7789_set_orientation(lv_disp_drv_t *drv, uint8_t orientation)
|
||||||
|
{
|
||||||
uint8_t data[] =
|
uint8_t data[] =
|
||||||
{
|
{
|
||||||
#if CONFIG_LV_PREDEFINED_DISPLAY_TTGO
|
#if CONFIG_LV_PREDEFINED_DISPLAY_TTGO
|
||||||
|
@ -216,8 +211,42 @@ static void st7789_set_orientation(uint8_t orientation)
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]);
|
st7789_send_cmd(drv, ST7789_MADCTL);
|
||||||
|
st7789_send_data(drv, (void *) &data[orientation], 1);
|
||||||
st7789_send_cmd(ST7789_MADCTL);
|
}
|
||||||
st7789_send_data((void *) &data[orientation], 1);
|
|
||||||
|
static void setup_initial_offsets(void)
|
||||||
|
{
|
||||||
|
#if (CONFIG_LV_TFT_DISPLAY_OFFSETS)
|
||||||
|
st7789_set_x_offset(CONFIG_LV_TFT_DISPLAY_X_OFFSET);
|
||||||
|
st7789_set_y_offset(CONFIG_LV_TFT_DISPLAY_Y_OFFSET);
|
||||||
|
|
||||||
|
#elif (LV_HOR_RES_MAX == 240) && (LV_VER_RES_MAX == 240)
|
||||||
|
#if (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT)
|
||||||
|
st7789_set_x_offset(80);
|
||||||
|
st7789_set_y_offset(0);
|
||||||
|
#elif (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
|
||||||
|
st7789_set_x_offset(0);
|
||||||
|
st7789_set_y_offset(80);
|
||||||
|
#endif
|
||||||
|
#elif (LV_HOR_RES_MAX == 240) && (LV_VER_RES_MAX == 135)
|
||||||
|
#if (CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT) || \
|
||||||
|
(CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
|
||||||
|
st7789_set_x_offset(40);
|
||||||
|
st7789_set_y_offset(53);
|
||||||
|
#endif
|
||||||
|
#elif (LV_HOR_RES_MAX == 135) && (LV_VER_RES_MAX == 240)
|
||||||
|
#if (CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE) || \
|
||||||
|
(CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
|
||||||
|
st7789_set_x_offset(52);
|
||||||
|
st7789_set_y_offset(40);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display update callback, we could update the orientation in here
|
||||||
|
* NOTE Available only for LVGL v8 */
|
||||||
|
void st7789_update_cb(lv_disp_drv_t *drv)
|
||||||
|
{
|
||||||
|
(void) drv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,22 +17,11 @@ extern "C"
|
||||||
#else
|
#else
|
||||||
#include "lvgl/lvgl.h"
|
#include "lvgl/lvgl.h"
|
||||||
#endif
|
#endif
|
||||||
#include "../lvgl_helpers.h"
|
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
/* For SPI transfers */
|
||||||
|
#include "lvgl_helpers.h"
|
||||||
#define ST7789_DC CONFIG_LV_DISP_PIN_DC
|
/* For ST7789 particular configurations */
|
||||||
#define ST7789_RST CONFIG_LV_DISP_PIN_RST
|
#include "display_config.h"
|
||||||
|
|
||||||
#if CONFIG_LV_DISP_USE_RST
|
|
||||||
#if CONFIG_LV_DISP_ST7789_SOFT_RESET
|
|
||||||
#define ST7789_SOFT_RST
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define ST7789_SOFT_RST
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ST7789_INVERT_COLORS CONFIG_LV_INVERT_COLORS
|
|
||||||
|
|
||||||
/* ST7789 commands */
|
/* ST7789 commands */
|
||||||
#define ST7789_NOP 0x00
|
#define ST7789_NOP 0x00
|
||||||
|
@ -110,11 +99,48 @@ extern "C"
|
||||||
#define ST7789_NVMSET 0xFC // NVM setting
|
#define ST7789_NVMSET 0xFC // NVM setting
|
||||||
#define ST7789_PROMACT 0xFE // Program action
|
#define ST7789_PROMACT 0xFE // Program action
|
||||||
|
|
||||||
void st7789_init(void);
|
/**
|
||||||
|
* Initialize the ST7789 display controller with default configuration
|
||||||
|
*
|
||||||
|
* @param drv Pointer to lv_disp_drv_t being used
|
||||||
|
*/
|
||||||
|
void st7789_init(lv_disp_drv_t *drv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send buffer content to display
|
||||||
|
*
|
||||||
|
* @param drv Pointer to lv_disp_drv_t being used
|
||||||
|
* @param area Pointer to area to be sent
|
||||||
|
* @param color_map Pointer to color map
|
||||||
|
*/
|
||||||
void st7789_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
|
void st7789_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
|
||||||
|
|
||||||
void st7789_send_cmd(uint8_t cmd);
|
/**
|
||||||
void st7789_send_data(void *data, uint16_t length);
|
* Set display buffer offset at x axis
|
||||||
|
*/
|
||||||
|
void st7789_set_x_offset(const uint16_t offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set display buffer offset at y axis
|
||||||
|
*/
|
||||||
|
void st7789_set_y_offset(const uint16_t offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get display buffer offset at x axis
|
||||||
|
*/
|
||||||
|
uint16_t st7789_x_offset(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get display buffer offset at y axis
|
||||||
|
*/
|
||||||
|
uint16_t st7789_y_offset(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display updated callback
|
||||||
|
*
|
||||||
|
* @param drv Pointer to lv_disp_drv_t being used
|
||||||
|
*/
|
||||||
|
void st7789_update_cb(lv_disp_drv_t *drv);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|
|
@ -9,14 +9,12 @@
|
||||||
#include "st7796s.h"
|
#include "st7796s.h"
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "ST7796S"
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
|
@ -38,6 +36,7 @@ static void st7796s_set_orientation(uint8_t orientation);
|
||||||
static void st7796s_send_cmd(uint8_t cmd);
|
static void st7796s_send_cmd(uint8_t cmd);
|
||||||
static void st7796s_send_data(void *data, uint16_t length);
|
static void st7796s_send_data(void *data, uint16_t length);
|
||||||
static void st7796s_send_color(void *data, uint16_t length);
|
static void st7796s_send_color(void *data, uint16_t length);
|
||||||
|
static void st7796s_reset(void);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
|
@ -81,22 +80,9 @@ void st7796s_init(void)
|
||||||
{0, {0}, 0xff},
|
{0, {0}, 0xff},
|
||||||
};
|
};
|
||||||
|
|
||||||
//Initialize non-SPI GPIOs
|
st7796s_reset();
|
||||||
gpio_pad_select_gpio(ST7796S_DC);
|
|
||||||
gpio_set_direction(ST7796S_DC, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
#if ST7796S_USE_RST
|
LV_LOG_INFO("Initialization.");
|
||||||
gpio_pad_select_gpio(ST7796S_RST);
|
|
||||||
gpio_set_direction(ST7796S_RST, GPIO_MODE_OUTPUT);
|
|
||||||
|
|
||||||
//Reset the display
|
|
||||||
gpio_set_level(ST7796S_RST, 0);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
gpio_set_level(ST7796S_RST, 1);
|
|
||||||
vTaskDelay(100 / portTICK_RATE_MS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Initialization.");
|
|
||||||
|
|
||||||
//Send all the commands
|
//Send all the commands
|
||||||
uint16_t cmd = 0;
|
uint16_t cmd = 0;
|
||||||
|
@ -189,25 +175,36 @@ static void st7796s_send_color(void *data, uint16_t length)
|
||||||
|
|
||||||
static void st7796s_set_orientation(uint8_t orientation)
|
static void st7796s_set_orientation(uint8_t orientation)
|
||||||
{
|
{
|
||||||
// ESP_ASSERT(orientation < 4);
|
assert(orientation < 4);
|
||||||
|
|
||||||
|
#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK
|
||||||
|
const uint8_t data[] = {0x68, 0x68, 0x08, 0x08};
|
||||||
|
#elif defined(CONFIG_LV_PREDEFINED_DISPLAY_WROVER4)
|
||||||
|
const uint8_t data[] = {0x4C, 0x88, 0x28, 0xE8};
|
||||||
|
#elif defined(CONFIG_LV_PREDEFINED_DISPLAY_WT32_SC01)
|
||||||
|
const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};
|
||||||
|
#else
|
||||||
|
const uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (LV_USE_LOG == 1)
|
||||||
const char *orientation_str[] = {
|
const char *orientation_str[] = {
|
||||||
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"};
|
"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE", "LANDSCAPE_INVERTED"};
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Display orientation: %s", orientation_str[orientation]);
|
LV_LOG_INFO("Display orientation: %s", orientation_str[orientation]);
|
||||||
|
LV_LOG_INFO("0x36 command value: 0x%02X", data[orientation]);
|
||||||
#if defined CONFIG_LV_PREDEFINED_DISPLAY_M5STACK
|
|
||||||
uint8_t data[] = {0x68, 0x68, 0x08, 0x08};
|
|
||||||
#elif defined(CONFIG_LV_PREDEFINED_DISPLAY_WROVER4)
|
|
||||||
uint8_t data[] = {0x4C, 0x88, 0x28, 0xE8};
|
|
||||||
#elif defined(CONFIG_LV_PREDEFINED_DISPLAY_WT32_SC01)
|
|
||||||
uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};
|
|
||||||
#elif defined(CONFIG_LV_PREDEFINED_DISPLAY_NONE)
|
|
||||||
uint8_t data[] = {0x48, 0x88, 0x28, 0xE8};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ESP_LOGI(TAG, "0x36 command value: 0x%02X", data[orientation]);
|
|
||||||
|
|
||||||
st7796s_send_cmd(0x36);
|
st7796s_send_cmd(0x36);
|
||||||
st7796s_send_data((void *)&data[orientation], 1);
|
st7796s_send_data((void *)&data[orientation], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void st7796s_reset(void)
|
||||||
|
{
|
||||||
|
#if ST7796S_USE_RST
|
||||||
|
gpio_set_level(ST7796S_RST, 0);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
gpio_set_level(ST7796S_RST, 1);
|
||||||
|
vTaskDelay(100 / portTICK_RATE_MS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -29,23 +29,37 @@
|
||||||
#include <freertos/task.h>
|
#include <freertos/task.h>
|
||||||
#include <freertos/event_groups.h>
|
#include <freertos/event_groups.h>
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <esp_log.h>
|
|
||||||
|
|
||||||
#include "disp_spi.h"
|
#include "disp_spi.h"
|
||||||
#include "disp_driver.h"
|
#include "disp_driver.h"
|
||||||
#include "uc8151d.h"
|
#include "uc8151d.h"
|
||||||
|
|
||||||
#define TAG "lv_uc8151d"
|
|
||||||
|
|
||||||
#define PIN_DC CONFIG_LV_DISP_PIN_DC
|
#define PIN_DC CONFIG_LV_DISP_PIN_DC
|
||||||
#define PIN_DC_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_DC)))
|
#define PIN_DC_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_DC)))
|
||||||
|
|
||||||
|
#if defined CONFIG_LV_DISP_PIN_RST
|
||||||
#define PIN_RST CONFIG_LV_DISP_PIN_RST
|
#define PIN_RST CONFIG_LV_DISP_PIN_RST
|
||||||
#define PIN_RST_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_RST)))
|
#define PIN_RST_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_RST)))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PIN_BUSY CONFIG_LV_DISP_PIN_BUSY
|
#define PIN_BUSY CONFIG_LV_DISP_PIN_BUSY
|
||||||
#define PIN_BUSY_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_BUSY)))
|
#define PIN_BUSY_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_BUSY)))
|
||||||
#define EVT_BUSY (1UL << 0UL)
|
#define EVT_BUSY (1UL << 0UL)
|
||||||
|
|
||||||
|
#if defined (LV_HOR_RES_MAX)
|
||||||
#define EPD_WIDTH LV_HOR_RES_MAX
|
#define EPD_WIDTH LV_HOR_RES_MAX
|
||||||
|
#else
|
||||||
|
/* ToDo Fix, 256 is just a magic number */
|
||||||
|
#define EPD_WIDTH 256u
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (LV_VER_RES_MAX)
|
||||||
#define EPD_HEIGHT LV_VER_RES_MAX
|
#define EPD_HEIGHT LV_VER_RES_MAX
|
||||||
|
#else
|
||||||
|
/* ToDo Fix, 128 is just a magic number */
|
||||||
|
#define EPD_HEIGHT 128u
|
||||||
|
#endif
|
||||||
|
|
||||||
#define EPD_ROW_LEN (EPD_HEIGHT / 8u)
|
#define EPD_ROW_LEN (EPD_HEIGHT / 8u)
|
||||||
|
|
||||||
#define BIT_SET(a, b) ((a) |= (1U << (b)))
|
#define BIT_SET(a, b) ((a) |= (1U << (b)))
|
||||||
|
@ -93,26 +107,6 @@ static void uc8151d_spi_send_data_byte(uint8_t data)
|
||||||
disp_spi_send_data(&data, 1);
|
disp_spi_send_data(&data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uc8151d_spi_send_fb(uint8_t *data, size_t len)
|
|
||||||
{
|
|
||||||
disp_wait_for_pending_transactions();
|
|
||||||
gpio_set_level(PIN_DC, 1); // DC = 1 for data
|
|
||||||
disp_spi_send_colors(data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void uc8151d_spi_send_seq(const uc8151d_seq_t *seq, size_t len)
|
|
||||||
{
|
|
||||||
ESP_LOGD(TAG, "Writing cmd/data sequence, count %u", len);
|
|
||||||
|
|
||||||
if (!seq || len < 1) return;
|
|
||||||
for (size_t cmd_idx = 0; cmd_idx < len; cmd_idx++) {
|
|
||||||
uc8151d_spi_send_cmd(seq[cmd_idx].cmd);
|
|
||||||
if (seq[cmd_idx].len > 0) {
|
|
||||||
uc8151d_spi_send_data((uint8_t *) seq[cmd_idx].data, seq[cmd_idx].len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t uc8151d_wait_busy(uint32_t timeout_ms)
|
static esp_err_t uc8151d_wait_busy(uint32_t timeout_ms)
|
||||||
{
|
{
|
||||||
uint32_t wait_ticks = (timeout_ms == 0 ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms));
|
uint32_t wait_ticks = (timeout_ms == 0 ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms));
|
||||||
|
@ -124,7 +118,7 @@ static esp_err_t uc8151d_wait_busy(uint32_t timeout_ms)
|
||||||
return ((bits & EVT_BUSY) != 0) ? ESP_OK : ESP_ERR_TIMEOUT;
|
return ((bits & EVT_BUSY) != 0) ? ESP_OK : ESP_ERR_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uc8151d_sleep()
|
static void uc8151d_sleep(void)
|
||||||
{
|
{
|
||||||
// Set VCOM to 0xf7
|
// Set VCOM to 0xf7
|
||||||
uc8151d_spi_send_cmd(0x50);
|
uc8151d_spi_send_cmd(0x50);
|
||||||
|
@ -139,14 +133,13 @@ static void uc8151d_sleep()
|
||||||
uc8151d_spi_send_data_byte(0xa5);
|
uc8151d_spi_send_data_byte(0xa5);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uc8151d_panel_init()
|
static void uc8151d_reset(void);
|
||||||
|
|
||||||
|
static void uc8151d_panel_init(void)
|
||||||
{
|
{
|
||||||
// Hardware reset for 3 times - not sure why but it's from official demo code
|
// Hardware reset for 3 times - not sure why but it's from official demo code
|
||||||
for (uint8_t cnt = 0; cnt < 3; cnt++) {
|
for (uint8_t cnt = 0; cnt < 3; cnt++) {
|
||||||
gpio_set_level(PIN_RST, 0);
|
uc8151d_reset();
|
||||||
vTaskDelay(pdMS_TO_TICKS(10)); // At least 10ms, leave 20ms for now just in case...
|
|
||||||
gpio_set_level(PIN_RST, 1);
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Power up
|
// Power up
|
||||||
|
@ -196,19 +189,20 @@ static void uc8151d_full_update(uint8_t *buf)
|
||||||
|
|
||||||
void uc8151d_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
|
void uc8151d_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
|
||||||
{
|
{
|
||||||
|
#if LV_USE_LOG
|
||||||
size_t len = ((area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1)) / 8;
|
size_t len = ((area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1)) / 8;
|
||||||
|
LV_LOG_INFO("x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", area->x1, area->x2, area->y1, area->y2);
|
||||||
ESP_LOGD(TAG, "x1: 0x%x, x2: 0x%x, y1: 0x%x, y2: 0x%x", area->x1, area->x2, area->y1, area->y2);
|
LV_LOG_INFO("Writing LVGL fb with len: %u", len);
|
||||||
ESP_LOGD(TAG, "Writing LVGL fb with len: %u", len);
|
#endif
|
||||||
|
|
||||||
uint8_t *buf = (uint8_t *) color_map;
|
uint8_t *buf = (uint8_t *) color_map;
|
||||||
uc8151d_full_update(buf);
|
uc8151d_full_update(buf);
|
||||||
|
|
||||||
lv_disp_flush_ready(drv);
|
lv_disp_flush_ready(drv);
|
||||||
ESP_LOGD(TAG, "Ready");
|
LV_LOG_INFO("Ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
void uc8151d_lv_set_fb_cb(struct _disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
void uc8151d_lv_set_fb_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||||
lv_color_t color, lv_opa_t opa)
|
lv_color_t color, lv_opa_t opa)
|
||||||
{
|
{
|
||||||
uint16_t byte_index = (x >> 3u) + (y * EPD_ROW_LEN);
|
uint16_t byte_index = (x >> 3u) + (y * EPD_ROW_LEN);
|
||||||
|
@ -217,12 +211,12 @@ void uc8151d_lv_set_fb_cb(struct _disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t
|
||||||
if (color.full) {
|
if (color.full) {
|
||||||
BIT_SET(buf[byte_index], 7 - bit_index);
|
BIT_SET(buf[byte_index], 7 - bit_index);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGD(TAG, "Clear at x: %u, y: %u", x, y);
|
LV_LOG_INFO("Clear at x: %u, y: %u", x, y);
|
||||||
BIT_CLEAR(buf[byte_index], 7 - bit_index);
|
BIT_CLEAR(buf[byte_index], 7 - bit_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uc8151d_lv_rounder_cb(struct _disp_drv_t *disp_drv, lv_area_t *area)
|
void uc8151d_lv_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area)
|
||||||
{
|
{
|
||||||
// Always send full framebuffer if it's not in partial mode
|
// Always send full framebuffer if it's not in partial mode
|
||||||
area->x1 = 0;
|
area->x1 = 0;
|
||||||
|
@ -231,25 +225,15 @@ void uc8151d_lv_rounder_cb(struct _disp_drv_t *disp_drv, lv_area_t *area)
|
||||||
area->y2 = EPD_HEIGHT - 1;
|
area->y2 = EPD_HEIGHT - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uc8151d_init()
|
void uc8151d_init(void)
|
||||||
{
|
{
|
||||||
// Initialise event group
|
// Initialise event group
|
||||||
uc8151d_evts = xEventGroupCreate();
|
uc8151d_evts = xEventGroupCreate();
|
||||||
if (!uc8151d_evts) {
|
if (!uc8151d_evts) {
|
||||||
ESP_LOGE(TAG, "Failed when initialising event group!");
|
LV_LOG_ERROR("Failed when initialising event group!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup output pins, output (PP)
|
|
||||||
gpio_config_t out_io_conf = {
|
|
||||||
.intr_type = GPIO_INTR_DISABLE,
|
|
||||||
.mode = GPIO_MODE_OUTPUT,
|
|
||||||
.pin_bit_mask = PIN_DC_BIT | PIN_RST_BIT,
|
|
||||||
.pull_down_en = 0,
|
|
||||||
.pull_up_en = 0,
|
|
||||||
};
|
|
||||||
ESP_ERROR_CHECK(gpio_config(&out_io_conf));
|
|
||||||
|
|
||||||
// Setup input pin, pull-up, input
|
// Setup input pin, pull-up, input
|
||||||
gpio_config_t in_io_conf = {
|
gpio_config_t in_io_conf = {
|
||||||
.intr_type = GPIO_INTR_POSEDGE,
|
.intr_type = GPIO_INTR_POSEDGE,
|
||||||
|
@ -262,7 +246,18 @@ void uc8151d_init()
|
||||||
gpio_install_isr_service(0);
|
gpio_install_isr_service(0);
|
||||||
gpio_isr_handler_add(PIN_BUSY, uc8151d_busy_intr, (void *) PIN_BUSY);
|
gpio_isr_handler_add(PIN_BUSY, uc8151d_busy_intr, (void *) PIN_BUSY);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "IO init finished");
|
LV_LOG_INFO("IO init finished");
|
||||||
uc8151d_panel_init();
|
uc8151d_panel_init();
|
||||||
ESP_LOGI(TAG, "Panel initialised");
|
LV_LOG_INFO("Panel initialised");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uc8151d_reset(void)
|
||||||
|
{
|
||||||
|
#if defined CONFIG_LV_DISP_USE_RST
|
||||||
|
gpio_set_level(PIN_RST, 0);
|
||||||
|
// At least 10ms, leave 20ms for now just in case...
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
|
gpio_set_level(PIN_RST, 1);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,11 @@
|
||||||
|
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
|
||||||
void uc8151d_init();
|
void uc8151d_init(void);
|
||||||
void uc8151d_lv_set_fb_cb(struct _disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
void uc8151d_lv_set_fb_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||||
lv_color_t color, lv_opa_t opa);
|
lv_color_t color, lv_opa_t opa);
|
||||||
|
|
||||||
void uc8151d_lv_rounder_cb(struct _disp_drv_t *disp_drv, lv_area_t *area);
|
void uc8151d_lv_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area);
|
||||||
void uc8151d_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
|
void uc8151d_lv_fb_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
|
||||||
|
|
||||||
#endif //LVGL_DEMO_UC8151D_H
|
#endif //LVGL_DEMO_UC8151D_H
|
||||||
|
|
|
@ -67,17 +67,14 @@ menu "LVGL Touch controller"
|
||||||
prompt "Touch Controller SPI Bus."
|
prompt "Touch Controller SPI Bus."
|
||||||
depends on LV_TOUCH_DRIVER_PROTOCOL_SPI
|
depends on LV_TOUCH_DRIVER_PROTOCOL_SPI
|
||||||
|
|
||||||
default LV_TOUCH_CONTROLLER_SPI_VSPI if !IDF_TARGET_ESP32S2
|
default LV_TOUCH_CONTROLLER_SPI2_HOST
|
||||||
default LV_TOUCH_CONTROLLER_SPI_FSPI if IDF_TARGET_ESP32S2
|
|
||||||
help
|
help
|
||||||
Select the SPI Bus the TFT Display is attached to.
|
Select the SPI Bus the touch controller is attached to.
|
||||||
|
|
||||||
config LV_TOUCH_CONTROLLER_SPI_HSPI
|
config LV_TOUCH_CONTROLLER_SPI2_HOST
|
||||||
bool "HSPI"
|
bool "SPI2_HOST"
|
||||||
config LV_TOUCH_CONTROLLER_SPI_VSPI
|
config LV_TOUCH_CONTROLLER_SPI3_HOST
|
||||||
bool "VSPI" if !IDF_TARGET_ESP32S2
|
bool "SPI3_HOST"
|
||||||
config LV_TOUCH_CONTROLLER_SPI_FSPI
|
|
||||||
bool "FSPI" if IDF_TARGET_ESP32S2
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
menu "Touchpanel (XPT2046) Pin Assignments"
|
menu "Touchpanel (XPT2046) Pin Assignments"
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#if CONFIG_LV_TOUCH_CONTROLLER_ADCRAW
|
#if CONFIG_LV_TOUCH_CONTROLLER_ADCRAW
|
||||||
|
|
||||||
#define TAG "ADCRAW"
|
|
||||||
#define CALIBRATIONINSET 1 // range 0 <= CALIBRATIONINSET <= 40
|
#define CALIBRATIONINSET 1 // range 0 <= CALIBRATIONINSET <= 40
|
||||||
#define SAMPLE_CALIBRATION_POINTS 4
|
#define SAMPLE_CALIBRATION_POINTS 4
|
||||||
// use this scale factor to avoid working in floating point numbers
|
// use this scale factor to avoid working in floating point numbers
|
||||||
|
|
|
@ -18,22 +18,24 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <esp_log.h>
|
|
||||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
#else
|
#else
|
||||||
#include <lvgl/lvgl.h>
|
#include <lvgl/lvgl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ft6x36.h"
|
#include "ft6x36.h"
|
||||||
#include "lvgl_i2c/i2c_manager.h"
|
#include "lvgl_i2c/i2c_manager.h"
|
||||||
|
|
||||||
#define TAG "FT6X36"
|
#define TAG "FT6X36"
|
||||||
#define FT6X36_TOUCH_QUEUE_ELEMENTS 1
|
#define FT6X36_TOUCH_QUEUE_ELEMENTS 1
|
||||||
|
|
||||||
|
|
||||||
static ft6x36_status_t ft6x36_status;
|
static ft6x36_status_t ft6x36_status;
|
||||||
static uint8_t current_dev_addr; // set during init
|
/* Set during initialization */
|
||||||
static ft6x36_touch_t touch_inputs = { -1, -1, LV_INDEV_STATE_REL }; // -1 coordinates to designate it was never touched
|
static uint8_t current_dev_addr;
|
||||||
|
/* -1 coordinates to designate it was never touched */
|
||||||
|
static ft6x36_touch_t touch_inputs = { -1, -1, LV_INDEV_STATE_REL };
|
||||||
|
|
||||||
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
|
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
|
||||||
QueueHandle_t ft6x36_touch_queue_handle;
|
QueueHandle_t ft6x36_touch_queue_handle;
|
||||||
#endif
|
#endif
|
||||||
|
@ -49,13 +51,13 @@ static esp_err_t ft6x06_i2c_read8(uint8_t slave_addr, uint8_t register_addr, uin
|
||||||
*/
|
*/
|
||||||
uint8_t ft6x36_get_gesture_id() {
|
uint8_t ft6x36_get_gesture_id() {
|
||||||
if (!ft6x36_status.inited) {
|
if (!ft6x36_status.inited) {
|
||||||
ESP_LOGE(TAG, "Init first!");
|
LV_LOG_ERROR("Init first!");
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
}
|
||||||
uint8_t data_buf;
|
uint8_t data_buf;
|
||||||
esp_err_t ret;
|
esp_err_t ret;
|
||||||
if ((ret = ft6x06_i2c_read8(current_dev_addr, FT6X36_GEST_ID_REG, &data_buf) != ESP_OK))
|
if ((ret = ft6x06_i2c_read8(current_dev_addr, FT6X36_GEST_ID_REG, &data_buf) != ESP_OK))
|
||||||
ESP_LOGE(TAG, "Error reading from device: %s", esp_err_to_name(ret));
|
LV_LOG_ERROR("Error reading from device: %s", esp_err_to_name(ret));
|
||||||
return data_buf;
|
return data_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,29 +72,29 @@ void ft6x06_init(uint16_t dev_addr) {
|
||||||
current_dev_addr = dev_addr;
|
current_dev_addr = dev_addr;
|
||||||
uint8_t data_buf;
|
uint8_t data_buf;
|
||||||
esp_err_t ret;
|
esp_err_t ret;
|
||||||
ESP_LOGI(TAG, "Found touch panel controller");
|
LV_LOG_INFO("Found touch panel controller");
|
||||||
if ((ret = ft6x06_i2c_read8(dev_addr, FT6X36_PANEL_ID_REG, &data_buf) != ESP_OK))
|
if ((ret = ft6x06_i2c_read8(dev_addr, FT6X36_PANEL_ID_REG, &data_buf) != ESP_OK))
|
||||||
ESP_LOGE(TAG, "Error reading from device: %s",
|
LV_LOG_ERROR("Error reading from device: %s",
|
||||||
esp_err_to_name(ret)); // Only show error the first time
|
esp_err_to_name(ret)); // Only show error the first time
|
||||||
ESP_LOGI(TAG, "\tDevice ID: 0x%02x", data_buf);
|
LV_LOG_INFO("\tDevice ID: 0x%02x", data_buf);
|
||||||
|
|
||||||
ft6x06_i2c_read8(dev_addr, FT6X36_CHIPSELECT_REG, &data_buf);
|
ft6x06_i2c_read8(dev_addr, FT6X36_CHIPSELECT_REG, &data_buf);
|
||||||
ESP_LOGI(TAG, "\tChip ID: 0x%02x", data_buf);
|
LV_LOG_INFO("\tChip ID: 0x%02x", data_buf);
|
||||||
|
|
||||||
ft6x06_i2c_read8(dev_addr, FT6X36_DEV_MODE_REG, &data_buf);
|
ft6x06_i2c_read8(dev_addr, FT6X36_DEV_MODE_REG, &data_buf);
|
||||||
ESP_LOGI(TAG, "\tDevice mode: 0x%02x", data_buf);
|
LV_LOG_INFO("\tDevice mode: 0x%02x", data_buf);
|
||||||
|
|
||||||
ft6x06_i2c_read8(dev_addr, FT6X36_FIRMWARE_ID_REG, &data_buf);
|
ft6x06_i2c_read8(dev_addr, FT6X36_FIRMWARE_ID_REG, &data_buf);
|
||||||
ESP_LOGI(TAG, "\tFirmware ID: 0x%02x", data_buf);
|
LV_LOG_INFO("\tFirmware ID: 0x%02x", data_buf);
|
||||||
|
|
||||||
ft6x06_i2c_read8(dev_addr, FT6X36_RELEASECODE_REG, &data_buf);
|
ft6x06_i2c_read8(dev_addr, FT6X36_RELEASECODE_REG, &data_buf);
|
||||||
ESP_LOGI(TAG, "\tRelease code: 0x%02x", data_buf);
|
LV_LOG_INFO("\tRelease code: 0x%02x", data_buf);
|
||||||
|
|
||||||
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
|
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
|
||||||
ft6x36_touch_queue_handle = xQueueCreate( FT6X36_TOUCH_QUEUE_ELEMENTS, sizeof( ft6x36_touch_t ) );
|
ft6x36_touch_queue_handle = xQueueCreate( FT6X36_TOUCH_QUEUE_ELEMENTS, sizeof( ft6x36_touch_t ) );
|
||||||
if( ft6x36_touch_queue_handle == NULL )
|
if( ft6x36_touch_queue_handle == NULL )
|
||||||
{
|
{
|
||||||
ESP_LOGE( TAG, "\tError creating touch input FreeRTOS queue" );
|
LV_LOG_ERROR("\tError creating touch input FreeRTOS queue" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xQueueSend( ft6x36_touch_queue_handle, &touch_inputs, 0 );
|
xQueueSend( ft6x36_touch_queue_handle, &touch_inputs, 0 );
|
||||||
|
@ -107,14 +109,14 @@ void ft6x06_init(uint16_t dev_addr) {
|
||||||
*/
|
*/
|
||||||
bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
||||||
if (!ft6x36_status.inited) {
|
if (!ft6x36_status.inited) {
|
||||||
ESP_LOGE(TAG, "Init first!");
|
LV_LOG_ERROR("Init first!");
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
}
|
||||||
uint8_t data_buf[5]; // 1 byte status, 2 bytes X, 2 bytes Y
|
uint8_t data_buf[5]; // 1 byte status, 2 bytes X, 2 bytes Y
|
||||||
|
|
||||||
esp_err_t ret = lvgl_i2c_read(CONFIG_LV_I2C_TOUCH_PORT, current_dev_addr, FT6X36_TD_STAT_REG, &data_buf[0], 5);
|
esp_err_t ret = lvgl_i2c_read(CONFIG_LV_I2C_TOUCH_PORT, current_dev_addr, FT6X36_TD_STAT_REG, &data_buf[0], 5);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Error talking to touch IC: %s", esp_err_to_name(ret));
|
LV_LOG_ERROR("Error talking to touch IC: %s", esp_err_to_name(ret));
|
||||||
}
|
}
|
||||||
uint8_t touch_pnt_cnt = data_buf[0]; // Number of detected touch points
|
uint8_t touch_pnt_cnt = data_buf[0]; // Number of detected touch points
|
||||||
|
|
||||||
|
@ -150,7 +152,7 @@ bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
||||||
data->point.x = touch_inputs.last_x;
|
data->point.x = touch_inputs.last_x;
|
||||||
data->point.y = touch_inputs.last_y;
|
data->point.y = touch_inputs.last_y;
|
||||||
data->state = touch_inputs.current_state;
|
data->state = touch_inputs.current_state;
|
||||||
ESP_LOGD(TAG, "X=%u Y=%u", data->point.x, data->point.y);
|
LV_LOG_INFO("X=%u Y=%u", data->point.x, data->point.y);
|
||||||
|
|
||||||
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
|
#if CONFIG_LV_FT6X36_COORDINATES_QUEUE
|
||||||
xQueueOverwrite( ft6x36_touch_queue_handle, &touch_inputs );
|
xQueueOverwrite( ft6x36_touch_queue_handle, &touch_inputs );
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <esp_log.h>
|
|
||||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
#else
|
#else
|
||||||
|
@ -28,8 +27,6 @@
|
||||||
|
|
||||||
#include "lvgl_i2c/i2c_manager.h"
|
#include "lvgl_i2c/i2c_manager.h"
|
||||||
|
|
||||||
#define TAG "GT911"
|
|
||||||
|
|
||||||
gt911_status_t gt911_status;
|
gt911_status_t gt911_status;
|
||||||
|
|
||||||
//TODO: handle multibyte read and refactor to just one read transaction
|
//TODO: handle multibyte read and refactor to just one read transaction
|
||||||
|
@ -53,9 +50,9 @@ void gt911_init(uint8_t dev_addr) {
|
||||||
uint8_t data_buf;
|
uint8_t data_buf;
|
||||||
esp_err_t ret;
|
esp_err_t ret;
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Checking for GT911 Touch Controller");
|
LV_LOG_INFO("Checking for GT911 Touch Controller");
|
||||||
if ((ret = gt911_i2c_read(dev_addr, GT911_PRODUCT_ID1, &data_buf, 1) != ESP_OK)) {
|
if ((ret = gt911_i2c_read(dev_addr, GT911_PRODUCT_ID1, &data_buf, 1) != ESP_OK)) {
|
||||||
ESP_LOGE(TAG, "Error reading from device: %s",
|
LV_LOG_ERROR("Error reading from device: %s",
|
||||||
esp_err_to_name(ret)); // Only show error the first time
|
esp_err_to_name(ret)); // Only show error the first time
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -64,22 +61,22 @@ void gt911_init(uint8_t dev_addr) {
|
||||||
for (int i = 0; i < GT911_PRODUCT_ID_LEN; i++) {
|
for (int i = 0; i < GT911_PRODUCT_ID_LEN; i++) {
|
||||||
gt911_i2c_read(dev_addr, (GT911_PRODUCT_ID1 + i), (uint8_t *)&(gt911_status.product_id[i]), 1);
|
gt911_i2c_read(dev_addr, (GT911_PRODUCT_ID1 + i), (uint8_t *)&(gt911_status.product_id[i]), 1);
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "\tProduct ID: %s", gt911_status.product_id);
|
LV_LOG_INFO("\tProduct ID: %s", gt911_status.product_id);
|
||||||
|
|
||||||
gt911_i2c_read(dev_addr, GT911_VENDOR_ID, &data_buf, 1);
|
gt911_i2c_read(dev_addr, GT911_VENDOR_ID, &data_buf, 1);
|
||||||
ESP_LOGI(TAG, "\tVendor ID: 0x%02x", data_buf);
|
LV_LOG_INFO("\tVendor ID: 0x%02x", data_buf);
|
||||||
|
|
||||||
gt911_i2c_read(dev_addr, GT911_X_COORD_RES_L, &data_buf, 1);
|
gt911_i2c_read(dev_addr, GT911_X_COORD_RES_L, &data_buf, 1);
|
||||||
gt911_status.max_x_coord = data_buf;
|
gt911_status.max_x_coord = data_buf;
|
||||||
gt911_i2c_read(dev_addr, GT911_X_COORD_RES_H, &data_buf, 1);
|
gt911_i2c_read(dev_addr, GT911_X_COORD_RES_H, &data_buf, 1);
|
||||||
gt911_status.max_x_coord |= ((uint16_t)data_buf << 8);
|
gt911_status.max_x_coord |= ((uint16_t)data_buf << 8);
|
||||||
ESP_LOGI(TAG, "\tX Resolution: %d", gt911_status.max_x_coord);
|
LV_LOG_INFO("\tX Resolution: %d", gt911_status.max_x_coord);
|
||||||
|
|
||||||
gt911_i2c_read(dev_addr, GT911_Y_COORD_RES_L, &data_buf, 1);
|
gt911_i2c_read(dev_addr, GT911_Y_COORD_RES_L, &data_buf, 1);
|
||||||
gt911_status.max_y_coord = data_buf;
|
gt911_status.max_y_coord = data_buf;
|
||||||
gt911_i2c_read(dev_addr, GT911_Y_COORD_RES_H, &data_buf, 1);
|
gt911_i2c_read(dev_addr, GT911_Y_COORD_RES_H, &data_buf, 1);
|
||||||
gt911_status.max_y_coord |= ((uint16_t)data_buf << 8);
|
gt911_status.max_y_coord |= ((uint16_t)data_buf << 8);
|
||||||
ESP_LOGI(TAG, "\tY Resolution: %d", gt911_status.max_y_coord);
|
LV_LOG_INFO("\tY Resolution: %d", gt911_status.max_y_coord);
|
||||||
gt911_status.inited = true;
|
gt911_status.inited = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +95,7 @@ bool gt911_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
||||||
uint8_t status_reg;
|
uint8_t status_reg;
|
||||||
|
|
||||||
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_STATUS_REG, &status_reg, 1);
|
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_STATUS_REG, &status_reg, 1);
|
||||||
// ESP_LOGI(TAG, "\tstatus: 0x%02x", status_reg);
|
// LV_LOG_INFO("\tstatus: 0x%02x", status_reg);
|
||||||
touch_pnt_cnt = status_reg & 0x0F;
|
touch_pnt_cnt = status_reg & 0x0F;
|
||||||
if ((status_reg & 0x80) || (touch_pnt_cnt < 6)) {
|
if ((status_reg & 0x80) || (touch_pnt_cnt < 6)) {
|
||||||
//Reset Status Reg Value
|
//Reset Status Reg Value
|
||||||
|
@ -112,7 +109,7 @@ bool gt911_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_TRACK_ID1, &data_buf, 1);
|
// gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_TRACK_ID1, &data_buf, 1);
|
||||||
// ESP_LOGI(TAG, "\ttrack_id: %d", data_buf);
|
// LV_LOG_INFO("\ttrack_id: %d", data_buf);
|
||||||
|
|
||||||
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_PT1_X_COORD_L, &data_buf, 1);
|
gt911_i2c_read(gt911_status.i2c_dev_addr, GT911_PT1_X_COORD_L, &data_buf, 1);
|
||||||
last_x = data_buf;
|
last_x = data_buf;
|
||||||
|
@ -138,7 +135,7 @@ bool gt911_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
||||||
data->point.x = last_x;
|
data->point.x = last_x;
|
||||||
data->point.y = last_y;
|
data->point.y = last_y;
|
||||||
data->state = LV_INDEV_STATE_PR;
|
data->state = LV_INDEV_STATE_PR;
|
||||||
ESP_LOGI(TAG, "X=%u Y=%u", data->point.x, data->point.y);
|
LV_LOG_INFO("X=%u Y=%u", data->point.x, data->point.y);
|
||||||
ESP_LOGV(TAG, "X=%u Y=%u", data->point.x, data->point.y);
|
LV_LOG_INFO("X=%u Y=%u", data->point.x, data->point.y);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
/*********************
|
/*********************
|
||||||
* INCLUDES
|
* INCLUDES
|
||||||
*********************/
|
*********************/
|
||||||
#include "esp_log.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
@ -23,7 +22,6 @@
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define DEBUG false
|
#define DEBUG false
|
||||||
#define TAG "RA8875-Touch"
|
|
||||||
|
|
||||||
#define DIV_ROUND_UP(n, d) (((n)+(d)-1)/(d))
|
#define DIV_ROUND_UP(n, d) (((n)+(d)-1)/(d))
|
||||||
|
|
||||||
|
@ -83,7 +81,7 @@ void ra8875_touch_init(void)
|
||||||
};
|
};
|
||||||
#define INIT_CMDS_SIZE (sizeof(init_cmds)/sizeof(init_cmds[0]))
|
#define INIT_CMDS_SIZE (sizeof(init_cmds)/sizeof(init_cmds[0]))
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Initializing RA8875 Touch...");
|
LV_LOG_INFO("Initializing RA8875 Touch...");
|
||||||
|
|
||||||
// Send all the commands
|
// Send all the commands
|
||||||
for (unsigned int i = 0; i < INIT_CMDS_SIZE; i++) {
|
for (unsigned int i = 0; i < INIT_CMDS_SIZE; i++) {
|
||||||
|
@ -94,7 +92,7 @@ void ra8875_touch_init(void)
|
||||||
|
|
||||||
void ra8875_touch_enable(bool enable)
|
void ra8875_touch_enable(bool enable)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "%s touch.", enable ? "Enabling" : "Disabling");
|
LV_LOG_INFO("%s touch.", enable ? "Enabling" : "Disabling");
|
||||||
uint8_t val = enable ? (0x80 | TPCR0_VAL) : (TPCR0_VAL);
|
uint8_t val = enable ? (0x80 | TPCR0_VAL) : (TPCR0_VAL);
|
||||||
ra8875_write_cmd(RA8875_REG_TPCR0, val);
|
ra8875_write_cmd(RA8875_REG_TPCR0, val);
|
||||||
}
|
}
|
||||||
|
@ -122,7 +120,7 @@ bool ra8875_touch_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||||
y = (y << 2) | ((xy >> 2) & 0x03);
|
y = (y << 2) | ((xy >> 2) & 0x03);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ESP_LOGI(TAG, "Touch Poll Raw: %d,%d", x, y);
|
LV_LOG_INFO("Touch Poll Raw: %d,%d", x, y);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Convert to display coordinates
|
// Convert to display coordinates
|
||||||
|
@ -136,7 +134,7 @@ bool ra8875_touch_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||||
data->point.y = y;
|
data->point.y = y;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ESP_LOGI(TAG, "Touch Poll - Event: %d; %d,%d", data->state, data->point.x, data->point.y);
|
LV_LOG_INFO("Touch Poll - Event: %d; %d,%d", data->state, data->point.x, data->point.y);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
*********************/
|
*********************/
|
||||||
#include "stmpe610.h"
|
#include "stmpe610.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
|
@ -17,8 +16,6 @@
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "STMPE610"
|
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
|
@ -55,11 +52,11 @@ void stmpe610_init(void)
|
||||||
uint8_t u8;
|
uint8_t u8;
|
||||||
uint16_t u16;
|
uint16_t u16;
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Initialization.");
|
LV_LOG_INFO("Initialization.");
|
||||||
|
|
||||||
// Get the initial SPI configuration
|
// Get the initial SPI configuration
|
||||||
//u8 = read_8bit_reg(STMPE_SPI_CFG);
|
//u8 = read_8bit_reg(STMPE_SPI_CFG);
|
||||||
//ESP_LOGI(TAG, "SPI_CFG = 0x%x", u8);
|
//LV_LOG_INFO("SPI_CFG = 0x%x", u8);
|
||||||
|
|
||||||
// Attempt a software reset
|
// Attempt a software reset
|
||||||
write_8bit_reg(STMPE_SYS_CTRL1, STMPE_SYS_CTRL1_RESET);
|
write_8bit_reg(STMPE_SYS_CTRL1, STMPE_SYS_CTRL1_RESET);
|
||||||
|
@ -69,12 +66,12 @@ void stmpe610_init(void)
|
||||||
u8 = read_8bit_reg(STMPE_SPI_CFG);
|
u8 = read_8bit_reg(STMPE_SPI_CFG);
|
||||||
write_8bit_reg(STMPE_SPI_CFG, u8 | STMPE_SPI_CFG_AA);
|
write_8bit_reg(STMPE_SPI_CFG, u8 | STMPE_SPI_CFG_AA);
|
||||||
u8 = read_8bit_reg(STMPE_SPI_CFG);
|
u8 = read_8bit_reg(STMPE_SPI_CFG);
|
||||||
ESP_LOGI(TAG, "SPI_CFG = 0x%x", u8);
|
LV_LOG_INFO("SPI_CFG = 0x%x", u8);
|
||||||
|
|
||||||
// Verify SPI communication
|
// Verify SPI communication
|
||||||
u16 = read_16bit_reg(STMPE_CHIP_ID);
|
u16 = read_16bit_reg(STMPE_CHIP_ID);
|
||||||
if (u16 != 0x811) {
|
if (u16 != 0x811) {
|
||||||
ESP_LOGE(TAG, "Incorrect version: 0x%x", u16);
|
LV_LOG_ERROR("Incorrect version: 0x%x", u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_8bit_reg(STMPE_SYS_CTRL2, 0x00); // Disable clocks
|
write_8bit_reg(STMPE_SYS_CTRL2, 0x00); // Disable clocks
|
||||||
|
@ -130,12 +127,12 @@ bool stmpe610_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c > 0) {
|
if (c > 0) {
|
||||||
//ESP_LOGI(TAG, "%d: %d %d %d", c, x, y, z);
|
//LV_LOG_INFO("%d: %d %d %d", c, x, y, z);
|
||||||
|
|
||||||
adjust_data(&x, &y);
|
adjust_data(&x, &y);
|
||||||
last_x = x;
|
last_x = x;
|
||||||
last_y = y;
|
last_y = y;
|
||||||
//ESP_LOGI(TAG, " ==> %d %d", x, y);
|
//LV_LOG_INFO(" ==> %d %d", x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
z = read_8bit_reg(STMPE_INT_STA); // Clear interrupts
|
z = read_8bit_reg(STMPE_INT_STA); // Clear interrupts
|
||||||
|
@ -144,7 +141,7 @@ bool stmpe610_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||||
// Clear the FIFO if we discover an overflow
|
// Clear the FIFO if we discover an overflow
|
||||||
write_8bit_reg(STMPE_FIFO_STA, STMPE_FIFO_STA_RESET);
|
write_8bit_reg(STMPE_FIFO_STA, STMPE_FIFO_STA_RESET);
|
||||||
write_8bit_reg(STMPE_FIFO_STA, 0); // unreset
|
write_8bit_reg(STMPE_FIFO_STA, 0); // unreset
|
||||||
ESP_LOGE(TAG, "Fifo overflow");
|
LV_LOG_ERROR("Fifo overflow");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
*********************/
|
*********************/
|
||||||
#include "xpt2046.h"
|
#include "xpt2046.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "tp_spi.h"
|
#include "tp_spi.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@ -16,8 +15,6 @@
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
#define TAG "XPT2046"
|
|
||||||
|
|
||||||
#define CMD_X_READ 0b10010000 // NOTE: XPT2046 data sheet says this is actually Y
|
#define CMD_X_READ 0b10010000 // NOTE: XPT2046 data sheet says this is actually Y
|
||||||
#define CMD_Y_READ 0b11010000 // NOTE: XPT2046 data sheet says this is actually X
|
#define CMD_Y_READ 0b11010000 // NOTE: XPT2046 data sheet says this is actually X
|
||||||
#define CMD_Z1_READ 0b10110000
|
#define CMD_Z1_READ 0b10110000
|
||||||
|
@ -59,7 +56,7 @@ uint8_t avg_last;
|
||||||
*/
|
*/
|
||||||
void xpt2046_init(void)
|
void xpt2046_init(void)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "XPT2046 Initialization");
|
LV_LOG_INFO("Initialization");
|
||||||
|
|
||||||
#if XPT2046_TOUCH_IRQ || XPT2046_TOUCH_IRQ_PRESS
|
#if XPT2046_TOUCH_IRQ || XPT2046_TOUCH_IRQ_PRESS
|
||||||
gpio_config_t irq_config = {
|
gpio_config_t irq_config = {
|
||||||
|
@ -94,19 +91,19 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||||
|
|
||||||
x = xpt2046_cmd(CMD_X_READ);
|
x = xpt2046_cmd(CMD_X_READ);
|
||||||
y = xpt2046_cmd(CMD_Y_READ);
|
y = xpt2046_cmd(CMD_Y_READ);
|
||||||
ESP_LOGI(TAG, "P(%d,%d)", x, y);
|
LV_LOG_INFO("P(%d,%d)", x, y);
|
||||||
|
|
||||||
/*Normalize Data back to 12-bits*/
|
/*Normalize Data back to 12-bits*/
|
||||||
x = x >> 4;
|
x = x >> 4;
|
||||||
y = y >> 4;
|
y = y >> 4;
|
||||||
ESP_LOGI(TAG, "P_norm(%d,%d)", x, y);
|
LV_LOG_INFO("P_norm(%d,%d)", x, y);
|
||||||
|
|
||||||
xpt2046_corr(&x, &y);
|
xpt2046_corr(&x, &y);
|
||||||
xpt2046_avg(&x, &y);
|
xpt2046_avg(&x, &y);
|
||||||
last_x = x;
|
last_x = x;
|
||||||
last_y = y;
|
last_y = y;
|
||||||
|
|
||||||
ESP_LOGI(TAG, "x = %d, y = %d", x, y);
|
LV_LOG_INFO("x = %d, y = %d", x, y);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue