From a38828651b17e83d21a78b643eede9bc861ba19a Mon Sep 17 00:00:00 2001 From: Vilem Zavodny Date: Mon, 7 Nov 2022 12:21:30 +0100 Subject: [PATCH] esp_lcd: Add function for register on color done callback. (cherry picked from commit 747c5993a8a83080c478be17726a14cf24a85e68) --- components/esp_lcd/include/esp_lcd_panel_io.h | 44 ++++++++++++++----- .../interface/esp_lcd_panel_io_interface.h | 13 ++++++ components/esp_lcd/src/esp_lcd_panel_io.c | 7 +++ components/esp_lcd/src/esp_lcd_panel_io_i2c.c | 16 +++++++ components/esp_lcd/src/esp_lcd_panel_io_i2s.c | 16 +++++++ components/esp_lcd/src/esp_lcd_panel_io_i80.c | 16 +++++++ components/esp_lcd/src/esp_lcd_panel_io_spi.c | 18 +++++++- 7 files changed, 117 insertions(+), 13 deletions(-) diff --git a/components/esp_lcd/include/esp_lcd_panel_io.h b/components/esp_lcd/include/esp_lcd_panel_io.h index f702a9251e..baa90a3035 100644 --- a/components/esp_lcd/include/esp_lcd_panel_io.h +++ b/components/esp_lcd/include/esp_lcd_panel_io.h @@ -19,6 +19,30 @@ 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 Type of LCD panel IO event data + */ +typedef struct { +} esp_lcd_panel_io_event_data_t; + +/** + * @brief Declare the prototype of the function that will be invoked when panel IO finishes transferring color data + * + * @param[in] panel_io LCD panel IO handle, which is created by factory API like `esp_lcd_new_panel_io_spi()` + * @param[in] edata Panel IO event data, fed by driver + * @param[in] user_ctx User data, passed from `esp_lcd_panel_io_xxx_config_t` + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*esp_lcd_panel_io_color_trans_done_cb_t)(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx); + +/** + * @brief Type of LCD panel IO callbacks + */ +typedef struct { + esp_lcd_panel_io_color_trans_done_cb_t on_color_trans_done; /*!< Callback invoked when color data transfer has finished */ +} esp_lcd_panel_io_callbacks_t; + + /** * @brief Transmit LCD command and receive corresponding parameters * @@ -85,20 +109,16 @@ esp_err_t esp_lcd_panel_io_tx_color(esp_lcd_panel_io_handle_t io, int lcd_cmd, c esp_err_t esp_lcd_panel_io_del(esp_lcd_panel_io_handle_t io); /** - * @brief Type of LCD panel IO event data - */ -typedef struct { -} esp_lcd_panel_io_event_data_t; - -/** - * @brief Declare the prototype of the function that will be invoked when panel IO finishes transferring color data + * @brief Register LCD panel IO callbacks * - * @param[in] panel_io LCD panel IO handle, which is created by factory API like `esp_lcd_new_panel_io_spi()` - * @param[in] edata Panel IO event data, fed by driver - * @param[in] user_ctx User data, passed from `esp_lcd_panel_io_xxx_config_t` - * @return Whether a high priority task has been waken up by this function + * @param[in] io LCD panel IO handle, which is created by factory API like `esp_lcd_new_panel_io_spi()` + * @param[in] cbs structure with all LCD panel IO callbacks + * @param[in] user_ctx User private data, passed directly to callback's user_ctx + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_OK on success */ -typedef bool (*esp_lcd_panel_io_color_trans_done_cb_t)(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx); +esp_err_t esp_lcd_panel_io_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx); /** * @brief Panel IO configuration structure, for SPI interface diff --git a/components/esp_lcd/interface/esp_lcd_panel_io_interface.h b/components/esp_lcd/interface/esp_lcd_panel_io_interface.h index 9f2226587e..88bf9db0d4 100644 --- a/components/esp_lcd/interface/esp_lcd_panel_io_interface.h +++ b/components/esp_lcd/interface/esp_lcd_panel_io_interface.h @@ -7,6 +7,7 @@ #include #include "esp_err.h" +#include "esp_lcd_panel_io.h" #ifdef __cplusplus extern "C" { @@ -73,6 +74,18 @@ struct esp_lcd_panel_io_t { * - ESP_OK on success */ esp_err_t (*del)(esp_lcd_panel_io_t *io); + + /** + * @brief Register LCD panel IO callbacks + * + * @param[in] io LCD panel IO handle, which is created by factory API like `esp_lcd_new_panel_io_spi()` + * @param[in] cbs structure with all LCD panel IO callbacks + * @param[in] user_ctx User private data, passed directly to callback's user_ctx + * @return + * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_OK on success + */ + esp_err_t (*register_event_callbacks)(esp_lcd_panel_io_t *io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx); }; #ifdef __cplusplus diff --git a/components/esp_lcd/src/esp_lcd_panel_io.c b/components/esp_lcd/src/esp_lcd_panel_io.c index cd0d5fd162..917ca6d4cf 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io.c +++ b/components/esp_lcd/src/esp_lcd_panel_io.c @@ -34,3 +34,10 @@ esp_err_t esp_lcd_panel_io_del(esp_lcd_panel_io_handle_t io) ESP_RETURN_ON_FALSE(io, ESP_ERR_INVALID_ARG, TAG, "invalid panel io handle"); return io->del(io); } + +esp_err_t esp_lcd_panel_io_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx) +{ + ESP_RETURN_ON_FALSE(io, ESP_ERR_INVALID_ARG, TAG, "invalid panel io handle"); + ESP_RETURN_ON_FALSE(cbs, ESP_ERR_INVALID_ARG, TAG, "invalid callbacks structure"); + return io->register_event_callbacks(io, cbs, user_ctx); +} diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i2c.c b/components/esp_lcd/src/esp_lcd_panel_io_i2c.c index 49469197a6..c8911b7e0b 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i2c.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i2c.c @@ -29,6 +29,7 @@ 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); +static esp_err_t panel_io_i2c_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx); typedef struct { esp_lcd_panel_io_t base; // Base class of generic lcd panel io @@ -69,6 +70,7 @@ esp_err_t esp_lcd_new_panel_io_i2c(esp_lcd_i2c_bus_handle_t bus, const esp_lcd_p 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; + i2c_panel_io->base.register_event_callbacks = panel_io_i2c_register_event_callbacks; *ret_io = &(i2c_panel_io->base); ESP_LOGD(TAG, "new i2c lcd panel io @%p", i2c_panel_io); @@ -87,6 +89,20 @@ static esp_err_t panel_io_i2c_del(esp_lcd_panel_io_t *io) return ret; } +static esp_err_t panel_io_i2c_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx) +{ + lcd_panel_io_i2c_t *i2c_panel_io = __containerof(io, lcd_panel_io_i2c_t, base); + + if(i2c_panel_io->on_color_trans_done != NULL) { + ESP_LOGW(TAG, "Callback on_color_trans_done was already set and now it was owerwritten!"); + } + + i2c_panel_io->on_color_trans_done = cbs->on_color_trans_done; + i2c_panel_io->user_ctx = user_ctx; + + return ESP_OK; +} + 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; diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c index 22b20499c4..24f0c57397 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c @@ -58,6 +58,7 @@ static esp_err_t i2s_lcd_configure_gpio(esp_lcd_i80_bus_handle_t bus, const esp_ static void i2s_lcd_trigger_quick_trans_done_event(esp_lcd_i80_bus_handle_t bus); static void lcd_i80_switch_devices(lcd_panel_io_i80_t *cur_device, lcd_panel_io_i80_t *next_device); static void lcd_default_isr_handler(void *args); +static esp_err_t panel_io_i80_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx); struct esp_lcd_i80_bus_t { int bus_id; // Bus ID, index from 0 @@ -295,6 +296,7 @@ esp_err_t esp_lcd_new_panel_io_i80(esp_lcd_i80_bus_handle_t bus, const esp_lcd_p i80_device->base.del = panel_io_i80_del; i80_device->base.tx_param = panel_io_i80_tx_param; i80_device->base.tx_color = panel_io_i80_tx_color; + i80_device->base.register_event_callbacks = panel_io_i80_register_event_callbacks; if (io_config->cs_gpio_num >= 0) { // CS signal is controlled by software gpio_set_level(io_config->cs_gpio_num, !io_config->flags.cs_active_high); // de-assert by default @@ -342,6 +344,20 @@ static esp_err_t panel_io_i80_del(esp_lcd_panel_io_t *io) return ESP_OK; } +static esp_err_t panel_io_i80_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx) +{ + lcd_panel_io_i80_t *i80_device = __containerof(io, lcd_panel_io_i80_t, base); + + if(i80_device->on_color_trans_done != NULL) { + ESP_LOGW(TAG, "Callback on_color_trans_done was already set and now it was owerwritten!"); + } + + i80_device->on_color_trans_done = cbs->on_color_trans_done; + i80_device->user_ctx = user_ctx; + + return ESP_OK; +} + static void i2s_lcd_prepare_cmd_buffer(lcd_i80_trans_descriptor_t *trans_desc, const void *cmd) { lcd_panel_io_i80_t *i80_device = trans_desc->i80_device; diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i80.c b/components/esp_lcd/src/esp_lcd_panel_io_i80.c index f5e42e0836..eee30dd27a 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i80.c @@ -56,6 +56,7 @@ static esp_err_t lcd_i80_bus_configure_gpio(esp_lcd_i80_bus_handle_t bus, const static void lcd_i80_switch_devices(lcd_panel_io_i80_t *cur_device, lcd_panel_io_i80_t *next_device); static void lcd_start_transaction(esp_lcd_i80_bus_t *bus, lcd_i80_trans_descriptor_t *trans_desc); static void lcd_default_isr_handler(void *args); +static esp_err_t panel_io_i80_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx); struct esp_lcd_i80_bus_t { int bus_id; // Bus ID, index from 0 @@ -285,6 +286,7 @@ esp_err_t esp_lcd_new_panel_io_i80(esp_lcd_i80_bus_handle_t bus, const esp_lcd_p i80_device->base.del = panel_io_i80_del; i80_device->base.tx_param = panel_io_i80_tx_param; i80_device->base.tx_color = panel_io_i80_tx_color; + i80_device->base.register_event_callbacks = panel_io_i80_register_event_callbacks; // we only configure the CS GPIO as output, don't connect to the peripheral signal at the moment // we will connect the CS GPIO to peripheral signal when switching devices in lcd_i80_switch_devices() if (io_config->cs_gpio_num >= 0) { @@ -333,6 +335,20 @@ static esp_err_t panel_io_i80_del(esp_lcd_panel_io_t *io) return ESP_OK; } +static esp_err_t panel_io_i80_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx) +{ + lcd_panel_io_i80_t *i80_device = __containerof(io, lcd_panel_io_i80_t, base); + + if(i80_device->on_color_trans_done != NULL) { + ESP_LOGW(TAG, "Callback on_color_trans_done was already set and now it was owerwritten!"); + } + + i80_device->on_color_trans_done = cbs->on_color_trans_done; + i80_device->user_ctx = user_ctx; + + return ESP_OK; +} + static void i80_lcd_prepare_cmd_buffer(esp_lcd_i80_bus_t *bus, lcd_panel_io_i80_t *i80_device, void *lcd_cmd) { uint8_t *from = (uint8_t *)lcd_cmd; 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 d63d9e1b6d..32f633fa3e 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_spi.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_spi.c @@ -32,6 +32,7 @@ static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons 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); +static esp_err_t panel_io_spi_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx); typedef struct { spi_transaction_t base; @@ -79,7 +80,7 @@ esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_p .spics_io_num = io_config->cs_gpio_num, .queue_size = io_config->trans_queue_depth, .pre_cb = lcd_spi_pre_trans_cb, // pre-transaction callback, mainly control DC gpio level - .post_cb = io_config->on_color_trans_done ? lcd_spi_post_trans_color_cb : NULL, // post-transaction, where we invoke user registered "on_color_trans_done()" + .post_cb = lcd_spi_post_trans_color_cb, // post-transaction, where we invoke user registered "on_color_trans_done()" }; ret = spi_bus_add_device((spi_host_device_t)bus, &devcfg, &spi_panel_io->spi_dev); ESP_GOTO_ON_ERROR(ret, err, TAG, "adding spi device to bus failed"); @@ -105,6 +106,7 @@ esp_err_t esp_lcd_new_panel_io_spi(esp_lcd_spi_bus_handle_t bus, const esp_lcd_p spi_panel_io->base.tx_param = panel_io_spi_tx_param; spi_panel_io->base.tx_color = panel_io_spi_tx_color; spi_panel_io->base.del = panel_io_spi_del; + spi_panel_io->base.register_event_callbacks = panel_io_spi_register_event_callbacks; *ret_io = &(spi_panel_io->base); ESP_LOGD(TAG, "new spi lcd panel io @%p", spi_panel_io); @@ -144,6 +146,20 @@ err: return ret; } +static esp_err_t panel_io_spi_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx) +{ + esp_lcd_panel_io_spi_t *spi_panel_io = __containerof(io, esp_lcd_panel_io_spi_t, base); + + if(spi_panel_io->on_color_trans_done != NULL) { + ESP_LOGW(TAG, "Callback on_color_trans_done was already set and now it was owerwritten!"); + } + + spi_panel_io->on_color_trans_done = cbs->on_color_trans_done; + spi_panel_io->user_ctx = user_ctx; + + return ESP_OK; +} + static void spi_lcd_prepare_cmd_buffer(esp_lcd_panel_io_spi_t *panel_io, const void *cmd) { uint8_t *from = (uint8_t *)cmd;