diff --git a/drivers/Touch_CST820.cpp b/drivers/Touch_CST820.cpp new file mode 100644 index 0000000..1c919c0 --- /dev/null +++ b/drivers/Touch_CST820.cpp @@ -0,0 +1,121 @@ +//TODO: preliminary version; needs to be adapted to lovyanGFX layer and maybe merged as PR + +#include "Touch_CST820.h" +#include "Arduino.h" +#include "Wire.h" + +#define I2C_ADDR_CST820 0x15 + +namespace lgfx +{ + inline namespace v1 + { + +bool Touch_CST820::init(void) +{ + // Initialize I2C + if (_sda != -1 && _scl != -1) { + Wire.begin(_sda, _scl); + } + else { + Wire.begin(); + } + + // Int Pin Configuration + if (_int != -1) { + pinMode(_int, OUTPUT); + digitalWrite(_int, HIGH); + delay(1); + digitalWrite(_int, LOW); + delay(1); + } + + // Reset Pin Configuration + if (_rst != -1) { + pinMode(_rst, OUTPUT); + digitalWrite(_rst, LOW); + delay(10); + digitalWrite(_rst, HIGH); + delay(300); + } + + // Initialize Touch + i2c_write(0xFE, 0XFF); + return true; +} + +uint_fast8_t Touch_CST820::getTouchRaw(touch_point_t* tp, uint_fast8_t count) +{ + uint8_t FingerIndex = i2c_read(0x02); + uint8_t gesture = i2c_read(0x01); + //if (!(gesture == SWIPE_UP || gesture == SWIPE_DOWN)) { + // gesture = NONE; + //} + + uint8_t readdata[4]; + i2c_read_continuous(0x03, readdata, 4); + uint16_t x = ((readdata[0] & 0x0f) << 8) | readdata[1]; + uint16_t y = ((readdata[2] & 0x0f) << 8) | readdata[3]; + + tp[0].id = 0; + tp[0].size = 1; + tp[0].x = x; // readdata[2] | (readdata[1] & 0x0F) << 8; + tp[0].y = y; //readdata[4] | (readdata[3] & 0x0F) << 8; + + return FingerIndex; +} + +uint8_t Touch_CST820::i2c_read(uint8_t addr) +{ + uint8_t rdData = 0; + uint8_t rdDataCount; + uint8_t loopCount = 0; + do { + Wire.beginTransmission(I2C_ADDR_CST820); + Wire.write(addr); + Wire.endTransmission(false); // Restart + rdDataCount = Wire.requestFrom(I2C_ADDR_CST820, 1); + } while (rdDataCount == 0 && loopCount++ < 10); + + while (Wire.available()) { + rdData = Wire.read(); + } + return rdData; +} + +uint8_t Touch_CST820::i2c_read_continuous(uint8_t addr, uint8_t *data, uint32_t length) +{ + Wire.beginTransmission(I2C_ADDR_CST820); + Wire.write(addr); + if (Wire.endTransmission(true)) return -1; + Wire.requestFrom(I2C_ADDR_CST820, length); + + for (int i = 0; i < length; i++) { + *data++ = Wire.read(); + } + return 0; +} + +void Touch_CST820::i2c_write(uint8_t addr, uint8_t data) +{ + Wire.beginTransmission(I2C_ADDR_CST820); + Wire.write(addr); + Wire.write(data); + Wire.endTransmission(); +} + +uint8_t Touch_CST820::i2c_write_continuous(uint8_t addr, const uint8_t *data, uint32_t length) +{ + Wire.beginTransmission(I2C_ADDR_CST820); + Wire.write(addr); + for (int i = 0; i < length; i++) { + Wire.write(*data++); + } + if (Wire.endTransmission(true)) return -1; + return 0; +} + + +} + +} \ No newline at end of file diff --git a/drivers/Touch_CST820.h b/drivers/Touch_CST820.h new file mode 100644 index 0000000..bb07d56 --- /dev/null +++ b/drivers/Touch_CST820.h @@ -0,0 +1,60 @@ +#ifndef _CST820_H +#define _CST820_H + +#include "lgfx/v1/Touch.hpp" + + +namespace lgfx +{ + inline namespace v1 + { + +/** + * @brief CST820 I2C CTP controller driver + * + */ +class Touch_CST820 : public ITouch +{ + enum CS820_GESTURE { + NONE = 0x00, + SWIPE_UP = 0x01, + SWIPE_DOWN = 0x02, + SWIPE_LEFT = 0x03, + SWIPE_RIGHT = 0x04, + SINGLE_CLICK = 0x05, + DOUBLE_CLICK = 0x0B, + LONG_PRESS = 0x0C + }; + +public: + Touch_CST820(int8_t sda_pin = -1, int8_t scl_pin = -1, int8_t rst_pin = -1, int8_t int_pin = -1) { + _sda = sda_pin; + _scl = scl_pin; + _rst = rst_pin; + _int = int_pin; + _cfg.i2c_addr = 0x15; + _cfg.x_min = 0; + _cfg.x_max = 320; + _cfg.y_min = 0; + _cfg.y_max = 320; + }; + + bool init(void) override; + + void wakeup(void) override {}; + void sleep(void) override {}; + + uint_fast8_t getTouchRaw(touch_point_t* tp, uint_fast8_t count) override; + +private: + int8_t _sda, _scl, _rst, _int; + + uint8_t i2c_read(uint8_t addr); + uint8_t i2c_read_continuous(uint8_t addr, uint8_t *data, uint32_t length); + void i2c_write(uint8_t addr, uint8_t data); + uint8_t i2c_write_continuous(uint8_t addr, const uint8_t *data, uint32_t length); +}; + +} +} +#endif \ No newline at end of file diff --git a/include/LGFXDriver.h b/include/LGFXDriver.h index a99f811..5d085b4 100644 --- a/include/LGFXDriver.h +++ b/include/LGFXDriver.h @@ -203,6 +203,8 @@ template void LGFXDriver::init_lgfx(void) uint16_t parameters[8] = {11, 19, 6, 314, 218, 15, 229, 313}; #elif defined(T_HMI) uint16_t parameters[8] = {399, 293, 309, 3701, 3649, 266, 3678, 3689}; +#elif defined(ESP32_2432S022) + uint16_t parameters[8] = {1, 2, 69, 313, 187, 5, 239, 314}; #elif defined(ESP32_2432S028RV1) uint16_t parameters[8] = {278, 3651, 228, 173, 3819, 3648, 3815, 179}; #elif defined(NODEMCU_32S) || defined(PORTDUINO) @@ -227,10 +229,10 @@ template void LGFXDriver::init_lgfx(void) TFTDriver::tft->calibrateTouch(parameters, fg, bg, std::max(TFTDriver::tft->width(), TFTDriver::tft->height()) >> 3); +#endif // FIXME: store parameters[] using lfs_file_write ILOG_DEBUG("Touchscreen calibration parameters: {%d, %d, %d, %d, %d, %d, %d, %d}\n", parameters[0], parameters[1], parameters[2], parameters[3], parameters[4], parameters[5], parameters[6], parameters[7]); -#endif #endif } } diff --git a/include/LGFX_ESP2432S022.h b/include/LGFX_ESP2432S022.h new file mode 100644 index 0000000..798941d --- /dev/null +++ b/include/LGFX_ESP2432S022.h @@ -0,0 +1,108 @@ +#pragma once + +#define LGFX_USE_V1 +#include +#include "Touch_CST820.h" + +#ifndef SPI_FREQUENCY +#define SPI_FREQUENCY 25000000 +#endif + +class LGFX_ESP2432S022 : public lgfx::LGFX_Device +{ + lgfx::Panel_ST7789 _panel_instance; + lgfx::Bus_Parallel8 _bus_instance; + lgfx::Light_PWM _light_instance; + lgfx::Touch_CST820 _touch_instance; + + public: + const uint32_t screenWidth = 320; + const uint32_t screenHeight = 240; + + LGFX_ESP2432S022(void) + { + { + auto cfg = _bus_instance.config(); + cfg.freq_write = SPI_FREQUENCY; + cfg.pin_rd = 2; + cfg.pin_wr = 4; + cfg.pin_rs = 16; + cfg.pin_d0 = 15; + cfg.pin_d1 = 13; + cfg.pin_d2 = 12; + cfg.pin_d3 = 14; + cfg.pin_d4 = 27; + cfg.pin_d5 = 25; + cfg.pin_d6 = 33; + cfg.pin_d7 = 32; + _bus_instance.config(cfg); + _panel_instance.setBus(&_bus_instance); + } + + { // Set the display panel control. + auto cfg = _panel_instance.config(); // Gets a structure for display panel settings. + + cfg.pin_cs = 17; // Pin number where CS is connected (-1 = disable) + cfg.pin_rst = -1; // Pin number where RST is connected (-1 = disable) + cfg.pin_busy = -1; // Pin number where BUSY is connected (-1 = disable) + + // The following setting values ​​are general initial values ​​for + // each panel, so please comment out any unknown items and try them. + + cfg.panel_width = screenHeight; // actual displayable width + cfg.panel_height = screenWidth; // actual displayable height + cfg.offset_x = 0; // Panel offset amount in X direction + cfg.offset_y = 0; // Panel offset amount in Y direction + cfg.offset_rotation = 1; // Rotation direction value offset 0~7 (4~7 is upside down) + //cfg.dummy_read_pixel = 8; // Number of bits for dummy read before pixel readout + //cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read + cfg.readable = false; // Set to true if data can be read + cfg.invert = false; // Set to true if the light/darkness of the panel is reversed + cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped + cfg.dlen_16bit = false; // Set to true for panels that transmit data length in 16-bit + // units with 16-bit parallel or SPI + cfg.bus_shared = false; // If the bus is shared with the SD card, set to + // true (bus control with drawJpgFile etc.) + + _panel_instance.config(cfg); + } + + // Set the backlight control. + { + auto cfg = _light_instance.config(); // Gets a structure for backlight settings. + + cfg.pin_bl = 0; // Pin number to which the backlight is connected + cfg.invert = false; // true to invert the brightness of the backlight + cfg.freq = 44100; + cfg.pwm_channel = 7; + + _light_instance.config(cfg); + _panel_instance.setLight(&_light_instance); // Set the backlight on the panel. + } +#if 1 + // Configure settings for touch screen control. + { + auto cfg = _touch_instance.config(); + + cfg.pin_cs = -1; + cfg.x_min = 0; + //cfg.x_max = screenWidth - 1; + cfg.y_min = 0; + //cfg.y_max = screenHeight - 1; + cfg.pin_int = -1; + cfg.bus_shared = false; + cfg.offset_rotation = 0; + + // I2C + cfg.i2c_port = 0; + cfg.pin_sda = 21; + cfg.pin_scl = 22; + cfg.freq = 100000; + + _touch_instance.config(cfg); + _panel_instance.setTouch(&_touch_instance); + } +#endif + setPanel(&_panel_instance); // Sets the panel to use. + } +}; diff --git a/include/lv_conf.h b/include/lv_conf.h index f801aee..1ec2e71 100644 --- a/include/lv_conf.h +++ b/include/lv_conf.h @@ -250,7 +250,9 @@ *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail *LV_LOG_LEVEL_USER Only logs added by the user *LV_LOG_LEVEL_NONE Do not log anything*/ +#ifndef LV_LOG_LEVEL #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN +#endif /*1: Print the log with 'printf'; *0: User need to register a callback with `lv_log_register_print_cb()`*/ @@ -259,7 +261,7 @@ /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ #define LV_LOG_TRACE_MEM 1 #define LV_LOG_TRACE_TIMER 0 - #define LV_LOG_TRACE_INDEV 1 + #define LV_LOG_TRACE_INDEV 0 #define LV_LOG_TRACE_DISP_REFR 0 #define LV_LOG_TRACE_EVENT 1 #define LV_LOG_TRACE_OBJ_CREATE 0 diff --git a/source/DisplayDriverFactory.cpp b/source/DisplayDriverFactory.cpp index f5fc227..4efb9d5 100644 --- a/source/DisplayDriverFactory.cpp +++ b/source/DisplayDriverFactory.cpp @@ -27,6 +27,9 @@ #ifdef UNPHONE #include "LGFX_UNPHONE.h" #endif +#ifdef ESP32_2432S022 +#include "LGFX_ESP2432S022.h" +#endif #ifdef ESP32_2432S028RV1 #include "LGFX_ESP2432S028RV1.h" #endif diff --git a/source/LVGLGraphics.cpp b/source/LVGLGraphics.cpp index 821dfc5..fdf0b4a 100644 --- a/source/LVGLGraphics.cpp +++ b/source/LVGLGraphics.cpp @@ -2,6 +2,10 @@ #include "ILog.h" #include "assert.h" +#ifndef BUFFER_LINES +#define BUFFER_LINES 10 +#endif + LVGLGraphics::LVGLGraphics(uint16_t width, uint16_t height) : screenWidth(width), screenHeight(height) { @@ -36,7 +40,7 @@ LVGLGraphics::LVGLGraphics(uint16_t width, uint16_t height) : screenWidth(width) draw_buf = (lv_disp_draw_buf_t *)heap_caps_aligned_alloc(16, sizeof(lv_disp_draw_buf_t), MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); assert(buf1 != 0); #else - bufsize = width * 10; + bufsize = width * BUFFER_LINES; ILOG_DEBUG("LVGL: allocating %u bytes heap memory for draw buffer\n", bufsize); draw_buf = new lv_disp_draw_buf_t; buf1 = new lv_color_t[bufsize]; // OK