kopia lustrzana https://github.com/espressif/esp-idf
esp_lcd: Add support for rx_param on I2C transport.
(cherry picked from commit 4a2766d906
)
pull/8958/head
rodzic
4222e93351
commit
c9b0be6ef7
|
@ -19,6 +19,25 @@ typedef void *esp_lcd_spi_bus_handle_t; /*!< Type of LCD S
|
|||
typedef void *esp_lcd_i2c_bus_handle_t; /*!< Type of LCD I2C bus handle */
|
||||
typedef struct esp_lcd_i80_bus_t *esp_lcd_i80_bus_handle_t; /*!< Type of LCD intel 8080 bus handle */
|
||||
|
||||
/**
|
||||
* @brief Transmit LCD command and receive corresponding parameters
|
||||
*
|
||||
* @note Commands sent by this function are short, so they are sent using polling transactions.
|
||||
* The function does not return before the command tranfer is completed.
|
||||
* If any queued transactions sent by `esp_lcd_panel_io_tx_color()` are still pending when this function is called,
|
||||
* this function will wait until they are finished and the queue is empty before sending the command(s).
|
||||
*
|
||||
* @param[in] io LCD panel IO handle, which is created by other factory API like `esp_lcd_new_panel_io_spi()`
|
||||
* @param[in] lcd_cmd The specific LCD command, set to -1 if no command needed
|
||||
* @param[out] param Buffer for the command data
|
||||
* @param[in] param_size Size of `param` buffer
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG if parameter is invalid
|
||||
* - ESP_ERR_NOT_SUPPORTED if read is not supported by transport
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_lcd_panel_io_rx_param(esp_lcd_panel_io_handle_t io, int lcd_cmd, void *param, size_t param_size);
|
||||
|
||||
/**
|
||||
* @brief Transmit LCD command and corresponding parameters
|
||||
*
|
||||
|
@ -125,6 +144,7 @@ typedef struct {
|
|||
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 disable_control_phase: 1; /*!< If this flag is enabled, the control phase isn't used */
|
||||
} flags;
|
||||
} esp_lcd_panel_io_i2c_config_t;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -18,6 +18,22 @@ typedef struct esp_lcd_panel_io_t esp_lcd_panel_io_t; /*!< Type of LCD panel IO
|
|||
* @brief LCD panel IO interface
|
||||
*/
|
||||
struct esp_lcd_panel_io_t {
|
||||
/**
|
||||
* @brief Transmit LCD command and receive corresponding parameters
|
||||
*
|
||||
* @note This is the panel-specific interface called by function `esp_lcd_panel_io_rx_param()`.
|
||||
*
|
||||
* @param[in] io LCD panel IO handle, which is created by other factory API like `esp_lcd_new_panel_io_spi()`
|
||||
* @param[in] lcd_cmd The specific LCD command, set to -1 if no command needed
|
||||
* @param[out] param Buffer for the command data
|
||||
* @param[in] param_size Size of `param` buffer
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG if parameter is invalid
|
||||
* - ESP_ERR_NOT_SUPPORTED if read is not supported by transport
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t (*rx_param)(esp_lcd_panel_io_t *io, int lcd_cmd, void *param, size_t param_size);
|
||||
|
||||
/**
|
||||
* @brief Transmit LCD command and corresponding parameters
|
||||
*
|
||||
|
|
|
@ -10,6 +10,13 @@
|
|||
|
||||
static const char *TAG = "lcd_panel.io";
|
||||
|
||||
esp_err_t esp_lcd_panel_io_rx_param(esp_lcd_panel_io_handle_t io, int lcd_cmd, void *param, size_t param_size)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(io, ESP_ERR_INVALID_ARG, TAG, "invalid panel io handle");
|
||||
ESP_RETURN_ON_FALSE(io->rx_param, ESP_ERR_NOT_SUPPORTED, TAG, "rx_param is not supported yet");
|
||||
return io->rx_param(io, lcd_cmd, param, param_size);
|
||||
}
|
||||
|
||||
esp_err_t esp_lcd_panel_io_tx_param(esp_lcd_panel_io_handle_t io, int lcd_cmd, const void *param, size_t param_size)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(io, ESP_ERR_INVALID_ARG, TAG, "invalid panel io handle");
|
||||
|
|
|
@ -22,6 +22,7 @@ static const char *TAG = "lcd_panel.io.i2c";
|
|||
#define BYTESHIFT(VAR, IDX) (((VAR) >> ((IDX) * 8)) & 0xFF)
|
||||
|
||||
static esp_err_t panel_io_i2c_del(esp_lcd_panel_io_t *io);
|
||||
static esp_err_t panel_io_i2c_rx_param(esp_lcd_panel_io_t *io, int lcd_cmd, void *param, size_t param_size);
|
||||
static esp_err_t panel_io_i2c_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, const void *param, size_t param_size);
|
||||
static esp_err_t panel_io_i2c_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, const void *color, size_t color_size);
|
||||
|
||||
|
@ -31,6 +32,7 @@ typedef struct {
|
|||
uint32_t dev_addr; // Device address
|
||||
int lcd_cmd_bits; // Bit width of LCD command
|
||||
int lcd_param_bits; // Bit width of LCD parameter
|
||||
bool control_phase_enabled; // Is control phase enabled
|
||||
uint32_t control_phase_cmd; // control byte when transferring command
|
||||
uint32_t control_phase_data; // control byte when transferring data
|
||||
esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; // User register's callback, invoked when color data trans done
|
||||
|
@ -52,10 +54,12 @@ esp_err_t esp_lcd_new_panel_io_i2c(esp_lcd_i2c_bus_handle_t bus, const esp_lcd_p
|
|||
i2c_panel_io->lcd_param_bits = io_config->lcd_param_bits;
|
||||
i2c_panel_io->on_color_trans_done = io_config->on_color_trans_done;
|
||||
i2c_panel_io->user_ctx = io_config->user_ctx;
|
||||
i2c_panel_io->control_phase_enabled = (!io_config->flags.disable_control_phase);
|
||||
i2c_panel_io->control_phase_data = (!io_config->flags.dc_low_on_data) << (io_config->dc_bit_offset);
|
||||
i2c_panel_io->control_phase_cmd = (io_config->flags.dc_low_on_data) << (io_config->dc_bit_offset);
|
||||
i2c_panel_io->dev_addr = io_config->dev_addr;
|
||||
i2c_panel_io->base.del = panel_io_i2c_del;
|
||||
i2c_panel_io->base.rx_param = panel_io_i2c_rx_param;
|
||||
i2c_panel_io->base.tx_param = panel_io_i2c_tx_param;
|
||||
i2c_panel_io->base.tx_color = panel_io_i2c_tx_color;
|
||||
*ret_io = &(i2c_panel_io->base);
|
||||
|
@ -76,6 +80,47 @@ static esp_err_t panel_io_i2c_del(esp_lcd_panel_io_t *io)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t panel_io_i2c_rx_buffer(esp_lcd_panel_io_t *io, int lcd_cmd, void *buffer, size_t buffer_size)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
lcd_panel_io_i2c_t *i2c_panel_io = __containerof(io, lcd_panel_io_i2c_t, base);
|
||||
bool send_param = (lcd_cmd >= 0);
|
||||
|
||||
i2c_cmd_handle_t cmd_link = i2c_cmd_link_create_static(i2c_panel_io->cmdlink_buffer, CMD_HANDLER_BUFFER_SIZE);
|
||||
ESP_GOTO_ON_FALSE(cmd_link, ESP_ERR_NO_MEM, err, TAG, "no mem for i2c cmd link");
|
||||
ESP_GOTO_ON_ERROR(i2c_master_start(cmd_link), err, TAG, "issue start failed"); // start phase
|
||||
ESP_GOTO_ON_ERROR(i2c_master_write_byte(cmd_link, (i2c_panel_io->dev_addr << 1) | I2C_MASTER_WRITE, true), err, TAG, "write address failed"); // address phase
|
||||
if (send_param) {
|
||||
if (i2c_panel_io->control_phase_enabled) {
|
||||
ESP_GOTO_ON_ERROR(i2c_master_write_byte(cmd_link, i2c_panel_io->control_phase_cmd, true),
|
||||
err, TAG, "write control phase failed"); // control phase
|
||||
}
|
||||
uint8_t cmds[4] = {BYTESHIFT(lcd_cmd, 3), BYTESHIFT(lcd_cmd, 2), BYTESHIFT(lcd_cmd, 1), BYTESHIFT(lcd_cmd, 0)};
|
||||
size_t cmds_size = i2c_panel_io->lcd_cmd_bits / 8;
|
||||
if (cmds_size > 0 && cmds_size <= sizeof(cmds)) {
|
||||
ESP_GOTO_ON_ERROR(i2c_master_write(cmd_link, cmds + (sizeof(cmds) - cmds_size), cmds_size, true), err, TAG, "write LCD cmd failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
ESP_GOTO_ON_ERROR(i2c_master_start(cmd_link), err, TAG, "issue start failed"); // start phase
|
||||
ESP_GOTO_ON_ERROR(i2c_master_write_byte(cmd_link, (i2c_panel_io->dev_addr << 1) | I2C_MASTER_READ, true), err, TAG, "write address failed"); // address phase
|
||||
ESP_GOTO_ON_ERROR(i2c_master_read(cmd_link, buffer, buffer_size, I2C_MASTER_LAST_NACK), err, TAG, "read data failed");
|
||||
}
|
||||
|
||||
ESP_GOTO_ON_ERROR(i2c_master_stop(cmd_link), err, TAG, "issue stop failed"); // stop phase
|
||||
ESP_GOTO_ON_ERROR(i2c_master_cmd_begin(i2c_panel_io->i2c_bus_id, cmd_link, portMAX_DELAY), err, TAG, "i2c transaction failed");
|
||||
|
||||
i2c_cmd_link_delete_static(cmd_link);
|
||||
|
||||
return ESP_OK;
|
||||
err:
|
||||
if (cmd_link) {
|
||||
i2c_cmd_link_delete_static(cmd_link);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t panel_io_i2c_tx_buffer(esp_lcd_panel_io_t *io, int lcd_cmd, const void *buffer, size_t buffer_size, bool is_param)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
@ -85,8 +130,10 @@ static esp_err_t panel_io_i2c_tx_buffer(esp_lcd_panel_io_t *io, int lcd_cmd, con
|
|||
ESP_GOTO_ON_FALSE(cmd_link, ESP_ERR_NO_MEM, err, TAG, "no mem for i2c cmd link");
|
||||
ESP_GOTO_ON_ERROR(i2c_master_start(cmd_link), err, TAG, "issue start failed"); // start phase
|
||||
ESP_GOTO_ON_ERROR(i2c_master_write_byte(cmd_link, (i2c_panel_io->dev_addr << 1) | I2C_MASTER_WRITE, true), err, TAG, "write address failed"); // address phase
|
||||
ESP_GOTO_ON_ERROR(i2c_master_write_byte(cmd_link, is_param ? i2c_panel_io->control_phase_cmd : i2c_panel_io->control_phase_data, true),
|
||||
err, TAG, "write control phase failed"); // control phase
|
||||
if (i2c_panel_io->control_phase_enabled) {
|
||||
ESP_GOTO_ON_ERROR(i2c_master_write_byte(cmd_link, is_param ? i2c_panel_io->control_phase_cmd : i2c_panel_io->control_phase_data, true),
|
||||
err, TAG, "write control phase failed"); // control phase
|
||||
}
|
||||
uint8_t cmds[4] = {BYTESHIFT(lcd_cmd, 3), BYTESHIFT(lcd_cmd, 2), BYTESHIFT(lcd_cmd, 1), BYTESHIFT(lcd_cmd, 0)};
|
||||
size_t cmds_size = i2c_panel_io->lcd_cmd_bits / 8;
|
||||
if (cmds_size > 0 && cmds_size <= sizeof(cmds)) {
|
||||
|
@ -116,6 +163,11 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t panel_io_i2c_rx_param(esp_lcd_panel_io_t *io, int lcd_cmd, void *param, size_t param_size)
|
||||
{
|
||||
return panel_io_i2c_rx_buffer(io, lcd_cmd, param, param_size);
|
||||
}
|
||||
|
||||
static esp_err_t panel_io_i2c_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, const void *param, size_t param_size)
|
||||
{
|
||||
return panel_io_i2c_tx_buffer(io, lcd_cmd, param, param_size, true);
|
||||
|
|
Ładowanie…
Reference in New Issue