#1 Cleanup and add L58 as driver in this component

This commit is contained in:
Martin Fasani 2021-06-22 10:07:38 +02:00
parent c55e32a9d4
commit a66706d139
12 changed files with 451 additions and 237 deletions

View file

@ -11,9 +11,7 @@ list(APPEND SOURCES "lvgl_tft/disp_driver.c")
if(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341)
list(APPEND SOURCES "lvgl_tft/ili9341.c")
elseif(CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER)
list(APPEND SOURCES "lvgl_tft/epdiy_epaper.cpp")
elseif(CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER)
list(APPEND SOURCES "lvgl_tft/calepd_epaper.cpp")
list(APPEND SOURCES "lvgl_tft/epdiy_epaper.c")
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481)
list(APPEND SOURCES "lvgl_tft/ili9481.c")
elseif(CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9486)
@ -67,6 +65,7 @@ if(CONFIG_LV_TOUCH_CONTROLLER)
elseif(CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
list(APPEND SOURCES "lvgl_touch/ft6x36.c")
elseif(CONFIG_LV_TOUCH_CONTROLLER_L58)
list(APPEND SOURCES "lvgl_touch/L58/L58Touch.cpp")
list(APPEND SOURCES "lvgl_touch/l58.cpp")
elseif(CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
list(APPEND SOURCES "lvgl_touch/stmpe610.c")

View file

@ -33,8 +33,10 @@ swap of RGB565 color on the LVGL configuration menuconfig (it's not handled auto
| FitiPower JD79653A/ GoodDisplay GDEW0154M09 | e-Paper | SPI | 1: 1byte per pixel | No |
| EPDiy supported epaper (needs PCB) | e-Paper | Parallel | 4: RGB232 16 grayscales | No
Please note that EPDiy supported epapers include also the Lilygo EPD47 that comes with it's own PCB and ESP32 WROVER. Is possible also to build your own EPDiy PCB, please find the [project KiCad source files, schematics, and documentation here](https://github.com/vroland/epdiy/tree/master/hardware/epaper-breakout)
To use an EPDiy supported epaper you need to add it [as a component](https://github.com/martinberlin/lv_port_esp32-epaper/tree/master/components) and also update the CMakeLists of lvgl component to [REQUIRE that library](https://github.com/martinberlin/lv_port_esp32-epaper/wiki).
Please note that EPDiy supported epapers include also the Lilygo EPD47 that comes with it's own PCB and ESP32 WROVER. Is possible also to build your own EPDiy PCB, please find the [project KiCad source files, schematics, and documentation here](https://github.com/vroland/epdiy/tree/master/hardware/epaper-breakout).
To use an EPDiy supported epaper you need to add it [as a component using git submodules](https://github.com/martinberlin/lv_port_esp32-epaper/tree/master/components) and also update the CMakeLists of lvgl component to [REQUIRE that library](https://github.com/martinberlin/lv_port_esp32-epaper/wiki).
git submodule add https://github.com/martinberlin/epdiy-rotation.git components/epd_driver
## Supported indev controllers
@ -43,6 +45,7 @@ To use an EPDiy supported epaper you need to add it [as a component](https://git
- other FT6X36 or the FT6206 controllers should work as well (not tested)
- STMPE610
- FT81x (Single, Dual, and Quad SPI)
- L58 touch component hook (Used in Lilygo EPD47 parallel with EPDiy driver)
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)

View file

@ -45,7 +45,7 @@ extern "C" {
// IMPORTANT: This will render the screen in 10 times:
#elif defined (CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER)
#define DISP_BUF_SIZE LV_HOR_RES_MAX*(LV_VER_RES_MAX/10)
#elif defined (CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER)
#elif defined ()
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 90)
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_HX8357

View file

@ -93,10 +93,7 @@ menu "LVGL TFT/Epaper Display controller"
bool
help
EPDIY parallel epaper controller.
config LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
bool
help
CalEPD SPI epaper controller.
config LV_TFT_DISPLAY_CONTROLLER_ILI9341
bool
help
@ -283,12 +280,6 @@ menu "LVGL TFT/Epaper Display controller"
bool "EPDIY_GENERIC"
select LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
select LV_EPAPER_DISPLAY_PROTOCOL_PARALLEL
config LV_EPAPER_DISPLAY_USER_CONTROLLER_CALEPD
bool "CALEPD_GENERIC"
# Use also Parallel to avoid LGVL SPI instantiation
select LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
select LV_EPAPER_DISPLAY_PROTOCOL_PARALLEL
config LV_TFT_DISPLAY_USER_CONTROLLER_ILI9341
bool "ILI9341"
select LV_TFT_DISPLAY_CONTROLLER_ILI9341

View file

@ -1,84 +0,0 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "calepd_epaper.h"
// NOTE: This needs Epdiy component https://github.com/vroland/epdiy
// Run idf.py menuconfig-> Component Config -> E-Paper driver and select:
// Display type: LILIGO 4.7 ED047TC1
// Board: LILIGO T5-4.7 Epaper
// In the same section Component Config -> ESP32 Specifics -> Enable PSRAM
//#include "parallel/ED047TC1.h"
//Ed047TC1 display;
// SPI Generic epapers (Goodisplay/ Waveshare)
// Select the right class for your SPI epaper: https://github.com/martinberlin/cale-idf/wiki
//#include <gdew0583t7.h>
#include <gdew027w3.h>
Gdew027w3 display(io);
EpdSpi io;
//Gdew0583T7 display(io);
/** test Display dimensions
* Do not forget to set: menuconfig -> Components -> LVGL configuration
* Max. Horizontal resolution 264 -> WIDTH of your epaper
* Max. Vertical resolution 176 -> HEIGHT
*/
/*********************
* DEFINES
*********************/
#define TAG "EPDIY"
uint16_t flushcalls = 0;
/* Display initialization routine */
void calepd_init(void)
{
printf("calepd_init\n");
display.init();
display.setRotation(0);
// Clear screen
//display.update();
}
/* Required by LVGL */
void calepd_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
++flushcalls;
printf("flush %d x:%d y:%d w:%d h:%d\n", flushcalls,area->x1,area->y1,lv_area_get_width(area),lv_area_get_height(area));
// Full update
if (lv_area_get_width(area)==display.width() && lv_area_get_height(area)==display.height()) {
display.update();
} else {
// Partial update:
display.update(); // Uncomment to disable partial update
//display.updateWindow(area->x1,area->y1,lv_area_get_width(area),lv_area_get_height(area), true);
//display.updateWindow(area->x1,area->y1,lv_area_get_width(area),lv_area_get_height(area));
}
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing */
lv_disp_flush_ready(drv);
}
/* Called for each pixel */
void calepd_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)
{
//If not drawing anything: Debug to see if this function is called:
//printf("set_px %d %d\n",(int16_t)x,(int16_t)y);
// Test using RGB232
int16_t epd_color = EPD_WHITE;
// Color setting use: RGB232
// Only monochrome:All what is not white, turn black
if ((int16_t)color.full<254) {
epd_color = EPD_BLACK;
}
display.drawPixel((int16_t)x, (int16_t)y, epd_color);
}

View file

@ -1,36 +0,0 @@
/**
* Display class for generic e-Paper driven by EPDiy class
*/
#ifndef CALEPD_H
#define CALEPD_H
#define EPDIY_COLUMNS (LV_HOR_RES_MAX / 8)
#ifdef __cplusplus
extern "C" {
#endif
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#include "sdkconfig.h"
/* Configure your display */
void calepd_init(void);
/* LVGL callbacks */
void calepd_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map);
/* Only for monochrome displays. But we use epdiy_set_px also for epapers */
//void epdiy_rounder(lv_disp_drv_t *disp_drv, lv_area_t *area);
void calepd_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);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* EPDIY_H */

View file

@ -12,8 +12,6 @@ void disp_driver_init(void)
ili9341_init();
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
epdiy_init();
#elif defined CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
calepd_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481
ili9481_init();
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
@ -54,9 +52,7 @@ void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t *
#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9341
ili9341_flush(drv, area, color_map);
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
epdiy_flush(drv, area, color_map);
#elif defined CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
calepd_flush(drv, area, color_map);
epdiy_flush(drv, area, color_map);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481
ili9481_flush(drv, area, color_map);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
@ -115,8 +111,6 @@ void disp_driver_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_
ssd1306_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
epdiy_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
calepd_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SH1107
sh1107_set_px_cb(disp_drv, buf, buf_w, x, y, color, opa);
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820

View file

@ -22,8 +22,6 @@ extern "C" {
#include "ili9341.h"
#elif defined CONFIG_LV_EPAPER_EPDIY_DISPLAY_CONTROLLER
#include "lvgl_tft/epdiy_epaper.h"
#elif defined CONFIG_LV_EPAPER_CALEPD_DISPLAY_CONTROLLER
#include "lvgl_tft/calepd_epaper.h"
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9481
#include "ili9481.h"
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488

View file

@ -1,92 +0,0 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "epdiy_epaper.h"
#include "epd_driver.h"
#include "epd_highlevel.h"
/**************************************************************************************************
* NOTE: This file iis the first version that writes directly on the set_px callback
* each pixel into the epaper display buffer. The second version is not epdiy_epaper.cpp
* It writes *buf and then it comes as *color_map on the flush callback.
* Feel free to experiment with this 2. epdiy_epaper.cpp works better to make a small UX
**************************************************************************************************/
#define TAG "EPDIY"
EpdiyHighlevelState hl;
uint16_t flushcalls = 0;
uint8_t * framebuffer;
uint8_t temperature = 25;
/* Display initialization routine */
void epdiy_init(void)
{
epd_init(EPD_OPTIONS_DEFAULT);
hl = epd_hl_init(EPD_BUILTIN_WAVEFORM);
framebuffer = epd_hl_get_framebuffer(&hl);
epd_poweron();
//Clear all always in init?
//epd_fullclear(&hl, temperature);
}
uint16_t xo = 0;
uint16_t yo = 0;
/* Required by LVGL */
void epdiy_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
++flushcalls;
xo = area->x1;
yo = area->y1;
uint16_t w = lv_area_get_width(area);
uint16_t h = lv_area_get_height(area);
EpdRect update_area = {
.x = xo,
.y = yo,
.width = w,
.height = h,
};
epd_hl_update_area(&hl, MODE_GC16, temperature, update_area); //update_area
printf("epdiy_flush %d x:%d y:%d w:%d h:%d\n", flushcalls,xo,yo,w,h);
/* Inform the graphics library that you are ready with the flushing */
lv_disp_flush_ready(drv);
}
/*
* Called for each pixel. Designed with the idea to fill the buffer directly, not to set each pixel, see:
* https://forum.lvgl.io/t/lvgl-port-to-be-used-with-epaper-displays/5630/3
*/
void epdiy_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)
{
// Debug where x y is printed, not all otherwise is too much Serial
/* if ((int16_t)y%10==0 && flushcalls>0){
if ((int16_t)x%2==0){
printf("x%d y%d\n", (int16_t)x, (int16_t)y);
}
}
*/
// Test using RGB232
int16_t epd_color = 255;
if ((int16_t)color.full<250) {
epd_color = (int16_t)color.full/3;
}
int16_t x1 = (int16_t)x;
int16_t y1 = (int16_t)y;
//Instead of using epd_draw_pixel: Set pixel directly in buffer
//epd_draw_pixel(x1, y1, epd_color, framebuffer);
uint8_t *buf_ptr = &framebuffer[y1 * buf_w / 2 + x1 / 2];
if (x % 2) {
*buf_ptr = (*buf_ptr & 0x0F) | (epd_color & 0xF0);
} else {
*buf_ptr = (*buf_ptr & 0xF0) | (epd_color >> 4);
}
}

316
lvgl_touch/L58/L58Touch.cpp Normal file
View file

@ -0,0 +1,316 @@
// This is the first experimental Touch component for the LILYGO EPD47 touch overlay
// Controller: L58 -> https://github.com/Xinyuan-LilyGO/LilyGo-EPD47/files/6059098/L58.V1.0.pdf
// Note: Rotation is only working for certain angles (0 works alright, 2 also) Others still need to be corrected
#include "L58Touch.h"
#define CONFIG_L58_DEBUG 0
L58Touch *L58Touch::_instance = nullptr;
static const char *TAG = "i2c-touch";
L58Touch::L58Touch(int8_t intPin)
{
_instance = this;
printf("I2C sda:%d scl:%d int:%d\n\n",
CONFIG_LV_TOUCH_I2C_SDA, CONFIG_LV_TOUCH_I2C_SCL, intPin);
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = (gpio_num_t)CONFIG_LV_TOUCH_I2C_SDA;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = (gpio_num_t)CONFIG_LV_TOUCH_I2C_SCL;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = 50000;
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0)
// !< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here.
conf.clk_flags = 0;
#endif
i2c_param_config(I2C_NUM_0, &conf);
esp_err_t i2c_driver = i2c_driver_install(I2C_NUM_0, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
if (i2c_driver == ESP_OK) {
printf("i2c_driver started correctly\n");
} else {
printf("i2c_driver error: %d\n", i2c_driver);
}
_intPin = intPin;
}
// Destructor does nothing for now
L58Touch::~L58Touch()
{
}
bool L58Touch::begin(uint16_t width, uint16_t height)
{
_touch_width = width;
_touch_height = height;
if (width == 0 || height ==0) {
ESP_LOGE(TAG,"begin(uint8_t threshold, uint16_t width, uint16_t height) did not receive the width / height so touch cannot be rotation aware");
}
// INT pin triggers the callback function on the Falling edge of the GPIO
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_POSEDGE;
io_conf.pin_bit_mask = 1ULL<< CONFIG_LV_TOUCH_INT;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_down_en = (gpio_pulldown_t) 0; // disable pull-down mode
io_conf.pull_up_en = (gpio_pullup_t) 1; // pull-up mode
gpio_config(&io_conf);
/* INT gpio is not declared as an interrupt PIN in this touch version since we cannot do
blocking functions in LVGL:
*/
uint8_t buf[2] = {0xD1, 0X06};
writeData(buf, sizeof(buf));
return true;
}
void L58Touch::registerTouchHandler(void (*fn)(TPoint point, TEvent e))
{
_touchHandler = fn;
if (CONFIG_L58_DEBUG) printf("Touch handler function registered\n");
}
TPoint L58Touch::loop()
{
_point = processTouch();
return _point;
}
TPoint L58Touch::processTouch()
{
TPoint point;
point.x = lastX;
point.y = lastY;
point.event = lastEvent;
if (gpio_get_level((gpio_num_t)CONFIG_LV_TOUCH_INT) == 0) {
TPoint point = scanPoint();
lastX = point.x;
lastY = point.y;
lastEvent = point.event;
}
return point;
}
uint8_t L58Touch::read8(uint8_t regName) {
uint8_t buf;
readRegister8(regName, &buf);
return buf;
}
TPoint L58Touch::scanPoint()
{
TPoint point{0,0,0};
uint8_t pointIdx = 0;
uint8_t buffer[40] = {0};
uint32_t sumL = 0, sumH = 0;
buffer[0] = 0xD0;
buffer[1] = 0x00;
readBytes(buffer, 7);
if (buffer[0] == 0xAB) {
clearFlags();
return point;
}
pointIdx = buffer[5] & 0xF;
if (pointIdx == 1) {
buffer[5] = 0xD0;
buffer[6] = 0x07;
readBytes( &buffer[5], 2);
sumL = buffer[5] << 8 | buffer [6];
} else if (pointIdx > 1) {
buffer[5] = 0xD0;
buffer[6] = 0x07;
readBytes( &buffer[5], 5 * (pointIdx - 1) + 3);
sumL = buffer[5 * pointIdx + 1] << 8 | buffer[5 * pointIdx + 2];
}
clearFlags();
for (int i = 0 ; i < 5 * pointIdx; ++i) {
sumH += buffer[i];
}
if (sumH != sumL) {
pointIdx = 0;
}
if (pointIdx) {
uint8_t offset;
for (int i = 0; i < pointIdx; ++i) {
if (i == 0) {
offset = 0;
} else {
offset = 4;
}
data[i].id = (buffer[i * 5 + offset] >> 4) & 0x0F;
data[i].event = buffer[i * 5 + offset] & 0x0F;
data[i].y = (uint16_t)((buffer[i * 5 + 1 + offset] << 4) | ((buffer[i * 5 + 3 + offset] >> 4) & 0x0F));
data[i].x = (uint16_t)((buffer[i * 5 + 2 + offset] << 4) | (buffer[i * 5 + 3 + offset] & 0x0F));
//printf("X[%d]:%d Y:%d E:%d\n", i, data[i].x, data[i].y, data[i].event);
}
} else {
// Only this one seems to be working (even pressing with 2 fingers)
pointIdx = 1;
data[0].id = (buffer[0] >> 4) & 0x0F;
data[0].event = (buffer[0] & 0x0F) >>1;
data[0].y = (uint16_t)((buffer[0 * 5 + 1] << 4) | ((buffer[0 * 5 + 3] >> 4) & 0x0F));
data[0].x = (uint16_t)((buffer[0 * 5 + 2] << 4) | (buffer[0 * 5 + 3] & 0x0F));
if (data[0].event == 3) { /** Press */
_touchStartTime = esp_timer_get_time()/1000;
}
if (data[0].event == 0) { /** Lift up */
_touchEndTime = esp_timer_get_time()/1000;
}
#if defined(CONFIG_L58_DEBUG) && CONFIG_L58_DEBUG==1
printf("X:%d Y:%d E:%d\n", data[0].x, data[0].y, data[0].event);
#endif
}
uint16_t x = data[0].x;
uint16_t y = data[0].y;
// Had some hope that state was event, but always come:
// id:1 st:6
// printf("id:%d st:%d\n", data[0].id, data[0].state);
// Make touch rotation aware
switch (_rotation)
{
// 0- no rotation: Works OK inverting Y axis
case 0:
y = _touch_height - y;
break;
case 1:
swap(x, y);
y = _touch_width - y;
x = _touch_height - x;
break;
case 2:
x = _touch_width - x;
break;
case 3:
swap(x, y);
break;
}
point = {x, y, data[0].event};
return point;
}
void L58Touch::writeRegister8(uint8_t reg, uint8_t value)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, L58_ADDR << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
i2c_master_write_byte(cmd, reg , ACK_CHECK_EN);
i2c_master_write_byte(cmd, value , ACK_CHECK_EN);
i2c_master_stop(cmd);
i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
}
void L58Touch::writeData(uint8_t *data, int len)
{
if (len==0) return;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write(cmd, data, len, ACK_CHECK_EN);
i2c_master_stop(cmd);
i2c_cmd_link_delete(cmd);
}
uint8_t L58Touch::readRegister8(uint8_t reg, uint8_t *data_buf)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, L58_ADDR << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
i2c_master_write_byte(cmd, reg, I2C_MASTER_ACK);
// Research: Why it's started a 2nd time here
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (L58_ADDR << 1) | I2C_MASTER_READ, true);
i2c_master_read_byte(cmd, data_buf, I2C_MASTER_NACK);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
#if defined(CONFIG_L58_DEBUG) && CONFIG_L58_DEBUG==1
printf("REG 0x%x: 0x%x\n",reg,ret);
#endif
return ret;
}
void L58Touch::readBytes(uint8_t *data, int len) {
if (len==0) return;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, L58_ADDR << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
i2c_master_write(cmd, data, 2, ACK_CHECK_EN);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, L58_ADDR << 1 | I2C_MASTER_READ, ACK_CHECK_EN);
i2c_master_read(cmd, data, len, (i2c_ack_type_t) ACK_VAL);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_OK) {
for (int i = 0; i < len; i++) {
printf("0x%02x ", data[i]);
if ((i + 1) % 16 == 0) {
printf("\r\n");
}
}
if (len % 16) {
printf("\r\n");
}
} else if (ret == ESP_ERR_TIMEOUT) {
// Getting a lot of this!
//ESP_LOGW(TAG, "Bus is busy");
} else {
ESP_LOGW(TAG, "Read failed");
}
}
void L58Touch::fireEvent(TPoint point, TEvent e)
{
if (_touchHandler)
_touchHandler(point, e);
}
void L58Touch::setRotation(uint8_t rotation) {
_rotation = rotation;
}
void L58Touch::setTouchWidth(uint16_t width) {
printf("touch w:%d\n",width);
_touch_width = width;
}
void L58Touch::setTouchHeight(uint16_t height) {
printf("touch h:%d\n",height);
_touch_height = height;
}
void L58Touch::clearFlags() {
uint8_t buf[3] = {0xD0, 0X00, 0XAB};
writeData(buf, sizeof(buf));
}
void L58Touch::sleep() {
uint8_t buf[2] = {0xD1, 0X05};
writeData(buf, sizeof(buf));
}

View file

@ -0,0 +1,125 @@
// This is the first experimental Touch component for the LILYGO EPD47 touch overlay
// NOTE: As in LVGL we cannot use blocking functions this is a variation of original library here:
// https://github.com/martinberlin/FT6X36-IDF
// More info about this epaper:
// https://github.com/martinberlin/cale-idf/wiki/Model-parallel-ED047TC1.h
#include <stdint.h>
//#include <cstdlib>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include <stdio.h>
#include "esp_log.h"
#include "driver/i2c.h"
#include "sdkconfig.h"
#include "esp_idf_version.h"
#ifndef touch_ttgo_h
#define touch_ttgo_h
// I2C Constants
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */
#define L58_ADDR 0x5A
// Note: We still could not read proper events, so we simulate Tap
enum class TEvent
{
None,
TouchStart,
TouchMove,
TouchEnd,
Tap
};
struct TPoint
{
uint16_t x;
uint16_t y;
uint8_t event;
};
class L58Touch
{
typedef struct {
uint8_t id;
uint8_t event;
uint16_t x;
uint16_t y;
} TouchData_t;
public:
// TwoWire * wire will be replaced by ESP-IDF https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2c.html
L58Touch(int8_t intPin);
~L58Touch();
bool begin(uint16_t width = 0, uint16_t height = 0);
void registerTouchHandler(void(*fn)(TPoint point, TEvent e));
uint8_t touched();
TPoint loop();
TPoint processTouch();
// Helper functions to make the touch display aware
void setRotation(uint8_t rotation);
void setTouchWidth(uint16_t width);
void setTouchHeight(uint16_t height);
// Pending implementation. How much x->touch y↓touch is placed (In case is smaller than display)
void setXoffset(uint16_t x_offset);
void setYoffset(uint16_t y_offset);
void sleep();
// Smart template from EPD to swap x,y:
template <typename T> static inline void
swap(T& a, T& b)
{
T t = a;
a = b;
b = t;
}
void(*_touchHandler)(TPoint point, TEvent e) = nullptr;
TouchData_t data[5];
// Tap detection is enabled by default
bool tapDetectionEnabled = true;
// Only if the time difference between press and release is minor than this milliseconds a Tap even is triggered
uint16_t tapDetectionMillisDiff = 100;
private:
TPoint scanPoint();
void writeRegister8(uint8_t reg, uint8_t val);
void writeData(uint8_t *data, int len);
void readBytes(uint8_t *data, int len);
uint8_t readRegister8(uint8_t reg, uint8_t *data_buf);
void fireEvent(TPoint point, TEvent e);
uint8_t read8(uint8_t regName);
void clearFlags();
static L58Touch * _instance;
uint8_t _intPin;
// Make touch rotation aware:
uint8_t _rotation = 0;
uint16_t _touch_width = 0;
uint16_t _touch_height = 0;
uint8_t _touches;
uint16_t _touchX[2], _touchY[2], _touchEvent[2];
TPoint _points[10];
TPoint _point;
uint8_t _pointIdx = 0;
unsigned long _touchStartTime = 0;
unsigned long _touchEndTime = 0;
uint8_t lastEvent = 3; // No event
uint16_t lastX = 0;
uint16_t lastY = 0;
bool _dragMode = false;
const uint8_t maxDeviation = 5;
};
#endif