From edb30f2517312801d74deb785ada84a962b9bcc2 Mon Sep 17 00:00:00 2001 From: Vilem Zavodny Date: Tue, 11 Feb 2025 15:01:39 +0100 Subject: [PATCH] bsp(esp32_p4_function_ev_board): Add deinit/remove/delete functions for display and touch. --- .../esp32_p4_function_ev_board.c | 117 ++++++++++++++---- .../idf_component.yml | 2 +- .../include/bsp/display.h | 21 +++- .../include/bsp/esp32_p4_function_ev_board.h | 15 ++- .../include/bsp/touch.h | 11 +- 5 files changed, 132 insertions(+), 34 deletions(-) diff --git a/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c b/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c index 3dd64ded0..26856c0bf 100644 --- a/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c +++ b/bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c @@ -50,6 +50,10 @@ static i2c_master_bus_handle_t i2c_handle = NULL; // I2C Handle static i2s_chan_handle_t i2s_tx_chan = NULL; static i2s_chan_handle_t i2s_rx_chan = NULL; static const audio_codec_data_if_t *i2s_data_if = NULL; /* Codec data interface */ +static bsp_lcd_handles_t disp_handles; +static esp_ldo_channel_handle_t disp_phy_pwr_chan = NULL; +static esp_lcd_touch_handle_t tp = NULL; +static esp_lcd_panel_io_handle_t tp_io_handle = NULL; /* Can be used for `i2s_std_gpio_config_t` and/or `i2s_std_config_t` initialization */ #define BSP_I2S_GPIO_CFG \ @@ -96,8 +100,10 @@ esp_err_t bsp_i2c_init(void) esp_err_t bsp_i2c_deinit(void) { - BSP_ERROR_CHECK_RETURN_ERR(i2c_del_master_bus(i2c_handle)); - i2c_initialized = false; + if (i2c_initialized && i2c_handle) { + BSP_ERROR_CHECK_RETURN_ERR(i2c_del_master_bus(i2c_handle)); + i2c_initialized = false; + } return ESP_OK; } @@ -348,6 +354,18 @@ esp_err_t bsp_display_brightness_init(void) return ESP_OK; } +esp_err_t bsp_display_brightness_deinit(void) +{ + const ledc_timer_config_t LCD_backlight_timer = { + .speed_mode = LEDC_LOW_SPEED_MODE, + .timer_num = 1, + .deconfigure = 1 + }; + BSP_ERROR_CHECK_RETURN_ERR(ledc_timer_pause(LEDC_LOW_SPEED_MODE, 1)); + BSP_ERROR_CHECK_RETURN_ERR(ledc_timer_config(&LCD_backlight_timer)); + return ESP_OK; +} + esp_err_t bsp_display_brightness_set(int brightness_percent) { if (brightness_percent > 100) { @@ -378,12 +396,11 @@ static esp_err_t bsp_enable_dsi_phy_power(void) { #if BSP_MIPI_DSI_PHY_PWR_LDO_CHAN > 0 // Turn on the power for MIPI DSI PHY, so it can go from "No Power" state to "Shutdown" state - static esp_ldo_channel_handle_t phy_pwr_chan = NULL; esp_ldo_channel_config_t ldo_cfg = { .chan_id = BSP_MIPI_DSI_PHY_PWR_LDO_CHAN, .voltage_mv = BSP_MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV, }; - ESP_RETURN_ON_ERROR(esp_ldo_acquire_channel(&ldo_cfg, &phy_pwr_chan), TAG, "Acquire LDO channel for DPHY failed"); + ESP_RETURN_ON_ERROR(esp_ldo_acquire_channel(&ldo_cfg, &disp_phy_pwr_chan), TAG, "Acquire LDO channel for DPHY failed"); ESP_LOGI(TAG, "MIPI DSI PHY Powered on"); #endif // BSP_MIPI_DSI_PHY_PWR_LDO_CHAN > 0 @@ -584,33 +601,60 @@ esp_err_t bsp_display_new_with_handles(const bsp_display_config_t *config, bsp_l /* Return all handles */ ret_handles->io = io; + disp_handles.io = io; +#if CONFIG_BSP_LCD_TYPE_HDMI + ret_handles->io_cec = io_cec_dsi; + disp_handles.io_cec = io_cec_dsi; + ret_handles->io_avi = io_avi; + disp_handles.io_avi = io_avi; +#endif ret_handles->mipi_dsi_bus = mipi_dsi_bus; + disp_handles.mipi_dsi_bus = mipi_dsi_bus; ret_handles->panel = disp_panel; + disp_handles.panel = disp_panel; ret_handles->control = NULL; + disp_handles.control = NULL; ESP_LOGI(TAG, "Display initialized"); return ret; err: - if (disp_panel) { - esp_lcd_panel_del(disp_panel); + bsp_display_delete(); + return ret; +} + +void bsp_display_delete(void) +{ + if (disp_handles.panel) { + esp_lcd_panel_del(disp_handles.panel); + disp_handles.panel = NULL; } - if (io) { - esp_lcd_panel_io_del(io); + if (disp_handles.io) { + esp_lcd_panel_io_del(disp_handles.io); + disp_handles.io = NULL; } #if CONFIG_BSP_LCD_TYPE_HDMI - if (io_cec_dsi) { - esp_lcd_panel_io_del(io_cec_dsi); + if (disp_handles.io_cec) { + esp_lcd_panel_io_del(disp_handles.io_cec); + disp_handles.io_cec = NULL; } - if (io_avi) { - esp_lcd_panel_io_del(io_avi); + if (disp_handles.io_avi) { + esp_lcd_panel_io_del(disp_handles.io_avi); + disp_handles.io_avi = NULL; } #endif - if (mipi_dsi_bus) { - esp_lcd_del_dsi_bus(mipi_dsi_bus); + if (disp_handles.mipi_dsi_bus) { + esp_lcd_del_dsi_bus(disp_handles.mipi_dsi_bus); + disp_handles.mipi_dsi_bus = NULL; } - return ret; + + if (disp_phy_pwr_chan) { + esp_ldo_release_channel(disp_phy_pwr_chan); + disp_phy_pwr_chan = NULL; + } + + esp_err_t err = bsp_display_brightness_deinit(); } #if !CONFIG_BSP_LCD_TYPE_HDMI @@ -640,20 +684,29 @@ esp_err_t bsp_touch_new(const bsp_touch_config_t *config, esp_lcd_touch_handle_t #endif }, }; - esp_lcd_panel_io_handle_t tp_io_handle = NULL; esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG(); tp_io_config.scl_speed_hz = CONFIG_BSP_I2C_CLK_SPEED_HZ; ESP_RETURN_ON_ERROR(esp_lcd_new_panel_io_i2c(i2c_handle, &tp_io_config, &tp_io_handle), TAG, ""); return esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, ret_touch); } + +void bsp_touch_delete(void) +{ + if (tp) { + esp_lcd_touch_del(tp); + } + if (tp_io_handle) { + esp_lcd_panel_io_del(tp_io_handle); + tp_io_handle = NULL; + } +} #endif //!CONFIG_BSP_LCD_TYPE_HDMI #if (BSP_CONFIG_NO_GRAPHIC_LIB == 0) static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg) { assert(cfg != NULL); - bsp_lcd_handles_t lcd_panels; - BSP_ERROR_CHECK_RETURN_NULL(bsp_display_new_with_handles(&cfg->hw_cfg, &lcd_panels)); + BSP_ERROR_CHECK_RETURN_NULL(bsp_display_new_with_handles(&cfg->hw_cfg, &disp_handles)); uint32_t display_hres = 0; uint32_t display_vres = 0; @@ -692,9 +745,9 @@ static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg) /* Add LCD screen */ ESP_LOGD(TAG, "Add LCD screen"); const lvgl_port_display_cfg_t disp_cfg = { - .io_handle = lcd_panels.io, - .panel_handle = lcd_panels.panel, - .control_handle = lcd_panels.control, + .io_handle = disp_handles.io, + .panel_handle = disp_handles.panel, + .control_handle = disp_handles.control, .buffer_size = cfg->buffer_size, .double_buffer = cfg->double_buffer, .hres = display_hres, @@ -748,7 +801,6 @@ static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg) #if !CONFIG_BSP_LCD_TYPE_HDMI static lv_indev_t *bsp_display_indev_init(lv_display_t *disp) { - esp_lcd_touch_handle_t tp; BSP_ERROR_CHECK_RETURN_NULL(bsp_touch_new(NULL, &tp)); assert(tp); @@ -816,6 +868,27 @@ lv_display_t *bsp_display_start_with_config(const bsp_display_cfg_t *cfg) return disp; } +void bsp_display_stop(lv_display_t *display) +{ + /* Deinit LVGL */ +#if !CONFIG_BSP_LCD_TYPE_HDMI + lvgl_port_remove_touch(disp_indev); +#endif + lvgl_port_remove_disp(display); + lvgl_port_deinit(); + +#if !CONFIG_BSP_LCD_TYPE_HDMI + /* Deinit touch */ + bsp_touch_delete(); +#endif + + /* Deinit display */ + bsp_display_delete(); + + /* Deinit I2C if initialized */ + bsp_i2c_deinit(); +} + lv_indev_t *bsp_display_get_input_dev(void) { return disp_indev; diff --git a/bsp/esp32_p4_function_ev_board/idf_component.yml b/bsp/esp32_p4_function_ev_board/idf_component.yml index 323ab7fc9..9d09bd18c 100644 --- a/bsp/esp32_p4_function_ev_board/idf_component.yml +++ b/bsp/esp32_p4_function_ev_board/idf_component.yml @@ -1,4 +1,4 @@ -version: "4.2.1" +version: "4.2.2" description: Board Support Package (BSP) for ESP32-P4 Function EV Board (preview) url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_p4_function_ev_board diff --git a/bsp/esp32_p4_function_ev_board/include/bsp/display.h b/bsp/esp32_p4_function_ev_board/include/bsp/display.h index 8d0d1b9be..9b09c612c 100644 --- a/bsp/esp32_p4_function_ev_board/include/bsp/display.h +++ b/bsp/esp32_p4_function_ev_board/include/bsp/display.h @@ -88,6 +88,10 @@ typedef struct { typedef struct { esp_lcd_dsi_bus_handle_t mipi_dsi_bus; /*!< MIPI DSI bus handle */ esp_lcd_panel_io_handle_t io; /*!< ESP LCD IO handle */ +#if CONFIG_BSP_LCD_TYPE_HDMI + esp_lcd_panel_io_handle_t io_cec; /*!< ESP LCD IO (HDMI CEC) handle */ + esp_lcd_panel_io_handle_t io_avi; /*!< ESP LCD IO (HDMI AVI) handle */ +#endif esp_lcd_panel_handle_t panel; /*!< ESP LCD panel (color) handle */ esp_lcd_panel_handle_t control; /*!< ESP LCD panel (control) handle */ } bsp_lcd_handles_t; @@ -125,13 +129,10 @@ esp_err_t bsp_display_new(const bsp_display_config_t *config, esp_lcd_panel_hand * The display's backlight is not turned on either. You can use bsp_display_backlight_on/off(), * bsp_display_brightness_set() (on supported boards) or implement your own backlight control. * - * If you want to free resources allocated by this function, you can use esp_lcd API, ie.: + * If you want to free resources allocated by this function, you can use API: * * \code{.c} - * esp_lcd_panel_del(panel); - * esp_lcd_panel_del(control); - * esp_lcd_panel_io_del(io); - * esp_lcd_del_dsi_bus(mipi_dsi_bus); + * bsp_display_delete(); * \endcode * * @param[in] config display configuration @@ -142,6 +143,11 @@ esp_err_t bsp_display_new(const bsp_display_config_t *config, esp_lcd_panel_hand */ esp_err_t bsp_display_new_with_handles(const bsp_display_config_t *config, bsp_lcd_handles_t *ret_handles); +/** + * @brief Delete display panel + */ +void bsp_display_delete(void); + /** * @brief Initialize display's brightness * @@ -153,6 +159,11 @@ esp_err_t bsp_display_new_with_handles(const bsp_display_config_t *config, bsp_l */ esp_err_t bsp_display_brightness_init(void); +/** + * @brief Deinitialize display's brightness + */ +esp_err_t bsp_display_brightness_deinit(void); + /** * @brief Set display's brightness * diff --git a/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h b/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h index 5829a5658..bcb11bc9b 100644 --- a/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h +++ b/bsp/esp32_p4_function_ev_board/include/bsp/esp32_p4_function_ev_board.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -284,7 +284,7 @@ typedef struct { /** * @brief Initialize display * - * This function initializes SPI, display controller and starts LVGL handling task. + * This function initializes MIPI-DSI, display controller and starts LVGL handling task. * LCD backlight must be enabled separately by calling bsp_display_brightness_set() * * @return Pointer to LVGL display or NULL when error occured @@ -294,7 +294,7 @@ lv_display_t *bsp_display_start(void); /** * @brief Initialize display * - * This function initializes SPI, display controller and starts LVGL handling task. + * This function initializes MIPI-DSI, display controller and starts LVGL handling task. * LCD backlight must be enabled separately by calling bsp_display_brightness_set() * * @param cfg display configuration @@ -303,6 +303,15 @@ lv_display_t *bsp_display_start(void); */ lv_display_t *bsp_display_start_with_config(const bsp_display_cfg_t *cfg); +/** + * @brief Deinitialize display + * + * This function deinitializes MIPI-DSI, display controller and stops LVGL. + * + * @param @param[in] disp Pointer to LVGL display + */ +void bsp_display_stop(lv_display_t *display); + /** * @brief Get pointer to input device (touch, buttons, ...) * diff --git a/bsp/esp32_p4_function_ev_board/include/bsp/touch.h b/bsp/esp32_p4_function_ev_board/include/bsp/touch.h index 095e8ce1d..0257c82d2 100644 --- a/bsp/esp32_p4_function_ev_board/include/bsp/touch.h +++ b/bsp/esp32_p4_function_ev_board/include/bsp/touch.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,10 +32,10 @@ typedef struct { /** * @brief Create new touchscreen * - * If you want to free resources allocated by this function, you can use esp_lcd_touch API, ie.: + * If you want to free resources allocated by this function, you can use API: * * \code{.c} - * esp_lcd_touch_del(tp); + * bsp_touch_delete(); * \endcode * * @param[in] config touch configuration @@ -46,6 +46,11 @@ typedef struct { */ esp_err_t bsp_touch_new(const bsp_touch_config_t *config, esp_lcd_touch_handle_t *ret_touch); +/** + * @brief Deinitialize touch + */ +void bsp_touch_delete(void); + #ifdef __cplusplus } #endif