Merge branch 'master' into feature/add_st7796s

This commit is contained in:
Carlos Diaz 2021-01-15 00:07:27 -06:00 committed by GitHub
commit fbdc247c25
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 272 additions and 176 deletions

View file

@ -0,0 +1,52 @@
# Is your driver not listed on the supported drivers list?
Consider contributing to this demo project by adding support to your driver.
## Display driver.
To enable LVGL to work with your display you would need to implement from one up to three callback functions (one function for RGB TFT displays, three functions for monochrome display controllers), you can add more functions to enable backlight control, etc.
All display controller code is stored on the `components/lvgl_esp32_drivers/lvgl_tft` directory, see `disp_driver` and `CMakeLists.txt` to add your code into the idf project.
Create a header and source file named after the display controller (in lowercase). On the header file declare the necessary functions, such as:
```c
/* Configure your display */
void x_init(void);
/* LVGL callbacks */
void x_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
/* Only for monochrome displays */
void x_rounder(lv_disp_drv_t *disp_drv, lv_area_t *area);
void x_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);
```
Where x is the controller name.
For more information on the function callbacks check LVGL documentation: (Display driver)[https://docs.lvgl.io/v7/en/html/porting/display.html#display-driver].
Add your display functions on `disp_driver_init`, `disp_driver_flush`, `disp_driver_rounder` and `disp_driver_set_px` on the `disp_driver.c` file.
## Input device driver.
To enable LVGL to work with your touch controller you would need to implement an initialization function and one function to get the data out from your touch controller.
All touch controller code is stored on the `components/lvgl_esp32_drivers/lvgl_touch` directory.
Create a header and source file named after the display controller (in lowercase). On the header file declare the necessary functions, such as:
```c
/* Configure your display */
void x_init(void);
/* LVGL callbacks */
bool x_read(lv_disp_drv_t *drv, lv_indev_data_t *data);
```
Where x is the controller name.
For more information on the function callbacks check LVGL documentation: (Display driver)[https://docs.lvgl.io/v7/en/html/porting/indev.html].
## Kconfig and Project Configuration
The ESP32 SDK (ESP-IDF) uses [kconfiglib](https://github.com/ulfalizer/Kconfiglib) which is a Python-based extension to the [Kconfig](https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt) system which provides a compile-time project configuration mechanism. Using `idf.py menuconfig` will update the file sdkconfig and, during build, provide the file sdkconfig.h.

View file

@ -1 +1,65 @@
# lvgl esp32 drivers
# Display and touchpad drivers for ESP32 using LVGL
For a ready to use ESP32 project take look at the [lv_port_esp32](https://github.com/lvgl/lv_port_esp32) repository.
#### Table of content
- [Supported display controllers](#supported-display-controllers)
- [Supported indev controllers](#supported-indev-controllers)
- [Support for predefined development kits](#support-for-predefined-development-kits)
**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).
## Supported display controllers
| Display Controller | Type | Interface | Color depth (LV_COLOR_DEPTH) | Swap RGB565 color (LV_COLOR_16_SWAP) |
|---------------------------------------------|------------|------------------------|------------------------------|----------------------------------------|
| ILI9341 | TFT | SPI | 16: RGB565 | Yes |
| ILI9486 | TFT | SPI | 16: RGB565 | Yes |
| ILI9488 | TFT | SPI | 16: RGB565 | No |
| HX8357B/HX8357D | TFT | SPI | 16: RGB565 | Yes |
| ST7789 | TFT | SPI | 16: RGB565 | Yes |
| ST7735S | TFT | SPI | 16: RGB565 | Yes |
| FT81x | TFT | Single, Dual, Quad SPI | 16: RGB565 | No |
| GC9A01 | TFT | SPI | 16: RGB565 | Yes |
| RA8875 | TFT | SPI | 16: RGB565 | Yes |
| SH1107 | Monochrome | SPI | 1: 1byte per pixel | No |
| SSD1306 | Monochrome | I2C | 1: 1byte per pixel | No |
| IL3820 | e-Paper | SPI | 1: 1byte per pixel | No |
| UC8151D/ GoodDisplay GDEW0154M10 DES | e-Paper | SPI | 1: 1byte per pixel | No |
| FitiPower JD79653A/ GoodDisplay GDEW0154M09 | e-Paper | SPI | 1: 1byte per pixel | No |
## Supported indev controllers
- XPT2046
- FT3236
- other FT6X36 or the FT6206 controllers should work as well (not tested)
- STMPE610
- FT81x (Single, Dual, and Quad SPI)
If your display or input device (touch) controller is not supported consider contributing to this repo by
adding support to it! [Contribute controller support](CONTRIBUTE_CONTROLLER_SUPPORT.md)
## Support for predefined development kits
You can also use the predefined kits, which selects the correct display controllers on the kit,
and sets the gpio numbers for the interface.
| Kit name | Display controller | Interface | Hor. Res. | Ver. Res. |
|---------------------------|-----------------------|-----------|-----------|-----------|
| ESP Wrover Kit v4.1 | ILI9341 | SPI | 240 | 320 |
| M5Stack | ILI9341 | SPI | 240 | 320 |
| M5Stick | SH1107 | SPI | - | - |
| M5StickC | ST7735S | SPI | 80 | 160 |
| Adafruit 3.5 Featherwing | HX8357 | SPI | 480 | 320 |
| RPi MPI3501 | ILI9486 | SPI | - | - |
| Wemos Lolin OLED | SSD1306 | SPI | 64 | 128 |
| ER-TFT035-6 | ILI9488 | SPI | 480 | 320 |
| AIRcable ATAGv3 | IL3820 | SPI | 128 | 296 |
| TTGO T-Display | ST7789 | SPI | 135 | 240 |
| TTGO Camera Plus | ST7789 | SPI | 240 | 240 |
**NOTE:** See [Supported display controllers](#supported-display-controllers) for more information on display configuration.
**NOTE:** See [Supported indev controllers](#supported-indev-controllers) for more information about indev configuration.

View file

@ -30,7 +30,7 @@ extern "C" {
#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 (CONFIG_LV_DISPLAY_WIDTH*CONFIG_LV_DISPLAY_HEIGHT)
#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
@ -40,20 +40,20 @@ extern "C" {
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 64)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306
#define DISP_BUF_SIZE (CONFIG_LV_DISPLAY_WIDTH*CONFIG_LV_DISPLAY_HEIGHT)
#define DISP_BUF_SIZE (LV_HOR_RES_MAX*LV_VER_RES_MAX)
#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 (CONFIG_LV_DISPLAY_HEIGHT * IL3820_COLUMNS)
#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 ((CONFIG_LV_DISPLAY_HEIGHT * CONFIG_LV_DISPLAY_WIDTH) / 8) // 5KB
#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 ((CONFIG_LV_DISPLAY_HEIGHT * CONFIG_LV_DISPLAY_WIDTH) / 8) // 2888 bytes
#define DISP_BUF_SIZE ((LV_VER_RES_MAX * LV_VER_RES_MAX) / 8) // 2888 bytes
#else
#error "No display controller selected"
#endif

View file

@ -183,6 +183,27 @@ menu "LVGL TFT Display controller"
help
Display controller protocol I2C
# Used in display init function to send display orientation commands
choice DISPLAY_ORIENTATION
prompt "Display orientation"
default DISPLAY_ORIENTATION_PORTRAIT
config DISPLAY_ORIENTATION_PORTRAIT
bool "Portrait"
config DISPLAY_ORIENTATION_PORTRAIT_INVERTED
bool "Portrait inverted"
config DISPLAY_ORIENTATION_LANDSCAPE
bool "Landscape"
config DISPLAY_ORIENTATION_LANDSCAPE_INVERTED
bool "Landscape inverted"
endchoice
config LV_DISPLAY_ORIENTATION
int
default 0 if DISPLAY_ORIENTATION_PORTRAIT
default 1 if DISPLAY_ORIENTATION_PORTRAIT_INVERTED
default 2 if DISPLAY_ORIENTATION_LANDSCAPE
default 3 if DISPLAY_ORIENTATION_LANDSCAPE_INVERTED
config LV_TFT_DISPLAY_OFFSETS
bool
help
@ -468,101 +489,6 @@ menu "LVGL TFT Display controller"
bool "I2C PORT 1"
endchoice
choice
prompt "Display orientation"
depends on LV_TFT_DISPLAY_CONTROLLER_ILI9341 || \
LV_TFT_DISPLAY_CONTROLLER_ILI9481 || \
LV_TFT_DISPLAY_CONTROLLER_ILI9486 || \
LV_TFT_DISPLAY_CONTROLLER_ILI9488 || \
LV_TFT_DISPLAY_CONTROLLER_SH1107 || \
LV_TFT_DISPLAY_CONTROLLER_SSD1306 || \
LV_TFT_DISPLAY_CONTROLLER_FT81X || \
LV_TFT_DISPLAY_CONTROLLER_ST7789 || \
LV_TFT_DISPLAY_CONTROLLER_GC9A01 || \
LV_TFT_DISPLAY_CONTROLLER_ST7735S || \
LV_TFT_DISPLAY_CONTROLLER_IL3820 || \
LV_TFT_DISPLAY_CONTROLLER_RA8875 || \
LV_TFT_DISPLAY_CONTROLLER_JD79653A || \
LV_TFT_DISPLAY_CONTROLLER_UC8151D || \
LV_TFT_DISPLAY_CONTROLLER_ST7796S
default LV_DISPLAY_ORIENTATION_LANDSCAPE \
if !LV_TFT_DISPLAY_CONTROLLER_JD79653A || \
!LV_TFT_DISPLAY_CONTROLLER_UC8151D
default LV_DISPLAY_ORIENTATION_PORTRAIT if LV_TFT_DISPLAY_CONTROLLER_JD79653A || LV_TFT_DISPLAY_CONTROLLER_UC8151D
help
Display orientation.
config LV_DISPLAY_ORIENTATION_PORTRAIT
bool "Portrait"
config LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED
bool "Inverted Portrait"
depends on !LV_TFT_DISPLAY_CONTROLLER_IL3820
config LV_DISPLAY_ORIENTATION_LANDSCAPE
bool "Landscape"
depends on !LV_TFT_DISPLAY_CONTROLLER_JD79653A
depends on !LV_TFT_DISPLAY_CONTROLLER_UC8151D
config LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED
bool "Inverted Landscape"
depends on !LV_TFT_DISPLAY_CONTROLLER_IL3820
depends on !LV_TFT_DISPLAY_CONTROLLER_JD79653A
depends on !LV_TFT_DISPLAY_CONTROLLER_UC8151D
endchoice
# Display orientation
# This symbol is meant to be used as parameter on the display_set_orientation
# function at init.
config LV_DISPLAY_ORIENTATION
int
default 0 if LV_DISPLAY_ORIENTATION_PORTRAIT
default 1 if LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED
default 2 if LV_DISPLAY_ORIENTATION_LANDSCAPE
default 3 if LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED
config LV_DISPLAY_WIDTH
int "TFT display width in pixels." if LV_PREDEFINED_DISPLAY_NONE || \
LV_TFT_DISPLAY_CONTROLLER_FT81X
default 240 if ( LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_WROVER4 ) && (LV_DISPLAY_ORIENTATION_PORTRAIT)
default 240 if ( LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_WROVER4 ) && (LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 320 if ( LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_WROVER4 ) && (LV_DISPLAY_ORIENTATION_LANDSCAPE)
default 320 if ( LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_WROVER4 ) && (LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
default 480 if LV_PREDEFINED_DISPLAY_WT32_SC01 && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
default 320 if LV_PREDEFINED_DISPLAY_WT32_SC01 && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 480 if LV_PREDEFINED_DISPLAY_ERTFT0356 || LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
default 64 if ( LV_PREDEFINED_DISPLAY_WEMOS_LOLIN || LV_PREDEFINED_DISPLAY_M5STICK ) && LV_DISPLAY_ORIENTATION_PORTRAIT
default 128 if ( LV_PREDEFINED_DISPLAY_WEMOS_LOLIN || LV_PREDEFINED_DISPLAY_M5STICK ) && LV_DISPLAY_ORIENTATION_LANDSCAPE
default 800 if LV_TFT_DISPLAY_CONTROLLER_FT81X
default 128 if LV_PREDEFINED_DISPLAY_ATAG && LV_DISPLAY_ORIENTATION_PORTRAIT
default 296 if LV_PREDEFINED_DISPLAY_ATAG && LV_DISPLAY_ORIENTATION_LANDSCAPE
default 80 if LV_PREDEFINED_DISPLAY_M5STICKC && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 160 if LV_PREDEFINED_DISPLAY_M5STICKC && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
default 135 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 240 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
default 240 if LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS
default 320
config LV_DISPLAY_HEIGHT
int "TFT display height in pixels." if LV_PREDEFINED_DISPLAY_NONE || \
LV_TFT_DISPLAY_CONTROLLER_FT81X
default 320 if ( LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_WROVER4 ) && (LV_DISPLAY_ORIENTATION_PORTRAIT)
default 320 if ( LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_WROVER4 ) && (LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 240 if ( LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_WROVER4 ) && (LV_DISPLAY_ORIENTATION_LANDSCAPE)
default 240 if ( LV_PREDEFINED_DISPLAY_M5STACK || LV_PREDEFINED_DISPLAY_WROVER4 ) && (LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
default 480 if LV_PREDEFINED_DISPLAY_WT32_SC01 && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 320 if LV_PREDEFINED_DISPLAY_WT32_SC01 && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
default 320 if LV_PREDEFINED_DISPLAY_ERTFT0356 || LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
default 128 if ( LV_PREDEFINED_DISPLAY_WEMOS_LOLIN || LV_PREDEFINED_DISPLAY_M5STICK ) && LV_DISPLAY_ORIENTATION_PORTRAIT
default 64 if ( LV_PREDEFINED_DISPLAY_WEMOS_LOLIN || LV_PREDEFINED_DISPLAY_M5STICK ) && LV_DISPLAY_ORIENTATION_LANDSCAPE
default 480 if LV_TFT_DISPLAY_CONTROLLER_FT81X
default 296 if LV_PREDEFINED_DISPLAY_ATAG && LV_DISPLAY_ORIENTATION_PORTRAIT
default 128 if LV_PREDEFINED_DISPLAY_ATAG && LV_DISPLAY_ORIENTATION_LANDSCAPE
default 160 if LV_PREDEFINED_DISPLAY_M5STICKC && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 80 if LV_PREDEFINED_DISPLAY_M5STICKC && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
default 240 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_PORTRAIT || LV_DISPLAY_ORIENTATION_PORTRAIT_INVERTED)
default 135 if LV_PREDEFINED_DISPLAY_TTGO && (LV_DISPLAY_ORIENTATION_LANDSCAPE || LV_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
default 240 if LV_PREDEFINED_DISPLAY_TTGO_CAMERA_PLUS
default 240
config LV_TFT_USE_CUSTOM_SPI_CLK_DIVIDER
bool "Use custom SPI clock frequency." if LV_TFT_DISPLAY_PROTOCOL_SPI
default n

View file

@ -49,7 +49,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
#define BIT_CLEAR(a,b) ((a) &= ~(1U<<(b)))
/* Number of pixels? */
#define IL3820_PIXEL (CONFIG_LV_DISPLAY_WIDTH * CONFIG_LV_DISPLAY_HEIGHT)
#define IL3820_PIXEL (LV_HOR_RES_MAX * LV_VER_RES_MAX)
#define EPD_PANEL_NUMOF_COLUMS EPD_PANEL_WIDTH
#define EPD_PANEL_NUMOF_ROWS_PER_PAGE 8

View file

@ -20,8 +20,8 @@ extern "C"
/* Values for Waveshare 2.9inch e-Paper Module, this values shouldn't be
* swapped to change display orientation */
#define EPD_PANEL_WIDTH CONFIG_LV_DISPLAY_WIDTH /* 128 */
#define EPD_PANEL_HEIGHT CONFIG_LV_DISPLAY_HEIGHT /* 296 */
#define EPD_PANEL_WIDTH LV_HOR_RES_MAX /* 128 */
#define EPD_PANEL_HEIGHT LV_VER_RES_MAX /* 296 */
/* 128 = panel width */
#define IL3820_COLUMNS (EPD_PANEL_WIDTH / 8)

View file

@ -43,8 +43,8 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
#define PIN_BUSY CONFIG_LV_DISP_PIN_BUSY
#define PIN_BUSY_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_BUSY)))
#define EVT_BUSY (1UL << 0UL)
#define EPD_WIDTH CONFIG_LV_DISPLAY_WIDTH
#define EPD_HEIGHT CONFIG_LV_DISPLAY_HEIGHT
#define EPD_WIDTH LV_HOR_RES_MAX
#define EPD_HEIGHT LV_VER_RES_MAX
#define EPD_ROW_LEN (EPD_HEIGHT / 8u)
#define EPD_PARTIAL_CNT 5;

View file

@ -37,8 +37,8 @@
#endif
#define BYTES_PER_PIXEL (LV_COLOR_DEPTH / 8)
#define HDWR_VAL (CONFIG_LV_DISPLAY_WIDTH/8 - 1)
#define VDHR_VAL (CONFIG_LV_DISPLAY_HEIGHT - 1)
#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)
@ -248,7 +248,7 @@ void ra8875_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
#if DEBUG
ESP_LOGI(TAG, "flush: set window (x1,x2): %d,%d -> %d,%d", x1, x2, area->x1, area->x2);
#endif
ra8875_set_window(area->x1, area->x2, 0, CONFIG_LV_DISPLAY_HEIGHT-1);
ra8875_set_window(area->x1, area->x2, 0, LV_VER_RES_MAX-1);
x1 = area->x1;
x2 = area->x2;
}
@ -264,7 +264,7 @@ void ra8875_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * colo
// Update to future cursor location
y = area->y2 + 1;
if (y >= CONFIG_LV_DISPLAY_HEIGHT) {
if (y >= LV_VER_RES_MAX) {
y = 0;
}

View file

@ -124,10 +124,10 @@ void sh1107_set_px_cb(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t b
uint8_t bit_index = 0;
#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
byte_index = y + (( x>>3 ) * CONFIG_LV_DISPLAY_HEIGHT);
byte_index = y + (( x>>3 ) * LV_VER_RES_MAX);
bit_index = x & 0x7;
#elif defined CONFIG_LV_DISPLAY_ORIENTATION_PORTRAIT
byte_index = x + (( y>>3 ) * CONFIG_LV_DISPLAY_WIDTH);
byte_index = x + (( y>>3 ) * LV_HOR_RES_MAX);
bit_index = y & 0x7;
#endif
@ -159,9 +159,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
size = area->y2 - area->y1 + 1;
#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
ptr = color_map + i * CONFIG_LV_DISPLAY_HEIGHT;
ptr = color_map + i * LV_VER_RES_MAX;
#else
ptr = color_map + i * CONFIG_LV_DISPLAY_WIDTH;
ptr = color_map + i * LV_HOR_RES_MAX;
#endif
if(i != row2){
sh1107_send_data( (void *) ptr, size);
@ -177,8 +177,8 @@ void sh1107_rounder(struct _disp_drv_t * disp_drv, lv_area_t *area)
// workaround: always send complete size display buffer
area->x1 = 0;
area->y1 = 0;
area->x2 = CONFIG_LV_DISPLAY_WIDTH-1;
area->y2 = CONFIG_LV_DISPLAY_HEIGHT-1;
area->x2 = LV_HOR_RES_MAX-1;
area->y2 = LV_VER_RES_MAX-1;
}
void sh1107_sleep_in()

View file

@ -130,7 +130,7 @@ void ssd1306_init()
i2c_cmd_link_delete(cmd);
}
void ssd1306_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 ssd1306_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) {
uint16_t byte_index = x + (( y>>3 ) * buf_w);
uint8_t bit_index = y & 0x7;
@ -147,13 +147,9 @@ void ssd1306_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t
uint8_t row1 = 0, row2 = 0;
i2c_cmd_handle_t cmd;
#if defined CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
row1 = area->y1>>3;
row2 = area->y2>>3;
#else
row1 = area->y1>>3;
row2 = area->y2>>3;
#endif
// Divide by 8
row1 = area->y1 >> 3;
row2 = area->y2 >> 3;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
@ -185,16 +181,19 @@ void ssd1306_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t
lv_disp_flush_ready(disp_drv);
}
void ssd1306_rounder(struct _disp_drv_t * disp_drv, lv_area_t *area)
// workaround: always send complete size display buffer, no partial update
void ssd1306_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area)
{
// area->y1 = (area->y1 & (~0x7));
// area->y2 = (area->y2 & (~0x7)) + 7;
// workaround: always send complete size display buffer
uint8_t hor_max = disp_drv->hor_res;
uint8_t ver_max = disp_drv->ver_res;
area->x1 = 0;
area->y1 = 0;
area->x2 = CONFIG_LV_DISPLAY_WIDTH-1;
area->y2 = CONFIG_LV_DISPLAY_HEIGHT-1;
area->x2 = hor_max - 1;
area->y2 = ver_max - 1;
}
void ssd1306_sleep_in()

View file

@ -38,8 +38,8 @@ extern "C" {
**********************/
void ssd1306_init(void);
void ssd1306_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map);
void ssd1306_rounder(struct _disp_drv_t * disp_drv, lv_area_t *area);
void ssd1306_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 ssd1306_rounder(lv_disp_drv_t * disp_drv, lv_area_t *area);
void ssd1306_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);
void ssd1306_sleep_in(void);

View file

@ -23,7 +23,6 @@ extern "C" {
/*********************
* DEFINES
*********************/
// #define DISP_BUF_SIZE (CONFIG_LV_DISPLAY_WIDTH*CONFIG_LV_DISPLAY_HEIGHT)
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40)
#define ST7735S_DC CONFIG_LV_DISP_PIN_DC

View file

@ -44,8 +44,8 @@
#define PIN_BUSY CONFIG_LV_DISP_PIN_BUSY
#define PIN_BUSY_BIT ((1ULL << (uint8_t)(CONFIG_LV_DISP_PIN_BUSY)))
#define EVT_BUSY (1UL << 0UL)
#define EPD_WIDTH CONFIG_LV_DISPLAY_WIDTH
#define EPD_HEIGHT CONFIG_LV_DISPLAY_HEIGHT
#define EPD_WIDTH LV_HOR_RES_MAX
#define EPD_HEIGHT LV_VER_RES_MAX
#define EPD_ROW_LEN (EPD_HEIGHT / 8u)
#define BIT_SET(a, b) ((a) |= (1U << (b)))

View file

@ -99,7 +99,6 @@ menu "LVGL Touch controller"
range 0 39
default 35 if LV_PREDEFINED_PINS_38V1
default 19
help
Configure the touchpanel MISO pin here.
@ -109,7 +108,6 @@ menu "LVGL Touch controller"
range 0 39
default 32 if LV_PREDEFINED_PINS_38V1
default 23
help
Configure the touchpanel MOSI pin here.
@ -135,7 +133,7 @@ menu "LVGL Touch controller"
default 27 if LV_PREDEFINED_PINS_38V4
default 25
help
Configure the touchpanel CS pin here.
Configure the touchpanel IRQ pin here.
endmenu
menu "Touchpanel Configuration (XPT2046)"
@ -180,6 +178,19 @@ menu "LVGL Touch controller"
prompt "Invert Y coordinate value."
default y
choice
prompt "Select touch detection method."
default LV_TOUCH_DETECT_IRQ
help
Select the controller for your touch panel.
config LV_TOUCH_DETECT_IRQ
bool "IRQ pin only"
config LV_TOUCH_DETECT_IRQ_PRESSURE
bool "IRQ pin and pressure"
config LV_TOUCH_DETECT_PRESSURE
bool "Pressure only"
endchoice
endmenu
menu "Touchpanel (FT6X06) Pin Assignments"

View file

@ -38,16 +38,16 @@ extern "C" {
/*GetMaxX Macro*/
#if CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
#define GetMaxX() (CONFIG_LV_DISPLAY_WIDTH - 1)
#define GetMaxX() (LV_HOR_RES_MAX - 1)
#else
#define GetMaxX() (CONFIG_LV_DISPLAY_HEIGHT - 1)
#define GetMaxX() (LV_VER_RES_MAX - 1)
#endif
/*GetMaxY Macro*/
#if CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
#define GetMaxY() (CONFIG_LV_DISPLAY_HEIGHT - 1)
#define GetMaxY() (LV_VER_RES_MAX - 1)
#else
#define GetMaxY() (CONFIG_LV_DISPLAY_WIDTH - 1)
#define GetMaxY() (LV_HOR_RES_MAX - 1)
#endif
#ifndef CONCAT3

View file

@ -27,6 +27,7 @@
#endif
#include "ft6x36.h"
#include "tp_i2c.h"
#include "../lvgl_i2c_conf.h"
#define TAG "FT6X36"
@ -46,7 +47,7 @@ esp_err_t ft6x06_i2c_read8(uint8_t slave_addr, uint8_t register_addr, uint8_t *d
i2c_master_read_byte(i2c_cmd, data_buf, I2C_MASTER_NACK);
i2c_master_stop(i2c_cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, i2c_cmd, 1000 / portTICK_RATE_MS);
esp_err_t ret = i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(i2c_cmd);
return ret;
}
@ -145,7 +146,7 @@ bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
i2c_master_read_byte(i2c_cmd, &data_xy[0], I2C_MASTER_ACK); // reads FT6X36_P1_XH_REG
i2c_master_read_byte(i2c_cmd, &data_xy[1], I2C_MASTER_NACK); // reads FT6X36_P1_XL_REG
i2c_master_stop(i2c_cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, i2c_cmd, 1000 / portTICK_RATE_MS);
esp_err_t ret = i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(i2c_cmd);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Error getting X coordinates: %s", esp_err_to_name(ret));
@ -168,7 +169,7 @@ bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
i2c_master_read_byte(i2c_cmd, &data_xy[2], I2C_MASTER_ACK); // reads FT6X36_P1_YH_REG
i2c_master_read_byte(i2c_cmd, &data_xy[3], I2C_MASTER_NACK); // reads FT6X36_P1_YL_REG
i2c_master_stop(i2c_cmd);
ret = i2c_master_cmd_begin(I2C_NUM_0, i2c_cmd, 1000 / portTICK_RATE_MS);
ret = i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(i2c_cmd);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Error getting Y coordinates: %s", esp_err_to_name(ret));

View file

@ -18,18 +18,26 @@
*********************/
#define TAG "XPT2046"
#define CMD_X_READ 0b10010000
#define CMD_Y_READ 0b11010000
#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_Z1_READ 0b10110000
#define CMD_Z2_READ 0b11000000
/**********************
* TYPEDEFS
**********************/
typedef enum {
TOUCH_NOT_DETECTED = 0,
TOUCH_DETECTED = 1,
} xpt2046_touch_detect_t;
/**********************
* STATIC PROTOTYPES
**********************/
static void xpt2046_corr(int16_t * x, int16_t * y);
static void xpt2046_avg(int16_t * x, int16_t * y);
static int16_t xpt2046_cmd(uint8_t cmd);
static xpt2046_touch_detect_t xpt2048_is_touch_detected();
/**********************
* STATIC VARIABLES
@ -51,6 +59,9 @@ uint8_t avg_last;
*/
void xpt2046_init(void)
{
ESP_LOGI(TAG, "XPT2046 Initialization");
#if XPT2046_TOUCH_IRQ || XPT2046_TOUCH_IRQ_PRESS
gpio_config_t irq_config = {
.pin_bit_mask = BIT64(XPT2046_IRQ),
.mode = GPIO_MODE_INPUT,
@ -59,10 +70,9 @@ void xpt2046_init(void)
.intr_type = GPIO_INTR_DISABLE,
};
ESP_LOGI(TAG, "XPT2046 Initialization");
esp_err_t ret = gpio_config(&irq_config);
assert(ret == ESP_OK);
#endif
}
/**
@ -74,21 +84,16 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
{
static int16_t last_x = 0;
static int16_t last_y = 0;
bool valid = true;
bool valid = false;
int16_t x = 0;
int16_t y = 0;
int16_t x = last_x;
int16_t y = last_y;
if (xpt2048_is_touch_detected() == TOUCH_DETECTED)
{
valid = true;
uint8_t irq = gpio_get_level(XPT2046_IRQ);
if (irq == 0) {
uint8_t data[2];
tp_spi_read_reg(CMD_X_READ, data, 2);
x = (data[0] << 8) | data[1];
tp_spi_read_reg(CMD_Y_READ, data, 2);
y = (data[0] << 8) | data[1];
x = xpt2046_cmd(CMD_X_READ);
y = xpt2046_cmd(CMD_Y_READ);
ESP_LOGI(TAG, "P(%d,%d)", x, y);
/*Normalize Data back to 12-bits*/
@ -102,11 +107,10 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
last_y = y;
ESP_LOGI(TAG, "x = %d, y = %d", x, y);
} else {
x = last_x;
y = last_y;
}
else
{
avg_last = 0;
valid = false;
}
data->point.x = x;
@ -119,6 +123,42 @@ bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
/**********************
* STATIC FUNCTIONS
**********************/
static xpt2046_touch_detect_t xpt2048_is_touch_detected()
{
// check IRQ pin if we IRQ or IRQ and preessure
#if XPT2046_TOUCH_IRQ || XPT2046_TOUCH_IRQ_PRESS
uint8_t irq = gpio_get_level(XPT2046_IRQ);
if (irq != 0) {
return TOUCH_NOT_DETECTED;
}
#endif
// check pressure if we are pressure or IRQ and pressure
#if XPT2046_TOUCH_PRESS || XPT2046_TOUCH_IRQ_PRESS
int16_t z1 = xpt2046_cmd(CMD_Z1_READ) >> 3;
int16_t z2 = xpt2046_cmd(CMD_Z2_READ) >> 3;
// this is not what the confusing datasheet says but it seems to
// be enough to detect real touches on the panel
int16_t z = z1 + 4096 - z2;
if (z < XPT2046_TOUCH_THRESHOLD)
{
return TOUCH_NOT_DETECTED;
}
#endif
return TOUCH_DETECTED;
}
static int16_t xpt2046_cmd(uint8_t cmd)
{
uint8_t data[2];
tp_spi_read_reg(cmd, data, 2);
int16_t val = (data[0] << 8) | data[1];
return val;
}
static void xpt2046_corr(int16_t * x, int16_t * y)
{
#if XPT2046_XY_SWAP != 0

View file

@ -35,6 +35,10 @@ extern "C" {
#define XPT2046_X_INV CONFIG_LV_TOUCH_INVERT_X
#define XPT2046_Y_INV CONFIG_LV_TOUCH_INVERT_Y
#define XPT2046_XY_SWAP CONFIG_LV_TOUCH_XY_SWAP
#define XPT2046_TOUCH_THRESHOLD 400 // Threshold for touch detection
#define XPT2046_TOUCH_IRQ CONFIG_LV_TOUCH_DETECT_IRQ
#define XPT2046_TOUCH_IRQ_PRESS CONFIG_LV_TOUCH_DETECT_IRQ_PRESSURE
#define XPT2046_TOUCH_PRESS CONFIG_LV_TOUCH_DETECT_PRESSURE
/**********************
* TYPEDEFS