mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-01 17:40:57 +02: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:
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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:
|
||||
|
4
components/esp_lcd/sdkconfig.rename
Normal file
4
components/esp_lcd/sdkconfig.rename
Normal 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
|
@@ -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_idf.utils import idf_parametrize
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'iram_safe',
|
||||
'cache_safe',
|
||||
'release',
|
||||
],
|
||||
indirect=True,
|
||||
|
@@ -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
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@@ -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));
|
||||
|
@@ -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));
|
||||
|
@@ -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));
|
||||
|
@@ -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));
|
||||
|
Reference in New Issue
Block a user