Parallel IO simulation of SPI or I80 Interfaced LCD
Parallel IO is not a bus-type peripheral. The driver directly creates a Parallel IO device for the LCD. Currently the driver supports SPI (1 bit data width) and I80 (8 bit data width) modes.
Create Parallel IO device by
esp_lcd_new_panel_io_parl()
. You need to set up the following parameters for a Parallel IO device:esp_lcd_panel_io_parl_config_t::clk_src
sets the clock source of the Parallel IO device. Note, the default clock source may be different between ESP targets.esp_lcd_panel_io_parl_config_t::clk_gpio_num
sets the GPIO number of the pixel clock (also referred asWR
orSCLK
in some LCD spec)esp_lcd_panel_io_parl_config_t::dc_gpio_num
sets the GPIO number of the data or command select pin (also referred asRS
in some LCD spec)esp_lcd_panel_io_parl_config_t::cs_gpio_num
sets the GPIO number of the chip select pin. (Note that the Parallel IO LCD driver only supports a single LCD device).esp_lcd_panel_io_parl_config_t::data_width
sets the bit width of the data bus (only support1
or8
)esp_lcd_panel_io_parl_config_t::data_gpio_nums
is the array of the GPIO number of the data bus. The number of GPIOs should be equal to theesp_lcd_panel_io_parl_config_t::data_width
value.esp_lcd_panel_io_parl_config_t::max_transfer_bytes
sets the maximum number of bytes that can be transferred in one transaction.esp_lcd_panel_io_parl_config_t::dma_burst_size
sets the number of bytes transferred by dma burst.esp_lcd_panel_io_parl_config_t::pclk_hz
sets the pixel clock frequency in Hz. Higher pixel clock frequency results in higher refresh rate, but may cause display abnormalities if the DMA bandwidth is not sufficient or the LCD controller chip does not support high pixel clock frequency.esp_lcd_panel_io_parl_config_t::dc_levels
sets the effective level for DC data selection and command selection.esp_lcd_panel_io_parl_config_t::lcd_cmd_bits
andesp_lcd_panel_io_parl_config_t::lcd_param_bits
set the bit width of the command and parameter that recognized by the LCD controller chip. This is chip specific, you should refer to your LCD spec in advance.esp_lcd_panel_io_parl_config_t::trans_queue_depth
sets the maximum number of transactions that can be queued in the Parallel IO device. A bigger value means more transactions can be queued up, but it also consumes more memory.
esp_lcd_panel_io_handle_t io_handle = NULL; esp_lcd_panel_io_parl_config_t io_config = { .clk_src = PARLIO_CLK_SRC_DEFAULT, .dc_gpio_num = EXAMPLE_PIN_NUM_DC, .clk_gpio_num = EXAMPLE_PIN_NUM_PCLK, .data_gpio_nums = { EXAMPLE_PIN_NUM_DATA0, // set DATA0 to drive SPI interfaced LCD or set DATA0~7 to drive I80 interfaced LCD }, .data_width = 1, // set 1 to drive SPI interfaced LCD or set 8 to drive I80 interfaced LCD .max_transfer_bytes = EXAMPLE_LCD_H_RES * 100 * sizeof(uint16_t), // transfer 100 lines of pixels (assume pixel is RGB565) at most in one transaction .dma_burst_size = EXAMPLE_DMA_BURST_SIZE, .cs_gpio_num = EXAMPLE_PIN_NUM_CS, .pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ, .trans_queue_depth = 10, .dc_levels = { .dc_cmd_level = 0, .dc_data_level = 1, }, .lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS, .lcd_param_bits = EXAMPLE_LCD_PARAM_BITS, }; ESP_ERROR_CHECK(esp_lcd_new_panel_io_parl(&io_config, io_handle));
Install the LCD controller driver. The LCD controller driver is responsible for sending the commands and parameters to the LCD controller chip. In this step, you need to specify the Parallel IO device handle that allocated in the last step, and some panel specific configurations:
esp_lcd_panel_dev_config_t::reset_gpio_num
sets the LCD's hardware reset GPIO number. If the LCD does not have a hardware reset pin, set this to-1
.esp_lcd_panel_dev_config_t::rgb_ele_order
sets the RGB element order of each color data.esp_lcd_panel_dev_config_t::bits_per_pixel
sets the bit width of the pixel color data. The LCD driver uses this value to calculate the number of bytes to send to the LCD controller chip.esp_lcd_panel_dev_config_t::data_endian
specifies the data endian to be transmitted to the screen. No need to specify for color data within one byte, like RGB232. For drivers that do not support specifying data endian, this field would be ignored.
esp_lcd_panel_handle_t panel_handle = NULL; esp_lcd_panel_dev_config_t panel_config = { .reset_gpio_num = EXAMPLE_PIN_NUM_RST, .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR, .bits_per_pixel = 16, }; // Create LCD panel handle for ST7789, with the Parallel IO device handle ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
API Reference
Header File
This header file can be included with:
#include "esp_lcd_io_parl.h"
This header file is a part of the API provided by the
esp_lcd
component. To declare that your component depends onesp_lcd
, add the following to your CMakeLists.txt:REQUIRES esp_lcd
or
PRIV_REQUIRES esp_lcd
Functions
-
esp_err_t esp_lcd_new_panel_io_parl(const esp_lcd_panel_io_parl_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io)
Create LCD panel IO, for parlio interface.
- Parameters
io_config -- [in] IO configuration, for parlio interface
ret_io -- [out] Returned panel IO handle
- Returns
ESP_ERR_INVALID_ARG if parameter is invalid
ESP_ERR_NOT_SUPPORTED if some configuration can't be satisfied, e.g. pixel clock out of the range
ESP_ERR_NO_MEM if out of memory
ESP_OK on success
-
void *esp_lcd_parlio_alloc_draw_buffer(esp_lcd_panel_io_handle_t io, size_t size, uint32_t caps)
Allocate a draw buffer that can be used by parlio interface LCD panel.
Note
This function differs from the normal 'heap_caps_*' functions in that it can also automatically handle the alignment required by DMA burst, cache line size, etc.
- Parameters
io -- [in] Panel IO handle, created by
esp_lcd_new_panel_io_parl()
size -- [in] Size of memory to be allocated
caps -- [in] Bitwise OR of MALLOC_CAP_* flags indicating the type of memory desired for the allocation
- Returns
Pointer to a new buffer of size 'size' with capabilities 'caps', or NULL if allocation failed
Structures
-
struct esp_lcd_panel_io_parl_config_t
Parallel Panel IO configuration structure, for intel 8080 interface(8 data-lines) or SPI interface(1 data-lines)
Public Members
-
int dc_gpio_num
GPIO used for D/C line
-
int clk_gpio_num
GPIO used for CLK line
-
int cs_gpio_num
GPIO used for CS line
-
int data_gpio_nums[ESP_PARLIO_LCD_WIDTH_MAX]
GPIOs used for data lines
-
size_t data_width
Number of data lines, 1(SPI) or 8(I80)
-
uint32_t pclk_hz
Frequency of pixel clock
-
parlio_clock_source_t clk_src
Clock source for the Parlio peripheral
-
size_t max_transfer_bytes
Maximum transfer size, this determines the length of internal DMA link
-
size_t dma_burst_size
DMA burst size, in bytes
-
size_t trans_queue_depth
Transaction queue size, larger queue, higher throughput
-
int lcd_cmd_bits
Bit-width of LCD command
-
int lcd_param_bits
Bit-width of LCD parameter
-
unsigned int dc_cmd_level
Level of DC line in CMD phase
-
unsigned int dc_data_level
Level of DC line in DATA phase
-
struct esp_lcd_panel_io_parl_config_t::[anonymous] dc_levels
Each LCD device might have its own D/C control logic
-
unsigned int cs_active_high
If set, a high level of CS line will select the device, otherwise, CS line is low level active
-
struct esp_lcd_panel_io_parl_config_t::[anonymous] flags
Panel IO config flags
-
int dc_gpio_num
Macros
-
ESP_PARLIO_LCD_WIDTH_MAX
Maximum data width of parlio lcd interface