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 24f0c57397..8089481257 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c @@ -36,6 +36,7 @@ #include "hal/dma_types.h" #include "hal/gpio_hal.h" #include "driver/gpio.h" +#include "clk_tree.h" #include "esp_private/periph_ctrl.h" #include "esp_private/i2s_platform.h" #include "soc/lcd_periph.h" @@ -348,7 +349,7 @@ static esp_err_t panel_io_i80_register_event_callbacks(esp_lcd_panel_io_handle_t { lcd_panel_io_i80_t *i80_device = __containerof(io, lcd_panel_io_i80_t, base); - if(i80_device->on_color_trans_done != NULL) { + if (i80_device->on_color_trans_done != NULL) { ESP_LOGW(TAG, "Callback on_color_trans_done was already set and now it was owerwritten!"); } @@ -605,23 +606,22 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons static esp_err_t i2s_lcd_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_clock_source_t src) { - esp_err_t ret = ESP_OK; - switch (src) { - case LCD_CLK_SRC_PLL160M: - bus->resolution_hz = 160000000 / LCD_PERIPH_CLOCK_PRE_SCALE; - i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_SRC_PLL_160M); -#if CONFIG_PM_ENABLE - ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i2s_controller_lcd", &bus->pm_lock); - ESP_RETURN_ON_ERROR(ret, TAG, "create ESP_PM_APB_FREQ_MAX lock failed"); - ESP_LOGD(TAG, "installed ESP_PM_APB_FREQ_MAX lock"); -#endif - break; - default: - ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "unsupported clock source: %d", src); - break; - } + // get clock source frequency + uint32_t src_clk_hz = 0; + ESP_RETURN_ON_ERROR(clk_tree_src_get_freq_hz((soc_module_clk_t)src, CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_hz), + TAG, "get clock source frequency failed"); + + i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_SRC_PLL_160M); i2s_ll_set_raw_mclk_div(bus->hal.dev, LCD_PERIPH_CLOCK_PRE_SCALE, 1, 0); - return ret; + // save the resolution of the i80 bus + bus->resolution_hz = src_clk_hz / LCD_PERIPH_CLOCK_PRE_SCALE; + + // create pm lock based on different clock source + // clock sources like PLL and XTAL will be turned off in light sleep +#if CONFIG_PM_ENABLE + ESP_RETURN_ON_ERROR(esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "i80_bus_lcd", &bus->pm_lock), TAG, "create pm lock failed"); +#endif + return ESP_OK; } static esp_err_t i2s_lcd_init_dma_link(esp_lcd_i80_bus_handle_t bus) 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 eee30dd27a..0b5e00f8dd 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i80.c @@ -25,7 +25,7 @@ #include "esp_lcd_panel_io.h" #include "esp_rom_gpio.h" #include "soc/soc_caps.h" -#include "esp_private/esp_clk.h" +#include "clk_tree.h" #include "esp_memory_utils.h" #include "hal/dma_types.h" #include "hal/gpio_hal.h" @@ -339,8 +339,8 @@ static esp_err_t panel_io_i80_register_event_callbacks(esp_lcd_panel_io_handle_t { 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!"); + if (i80_device->on_color_trans_done != NULL) { + ESP_LOGW(TAG, "Callback on_color_trans_done was already set and now it was overwritten!"); } i80_device->on_color_trans_done = cbs->on_color_trans_done; @@ -486,27 +486,23 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_clock_source_t clk_src) { - esp_err_t ret = ESP_OK; + // get clock source frequency + uint32_t src_clk_hz = 0; + ESP_RETURN_ON_ERROR(clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_hz), + TAG, "get clock source frequency failed"); + // force to use integer division, as fractional division might lead to clock jitter lcd_ll_select_clk_src(bus->hal.dev, clk_src); lcd_ll_set_group_clock_coeff(bus->hal.dev, LCD_PERIPH_CLOCK_PRE_SCALE, 0, 0); - switch (clk_src) { - case LCD_CLK_SRC_PLL160M: - bus->resolution_hz = 160000000 / LCD_PERIPH_CLOCK_PRE_SCALE; + + // save the resolution of the i80 bus + bus->resolution_hz = src_clk_hz / LCD_PERIPH_CLOCK_PRE_SCALE; + // create pm lock based on different clock source + // clock sources like PLL and XTAL will be turned off in light sleep #if CONFIG_PM_ENABLE - ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i80_bus_lcd", &bus->pm_lock); - ESP_RETURN_ON_ERROR(ret, TAG, "create ESP_PM_APB_FREQ_MAX lock failed"); - ESP_LOGD(TAG, "installed ESP_PM_APB_FREQ_MAX lock"); + ESP_RETURN_ON_ERROR(esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "i80_bus_lcd", &bus->pm_lock), TAG, "create pm lock failed"); #endif - break; - case LCD_CLK_SRC_XTAL: - bus->resolution_hz = esp_clk_xtal_freq() / LCD_PERIPH_CLOCK_PRE_SCALE; - break; - default: - ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "unsupported clock source: %d", clk_src); - break; - } - return ret; + return ESP_OK; } static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus) diff --git a/components/esp_lcd/src/esp_lcd_panel_rgb.c b/components/esp_lcd/src/esp_lcd_panel_rgb.c index c8dd1d9fea..ae61c4f0cc 100644 --- a/components/esp_lcd/src/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/src/esp_lcd_panel_rgb.c @@ -26,7 +26,7 @@ #include "esp_lcd_panel_ops.h" #include "esp_rom_gpio.h" #include "soc/soc_caps.h" -#include "esp_private/esp_clk.h" +#include "clk_tree.h" #include "hal/dma_types.h" #include "hal/gpio_hal.h" #include "esp_private/gdma.h" @@ -114,7 +114,7 @@ struct esp_rgb_panel_t { int y_gap; // Extra gap in y coordinate, it's used when calculate the flush window portMUX_TYPE spinlock; // to protect panel specific resource from concurrent access (e.g. between task and ISR) int lcd_clk_flags; // LCD clock calculation flags - int rotate_mask; // panel rotate_mask mask, Or'ed of `panel_rotate_mask_t` + int rotate_mask; // panel rotate_mask mask, Or'ed of `panel_rotate_mask_t` struct { uint32_t disp_en_level: 1; // The level which can turn on the screen by `disp_gpio_num` uint32_t stream_mode: 1; // If set, the LCD transfers data continuously, otherwise, it stops refreshing the LCD when transaction done @@ -919,33 +919,23 @@ static esp_err_t lcd_rgb_panel_configure_gpio(esp_rgb_panel_t *panel, const esp_ static esp_err_t lcd_rgb_panel_select_clock_src(esp_rgb_panel_t *panel, lcd_clock_source_t clk_src) { - esp_err_t ret = ESP_OK; - switch (clk_src) { - case LCD_CLK_SRC_PLL240M: - panel->src_clk_hz = 240000000; - break; - case LCD_CLK_SRC_PLL160M: - panel->src_clk_hz = 160000000; - break; - case LCD_CLK_SRC_XTAL: - panel->src_clk_hz = esp_clk_xtal_freq(); - break; - default: - ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "unsupported clock source: %d", clk_src); - break; - } + // get clock source frequency + uint32_t src_clk_hz = 0; + ESP_RETURN_ON_ERROR(clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_hz), + TAG, "get clock source frequency failed"); + panel->src_clk_hz = src_clk_hz; lcd_ll_select_clk_src(panel->hal.dev, clk_src); - if (clk_src == LCD_CLK_SRC_PLL240M || clk_src == LCD_CLK_SRC_PLL160M) { + // create pm lock based on different clock source + // clock sources like PLL and XTAL will be turned off in light sleep #if CONFIG_PM_ENABLE - ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "rgb_panel", &panel->pm_lock); - ESP_RETURN_ON_ERROR(ret, TAG, "create ESP_PM_APB_FREQ_MAX lock failed"); - // hold the lock during the whole lifecycle of RGB panel - esp_pm_lock_acquire(panel->pm_lock); - ESP_LOGD(TAG, "installed ESP_PM_APB_FREQ_MAX lock and hold the lock during the whole panel lifecycle"); + ESP_RETURN_ON_ERROR(esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "rgb_panel", &panel->pm_lock), TAG, "create pm lock failed"); + // hold the lock during the whole lifecycle of RGB panel + esp_pm_lock_acquire(panel->pm_lock); + ESP_LOGD(TAG, "installed pm lock and hold the lock during the whole panel lifecycle"); #endif - } - return ret; + + return ESP_OK; } static IRAM_ATTR bool lcd_rgb_panel_fill_bounce_buffer(esp_rgb_panel_t *panel, uint8_t *buffer) diff --git a/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults index b308cb2ddd..ccc43c6fdf 100644 --- a/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults +++ b/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults @@ -1,2 +1,5 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +# CONFIG_ESP_TASK_WDT_INIT is not set CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults index b308cb2ddd..ccc43c6fdf 100644 --- a/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults +++ b/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults @@ -1,2 +1,5 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +# CONFIG_ESP_TASK_WDT_INIT is not set CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults index b308cb2ddd..ccc43c6fdf 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults +++ b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults @@ -1,2 +1,5 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +# CONFIG_ESP_TASK_WDT_INIT is not set CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults index b308cb2ddd..ccc43c6fdf 100644 --- a/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults +++ b/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults @@ -1,2 +1,5 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +# CONFIG_ESP_TASK_WDT_INIT is not set CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT=n diff --git a/components/soc/esp32/include/soc/clk_tree_defs.h b/components/soc/esp32/include/soc/clk_tree_defs.h index c5ee852e14..83ef092220 100644 --- a/components/soc/esp32/include/soc/clk_tree_defs.h +++ b/components/soc/esp32/include/soc/clk_tree_defs.h @@ -165,16 +165,14 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of LCD */ -#define SOC_LCD_CLKS {SOC_MOD_CLK_PLL_D2, SOC_MOD_CLK_APLL, SOC_MOD_CLK_XTAL} +#define SOC_LCD_CLKS {SOC_MOD_CLK_PLL_F160M} /** * @brief Type of LCD clock source */ typedef enum { - LCD_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_D2, /*!< Select PLL_D2 (default to 160MHz) as the source clock */ - LCD_CLK_SRC_APLL = SOC_MOD_CLK_APLL, /*!< Select APLL as the source clock */ - LCD_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ - LCD_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_D2, /*!< Select PLL_D2 (default to 160MHz) as the default choice */ + LCD_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_160M as the source clock */ + LCD_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_160M as the default choice */ } soc_periph_lcd_clk_src_t; //////////////////////////////////////////////////RMT/////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32s2/include/soc/clk_tree_defs.h b/components/soc/esp32s2/include/soc/clk_tree_defs.h index 0bcae629a9..5eb67a1921 100644 --- a/components/soc/esp32s2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32s2/include/soc/clk_tree_defs.h @@ -165,15 +165,13 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of LCD */ -#define SOC_LCD_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_APLL, SOC_MOD_CLK_XTAL} +#define SOC_LCD_CLKS {SOC_MOD_CLK_PLL_F160M} /** * @brief Type of LCD clock source */ typedef enum { LCD_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ - LCD_CLK_SRC_APLL = SOC_MOD_CLK_APLL, /*!< Select APLL as the source clock */ - LCD_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ LCD_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default choice */ } soc_periph_lcd_clk_src_t;