feat(dsi): split the dphy config clock and pll reference clock

this is a breaking change in the esp32p4 ver3.0 silicon.
This commit is contained in:
morris
2025-09-08 18:57:46 +08:00
parent b7fc7acb23
commit eedbd9f8e3
24 changed files with 469 additions and 235 deletions

View File

@@ -1,10 +1,4 @@
menu "ESP-Driver:LCD Controller Configurations"
config LCD_ENABLE_DEBUG_LOG
bool "Enable debug log"
default n
help
whether to enable the debug log message for LCD driver.
Note that, this option only controls the LCD driver log, won't affect other drivers.
if SOC_LCD_RGB_SUPPORTED
config LCD_RGB_ISR_IRAM_SAFE
@@ -28,14 +22,37 @@ menu "ESP-Driver:LCD Controller Configurations"
endif # SOC_LCD_RGB_SUPPORTED
if SOC_MIPI_DSI_SUPPORTED
config LCD_DSI_ISR_IRAM_SAFE
bool "DSI LCD ISR IRAM-Safe"
default n
select DW_GDMA_ISR_IRAM_SAFE # relies on DW_GDMA Full trans done interrupt
config LCD_DSI_ISR_HANDLER_IN_IRAM
bool "Place DSI ISR handler in IRAM to reduce latency"
default y
select LCD_DSI_OBJ_FORCE_INTERNAL
help
Ensure the LCD interrupt is IRAM-Safe by allowing the interrupt handler to be
executable when the cache is disabled (e.g. SPI Flash write).
If you want the LCD driver to keep flushing the screen even when cache ops disabled,
you can enable this option. Note, this will also increase the IRAM usage.
Place DSI ISR handler in IRAM to reduce latency caused by cache miss.
config LCD_DSI_ISR_CACHE_SAFE
bool "Allow DSI ISR to execute when cache is disabled" if !SPI_FLASH_AUTO_SUSPEND
select LCD_DSI_ISR_HANDLER_IN_IRAM
select DW_GDMA_ISR_IRAM_SAFE # relies on DW_GDMA Full trans done interrupt
default n
help
Enable this option to allow the DSI Interrupt Service Routine (ISR)
to execute even when the cache is disabled. This can be useful in scenarios where the cache
might be turned off, but the DSI functionality is still required to operate correctly.
config LCD_DSI_OBJ_FORCE_INTERNAL
bool
default n
help
This will ensure the DSI driver object will always be allocated in internal RAM.
endif # SOC_MIPI_DSI_SUPPORTED
config LCD_ENABLE_DEBUG_LOG
bool "Force enable debug log"
default n
help
If enabled, LCD driver component will:
1. ignore the global logging settings
2. compile all log messages into the binary
3. set the runtime log level to VERBOSE
Please enable this option by caution, as it will increase the binary size.
endmenu

View File

@@ -1,19 +1,12 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/soc_caps.h"
#include "esp_check.h"
#include "esp_lcd_mipi_dsi.h"
#include "esp_clk_tree.h"
#include "esp_private/esp_clk_tree_common.h"
#include "mipi_dsi_priv.h"
static const char *TAG = "lcd.dsi.bus";
#define MIPI_DSI_DEFAULT_TIMEOUT_CLOCK_FREQ_MHZ 10
// TxClkEsc frequency must be configured between 2 and 20 MHz
#define MIPI_DSI_DEFAULT_ESCAPE_CLOCK_FREQ_MHZ 18
@@ -38,25 +31,31 @@ esp_err_t esp_lcd_new_dsi_bus(const esp_lcd_dsi_bus_config_t *bus_config, esp_lc
dsi_bus->bus_id = bus_id;
// Enable the APB clock for accessing the DSI host and bridge registers
DSI_RCC_ATOMIC() {
PERIPH_RCC_ATOMIC() {
mipi_dsi_ll_enable_bus_clock(bus_id, true);
mipi_dsi_ll_reset_register(bus_id);
}
// if the clock source is not assigned, fallback to the default clock source
mipi_dsi_phy_clock_source_t phy_clk_src = bus_config->phy_clk_src;
mipi_dsi_phy_pllref_clock_source_t phy_clk_src = bus_config->phy_clk_src;
if (phy_clk_src == 0) {
phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT;
#if SOC_IS(ESP32P4) && HAL_CONFIG(CHIP_SUPPORT_MIN_REV) < 300
phy_clk_src = MIPI_DSI_PHY_PLLREF_CLK_SRC_DEFAULT_LEGACY;
#else
phy_clk_src = MIPI_DSI_PHY_PLLREF_CLK_SRC_DEFAULT;
#endif
}
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)phy_clk_src, true), err, TAG, "clock source enable failed");
// enable the clock source for DSI PHY
DSI_CLOCK_SRC_ATOMIC() {
// set clock source for DSI PHY
mipi_dsi_ll_set_phy_clock_source(bus_id, phy_clk_src);
PERIPH_RCC_ATOMIC() {
// set the DSI PHY configuration clock
// the configuration clock is used for all modes except the shutdown mode
mipi_dsi_ll_set_phy_config_clock_source(bus_id, MIPI_DSI_PHY_CFG_CLK_SRC_DEFAULT);
mipi_dsi_ll_enable_phy_config_clock(bus_id, true);
// enable the clock for generating the serial clock
mipi_dsi_ll_enable_phy_reference_clock(bus_id, true);
// set the DSI PHY PLL reference clock
mipi_dsi_ll_set_phy_pllref_clock_source(bus_id, phy_clk_src);
mipi_dsi_ll_set_phy_pll_ref_clock_div(bus_id, 1); // no division
mipi_dsi_ll_enable_phy_pllref_clock(bus_id, true);
}
#if CONFIG_PM_ENABLE
@@ -135,12 +134,12 @@ esp_err_t esp_lcd_del_dsi_bus(esp_lcd_dsi_bus_handle_t bus)
ESP_RETURN_ON_FALSE(bus, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
int bus_id = bus->bus_id;
// disable the clock source for DSI PHY
DSI_CLOCK_SRC_ATOMIC() {
mipi_dsi_ll_enable_phy_reference_clock(bus_id, false);
PERIPH_RCC_ATOMIC() {
mipi_dsi_ll_enable_phy_pllref_clock(bus_id, false);
mipi_dsi_ll_enable_phy_config_clock(bus_id, false);
}
// disable the APB clock for accessing the DSI peripheral registers
DSI_RCC_ATOMIC() {
PERIPH_RCC_ATOMIC() {
mipi_dsi_ll_enable_bus_clock(bus_id, false);
}
#if CONFIG_PM_ENABLE
@@ -152,3 +151,11 @@ esp_err_t esp_lcd_del_dsi_bus(esp_lcd_dsi_bus_handle_t bus)
free(bus);
return ESP_OK;
}
#if CONFIG_LCD_ENABLE_DEBUG_LOG
__attribute__((constructor))
static void mipi_dsi_override_default_log_level(void)
{
esp_log_level_set(TAG, ESP_LOG_VERBOSE);
}
#endif

View File

@@ -4,11 +4,6 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "soc/soc_caps.h"
#include "esp_check.h"
#include "esp_lcd_panel_interface.h"
#include "esp_lcd_mipi_dsi.h"
#include "esp_clk_tree.h"
@@ -17,13 +12,8 @@
#include "esp_async_fbcpy.h"
#include "esp_memory_utils.h"
#include "esp_private/dw_gdma.h"
#include "esp_private/esp_clk_tree_common.h"
#include "hal/cache_hal.h"
#include "hal/cache_ll.h"
#include "hal/color_hal.h"
static const char *TAG = "lcd.dsi.dpi";
typedef struct esp_lcd_dpi_panel_t esp_lcd_dpi_panel_t;
static esp_err_t dpi_panel_del(esp_lcd_panel_t *panel);
@@ -77,8 +67,7 @@ static bool async_fbcpy_done_cb(esp_async_fbcpy_handle_t mcp, esp_async_fbcpy_ev
return need_yield;
}
IRAM_ATTR
static bool dma_trans_done_cb(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data)
bool mipi_dsi_dma_trans_done_cb(dw_gdma_channel_handle_t chan, const dw_gdma_trans_done_event_data_t *event_data, void *user_data)
{
bool yield_needed = false;
esp_lcd_dpi_panel_t *dpi_panel = (esp_lcd_dpi_panel_t *)user_data;
@@ -152,7 +141,7 @@ static esp_err_t dpi_panel_create_dma_link(esp_lcd_dpi_panel_t *dpi_panel)
// register DMA ISR callbacks
dw_gdma_event_callbacks_t dsi_dma_cbs = {
.on_full_trans_done = dma_trans_done_cb,
.on_full_trans_done = mipi_dsi_dma_trans_done_cb,
};
ESP_RETURN_ON_ERROR(dw_gdma_channel_register_event_callbacks(dma_chan, &dsi_dma_cbs, dpi_panel), TAG, "register DMA callbacks failed");
@@ -232,20 +221,16 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
dpi_panel->num_fbs = num_fbs;
// allocate frame buffer from PSRAM
uint32_t cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
// DMA doesn't have requirement on the buffer alignment, but the cache does
uint32_t alignment = cache_line_size;
size_t fb_size = panel_config->video_timing.h_size * panel_config->video_timing.v_size * bits_per_pixel / 8;
uint8_t *frame_buffer = NULL;
for (int i = 0; i < num_fbs; i++) {
frame_buffer = heap_caps_aligned_calloc(alignment, 1, fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
uint8_t *frame_buffer = heap_caps_calloc(1, fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
ESP_GOTO_ON_FALSE(frame_buffer, ESP_ERR_NO_MEM, err, TAG, "no memory for frame buffer");
dpi_panel->fbs[i] = frame_buffer;
ESP_LOGD(TAG, "fb[%d] @%p", i, frame_buffer);
// preset the frame buffer with black color
// the frame buffer address alignment is ensured by `heap_caps_aligned_calloc`
// the frame buffer address alignment is ensured by `heap_caps_calloc`
// while the value of the fb_size may not be aligned to the cache line size
// but that's not a problem because the `heap_caps_aligned_calloc` internally allocated a buffer whose size is aligned up to the cache line size
// but that's not a problem because the `heap_caps_calloc` internally allocated a buffer whose size is aligned up to the cache line size
ESP_GOTO_ON_ERROR(esp_cache_msync(frame_buffer, fb_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED),
err, TAG, "cache write back failed");
}
@@ -278,7 +263,7 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
uint32_t dpi_div = mipi_dsi_hal_host_dpi_calculate_divider(hal, dpi_clk_src_freq_hz / 1000 / 1000, panel_config->dpi_clock_freq_mhz);
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)dpi_clk_src, true), err, TAG, "clock source enable failed");
// set the clock source, set the divider, and enable the dpi clock
DSI_CLOCK_SRC_ATOMIC() {
PERIPH_RCC_ATOMIC() {
mipi_dsi_ll_set_dpi_clock_source(bus_id, dpi_clk_src);
mipi_dsi_ll_set_dpi_clock_div(bus_id, dpi_div);
mipi_dsi_ll_enable_dpi_clock(bus_id, true);
@@ -297,7 +282,7 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
ESP_GOTO_ON_ERROR(dpi_panel_create_dma_link(dpi_panel), err, TAG, "initialize DMA link failed");
mipi_dsi_host_ll_dpi_set_vcid(hal->host, panel_config->virtual_channel);
mipi_dsi_hal_host_dpi_set_color_coding(hal, out_color_format, 0);
mipi_dsi_host_ll_dpi_set_color_coding(hal->host, out_color_format, 0);
// these signals define how the DPI interface interacts with the controller
mipi_dsi_host_ll_dpi_set_timing_polarity(hal->host, false, false, false, false, false);
@@ -335,8 +320,9 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
panel_config->video_timing.vsync_front_porch);
mipi_dsi_brg_ll_set_num_pixel_bits(hal->bridge, panel_config->video_timing.h_size * panel_config->video_timing.v_size * bits_per_pixel);
mipi_dsi_brg_ll_set_underrun_discard_count(hal->bridge, panel_config->video_timing.h_size);
// set input color space
mipi_dsi_brg_ll_set_input_color_space(hal->bridge, COLOR_SPACE_TYPE(in_color_format));
// set the in/out color formats in the DSI bridge
mipi_dsi_brg_ll_set_input_color_format(hal->bridge, in_color_format);
mipi_dsi_brg_ll_set_output_color_format(hal->bridge, out_color_format, 0);
// use the DW_GDMA as the flow controller
mipi_dsi_brg_ll_set_flow_controller(hal->bridge, MIPI_DSI_LL_FLOW_CONTROLLER_DMA);
mipi_dsi_brg_ll_set_multi_block_number(hal->bridge, DPI_PANEL_MIN_DMA_NODES_PER_LINK);
@@ -366,7 +352,7 @@ static esp_err_t dpi_panel_del(esp_lcd_panel_t *panel)
int bus_id = bus->bus_id;
mipi_dsi_hal_context_t *hal = &bus->hal;
// disable the DPI clock
DSI_CLOCK_SRC_ATOMIC() {
PERIPH_RCC_ATOMIC() {
mipi_dsi_ll_enable_dpi_clock(bus_id, false);
}
// disable the DSI bridge
@@ -588,6 +574,7 @@ esp_err_t esp_lcd_dpi_panel_set_color_conversion(esp_lcd_panel_handle_t panel, c
if (dpi_panel->in_color_format == COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422)
&& COLOR_SPACE_TYPE(dpi_panel->out_color_format) == LCD_COLOR_SPACE_RGB) {
// YUV422->RGB
mipi_dsi_brg_ll_set_input_color_range(hal->bridge, config->in_color_range);
mipi_dsi_brg_ll_set_yuv_convert_std(hal->bridge, config->spec.yuv.conv_std);
mipi_dsi_brg_ll_set_yuv422_pack_order(hal->bridge, config->spec.yuv.yuv422.in_pack_order);
} else {
@@ -625,7 +612,7 @@ esp_err_t esp_lcd_dpi_panel_register_event_callbacks(esp_lcd_panel_handle_t pane
{
ESP_RETURN_ON_FALSE(panel && cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
esp_lcd_dpi_panel_t *dpi_panel = __containerof(panel, esp_lcd_dpi_panel_t, base);
#if CONFIG_LCD_DSI_ISR_IRAM_SAFE
#if CONFIG_LCD_DSI_ISR_HANDLER_IN_IRAM
if (cbs->on_color_trans_done) {
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_color_trans_done), ESP_ERR_INVALID_ARG, TAG, "on_color_trans_done callback not in IRAM");
}
@@ -635,7 +622,7 @@ esp_err_t esp_lcd_dpi_panel_register_event_callbacks(esp_lcd_panel_handle_t pane
if (user_ctx) {
ESP_RETURN_ON_FALSE(esp_ptr_internal(user_ctx), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM");
}
#endif // CONFIG_LCD_RGB_ISR_IRAM_SAFE
#endif // CONFIG_LCD_DSI_ISR_HANDLER_IN_IRAM
dpi_panel->on_color_trans_done = cbs->on_color_trans_done;
dpi_panel->on_refresh_done = cbs->on_refresh_done;
dpi_panel->user_ctx = user_ctx;

View File

@@ -1,18 +1,12 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/soc_caps.h"
#include "esp_check.h"
#include "esp_lcd_panel_io_interface.h"
#include "esp_lcd_mipi_dsi.h"
#include "mipi_dsi_priv.h"
static const char *TAG = "lcd.dsi.dbi";
typedef struct esp_lcd_dbi_io_t esp_lcd_dbi_io_t;
struct esp_lcd_dbi_io_t {

View File

@@ -23,7 +23,7 @@ extern "C" {
typedef struct {
int bus_id; /*!< Select which DSI controller, index from 0 */
uint8_t num_data_lanes; /*!< Number of data lanes, if set to 0, the driver will fallback to use maximum number of lanes */
mipi_dsi_phy_clock_source_t phy_clk_src; /*!< MIPI DSI PHY clock source */
mipi_dsi_phy_pllref_clock_source_t phy_clk_src; /*!< The clock source for the PHY PLL */
uint32_t lane_bit_rate_mbps; /*!< Lane bit rate in Mbps */
} esp_lcd_dsi_bus_config_t;

View File

@@ -1,29 +1,33 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "hal/mipi_dsi_hal.h"
#include "hal/mipi_dsi_ll.h"
#include <stdint.h>
#include "sdkconfig.h"
#if CONFIG_LCD_ENABLE_DEBUG_LOG
// The local log level must be defined before including esp_log.h
// Set the maximum log level for gptimer driver
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#endif
#include "soc/soc_caps_full.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "esp_attr.h"
#include "esp_heap_caps.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_pm.h"
#include "hal/mipi_dsi_hal.h"
#include "hal/mipi_dsi_ll.h"
#if SOC_PERIPH_CLK_CTRL_SHARED
#define DSI_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define DSI_CLOCK_SRC_ATOMIC()
#endif
#if !SOC_RCC_IS_INDEPENDENT
#define DSI_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define DSI_RCC_ATOMIC()
#endif
#if CONFIG_LCD_DSI_ISR_IRAM_SAFE
#if CONFIG_LCD_DSI_OBJ_FORCE_INTERNAL
#define DSI_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#else
#define DSI_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
@@ -32,6 +36,9 @@
#define DPI_PANEL_MAX_FB_NUM 3 // maximum number of frame buffers that can be maintained by the driver
#define DPI_PANEL_MIN_DMA_NODES_PER_LINK 1 // NOTE: we assume 1 DMA link item can carry the WHOLE image
///!< Logging settings
#define TAG "lcd.dsi"
#ifdef __cplusplus
extern "C" {
#endif

View File

@@ -1,17 +1,28 @@
[mapping:esp_lcd_gdma]
[mapping:esp_lcd_dsi]
archive: libesp_lcd.a
entries:
if LCD_DSI_ISR_HANDLER_IN_IRAM = y:
esp_lcd_panel_dpi: mipi_dsi_dma_trans_done_cb (noflash)
[mapping:esp_lcd_dsi_dma]
archive: libesp_hw_support.a
entries:
if LCD_DSI_ISR_HANDLER_IN_IRAM = y:
# Control dw_gdma function placement granularly
dw_gdma: dw_gdma_link_list_get_item (noflash)
dw_gdma: dw_gdma_lli_set_block_markers (noflash)
dw_gdma: dw_gdma_channel_use_link_list (noflash)
dw_gdma: dw_gdma_channel_enable_ctrl (noflash)
[mapping:esp_lcd_rgb_dma]
archive: libesp_hw_support.a
entries:
if LCD_RGB_ISR_IRAM_SAFE = y:
gdma: gdma_reset (noflash)
gdma: gdma_start (noflash)
gdma_link: gdma_link_get_head_addr (noflash)
if LCD_DSI_ISR_IRAM_SAFE = y:
dw_gdma: dw_gdma_link_list_get_item (noflash)
dw_gdma: dw_gdma_lli_set_block_markers (noflash)
dw_gdma: dw_gdma_channel_use_link_list (noflash)
dw_gdma: dw_gdma_channel_enable_ctrl (noflash)
[mapping:esp_lcd_hal]
[mapping:esp_lcd_rgb_hal]
archive: libhal.a
entries:
if LCD_RGB_ISR_IRAM_SAFE = y:

View File

@@ -0,0 +1,4 @@
# sdkconfig replacement configurations for deprecated options formatted as
# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
CONFIG_LCD_DSI_ISR_IRAM_SAFE CONFIG_LCD_DSI_ISR_CACHE_SAFE

View File

@@ -2,7 +2,7 @@ set(srcs "test_app_main.c"
"test_mipi_dsi_board.c"
"test_mipi_dsi_panel.c")
if(CONFIG_LCD_DSI_ISR_IRAM_SAFE)
if(CONFIG_LCD_DSI_ISR_CACHE_SAFE)
list(APPEND srcs "test_mipi_dsi_iram.c")
endif()

View File

@@ -46,7 +46,6 @@ TEST_CASE("MIPI DSI draw bitmap (EK79007) IRAM Safe", "[mipi_dsi]")
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0,
.num_data_lanes = 2,
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
.lane_bit_rate_mbps = 1000, // 1000 Mbps
};
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));

View File

@@ -28,7 +28,6 @@ TEST_CASE("MIPI DSI Pattern Generator (EK79007)", "[mipi_dsi]")
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0,
.num_data_lanes = 2,
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
.lane_bit_rate_mbps = 1000, // 1000 Mbps
};
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
@@ -103,7 +102,6 @@ TEST_CASE("MIPI DSI draw bitmap (EK79007)", "[mipi_dsi]")
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0,
.num_data_lanes = 2,
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
.lane_bit_rate_mbps = 1000, // 1000 Mbps
};
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
@@ -175,7 +173,6 @@ TEST_CASE("MIPI DSI with multiple frame buffers (EK79007)", "[mipi_dsi]")
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0,
.num_data_lanes = 2,
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
.lane_bit_rate_mbps = 1000, // 1000 Mbps
};
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
@@ -258,7 +255,6 @@ TEST_CASE("MIPI DSI draw YUV422 (EK79007)", "[mipi_dsi]")
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0,
.num_data_lanes = 2,
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
.lane_bit_rate_mbps = 1000, // 1000 Mbps
};
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));

View File

@@ -9,7 +9,7 @@ from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.parametrize(
'config',
[
'iram_safe',
'cache_safe',
'release',
],
indirect=True,

View File

@@ -1,6 +1,8 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_LCD_DSI_ISR_CACHE_SAFE=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
CONFIG_LCD_DSI_ISR_IRAM_SAFE=y
CONFIG_HAL_ASSERTION_SILENT=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y

View File

@@ -300,6 +300,7 @@ static inline void dw_gdma_ll_channel_clear_intr(dw_gdma_dev_t *dev, uint8_t cha
* @param channel Channel number
* @param en True to enable, false to disable
*/
__attribute__((always_inline))
static inline void dw_gdma_ll_channel_enable(dw_gdma_dev_t *dev, uint8_t channel, bool en)
{
if (en) {
@@ -818,6 +819,7 @@ static inline void dw_gdma_ll_channel_set_dst_outstanding_limit(dw_gdma_dev_t *d
* @param channel Channel number
* @param addr Address of the first link list item, it must be aligned 64 bytes
*/
__attribute__((always_inline))
static inline void dw_gdma_ll_channel_set_link_list_head_addr(dw_gdma_dev_t *dev, uint8_t channel, uint32_t addr)
{
dev->ch[channel].llp0.loc0 = addr >> 6;
@@ -846,6 +848,7 @@ static inline intptr_t dw_gdma_ll_channel_get_current_link_list_item_addr(dw_gdm
* @param channel Channel number
* @param port Master port
*/
__attribute__((always_inline))
static inline void dw_gdma_ll_channel_set_link_list_master_port(dw_gdma_dev_t *dev, uint8_t channel, uint32_t port)
{
dev->ch[channel].llp0.lms = port;

View File

@@ -16,6 +16,7 @@
#define MIPI_DSI_LL_GET_BRG(bus_id) (bus_id == 0 ? &MIPI_DSI_BRIDGE : NULL)
#define MIPI_DSI_LL_EVENT_UNDERRUN (1 << 0)
#define MIPI_DSI_LL_EVENT_VSYNC (1 << 1)
#ifdef __cplusplus
extern "C" {
@@ -167,78 +168,6 @@ static inline void mipi_dsi_brg_ll_credit_reset(dsi_brg_dev_t *dev)
dev->raw_buf_credit_ctl.credit_reset = 1;
}
/**
* @brief Set the color coding for the bridge controller
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_coding Color coding value
* @param sub_config Sub configuration
*/
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
static inline void mipi_dsi_brg_ll_set_pixel_format(dsi_brg_dev_t *dev, lcd_color_format_t color_coding, uint32_t sub_config)
{
switch (color_coding) {
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.raw_type = 2;
dev->pixel_type.dpi_type = 2;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.raw_type = 1;
dev->pixel_type.dpi_type = 1;
break;
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.raw_type = 0;
dev->pixel_type.dpi_type = 0;
break;
default:
// MIPI DSI host can only accept RGB data, no YUV data
HAL_ASSERT(false);
break;
}
dev->pixel_type.dpi_config = sub_config;
}
#else
static inline void mipi_dsi_brg_ll_set_pixel_format(dsi_brg_dev_t *dev, lcd_color_format_t color_coding, uint32_t sub_config)
{
switch (color_coding) {
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.raw_type = 2;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.raw_type = 1;
break;
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.raw_type = 0;
break;
default:
// MIPI DSI host can only accept RGB data, no YUV data
HAL_ASSERT(false);
break;
}
dev->pixel_type.dpi_config = sub_config;
}
#endif
/**
* @brief Set the color space for input color data
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_space Color space type
*/
static inline void mipi_dsi_brg_ll_set_input_color_space(dsi_brg_dev_t *dev, lcd_color_space_t color_space)
{
switch (color_space) {
case LCD_COLOR_SPACE_RGB:
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_SPACE_YUV:
dev->pixel_type.data_in_type = 1;
break;
default:
abort();
}
}
/**
* @brief Set the vertical timing parameters for the bridge controller
*
@@ -402,6 +331,157 @@ static inline void mipi_dsi_brg_ll_set_yuv422_pack_order(dsi_brg_dev_t *dev, lcd
}
}
/**********************************************************************************************************************/
/************************ The following functions behave differently based on the chip revision ***********************/
/**********************************************************************************************************************/
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
/**
* @brief Set the color format for the input color data
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_format Color format
*/
static inline void mipi_dsi_brg_ll_set_input_color_format(dsi_brg_dev_t *dev, lcd_color_format_t color_format)
{
switch (color_format) {
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.raw_type = 0;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.raw_type = 1;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.raw_type = 2;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_YUV422:
dev->pixel_type.raw_type = 9;
dev->pixel_type.data_in_type = 1;
break;
default:
abort();
}
}
/**
* @brief Set the color space for output color data
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_format Color format
*/
static inline void mipi_dsi_brg_ll_set_output_color_format(dsi_brg_dev_t *dev, lcd_color_format_t color_format, uint32_t sub_config)
{
switch (color_format) {
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.dpi_type = 0;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.dpi_type = 1;
break;
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.dpi_type = 2;
break;
default:
abort();
}
dev->pixel_type.dpi_config = sub_config;
}
/**
* @brief Reset the DSI bridge module
*
* @param dev Pointer to the DSI bridge controller register base address
*/
static inline void mipi_dsi_brg_ll_reset(dsi_brg_dev_t *dev)
{
dev->en.dsi_brig_rst = 1;
dev->en.dsi_brig_rst = 0;
}
/**
* @brief Set the color range of input data
*
* @param dev LCD register base address
* @param range Color range
*/
static inline void mipi_dsi_brg_ll_set_input_color_range(dsi_brg_dev_t *dev, lcd_color_range_t range)
{
if (range == LCD_COLOR_RANGE_LIMIT) {
dev->yuv_cfg.yuv_range = 0;
} else if (range == LCD_COLOR_RANGE_FULL) {
dev->yuv_cfg.yuv_range = 1;
}
}
#else
/**
* @brief Set the color format for the input color data
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_format Color format
*/
static inline void mipi_dsi_brg_ll_set_input_color_format(dsi_brg_dev_t *dev, lcd_color_format_t color_format)
{
switch (color_format) {
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.raw_type = 0;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.raw_type = 1;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.raw_type = 2;
dev->pixel_type.data_in_type = 0;
break;
case LCD_COLOR_FMT_YUV422:
dev->pixel_type.data_in_type = 1;
break;
default:
abort();
}
}
/**
* @brief Set the color space for output color data
*
* @param dev Pointer to the DSI bridge controller register base address
* @param color_format Color format
*/
static inline void mipi_dsi_brg_ll_set_output_color_format(dsi_brg_dev_t *dev, lcd_color_format_t color_format, uint32_t sub_config)
{
switch (color_format) {
case LCD_COLOR_FMT_RGB565:
dev->pixel_type.raw_type = 2;
break;
case LCD_COLOR_FMT_RGB666:
dev->pixel_type.raw_type = 1;
break;
case LCD_COLOR_FMT_RGB888:
dev->pixel_type.raw_type = 0;
break;
default:
abort();
}
dev->pixel_type.dpi_config = sub_config;
}
static inline void mipi_dsi_brg_ll_reset(dsi_brg_dev_t *dev)
{
// Not supported
}
static inline void mipi_dsi_brg_ll_set_input_color_range(dsi_brg_dev_t *dev, lcd_color_range_t range)
{
// Not supported
}
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -10,6 +10,7 @@
#include <stdint.h>
#include "soc/hp_sys_clkrst_struct.h"
#include "hal/misc.h"
#include "hal/config.h"
#include "hal/mipi_dsi_host_ll.h"
#include "hal/mipi_dsi_brg_ll.h"
#include "hal/mipi_dsi_phy_ll.h"
@@ -91,11 +92,14 @@ static inline void mipi_dsi_ll_set_dpi_clock_source(int group_id, mipi_dsi_dpi_c
case MIPI_DSI_DPI_CLK_SRC_XTAL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 0;
break;
case MIPI_DSI_DPI_CLK_SRC_PLL_F240M:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 1;
break;
case MIPI_DSI_DPI_CLK_SRC_PLL_F160M:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 2;
break;
case MIPI_DSI_DPI_CLK_SRC_PLL_F240M:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 1;
case MIPI_DSI_DPI_CLK_SRC_APLL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 3;
break;
default:
abort();
@@ -148,41 +152,22 @@ static inline void mipi_dsi_ll_enable_phy_config_clock(int group_id, bool enable
} while(0)
/**
* @brief Enable MIPI DSI PHY PLL reference clock
*
* @param group_id Group ID
* @param enable true to enable, false to disable
*/
static inline void mipi_dsi_ll_enable_phy_reference_clock(int group_id, bool enable)
{
(void)group_id;
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_enable_phy_reference_clock(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
mipi_dsi_ll_enable_phy_reference_clock(__VA_ARGS__); \
} while(0)
/**
* @brief Set the clock source for the DSI PHY interface
* @brief Set the clock source for the DSI PHY configuration interface
*
* @param group_id Group ID
* @param source Clock source
*/
static inline void mipi_dsi_ll_set_phy_clock_source(int group_id, mipi_dsi_phy_clock_source_t source)
static inline void _mipi_dsi_ll_set_phy_config_clock_source(int group_id, soc_periph_mipi_dsi_phy_cfg_clk_src_t source)
{
(void)group_id;
switch (source) {
case MIPI_DSI_PHY_CLK_SRC_PLL_F20M:
case MIPI_DSI_PHY_CFG_CLK_SRC_PLL_F20M:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 0;
break;
case MIPI_DSI_PHY_CLK_SRC_RC_FAST:
case MIPI_DSI_PHY_CFG_CLK_SRC_RC_FAST:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 1;
break;
case MIPI_DSI_PHY_CLK_SRC_PLL_F25M:
case MIPI_DSI_PHY_CFG_CLK_SRC_PLL_F25M:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 2;
break;
default:
@@ -192,11 +177,136 @@ static inline void mipi_dsi_ll_set_phy_clock_source(int group_id, mipi_dsi_phy_c
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_set_phy_clock_source(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
mipi_dsi_ll_set_phy_clock_source(__VA_ARGS__); \
#define mipi_dsi_ll_set_phy_config_clock_source(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_mipi_dsi_ll_set_phy_config_clock_source(__VA_ARGS__); \
} while(0)
/**
* @brief Enable MIPI DSI PHY PLL reference clock
*
* @param group_id Group ID
* @param enable true to enable, false to disable
*/
static inline void mipi_dsi_ll_enable_phy_pllref_clock(int group_id, bool enable)
{
(void)group_id;
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_enable_phy_pllref_clock(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
mipi_dsi_ll_enable_phy_pllref_clock(__VA_ARGS__); \
} while(0)
/**********************************************************************************************************************/
/************************ The following functions behave differently based on the chip revision ***********************/
/**********************************************************************************************************************/
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
/**
* @brief Set the clock source for the DSI PHY PLL reference clock
*
* @param group_id Group ID
* @param source Clock source
*/
static inline void _mipi_dsi_ll_set_phy_pllref_clock_source(int group_id, mipi_dsi_phy_pllref_clock_source_t source)
{
(void)group_id;
switch (source) {
case MIPI_DSI_PHY_PLLREF_CLK_SRC_XTAL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_src_sel = 0;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_APLL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_src_sel = 1;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_CPLL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_src_sel = 2;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_SPLL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_src_sel = 3;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_MPLL:
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dphy_pll_refclk_src_sel = 4;
break;
default:
abort();
}
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_set_phy_pllref_clock_source(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_mipi_dsi_ll_set_phy_pllref_clock_source(__VA_ARGS__); \
} while(0)
/**
* @brief Set the clock division factor for the DSI PHY clock source
*
* @param group_id Group ID
* @param div Division factor
*/
static inline void _mipi_dsi_ll_set_phy_pll_ref_clock_div(int group_id, uint32_t div)
{
(void) group_id;
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl03, reg_mipi_dsi_dphy_pll_refclk_div_num, div - 1);
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_set_phy_pll_ref_clock_div(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_mipi_dsi_ll_set_phy_pll_ref_clock_div(__VA_ARGS__);\
} while (0)
#else
/**
* @brief Set the clock source for the DSI PHY PLL reference clock
*
* @note The PHY PLL reference clock source is same as PHY configuration clock source
*
* @param group_id Group ID
* @param source Clock source
*/
static inline void _mipi_dsi_ll_set_phy_pllref_clock_source(int group_id, mipi_dsi_phy_pllref_clock_source_t source)
{
(void)group_id;
switch (source) {
case MIPI_DSI_PHY_PLLREF_CLK_SRC_PLL_F20M:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 0;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_RC_FAST:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 1;
break;
case MIPI_DSI_PHY_PLLREF_CLK_SRC_PLL_F25M:
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 2;
break;
default:
abort();
}
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define mipi_dsi_ll_set_phy_pllref_clock_source(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_mipi_dsi_ll_set_phy_pllref_clock_source(__VA_ARGS__); \
} while(0)
static inline void mipi_dsi_ll_set_phy_pll_ref_clock_div(int group_id, uint32_t div)
{
// not supported
(void)group_id;
(void)div;
}
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -143,15 +143,6 @@ void mipi_dsi_hal_host_gen_write_short_packet(mipi_dsi_hal_context_t *hal, uint8
void mipi_dsi_hal_host_gen_read_short_packet(mipi_dsi_hal_context_t *hal, uint8_t vc,
mipi_dsi_data_type_t dt, uint16_t header_data, void *ret_buffer, uint16_t buffer_size);
/**
* @brief Set DPI color coding
*
* @param hal Pointer to the HAL driver context
* @param color_coding Color coding
* @param sub_config Sub configuration
*/
void mipi_dsi_hal_host_dpi_set_color_coding(mipi_dsi_hal_context_t *hal, lcd_color_format_t color_coding, uint32_t sub_config);
/**
* @brief Set horizontal timing parameters for DPI
*

View File

@@ -9,6 +9,7 @@
#include <stdint.h>
#include "soc/clk_tree_defs.h"
#include "esp_assert.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
@@ -58,17 +59,25 @@ typedef enum {
} mipi_dsi_pattern_type_t;
#if SOC_MIPI_DSI_SUPPORTED
/**
* @brief MIPI DSI PHY clock source
* @brief MIPI DSI PHY PLL reference clock source
*/
typedef soc_periph_mipi_dsi_phy_clk_src_t mipi_dsi_phy_clock_source_t;
typedef soc_periph_mipi_dsi_phy_pllref_clk_src_t mipi_dsi_phy_pllref_clock_source_t;
/**
* @brief MIPI DSI DPI clock source
*/
typedef soc_periph_mipi_dsi_dpi_clk_src_t mipi_dsi_dpi_clock_source_t;
/**
* @brief For backward compatibility
*/
typedef mipi_dsi_phy_pllref_clock_source_t mipi_dsi_phy_clock_source_t;
#else
typedef int mipi_dsi_phy_clock_source_t;
typedef int mipi_dsi_phy_pllref_clock_source_t;
typedef int mipi_dsi_dpi_clock_source_t;
#endif // SOC_MIPI_DSI_SUPPORTED

View File

@@ -25,6 +25,8 @@ void mipi_dsi_hal_init(mipi_dsi_hal_context_t *hal, const mipi_dsi_hal_config_t
mipi_dsi_phy_ll_reset(hal->host);
mipi_dsi_phy_ll_enable_clock_lane(hal->host, true);
mipi_dsi_phy_ll_force_pll(hal->host, true);
// reset the dsi bridge
mipi_dsi_brg_ll_reset(hal->bridge);
}
void mipi_dsi_hal_deinit(mipi_dsi_hal_context_t *hal)
@@ -227,12 +229,6 @@ void mipi_dsi_hal_host_gen_read_dcs_command(mipi_dsi_hal_context_t *hal, uint8_t
mipi_dsi_hal_host_gen_read_short_packet(hal, vc, MIPI_DSI_DT_DCS_READ_0, header_data, ret_param, param_buf_size);
}
void mipi_dsi_hal_host_dpi_set_color_coding(mipi_dsi_hal_context_t *hal, lcd_color_format_t color_coding, uint32_t sub_config)
{
mipi_dsi_host_ll_dpi_set_color_coding(hal->host, color_coding, sub_config);
mipi_dsi_brg_ll_set_pixel_format(hal->bridge, color_coding, sub_config);
}
void mipi_dsi_hal_host_dpi_set_horizontal_timing(mipi_dsi_hal_context_t *hal, uint32_t hsw, uint32_t hbp, uint32_t active_width, uint32_t hfp)
{
float dpi2lane_clk_ratio = (float)hal->lane_bit_rate_mbps / hal->dpi_clock_freq_mhz / 8;

View File

@@ -413,7 +413,7 @@ typedef enum {
CAM_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default choice */
} soc_periph_cam_clk_src_t;
/////////////////////////////////////////////////MIPI///////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////MIPI CSI///////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of MIPI CSI PHY interface
@@ -430,10 +430,12 @@ typedef enum {
MIPI_CSI_PHY_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F20M, /*!< Select PLL_F20M as default clock */
} soc_periph_mipi_csi_phy_clk_src_t;
/////////////////////////////////////////////////MIPI DSI///////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of MIPI DSI DPI interface
*/
#define SOC_MIPI_DSI_DPI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_PLL_F240M}
#define SOC_MIPI_DSI_DPI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_PLL_F240M, SOC_MOD_CLK_APLL}
/**
* @brief Type of MIPI DSI DPI clock source
@@ -442,23 +444,46 @@ typedef enum {
MIPI_DSI_DPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as MIPI DSI DPI source clock */
MIPI_DSI_DPI_CLK_SRC_PLL_F160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as MIPI DSI DPI source clock */
MIPI_DSI_DPI_CLK_SRC_PLL_F240M = SOC_MOD_CLK_PLL_F240M, /*!< Select PLL_F240M as MIPI DSI DPI source clock */
MIPI_DSI_DPI_CLK_SRC_APLL = SOC_MOD_CLK_APLL, /*!< Select APLL as MIPI DSI DPI source clock */
MIPI_DSI_DPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F240M, /*!< Select PLL_F240M as default clock */
} soc_periph_mipi_dsi_dpi_clk_src_t;
/**
* @brief Array initializer for all supported clock sources of MIPI DSI PHY interface
*/
#define SOC_MIPI_DSI_PHY_CLKS {SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_PLL_F25M, SOC_MOD_CLK_PLL_F20M}
/**
* @brief Type of MIPI DSI PHY clock source
* @brief Type of MIPI DSI PHY configuration clock source
*/
typedef enum {
MIPI_DSI_PHY_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as MIPI DSI PHY source clock */
MIPI_DSI_PHY_CLK_SRC_PLL_F25M = SOC_MOD_CLK_PLL_F25M, /*!< Select PLL_F25M as MIPI DSI PHY source clock */
MIPI_DSI_PHY_CLK_SRC_PLL_F20M = SOC_MOD_CLK_PLL_F20M, /*!< Select PLL_F20M as MIPI DSI PHY source clock */
MIPI_DSI_PHY_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F20M, /*!< Select PLL_F20M as default clock */
} soc_periph_mipi_dsi_phy_clk_src_t;
MIPI_DSI_PHY_CFG_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as MIPI DSI PHY configuration source clock */
MIPI_DSI_PHY_CFG_CLK_SRC_PLL_F25M = SOC_MOD_CLK_PLL_F25M, /*!< Select PLL_F25M as MIPI DSI PHY configuration source clock */
MIPI_DSI_PHY_CFG_CLK_SRC_PLL_F20M = SOC_MOD_CLK_PLL_F20M, /*!< Select PLL_F20M as MIPI DSI PHY configuration source clock */
MIPI_DSI_PHY_CFG_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F20M, /*!< Select PLL_F20M as default clock */
} soc_periph_mipi_dsi_phy_cfg_clk_src_t;
/**
* @brief Type of MIPI DSI PHY PLL reference clock source
*/
typedef enum {
// only available on esp32p4 version < 3.0
MIPI_DSI_PHY_PLLREF_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as MIPI DSI PHY PLL reference clock */
MIPI_DSI_PHY_PLLREF_CLK_SRC_PLL_F25M = SOC_MOD_CLK_PLL_F25M, /*!< Select PLL_F25M as MIPI DSI PHY PLL reference clock */
MIPI_DSI_PHY_PLLREF_CLK_SRC_PLL_F20M = SOC_MOD_CLK_PLL_F20M, /*!< Select PLL_F20M as MIPI DSI PHY PLL reference clock */
MIPI_DSI_PHY_PLLREF_CLK_SRC_DEFAULT_LEGACY = SOC_MOD_CLK_PLL_F20M, /*!< Select PLL_F20M as default clock */
// only available on esp32p4 version >= 3.0
MIPI_DSI_PHY_PLLREF_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as MIPI DSI PHY PLL reference clock */
MIPI_DSI_PHY_PLLREF_CLK_SRC_APLL = SOC_MOD_CLK_APLL, /*!< Select APLL as MIPI DSI PHY PLL reference clock */
MIPI_DSI_PHY_PLLREF_CLK_SRC_CPLL = SOC_MOD_CLK_CPLL, /*!< Select CPLL as MIPI DSI PHY PLL reference clock */
MIPI_DSI_PHY_PLLREF_CLK_SRC_SPLL = SOC_MOD_CLK_SPLL, /*!< Select SPLL as MIPI DSI PHY PLL reference clock */
MIPI_DSI_PHY_PLLREF_CLK_SRC_MPLL = SOC_MOD_CLK_MPLL, /*!< Select MPLL as MIPI DSI PHY PLL reference clock */
MIPI_DSI_PHY_PLLREF_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as default clock */
} soc_periph_mipi_dsi_phy_pllref_clk_src_t;
/**
* @brief For backward compatibility, old macro definitions are kept. Remove it in the next major release (esp-idf v7.0)
*/
#define MIPI_DSI_PHY_CLK_SRC_RC_FAST SOC_MOD_CLK_RC_FAST
#define MIPI_DSI_PHY_CLK_SRC_PLL_F25M SOC_MOD_CLK_PLL_F25M
#define MIPI_DSI_PHY_CLK_SRC_PLL_F20M SOC_MOD_CLK_PLL_F20M
#define MIPI_DSI_PHY_CLK_SRC_DEFAULT SOC_MOD_CLK_PLL_F20M
/////////////////////////////////////////////////I2C////////////////////////////////////////////////////////////////////

View File

@@ -11,7 +11,6 @@ MIPI DSI Interfaced LCD
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0, // index from 0, specify the DSI host to use
.num_data_lanes = 2, // Number of data lanes to use, can't set a value that exceeds the chip's capability
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT, // Clock source for the DPHY
.lane_bit_rate_mbps = EXAMPLE_MIPI_DSI_LANE_BITRATE_MBPS, // Bit rate of the data lanes, in Mbps
};
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));

View File

@@ -11,7 +11,6 @@ MIPI DSI 接口的 LCD
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0, // 从 0 开始编号,指定要使用的 DSI 主机
.num_data_lanes = 2, // 要使用的数据通道数,不能超过芯片支持的数量
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT, // DPHY 的时钟源
.lane_bit_rate_mbps = EXAMPLE_MIPI_DSI_LANE_BITRATE_MBPS, // 数据通道的比特率 (Mbps)
};
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));

View File

@@ -21,7 +21,6 @@ void example_dsi_resource_alloc(esp_lcd_dsi_bus_handle_t *mipi_dsi_bus, esp_lcd_
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0,
.num_data_lanes = 2,
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
.lane_bit_rate_mbps = 1000, // 1000 Mbps
};
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, mipi_dsi_bus));

View File

@@ -197,7 +197,6 @@ void app_main(void)
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0,
.num_data_lanes = EXAMPLE_MIPI_DSI_LANE_NUM,
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
.lane_bit_rate_mbps = EXAMPLE_MIPI_DSI_LANE_BITRATE_MBPS,
};
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));