lcd: support i80 LCD on esp32/s2/s3

This commit is contained in:
morris
2021-08-04 20:11:31 +08:00
parent 3bcd9278fa
commit 6fdc5877cd
28 changed files with 1717 additions and 228 deletions

View File

@@ -18,8 +18,8 @@
static const char *TAG = "lcd_panel.io.spi";
static esp_err_t panel_io_spi_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, int lcd_cmd_bits, const void *param, size_t param_size);
static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, int lcd_cmd_bits, const void *color, size_t color_size);
static esp_err_t panel_io_spi_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, const void *param, size_t param_size);
static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, const void *color, size_t color_size);
static esp_err_t panel_io_spi_del(esp_lcd_panel_io_t *io);
static void lcd_spi_pre_trans_cb(spi_transaction_t *trans);
static void lcd_spi_post_trans_color_cb(spi_transaction_t *trans);
@@ -39,12 +39,14 @@ typedef struct {
bool (*on_color_trans_done)(esp_lcd_panel_io_handle_t panel_io, void *user_data, void *event_data); // User register's callback, invoked when color data trans done
void *user_data; // User's private data, passed directly to callback on_color_trans_done
size_t queue_size; // Size of transaction queue
size_t num_trans_working; // Number of transactions that are undergoing (the descriptor not recycled yet)
size_t num_trans_inflight; // Number of transactions that are undergoing (the descriptor not recycled yet)
int lcd_cmd_bits; // Bit width of LCD command
int lcd_param_bits; // Bit width of LCD parameter
struct {
int dc_as_cmd_phase: 1; // D/C line value is encoded into SPI transaction command phase
int dc_data_level: 1; // Indicates the level of DC line when tranfering data
unsigned int dc_as_cmd_phase: 1; // D/C line value is encoded into SPI transaction command phase
unsigned int dc_data_level: 1; // Indicates the level of DC line when tranfering data
} flags;
lcd_spi_trans_descriptor_t trans_pool[0]; // Transaction pool
lcd_spi_trans_descriptor_t trans_pool[]; // Transaction pool
} esp_lcd_panel_io_spi_t;
esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_panel_io_spi_config_t *io_config, esp_lcd_panel_io_handle_t *ret_io)
@@ -81,6 +83,8 @@ esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_p
spi_panel_io->flags.dc_as_cmd_phase = io_config->flags.dc_as_cmd_phase;
spi_panel_io->flags.dc_data_level = !io_config->flags.dc_low_on_data;
spi_panel_io->on_color_trans_done = io_config->on_color_trans_done;
spi_panel_io->lcd_cmd_bits = io_config->lcd_cmd_bits;
spi_panel_io->lcd_param_bits = io_config->lcd_param_bits;
spi_panel_io->user_data = io_config->user_data;
spi_panel_io->dc_gpio_num = io_config->dc_gpio_num;
spi_panel_io->queue_size = io_config->trans_queue_depth;
@@ -109,7 +113,7 @@ static esp_err_t panel_io_spi_del(esp_lcd_panel_io_t *io)
esp_lcd_panel_io_spi_t *spi_panel_io = __containerof(io, esp_lcd_panel_io_spi_t, base);
// wait all pending transaction to finish
for (size_t i = 0; i < spi_panel_io->num_trans_working; i++) {
for (size_t i = 0; i < spi_panel_io->num_trans_inflight; i++) {
ret = spi_device_get_trans_result(spi_panel_io->spi_dev, &spi_trans, portMAX_DELAY);
ESP_GOTO_ON_ERROR(ret, err, TAG, "recycle spi transactions failed");
}
@@ -124,7 +128,7 @@ err:
return ret;
}
static esp_err_t panel_io_spi_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, int lcd_cmd_bits, const void *param, size_t param_size)
static esp_err_t panel_io_spi_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, const void *param, size_t param_size)
{
esp_err_t ret = ESP_OK;
spi_transaction_t *spi_trans = NULL;
@@ -132,16 +136,16 @@ static esp_err_t panel_io_spi_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, int
esp_lcd_panel_io_spi_t *spi_panel_io = __containerof(io, esp_lcd_panel_io_spi_t, base);
// before issue a polling transaction, need to wait queued transactions finished
for (size_t i = 0; i < spi_panel_io->num_trans_working; i++) {
for (size_t i = 0; i < spi_panel_io->num_trans_inflight; i++) {
ret = spi_device_get_trans_result(spi_panel_io->spi_dev, &spi_trans, portMAX_DELAY);
ESP_GOTO_ON_ERROR(ret, err, TAG, "recycle spi transactions failed");
}
spi_panel_io->num_trans_working = 0;
spi_panel_io->num_trans_inflight = 0;
lcd_trans = &spi_panel_io->trans_pool[0];
memset(lcd_trans, 0, sizeof(lcd_spi_trans_descriptor_t));
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->base.length = lcd_cmd_bits;
lcd_trans->base.length = spi_panel_io->lcd_cmd_bits;
lcd_trans->base.tx_buffer = &lcd_cmd;
if (spi_panel_io->flags.dc_as_cmd_phase) { // encoding DC value to SPI command phase when necessary
lcd_trans->base.cmd = !spi_panel_io->flags.dc_data_level;
@@ -166,7 +170,7 @@ err:
return ret;
}
static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, int lcd_cmd_bits, const void *color, size_t color_size)
static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, const void *color, size_t color_size)
{
esp_err_t ret = ESP_OK;
spi_transaction_t *spi_trans = NULL;
@@ -174,16 +178,16 @@ static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, int
esp_lcd_panel_io_spi_t *spi_panel_io = __containerof(io, esp_lcd_panel_io_spi_t, base);
// before issue a polling transaction, need to wait queued transactions finished
for (size_t i = 0; i < spi_panel_io->num_trans_working; i++) {
for (size_t i = 0; i < spi_panel_io->num_trans_inflight; i++) {
ret = spi_device_get_trans_result(spi_panel_io->spi_dev, &spi_trans, portMAX_DELAY);
ESP_GOTO_ON_ERROR(ret, err, TAG, "recycle spi transactions failed");
}
spi_panel_io->num_trans_working = 0;
spi_panel_io->num_trans_inflight = 0;
lcd_trans = &spi_panel_io->trans_pool[0];
memset(lcd_trans, 0, sizeof(lcd_spi_trans_descriptor_t));
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->base.length = lcd_cmd_bits;
lcd_trans->base.length = spi_panel_io->lcd_cmd_bits;
lcd_trans->base.tx_buffer = &lcd_cmd;
if (spi_panel_io->flags.dc_as_cmd_phase) { // encoding DC value to SPI command phase when necessary
lcd_trans->base.cmd = !spi_panel_io->flags.dc_data_level;
@@ -203,7 +207,7 @@ static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, int
// color data is usually large, using queue+blocking mode
ret = spi_device_queue_trans(spi_panel_io->spi_dev, &lcd_trans->base, portMAX_DELAY);
ESP_GOTO_ON_ERROR(ret, err, TAG, "spi transmit (queue) color failed");
spi_panel_io->num_trans_working++;
spi_panel_io->num_trans_inflight++;
err:
return ret;