diff --git a/src/M5GFX.cpp b/src/M5GFX.cpp index ea36616..39d715b 100644 --- a/src/M5GFX.cpp +++ b/src/M5GFX.cpp @@ -31,6 +31,7 @@ #include "lgfx/v1/platforms/esp32p4/Bus_DSI.hpp" #include "lgfx/v1/platforms/esp32p4/Panel_ILI9881C.hpp" +#include "lgfx/v1/platforms/esp32p4/Panel_ST7121.hpp" #include "lgfx/v1/platforms/esp32p4/Panel_ST7123.hpp" #include "lgfx/v1/platforms/esp32p4/Touch_ST7123.hpp" @@ -2571,6 +2572,8 @@ The usage of each pin is as follows. i2c_write_register8_array(in_i2c_port, pi4io2_i2c_addr, reg_data_io2, 100000); lgfx::delay(10); i2c_write_register8_array(in_i2c_port, pi4io1_i2c_addr, reg_data_io1_2, 100000); + lgfx::pinMode(GPIO_NUM_23, lgfx::pin_mode_t::input); // TP INT + lgfx::delay(100); #if !CONFIG_SPIRAM ESP_LOGE(LIBRARY_NAME, "M5Tab5 need PSRAM enabled"); @@ -2585,26 +2588,49 @@ The usage of each pin is as follows. #endif { + bool hit_st7121 = false; + bool hit_st7123 = false; + bool read_st_touch_fw = false; + for (int i = 0; i < 3; ++i) { + uint8_t fw_version = 0; + uint8_t fw_reg[2] = { 0, 0 }; + if (lgfx::i2c::transactionWriteRead(in_i2c_port, Touch_ST7123::default_addr, fw_reg, sizeof(fw_reg), &fw_version, 1, 100000).has_value()) { + read_st_touch_fw = true; + ESP_LOGI(LIBRARY_NAME, "M5Tab5 ST touch FW version %02x", fw_version); + if (fw_version == 1) { + hit_st7121 = true; + break; + } + if (fw_version == 3) { + hit_st7123 = true; + break; + } + ESP_LOGW(LIBRARY_NAME, "M5Tab5 unknown ST touch FW version %02x", fw_version); + } + lgfx::delay(10); + } + if (!read_st_touch_fw) { + ESP_LOGW(LIBRARY_NAME, "M5Tab5 ST touch FW version read failed"); + } + auto bus_dsi = new Bus_DSI(); _bus_last.reset(bus_dsi); auto bus_cfg = bus_dsi->config(); bus_cfg.bus_id = 0; bus_cfg.lane_num = 2; - bus_cfg.lane_mbps = 1040; + bus_cfg.lane_mbps = hit_st7121 ? 900 : 1040; bus_cfg.ldo_chan_id = 3; bus_cfg.ldo_voltage_mv = 2500; bus_dsi->config(bus_cfg); if (bus_dsi->init()) { bool hit_ili9881 = false; - bool hit_st7123 = false; lgfx::delay(80); - for (int i = 0; i < 3; ++i) { + for (int i = 0; !hit_st7121 && !hit_st7123 && !hit_ili9881 && i < 3; ++i) { uint8_t id[3] = { 0, }; bus_dsi->readParams( 0xF4, id, 2 ); ESP_LOGD(LIBRARY_NAME, "ST ID %02x %02x", id[0], id[1]); if (id[0] == 0x71 && id[1] == 0x23) { - hit_st7123 = true; - break; + ESP_LOGI(LIBRARY_NAME, "M5Tab5 ST DSI ID matched 71 23"); } static constexpr uint8_t params_page1[] = { 0x98, 0x81, 0x01 }; bus_dsi->writeParams( 0xFF, params_page1, 3); @@ -2632,7 +2658,23 @@ The usage of each pin is as follows. det.vsync_pulse_width = 4; det.vsync_front_porch = 20; p->config_detail(det); + } else if (hit_st7121) { + ESP_LOGI(LIBRARY_NAME, "M5Tab5 detected ST7121 display"); + _touch_last.reset(new Touch_ST7123()); + auto p = new Panel_ST7121(); + _panel_last.reset(p); + auto det = p->config_detail(); + + det.dpi_freq_mhz = 70; + det.hsync_back_porch = 40; + det.hsync_pulse_width = 2; + det.hsync_front_porch = 40; + det.vsync_back_porch = 24; + det.vsync_pulse_width = 20; + det.vsync_front_porch = 200; + p->config_detail(det); } else if (hit_st7123) { + ESP_LOGI(LIBRARY_NAME, "M5Tab5 detected ST7123 display"); _touch_last.reset(new Touch_ST7123()); auto p = new Panel_ST7123(); _panel_last.reset(p); @@ -2649,6 +2691,10 @@ The usage of each pin is as follows. det.vsync_front_porch = 220; p->config_detail(det); } + if (_panel_last == nullptr) { + ESP_LOGE(LIBRARY_NAME, "M5Tab5 display panel was not detected"); + goto init_clear; + } { auto p = _panel_last.get(); auto cfg = p->config(); diff --git a/src/lgfx/v1/platforms/esp32p4/Panel_ST7121.hpp b/src/lgfx/v1/platforms/esp32p4/Panel_ST7121.hpp new file mode 100644 index 0000000..ca409d8 --- /dev/null +++ b/src/lgfx/v1/platforms/esp32p4/Panel_ST7121.hpp @@ -0,0 +1,150 @@ +/*----------------------------------------------------------------------------/ + Lovyan GFX - Graphics library for embedded devices. + +Original Source: + https://github.com/lovyan03/LovyanGFX/ + +Licence: + [FreeBSD](https://github.com/lovyan03/LovyanGFX/blob/master/license.txt) + +Author: + [lovyan03](https://twitter.com/lovyan03) + +Contributors: + [ciniml](https://github.com/ciniml) + [mongonta0716](https://github.com/mongonta0716) + [tobozo](https://github.com/tobozo) +/----------------------------------------------------------------------------*/ +#pragma once + +#include "Panel_DSI.hpp" +#if SOC_MIPI_DSI_SUPPORTED + +namespace lgfx +{ + inline namespace v1 + { +//---------------------------------------------------------------------------- + + struct Panel_ST7121 : public Panel_DSI + { + public: + protected: + + const uint8_t* getInitParams(size_t listno) const override + { + static constexpr uint8_t list0[] = + {//len(cmd+params), cmd, params + 4, 0x60, 0x71, 0x21, 0xA2, + 4, 0x60, 0x71, 0x21, 0xA3, + 4, 0x60, 0x71, 0x21, 0xA4, + 2, 0x78, 0x21, + 2, 0x79, 0xEF, + 2, 0xA4, 0x31, + 7, 0xB7, 0x00, 0x00, 0x5F, 0x5F, 0x44, 0x1A, + 8, 0xB0, 0x22, 0x6B, 0x11, 0x89, 0x25, 0x43, 0x43, + 3, 0xBF, 0xA7, 0xA7, + 3, 0xA5, 0xF0, 0x03, + 7, 0xD7, 0x10, 0x2C, 0x14, 0x2A, 0x80, 0x80, + 8, 0x90, 0x71, 0x23, 0x5A, 0x20, 0x24, 0x11, 0x21, + + 40, 0xA3, 0x80, 0x01, 0x8C, 0xFF, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x00, 0x00, 0x1E, 0x5C, 0x1E, 0x80, 0x10, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x1E, 0x5C, + 0x1E, 0x80, 0x10, 0xEF, 0x58, 0x00, 0x00, 0x00, 0xFF, + + 56, 0xA6, 0x0A, 0x00, 0x24, 0x71, 0x36, 0x00, 0x00, 0x00, 0x68, 0x68, + 0x91, 0xFF, 0x00, 0x24, 0x71, 0x37, 0x00, 0x00, 0x00, 0x68, + 0x68, 0x91, 0xFF, 0x00, 0x24, 0x71, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x68, 0x91, 0xFF, 0x00, 0x2C, 0x71, 0x00, 0x01, 0x00, + 0x00, 0x68, 0x68, 0xFF, 0xFF, 0x00, 0x08, 0x80, 0x08, 0x80, + 0x06, 0x00, 0x00, 0x00, 0x00, + + 61, 0xA7, 0x1A, 0x1A, 0xC0, 0x64, 0x40, 0x04, 0x15, 0x40, 0x00, 0x40, + 0x00, 0x68, 0x68, 0x91, 0xFF, 0x08, 0x80, 0x64, 0x40, 0x26, + 0x37, 0x40, 0x00, 0x00, 0x00, 0x68, 0x68, 0x91, 0xFF, 0x08, + 0x80, 0x64, 0x40, 0x8C, 0x9D, 0x40, 0x00, 0x00, 0x00, 0x68, + 0x68, 0x91, 0xFF, 0x08, 0x80, 0x64, 0x40, 0xAE, 0xBF, 0x00, + 0x00, 0x20, 0x00, 0x68, 0x68, 0x91, 0xFF, 0x08, 0x80, 0x79, + + 45, 0xAC, 0x1D, 0x18, 0x19, 0x1D, 0x18, 0x19, 0x04, 0x1C, 0x1D, 0x08, + 0x0A, 0x10, 0x12, 0x0C, 0x0E, 0x14, 0x16, 0x00, 0x1D, 0x1D, + 0x1D, 0x1D, 0x1D, 0x18, 0x19, 0x1D, 0x18, 0x19, 0x06, 0x1C, + 0x1D, 0x09, 0x0B, 0x11, 0x13, 0x0D, 0x0F, 0x15, 0x17, 0x02, + 0x1D, 0x1D, 0x1D, 0x1D, + + 26, 0xAD, 0x0C, 0x40, 0x46, 0x00, 0x07, 0x4B, 0x4B, 0xFF, 0xFF, 0xF0, + 0x40, 0x0E, 0x01, 0x07, 0x42, 0x42, 0xFF, 0xFF, 0x01, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + + 8, 0xAE, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x03, 0x00, + 18, 0xB2, 0x15, 0x19, 0x05, 0x23, 0x49, 0x2D, 0x03, 0x2E, 0x5C, 0xD2, + 0xFF, 0x10, 0x60, 0xFD, 0x20, 0xC0, 0x00, + 15, 0xE8, 0x20, 0x60, 0x04, 0x8E, 0x8E, 0x3E, 0x04, 0xDC, 0xDC, 0x3E, + 0x06, 0xFA, 0x26, 0x3E, + 3, 0x75, 0x03, 0x04, + + 43, 0xE7, 0x4B, 0x00, 0x00, 0xBE, 0x4B, 0x8C, 0x20, 0x1A, 0xF0, 0x7D, + 0x14, 0x7D, 0x14, 0x7D, 0x14, 0x7D, 0x14, 0xFF, 0x00, 0x32, + 0x30, 0x73, 0x00, 0x00, 0xC8, 0x6A, 0xFF, 0x5A, 0x64, 0x38, + 0x88, 0x15, 0xB1, 0x01, 0x01, 0x64, 0x01, 0x01, 0x7C, 0xFF, + 0x1A, 0x51, + + 3, 0xE1, 0x0C, 0x0C, + 4, 0xEA, 0x15, 0x00, 0x01, + 38, 0xC8, 0x00, 0x00, 0x04, 0x08, 0x10, 0x00, 0x1F, 0x01, 0x39, 0x3E, + 0x00, 0x78, 0x06, 0xE2, 0x02, 0x11, 0x33, 0x01, 0x7A, 0x0D, + 0x21, 0xC4, 0x0B, 0x19, 0x08, 0x32, 0xA0, 0x08, 0x1A, 0x0A, + 0xF3, 0x7F, 0x0E, 0xC5, 0xE8, 0x03, 0xFF, + 38, 0xC9, 0x00, 0x00, 0x04, 0x08, 0x10, 0x00, 0x1F, 0x01, 0x39, 0x3E, + 0x00, 0x78, 0x06, 0xE2, 0x02, 0x11, 0x33, 0x01, 0x7A, 0x0D, + 0x21, 0xC4, 0x0B, 0x19, 0x08, 0x32, 0xA0, 0x08, 0x1A, 0x0A, + 0xF3, 0x7F, 0x0E, 0xC5, 0xE8, 0x03, 0xFF, + 4, 0x60, 0x71, 0x21, 0x00, + 0, // end + }; + + static constexpr uint8_t list1[] = + {//len(cmd+params), cmd, params + 1, CMD_SLPOUT, + 0, // end + }; + + static constexpr uint8_t list2[] = + {//len(cmd+params), cmd, params + 1, CMD_DISPON, + 0, // end + }; + + static constexpr uint8_t list3[] = + {//len(cmd+params), cmd, params + 2, 0x35, 0x00, + 0, // end + }; + + switch (listno) + { + case 0: return list0; + case 1: return list1; + case 2: return list2; + case 3: return list3; + default: return nullptr; + } + } + + size_t getInitDelay(size_t listno) const override + { + switch (listno) + { + case 1: return 80; // after SLPOUT + case 2: return 800; // after DISPON + default: return 0; + } + } + }; + +//---------------------------------------------------------------------------- + } +} + +#endif