From 3078210b26a6f51f2fc1ec201f7cbad31bc6970e Mon Sep 17 00:00:00 2001 From: Kit Sczudlo Date: Mon, 1 Jan 2024 09:00:24 -0800 Subject: [PATCH] feat(spi_lcd): control DC level for cmd, param, color phase separately Closes https://github.com/espressif/esp-idf/issues/10635 Merges https://github.com/espressif/esp-idf/pull/12908 --- components/esp_lcd/include/esp_lcd_panel_io.h | 8 +++++--- components/esp_lcd/src/esp_lcd_panel_io_spi.c | 20 +++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/components/esp_lcd/include/esp_lcd_panel_io.h b/components/esp_lcd/include/esp_lcd_panel_io.h index 2c2cc086bbc..12e0cf913d5 100644 --- a/components/esp_lcd/include/esp_lcd_panel_io.h +++ b/components/esp_lcd/include/esp_lcd_panel_io.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -134,10 +134,12 @@ typedef struct { int lcd_cmd_bits; /*!< Bit-width of LCD command */ int lcd_param_bits; /*!< Bit-width of LCD parameter */ struct { - unsigned int dc_low_on_data: 1; /*!< If this flag is enabled, DC line = 0 means transfer data, DC line = 1 means transfer command; vice versa */ + unsigned int dc_high_on_cmd: 1; /*!< If enabled, DC level = 1 indicates command transfer */ + unsigned int dc_low_on_data: 1; /*!< If enabled, DC level = 0 indicates color data transfer */ + unsigned int dc_low_on_param: 1; /*!< If enabled, DC level = 0 indicates parameter transfer */ unsigned int octal_mode: 1; /*!< transmit with octal mode (8 data lines), this mode is used to simulate Intel 8080 timing */ unsigned int quad_mode: 1; /*!< transmit with quad mode (4 data lines), this mode is useful when transmitting LCD parameters (Only use one line for command) */ - unsigned int sio_mode: 1; /*!< Read and write through a single data line (MOSI) */ + unsigned int sio_mode: 1; /*!< Read and write through a single data line (MOSI) */ unsigned int lsb_first: 1; /*!< transmit LSB bit first */ unsigned int cs_high_active: 1; /*!< CS line is high active */ } flags; /*!< Extra flags to fine-tune the SPI device */ diff --git a/components/esp_lcd/src/esp_lcd_panel_io_spi.c b/components/esp_lcd/src/esp_lcd_panel_io_spi.c index 7f3e8084e18..d3ac1004b85 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_spi.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_spi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -52,7 +52,9 @@ typedef struct { int lcd_cmd_bits; // Bit width of LCD command int lcd_param_bits; // Bit width of LCD parameter struct { - unsigned int dc_data_level: 1; // Indicates the level of DC line when tranfering data + unsigned int dc_cmd_level: 1; // Indicates the level of DC line when transferring command + unsigned int dc_data_level: 1; // Indicates the level of DC line when transferring color data + unsigned int dc_param_level: 1; // Indicates the level of DC line when transferring parameters unsigned int octal_mode: 1; // Indicates whether the transmitting is enabled with octal mode (8 data lines) unsigned int quad_mode: 1; // Indicates whether the transmitting is enabled with quad mode (4 data lines) } flags; @@ -94,7 +96,9 @@ esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_p ESP_GOTO_ON_ERROR(gpio_config(&io_conf), err, TAG, "configure GPIO for D/C line failed"); } + spi_panel_io->flags.dc_cmd_level = io_config->flags.dc_high_on_cmd; spi_panel_io->flags.dc_data_level = !io_config->flags.dc_low_on_data; + spi_panel_io->flags.dc_param_level = !io_config->flags.dc_low_on_param; spi_panel_io->flags.octal_mode = io_config->flags.octal_mode; spi_panel_io->flags.quad_mode = io_config->flags.quad_mode; spi_panel_io->on_color_trans_done = io_config->on_color_trans_done; @@ -225,7 +229,7 @@ static esp_err_t panel_io_spi_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons if (send_cmd) { spi_lcd_prepare_cmd_buffer(spi_panel_io, &lcd_cmd); - lcd_trans->flags.dc_gpio_level = !spi_panel_io->flags.dc_data_level; // set D/C line to command mode + lcd_trans->flags.dc_gpio_level = spi_panel_io->flags.dc_cmd_level; // set D/C level in command phase lcd_trans->base.length = spi_panel_io->lcd_cmd_bits; lcd_trans->base.tx_buffer = &lcd_cmd; // command is short, using polling mode @@ -235,7 +239,7 @@ static esp_err_t panel_io_spi_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons if (param && param_size) { spi_lcd_prepare_param_buffer(spi_panel_io, param, param_size); - lcd_trans->flags.dc_gpio_level = spi_panel_io->flags.dc_data_level; // set D/C line to data mode + lcd_trans->flags.dc_gpio_level = spi_panel_io->flags.dc_param_level; // set D/C level in param phase lcd_trans->base.length = param_size * 8; // transaction length is in bits lcd_trans->base.tx_buffer = param; lcd_trans->base.flags &= ~SPI_TRANS_CS_KEEP_ACTIVE; @@ -279,7 +283,7 @@ static esp_err_t panel_io_spi_rx_param(esp_lcd_panel_io_t *io, int lcd_cmd, void if (send_cmd) { spi_lcd_prepare_cmd_buffer(spi_panel_io, &lcd_cmd); - lcd_trans->flags.dc_gpio_level = !spi_panel_io->flags.dc_data_level; // set D/C line to command mode + lcd_trans->flags.dc_gpio_level = spi_panel_io->flags.dc_cmd_level; // set D/C level in command phase lcd_trans->base.length = spi_panel_io->lcd_cmd_bits; lcd_trans->base.tx_buffer = &lcd_cmd; // command is short, using polling mode @@ -288,7 +292,7 @@ static esp_err_t panel_io_spi_rx_param(esp_lcd_panel_io_t *io, int lcd_cmd, void } if (param && param_size) { - lcd_trans->flags.dc_gpio_level = spi_panel_io->flags.dc_data_level; // set D/C line to data mode + lcd_trans->flags.dc_gpio_level = spi_panel_io->flags.dc_param_level; // set D/C level in param phase lcd_trans->base.length = 0; lcd_trans->base.tx_buffer = NULL; lcd_trans->base.rxlength = param_size * 8; // Read length in bits @@ -328,7 +332,7 @@ static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons spi_lcd_prepare_cmd_buffer(spi_panel_io, &lcd_cmd); lcd_trans->base.user = spi_panel_io; - lcd_trans->flags.dc_gpio_level = !spi_panel_io->flags.dc_data_level; // set D/C line to command mode + lcd_trans->flags.dc_gpio_level = spi_panel_io->flags.dc_cmd_level; // set D/C level in command phase lcd_trans->base.length = spi_panel_io->lcd_cmd_bits; lcd_trans->base.tx_buffer = &lcd_cmd; if(color && color_size) { @@ -371,7 +375,7 @@ static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons } lcd_trans->base.user = spi_panel_io; - lcd_trans->flags.dc_gpio_level = spi_panel_io->flags.dc_data_level; // set D/C line to data mode + lcd_trans->flags.dc_gpio_level = spi_panel_io->flags.dc_data_level; // set D/C level in data phase lcd_trans->base.length = chunk_size * 8; // transaction length is in bits lcd_trans->base.tx_buffer = color; if (spi_panel_io->flags.octal_mode) {