From 236e2975b28b3facaea8d04a84d8206c5fa208e0 Mon Sep 17 00:00:00 2001 From: fvanroie <15969459+fvanroie@users.noreply.github.com> Date: Wed, 3 Nov 2021 01:36:05 +0100 Subject: [PATCH] Add parallel bus and extra tft/touch drivers #220 --- src/drv/tft/tft_driver_lovyangfx.cpp | 246 +++++++++++++++++---------- src/drv/tft/tft_driver_lovyangfx.h | 4 + 2 files changed, 159 insertions(+), 91 deletions(-) diff --git a/src/drv/tft/tft_driver_lovyangfx.cpp b/src/drv/tft/tft_driver_lovyangfx.cpp index 4d2b74ef..b90e24a0 100644 --- a/src/drv/tft/tft_driver_lovyangfx.cpp +++ b/src/drv/tft/tft_driver_lovyangfx.cpp @@ -30,13 +30,15 @@ static uint32_t _read_panel_id(lgfx::Bus_SPI* bus, int32_t pin_cs, uint32_t cmd bus->endTransaction(); _pin_level(pin_cs, true); - LOG_VERBOSE(TAG_DRVR, "[Autodetect] read cmd:%u = %u", cmd, res); - LOG_VERBOSE(TAG_DRVR, "[Autodetect] read cmd:%02x = %08x", cmd, res); + LOG_VERBOSE(TAG_TFT, "[Autodetect] read cmd:%u = %u", cmd, res); + LOG_VERBOSE(TAG_TFT, "[Autodetect] read cmd:%02x = %08x", cmd, res); return res; } void LovyanGfx::init(int w, int h) { + LOG_VERBOSE(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); + #ifdef USE_DMA_TO_TFT int dma_channel = 1; // Set the DMA channel (1 or 2. 0=disable) #else @@ -45,22 +47,30 @@ void LovyanGfx::init(int w, int h) uint32_t tft_driver = 0; -#ifdef ST7796_DRIVER - tft_driver = 0x7796; +#ifdef ILI9341_DRIVER + tft_driver = 0x9341; #endif #ifdef ILI9481_DRIVER tft_driver = 0x9481; #endif -#ifdef ILI9341_DRIVER - tft_driver = 0x9481; -#endif - #ifdef ILI9488_DRIVER tft_driver = 0x9488; #endif +#ifdef ST7789_DRIVER + tft_driver = 0x7789; +#endif + +#ifdef ST7796_DRIVER + tft_driver = 0x7796; +#endif + +#ifdef HX8357D_DRIVER + tft_driver = 0x8357D; // Adafruit Feather Wing 3.5" +#endif + if(tft_driver == 0x9341) tft._panel_instance = new lgfx::Panel_ILI9341(); else if(tft_driver == 0x9481) @@ -69,97 +79,143 @@ void LovyanGfx::init(int w, int h) tft._panel_instance = new lgfx::Panel_ILI9488(); else if(tft_driver == 0x7796) tft._panel_instance = new lgfx::Panel_ST7796(); + else if(tft_driver == 0x8357D) + tft._panel_instance = new lgfx::Panel_HX8357D(); + else { + LOG_VERBOSE(TAG_TFT, F("Unknown display driver")); // Needs to be in curly braces + } + LOG_VERBOSE(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); - { // バス制御の設定を行います。 - auto bus = (lgfx::v1::Bus_SPI*)tft._bus_instance; - auto cfg = bus->config(); // バス設定用の構造体を取得します。 - cfg.spi_host = HSPI_HOST; // 使用するSPIを選択 (VSPI_HOST or HSPI_HOST) - cfg.spi_mode = 0; // SPI通信モードを設定 (0 ~ 3) - cfg.freq_write = SPI_FREQUENCY; // 送信時のSPIクロック (最大80MHz, 80MHzを整数で割った値に丸められます) - cfg.freq_read = SPI_READ_FREQUENCY; // 受信時のSPIクロック - cfg.spi_3wire = false; // 受信をMOSIピンで行う場合はtrueを設定 - cfg.use_lock = true; // トランザクションロックを使用する場合はtrueを設定 +#ifdef ESP32_PARALLEL + { // Set 8-bit parallel bus control + auto bus = (lgfx::v1::Bus_Parallel8*)tft._bus_instance; + auto cfg = bus->config(); // バス設定用の構造体を取得します。 + cfg.i2s_port = I2S_NUM_0; + cfg.freq_write = 20000000; + cfg.pin_wr = TFT_WR; + cfg.pin_rd = TFT_RD; + cfg.pin_rs = TFT_DC; + cfg.pin_d0 = TFT_D0; + cfg.pin_d1 = TFT_D1; + cfg.pin_d2 = TFT_D2; + cfg.pin_d3 = TFT_D3; + cfg.pin_d4 = TFT_D4; + cfg.pin_d5 = TFT_D5; + cfg.pin_d6 = TFT_D6; + cfg.pin_d7 = TFT_D7 bus->config(cfg); // 設定値をバスに反映します。 + tft._panel_instance.setBus(bus); // バスをパネルにセットします。 + } +#else + { // Set SPI bus control + auto bus = (lgfx::v1::Bus_SPI*)tft._bus_instance; + auto cfg = bus->config(); // Get the structure for bus configuration. + cfg.spi_host = HSPI_HOST; // Select the SPI to use (VSPI_HOST or HSPI_HOST) + cfg.spi_mode = 0; // Set SPI communication mode (0 ~ 3) + cfg.freq_write = SPI_FREQUENCY; // SPI clock during transmission (Max 80MHz, 80MHz Can be rounded to the value + // divided by an integer ) + cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving + cfg.spi_3wire = false; // Set true when receiving with MOSI pin + cfg.use_lock = true; // Set to true when using transaction lock cfg.dma_channel = dma_channel; // Set the DMA channel (1 or 2. 0=disable) - cfg.pin_sclk = TFT_SCLK; // SPIのSCLKピン番号を設定 - cfg.pin_mosi = TFT_MOSI; // SPIのMOSIピン番号を設定 - cfg.pin_miso = TFT_MISO; // SPIのMISOピン番号を設定 (-1 = disable) - cfg.pin_dc = TFT_DC; // SPIのD/Cピン番号を設定 (-1 = disable) - bus->config(cfg); // 設定値をバスに反映します。 + cfg.pin_sclk = TFT_SCLK; // Set SPI SCLK pin number + cfg.pin_mosi = TFT_MOSI; // Set SPI MOSI pin number + cfg.pin_miso = TFT_MISO; // Set SPI MISO pin number (-1 = disable) + cfg.pin_dc = TFT_DC; // Set SPI D/C pin number (-1 = disable) + bus->config(cfg); // The set value is reflected on the bus. bus->init(); _read_panel_id(bus, TFT_CS, 0x00); _read_panel_id(bus, TFT_CS, 0x04); _read_panel_id(bus, TFT_CS, 0x09); _read_panel_id(bus, TFT_CS, 0xBF); - tft._panel_instance->setBus(bus); // バスをパネルにセットします。 + tft._panel_instance->setBus(bus); // Set the bus on the panel. } +#endif + LOG_VERBOSE(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); - { // 表示パネル制御の設定を行います。 - auto cfg = tft._panel_instance->config(); // 表示パネル設定用の構造体を取得します。 - cfg.pin_cs = TFT_CS; // CSが接続されているピン番号 (-1 = disable) - cfg.pin_rst = TFT_RST; // RSTが接続されているピン番号 (-1 = disable) - cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable) - cfg.memory_width = w; // ドライバICがサポートしている最大の幅 - cfg.memory_height = h; // ドライバICがサポートしている最大の高さ - cfg.panel_width = w; // 実際に表示可能な幅 - cfg.panel_height = h; // 実際に表示可能な高さ - cfg.offset_x = 0; // パネルのX方向オフセット量 - cfg.offset_y = 0; // パネルのY方向オフセット量 - cfg.offset_rotation = 0; // 回転方向の値のオフセット 0~7 (4~7は上下反転) - cfg.dummy_read_pixel = 8; // ピクセル読出し前のダミーリードのビット数 - cfg.dummy_read_bits = 1; // ピクセル以外のデータ読出し前のダミーリードのビット数 - cfg.readable = true; // データ読出しが可能な場合 trueに設定 - cfg.invert = false; // パネルの明暗が反転してしまう場合 trueに設定 - cfg.rgb_order = false; // パネルの赤と青が入れ替わってしまう場合 trueに設定 - cfg.dlen_16bit = false; // データ長を16bit単位で送信するパネルの場合 trueに設定 - cfg.bus_shared = true; // SDカードとバスを共有している場合 trueに設定(drawJpgFile等でバス制御を行います) - + { // Set the display panel control. + auto cfg = tft._panel_instance->config(); // Gets the structure for display panel settings. + cfg.pin_cs = TFT_CS; // CS Pin Number (-1 = disable) + cfg.pin_rst = TFT_RST; // RST Pin Number (-1 = disable) + cfg.pin_busy = -1; // BUSY Pin Number (-1 = disable) + cfg.memory_width = w; // Maximum width supported by driver IC + cfg.memory_height = h; // Maximum height supported by driver IC + cfg.panel_width = w; // Actually displayable width + cfg.panel_height = h; // Actually displayable height + cfg.offset_x = 0; // Amount of X-direction offset of the panel + cfg.offset_y = 0; // Amount of Y-direction offset of the panel + cfg.offset_rotation = 0; // Offset of values in the direction of rotation 0 ~ 7 (4 ~ 7 are upside down) + cfg.dummy_read_pixel = 8; // Number of dummy read bits before pixel reading + cfg.dummy_read_bits = 1; // Number of bits of dummy read before reading data other than pixels + cfg.readable = true; // Set to true if data can be read + cfg.invert = false; // Set to true if the light and darkness of the panel is reversed + cfg.rgb_order = false; // Set to true if the red and blue of the panel are swapped + cfg.dlen_16bit = false; // Set to true for panels that send data length in 16-bit units + cfg.bus_shared = + true; // Set to true if the bus is shared with the SD card (bus control is performed with drawJpgFile etc.) tft._panel_instance->config(cfg); } - { // バックライト制御の設定を行います。(必要なければ削除) - auto cfg = tft._light_instance.config(); // バックライト設定用の構造体を取得します。 + LOG_VERBOSE(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); - cfg.pin_bl = TFT_BCKL; // バックライトが接続されているピン番号 - cfg.invert = false; // バックライトの輝度を反転させる場合 true - cfg.freq = 44100; // バックライトのPWM周波数 - cfg.pwm_channel = 0; // 使用するPWMのチャンネル番号 +#if 1 + { // Set the backlight control. (Delete if not needed) + auto cfg = tft._light_instance.config(); // Get the backlight structure for configuration. + + cfg.pin_bl = TFT_BCKL; // Backlight Pin Number + cfg.invert = false; // True if you want to invert the brightness of the Backlight + cfg.freq = 44100; // Backlight PWM frequency + cfg.pwm_channel = 0; // PWM channel number to use tft._light_instance.config(cfg); - tft._panel_instance->setLight(&tft._light_instance); // バックライトをパネルにセットします。 + tft._panel_instance->setLight(&tft._light_instance); // Set the Backlight on the panel. } +#endif + + LOG_VERBOSE(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); tft._touch_instance = new lgfx::Touch_FT5x06(); - { // タッチスクリーン制御の設定を行います。(必要なければ削除) + { // Set the touch screen control. (Delete if not needed) auto cfg = tft._touch_instance->config(); - cfg.x_min = 0; // タッチスクリーンから得られる最小のX値(生の値) - cfg.x_max = 319; // タッチスクリーンから得られる最大のX値(生の値) - cfg.y_min = 0; // タッチスクリーンから得られる最小のY値(生の値) - cfg.y_max = 479; // タッチスクリーンから得られる最大のY値(生の値) - cfg.pin_int = -1; // INTが接続されているピン番号 - cfg.bus_shared = true; // 画面と共通のバスを使用している場合 trueを設定 - cfg.offset_rotation = 0; // 表示とタッチの向きのが一致しない場合の調整 0~7の値で設定 -#ifdef TOUCH_CS - cfg.spi_host = HSPI_HOST; // 使用するSPIを選択 (HSPI_HOST or VSPI_HOST) - cfg.pin_sclk = TFT_SCLK; // SCLKが接続されているピン番号 - cfg.pin_mosi = TFT_MOSI; // MOSIが接続されているピン番号 - cfg.pin_miso = TFT_MISO; // MISOが接続されているピン番号 - cfg.pin_cs = TOUCH_CS; // CSが接続されているピン番号 - cfg.freq = SPI_TOUCH_FREQUENCY; // SPIクロックを設定 -#else - cfg.pin_sda = TOUCH_SDA; - cfg.pin_scl = TOUCH_SCL; - cfg.i2c_port = I2C_TOUCH_PORT; // 使用するI2Cを選択 (0 or 1) - cfg.i2c_addr = I2C_TOUCH_ADDRESS; // I2Cデバイスアドレス番号 - cfg.freq = I2C_TOUCH_FREQUENCY; // SPIクロックを設定 + cfg.pin_int = TOUCH_IRQ; // INT Pin Number + cfg.offset_rotation = 0; // Adjustment when the display and touch orientation do not match: + // Set with a value from 0 to 7 +#if(TOUCH_DRIVER == 2046) || (TOUCH_DRIVER == 610) + cfg.bus_shared = true; // Set to true if you are using the same bus as the screen + cfg.spi_host = HSPI_HOST; // Select the SPI to use (HSPI_HOST or VSPI_HOST) + cfg.pin_sclk = TFT_SCLK; // SCLK Pin Number + cfg.pin_mosi = TFT_MOSI; // MOSI Pin Number + cfg.pin_miso = TFT_MISO; // MISO Pin Number + cfg.pin_cs = TOUCH_CS; // CS Pin Number + cfg.freq = SPI_TOUCH_FREQUENCY; // Set SPI clock + cfg.x_min = 0; // Minimum X value (raw value) obtained from touch screen + cfg.x_max = w - 1; // Maximum X value (raw value) obtained from touch screen + cfg.y_min = 0; // Minimum Y value (raw value) obtained from touch screen + cfg.y_max = h - 1; // Maximum Y value (raw value) obtained from touch screen + +#elif(TOUCH_DRIVER == 911) || (TOUCH_DRIVER == 6336) + cfg.bus_shared = false; // Set to true if you are using the same bus as the screen + cfg.pin_sda = TOUCH_SDA; + cfg.pin_scl = TOUCH_SCL; + cfg.i2c_port = I2C_TOUCH_PORT; // Select I2C to use (0 or 1) + cfg.i2c_addr = I2C_TOUCH_ADDRESS; // I2C device address number + cfg.freq = I2C_TOUCH_FREQUENCY; // Set I2C clock + cfg.x_min = 0; // Minimum X value (raw value) obtained from touch screen + cfg.x_max = w - 1; // Maximum X value (raw value) obtained from touch screen + cfg.y_min = 0; // Minimum Y value (raw value) obtained from touch screen + cfg.y_max = h - 1; // Maximum Y value (raw value) obtained from touch screen #endif tft._touch_instance->config(cfg); - tft._panel_instance->setTouch(tft._touch_instance); // タッチスクリーンをパネルにセットします。 + tft._panel_instance->setTouch(tft._touch_instance); // Set the touch screen on the panel. } - tft.setPanel(tft._panel_instance); // 使用するパネルをセットします。 + tft.setPanel(tft._panel_instance); // Set the panel to be used. + + LOG_VERBOSE(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); /* TFT init */ tft.begin(); tft.setSwapBytes(true); /* set endianess */ + + LOG_VERBOSE(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); } void LovyanGfx::show_info() @@ -168,33 +224,53 @@ void LovyanGfx::show_info() LOG_VERBOSE(TAG_TFT, F("LovyanGFX : v%d.%d.%d"), LGFX_VERSION_MAJOR, LGFX_VERSION_MINOR, LGFX_VERSION_PATCH); - // LOG_VERBOSE(TAG_TFT, F("Transactns : %s"), (tftSetup.trans == 1) ? PSTR(D_YES) : PSTR(D_NO)); - // LOG_VERBOSE(TAG_TFT, F("Interface : %s"), (tftSetup.serial == 1) ? PSTR("SPI") : PSTR("Parallel")); +// LOG_VERBOSE(TAG_TFT, F("Transactns : %s"), (tftSetup.trans == 1) ? PSTR(D_YES) : PSTR(D_NO)); +// LOG_VERBOSE(TAG_TFT, F("Interface : %s"), (tftSetup.serial == 1) ? PSTR("SPI") : PSTR("Parallel")); +#ifdef ESP32_PARALLEL + { + auto bus = (lgfx::v1::Bus_Parallel8*)tft._bus_instance; + auto cfg = bus->config(); // Get the structure for bus configuration. + tftPinInfo(F("TFT_WR"), cfg.pin_wr); + tftPinInfo(F("TFT_RD"), cfg.pin_rd); + tftPinInfo(F("TFT_RS"), cfg.pin_rs); + tftPinInfo(F("TFT_D0"), cfg.pin_d0); + tftPinInfo(F("TFT_D1"), cfg.pin_d1); + tftPinInfo(F("TFT_D2"), cfg.pin_d2); + tftPinInfo(F("TFT_D3"), cfg.pin_d3); + tftPinInfo(F("TFT_D4"), cfg.pin_d4); + tftPinInfo(F("TFT_D5"), cfg.pin_d5); + tftPinInfo(F("TFT_D6"), cfg.pin_d6); + tftPinInfo(F("TFT_D7"), cfg.pin_d7); + } +#else { auto bus = (lgfx::v1::Bus_SPI*)tft._bus_instance; - auto cfg = bus->config(); // バス設定用の構造体を取得します。 + auto cfg = bus->config(); // Get the structure for bus configuration. tftPinInfo(F("MOSI"), cfg.pin_mosi); tftPinInfo(F("MISO"), cfg.pin_miso); tftPinInfo(F("SCLK"), cfg.pin_sclk); tftPinInfo(F("TFT_DC"), cfg.pin_dc); } +#endif { - auto cfg = tft._panel_instance->config(); // バス設定用の構造体を取得します。 + auto cfg = tft._panel_instance->config(); // Get the structure for bus configuration. tftPinInfo(F("TFT_CS"), cfg.pin_cs); tftPinInfo(F("TFT_RST"), cfg.pin_rst); } +#ifndef ESP32_PARALLEL { auto bus = (lgfx::v1::Bus_SPI*)tft._bus_instance; - auto cfg = bus->config(); // バス設定用の構造体を取得します。 + auto cfg = bus->config(); // Get the structure for bus configuration. uint32_t freq = cfg.freq_write / 100000; LOG_VERBOSE(TAG_TFT, F("Display SPI freq. : %d.%d MHz"), freq / 10, freq % 10); } +#endif { - auto cfg = tft._touch_instance->config(); // バス設定用の構造体を取得します。 + auto cfg = tft._touch_instance->config(); // Get the structure for bus configuration. if(cfg.pin_cs != -1) { tftPinInfo(F("TOUCH_CS"), cfg.pin_cs); uint32_t freq = cfg.freq / 100000; @@ -210,18 +286,6 @@ void LovyanGfx::show_info() } } - // tftPinInfo(F("TFT_WR"), tftSetup.pin_tft_wr); - // tftPinInfo(F("TFT_RD"), tftSetup.pin_tft_rd); - - // tftPinInfo(F("TFT_D0"), tftSetup.pin_tft_d0); - // tftPinInfo(F("TFT_D1"), tftSetup.pin_tft_d1); - // tftPinInfo(F("TFT_D2"), tftSetup.pin_tft_d2); - // tftPinInfo(F("TFT_D3"), tftSetup.pin_tft_d3); - // tftPinInfo(F("TFT_D4"), tftSetup.pin_tft_d4); - // tftPinInfo(F("TFT_D5"), tftSetup.pin_tft_d5); - // tftPinInfo(F("TFT_D6"), tftSetup.pin_tft_d6); - // tftPinInfo(F("TFT_D7"), tftSetup.pin_tft_d7); - // if(tftSetup.serial == 1) { // LOG_VERBOSE(TAG_TFT, F("Display SPI freq. : %d.%d MHz"), tftSetup.tft_spi_freq / 10, // tftSetup.tft_spi_freq % 10); diff --git a/src/drv/tft/tft_driver_lovyangfx.h b/src/drv/tft/tft_driver_lovyangfx.h index 2648f236..cae5b530 100644 --- a/src/drv/tft/tft_driver_lovyangfx.h +++ b/src/drv/tft/tft_driver_lovyangfx.h @@ -21,6 +21,10 @@ #include "custom/bootlogo_template.h" // Sketch tab header for xbm images #endif +#ifndef TOUCH_IRQ +#define TOUCH_IRQ -1 +#endif + namespace dev { class LGFX : public lgfx::LGFX_Device { public: