mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
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:
+31
-14
@@ -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
|
||||
@@ -27,14 +21,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
|
||||
|
||||
@@ -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,35 @@ 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 CONFIG_IDF_TARGET_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_clk_tree_enable_src((soc_module_clk_t)phy_clk_src, true);
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)phy_clk_src, true), err, TAG, "clock source enable failed");
|
||||
|
||||
// always use the default clock source for the DSI PHY configuration
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)MIPI_DSI_PHY_CFG_CLK_SRC_DEFAULT, 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 +138,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 (bus->pm_lock) {
|
||||
@@ -150,3 +153,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
|
||||
|
||||
@@ -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);
|
||||
@@ -75,8 +65,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;
|
||||
@@ -150,7 +139,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");
|
||||
|
||||
@@ -175,7 +164,10 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(num_fbs <= DPI_PANEL_MAX_FB_NUM, ESP_ERR_INVALID_ARG, TAG, "num_fbs not within [1,%d]", DPI_PANEL_MAX_FB_NUM);
|
||||
|
||||
size_t bits_per_pixel = 0;
|
||||
// by default, use RGB888 as the input color format
|
||||
lcd_color_format_t in_color_format = LCD_COLOR_FMT_RGB888;
|
||||
size_t bits_per_pixel = 24;
|
||||
// the deprecated way to set the pixel format
|
||||
switch (panel_config->pixel_format) {
|
||||
case LCD_COLOR_PIXEL_FORMAT_RGB565:
|
||||
bits_per_pixel = 16;
|
||||
@@ -188,15 +180,17 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
|
||||
bits_per_pixel = 24;
|
||||
break;
|
||||
}
|
||||
lcd_color_format_t in_color_format = COLOR_TYPE_ID(COLOR_SPACE_RGB, panel_config->pixel_format);
|
||||
// if user sets the in_color_format, it can override the pixel format setting
|
||||
in_color_format = COLOR_TYPE_ID(COLOR_SPACE_RGB, panel_config->pixel_format);
|
||||
// the recommended way to set the input color format
|
||||
if (panel_config->in_color_format) {
|
||||
in_color_format = panel_config->in_color_format;
|
||||
// if user sets the in_color_format, it can override the pixel format setting
|
||||
color_space_pixel_format_t in_color_id = {
|
||||
.color_type_id = panel_config->in_color_format,
|
||||
.color_type_id = in_color_format,
|
||||
};
|
||||
bits_per_pixel = color_hal_pixel_format_get_bit_depth(in_color_id);
|
||||
in_color_format = panel_config->in_color_format;
|
||||
}
|
||||
// by default, out_color_format is the same as in_color_format (i.e. no color format conversion)
|
||||
lcd_color_format_t out_color_format = in_color_format;
|
||||
if (panel_config->out_color_format) {
|
||||
out_color_format = panel_config->out_color_format;
|
||||
@@ -216,20 +210,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");
|
||||
}
|
||||
@@ -262,7 +252,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_clk_tree_enable_src((soc_module_clk_t)dpi_clk_src, true);
|
||||
// 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);
|
||||
@@ -281,7 +271,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);
|
||||
|
||||
@@ -319,8 +309,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);
|
||||
@@ -350,7 +341,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
|
||||
@@ -568,6 +559,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 {
|
||||
@@ -605,7 +597,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_CACHE_SAFE
|
||||
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");
|
||||
}
|
||||
@@ -615,7 +607,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_CACHE_SAFE
|
||||
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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -22,7 +22,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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -9,7 +9,7 @@ from pytest_embedded import Dut
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'iram_safe',
|
||||
'cache_safe',
|
||||
'release',
|
||||
],
|
||||
indirect=True,
|
||||
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
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_HAL_ASSERTION_SILENT=y
|
||||
# place non-ISR FreeRTOS functions in Flash
|
||||
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||
CONFIG_LCD_DSI_ISR_IRAM_SAFE=y
|
||||
Reference in New Issue
Block a user