mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 01:50:58 +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"
|
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
|
if SOC_LCD_RGB_SUPPORTED
|
||||||
config LCD_RGB_ISR_IRAM_SAFE
|
config LCD_RGB_ISR_IRAM_SAFE
|
||||||
@@ -28,14 +22,37 @@ menu "ESP-Driver:LCD Controller Configurations"
|
|||||||
endif # SOC_LCD_RGB_SUPPORTED
|
endif # SOC_LCD_RGB_SUPPORTED
|
||||||
|
|
||||||
if SOC_MIPI_DSI_SUPPORTED
|
if SOC_MIPI_DSI_SUPPORTED
|
||||||
config LCD_DSI_ISR_IRAM_SAFE
|
config LCD_DSI_ISR_HANDLER_IN_IRAM
|
||||||
bool "DSI LCD ISR IRAM-Safe"
|
bool "Place DSI ISR handler in IRAM to reduce latency"
|
||||||
default n
|
default y
|
||||||
select DW_GDMA_ISR_IRAM_SAFE # relies on DW_GDMA Full trans done interrupt
|
select LCD_DSI_OBJ_FORCE_INTERNAL
|
||||||
help
|
help
|
||||||
Ensure the LCD interrupt is IRAM-Safe by allowing the interrupt handler to be
|
Place DSI ISR handler in IRAM to reduce latency caused by cache miss.
|
||||||
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,
|
config LCD_DSI_ISR_CACHE_SAFE
|
||||||
you can enable this option. Note, this will also increase the IRAM usage.
|
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
|
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
|
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
|
* 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_lcd_mipi_dsi.h"
|
||||||
#include "esp_clk_tree.h"
|
#include "esp_clk_tree.h"
|
||||||
#include "esp_private/esp_clk_tree_common.h"
|
|
||||||
#include "mipi_dsi_priv.h"
|
#include "mipi_dsi_priv.h"
|
||||||
|
|
||||||
static const char *TAG = "lcd.dsi.bus";
|
|
||||||
|
|
||||||
#define MIPI_DSI_DEFAULT_TIMEOUT_CLOCK_FREQ_MHZ 10
|
#define MIPI_DSI_DEFAULT_TIMEOUT_CLOCK_FREQ_MHZ 10
|
||||||
// TxClkEsc frequency must be configured between 2 and 20 MHz
|
// TxClkEsc frequency must be configured between 2 and 20 MHz
|
||||||
#define MIPI_DSI_DEFAULT_ESCAPE_CLOCK_FREQ_MHZ 18
|
#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;
|
dsi_bus->bus_id = bus_id;
|
||||||
|
|
||||||
// Enable the APB clock for accessing the DSI host and bridge registers
|
// 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_enable_bus_clock(bus_id, true);
|
||||||
mipi_dsi_ll_reset_register(bus_id);
|
mipi_dsi_ll_reset_register(bus_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the clock source is not assigned, fallback to the default clock source
|
// 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) {
|
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");
|
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
|
// enable the clock source for DSI PHY
|
||||||
DSI_CLOCK_SRC_ATOMIC() {
|
PERIPH_RCC_ATOMIC() {
|
||||||
// set clock source for DSI PHY
|
// set the DSI PHY configuration clock
|
||||||
mipi_dsi_ll_set_phy_clock_source(bus_id, phy_clk_src);
|
|
||||||
// the configuration clock is used for all modes except the shutdown mode
|
// 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);
|
mipi_dsi_ll_enable_phy_config_clock(bus_id, true);
|
||||||
// enable the clock for generating the serial clock
|
// set the DSI PHY PLL reference clock
|
||||||
mipi_dsi_ll_enable_phy_reference_clock(bus_id, true);
|
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
|
#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");
|
ESP_RETURN_ON_FALSE(bus, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||||
int bus_id = bus->bus_id;
|
int bus_id = bus->bus_id;
|
||||||
// disable the clock source for DSI PHY
|
// disable the clock source for DSI PHY
|
||||||
DSI_CLOCK_SRC_ATOMIC() {
|
PERIPH_RCC_ATOMIC() {
|
||||||
mipi_dsi_ll_enable_phy_reference_clock(bus_id, false);
|
mipi_dsi_ll_enable_phy_pllref_clock(bus_id, false);
|
||||||
mipi_dsi_ll_enable_phy_config_clock(bus_id, false);
|
mipi_dsi_ll_enable_phy_config_clock(bus_id, false);
|
||||||
}
|
}
|
||||||
// disable the APB clock for accessing the DSI peripheral registers
|
// 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);
|
mipi_dsi_ll_enable_bus_clock(bus_id, false);
|
||||||
}
|
}
|
||||||
#if CONFIG_PM_ENABLE
|
#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);
|
free(bus);
|
||||||
return ESP_OK;
|
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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
#include <sys/param.h>
|
#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_panel_interface.h"
|
||||||
#include "esp_lcd_mipi_dsi.h"
|
#include "esp_lcd_mipi_dsi.h"
|
||||||
#include "esp_clk_tree.h"
|
#include "esp_clk_tree.h"
|
||||||
@@ -17,13 +12,8 @@
|
|||||||
#include "esp_async_fbcpy.h"
|
#include "esp_async_fbcpy.h"
|
||||||
#include "esp_memory_utils.h"
|
#include "esp_memory_utils.h"
|
||||||
#include "esp_private/dw_gdma.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"
|
#include "hal/color_hal.h"
|
||||||
|
|
||||||
static const char *TAG = "lcd.dsi.dpi";
|
|
||||||
|
|
||||||
typedef struct esp_lcd_dpi_panel_t esp_lcd_dpi_panel_t;
|
typedef struct esp_lcd_dpi_panel_t esp_lcd_dpi_panel_t;
|
||||||
|
|
||||||
static esp_err_t dpi_panel_del(esp_lcd_panel_t *panel);
|
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;
|
return need_yield;
|
||||||
}
|
}
|
||||||
|
|
||||||
IRAM_ATTR
|
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)
|
||||||
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 yield_needed = false;
|
bool yield_needed = false;
|
||||||
esp_lcd_dpi_panel_t *dpi_panel = (esp_lcd_dpi_panel_t *)user_data;
|
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
|
// register DMA ISR callbacks
|
||||||
dw_gdma_event_callbacks_t dsi_dma_cbs = {
|
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");
|
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;
|
dpi_panel->num_fbs = num_fbs;
|
||||||
|
|
||||||
// allocate frame buffer from PSRAM
|
// 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;
|
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++) {
|
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");
|
ESP_GOTO_ON_FALSE(frame_buffer, ESP_ERR_NO_MEM, err, TAG, "no memory for frame buffer");
|
||||||
dpi_panel->fbs[i] = frame_buffer;
|
dpi_panel->fbs[i] = frame_buffer;
|
||||||
ESP_LOGD(TAG, "fb[%d] @%p", i, frame_buffer);
|
ESP_LOGD(TAG, "fb[%d] @%p", i, frame_buffer);
|
||||||
// preset the frame buffer with black color
|
// 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
|
// 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),
|
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");
|
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);
|
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");
|
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
|
// 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_source(bus_id, dpi_clk_src);
|
||||||
mipi_dsi_ll_set_dpi_clock_div(bus_id, dpi_div);
|
mipi_dsi_ll_set_dpi_clock_div(bus_id, dpi_div);
|
||||||
mipi_dsi_ll_enable_dpi_clock(bus_id, true);
|
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");
|
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_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
|
// 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);
|
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);
|
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_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);
|
mipi_dsi_brg_ll_set_underrun_discard_count(hal->bridge, panel_config->video_timing.h_size);
|
||||||
// set input color space
|
// set the in/out color formats in the DSI bridge
|
||||||
mipi_dsi_brg_ll_set_input_color_space(hal->bridge, COLOR_SPACE_TYPE(in_color_format));
|
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
|
// 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_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);
|
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;
|
int bus_id = bus->bus_id;
|
||||||
mipi_dsi_hal_context_t *hal = &bus->hal;
|
mipi_dsi_hal_context_t *hal = &bus->hal;
|
||||||
// disable the DPI clock
|
// disable the DPI clock
|
||||||
DSI_CLOCK_SRC_ATOMIC() {
|
PERIPH_RCC_ATOMIC() {
|
||||||
mipi_dsi_ll_enable_dpi_clock(bus_id, false);
|
mipi_dsi_ll_enable_dpi_clock(bus_id, false);
|
||||||
}
|
}
|
||||||
// disable the DSI bridge
|
// 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)
|
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) {
|
&& COLOR_SPACE_TYPE(dpi_panel->out_color_format) == LCD_COLOR_SPACE_RGB) {
|
||||||
// YUV422->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_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);
|
mipi_dsi_brg_ll_set_yuv422_pack_order(hal->bridge, config->spec.yuv.yuv422.in_pack_order);
|
||||||
} else {
|
} 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_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);
|
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) {
|
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");
|
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) {
|
if (user_ctx) {
|
||||||
ESP_RETURN_ON_FALSE(esp_ptr_internal(user_ctx), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM");
|
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_color_trans_done = cbs->on_color_trans_done;
|
||||||
dpi_panel->on_refresh_done = cbs->on_refresh_done;
|
dpi_panel->on_refresh_done = cbs->on_refresh_done;
|
||||||
dpi_panel->user_ctx = user_ctx;
|
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
|
* 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_panel_io_interface.h"
|
||||||
#include "esp_lcd_mipi_dsi.h"
|
#include "esp_lcd_mipi_dsi.h"
|
||||||
#include "mipi_dsi_priv.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;
|
typedef struct esp_lcd_dbi_io_t esp_lcd_dbi_io_t;
|
||||||
|
|
||||||
struct esp_lcd_dbi_io_t {
|
struct esp_lcd_dbi_io_t {
|
||||||
|
@@ -23,7 +23,7 @@ extern "C" {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
int bus_id; /*!< Select which DSI controller, index from 0 */
|
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 */
|
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 */
|
uint32_t lane_bit_rate_mbps; /*!< Lane bit rate in Mbps */
|
||||||
} esp_lcd_dsi_bus_config_t;
|
} 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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "hal/mipi_dsi_hal.h"
|
#include <stdint.h>
|
||||||
#include "hal/mipi_dsi_ll.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_heap_caps.h"
|
||||||
#include "esp_private/periph_ctrl.h"
|
#include "esp_private/periph_ctrl.h"
|
||||||
|
#include "esp_private/esp_clk_tree_common.h"
|
||||||
#include "esp_pm.h"
|
#include "esp_pm.h"
|
||||||
|
#include "hal/mipi_dsi_hal.h"
|
||||||
|
#include "hal/mipi_dsi_ll.h"
|
||||||
|
|
||||||
#if SOC_PERIPH_CLK_CTRL_SHARED
|
#if CONFIG_LCD_DSI_OBJ_FORCE_INTERNAL
|
||||||
#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
|
|
||||||
#define DSI_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
|
#define DSI_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
|
||||||
#else
|
#else
|
||||||
#define DSI_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
#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_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
|
#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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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
|
archive: libesp_hw_support.a
|
||||||
entries:
|
entries:
|
||||||
if LCD_RGB_ISR_IRAM_SAFE = y:
|
if LCD_RGB_ISR_IRAM_SAFE = y:
|
||||||
gdma: gdma_reset (noflash)
|
gdma: gdma_reset (noflash)
|
||||||
gdma: gdma_start (noflash)
|
gdma: gdma_start (noflash)
|
||||||
gdma_link: gdma_link_get_head_addr (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
|
archive: libhal.a
|
||||||
entries:
|
entries:
|
||||||
if LCD_RGB_ISR_IRAM_SAFE = y:
|
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_board.c"
|
||||||
"test_mipi_dsi_panel.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")
|
list(APPEND srcs "test_mipi_dsi_iram.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@@ -46,7 +46,6 @@ TEST_CASE("MIPI DSI draw bitmap (EK79007) IRAM Safe", "[mipi_dsi]")
|
|||||||
esp_lcd_dsi_bus_config_t bus_config = {
|
esp_lcd_dsi_bus_config_t bus_config = {
|
||||||
.bus_id = 0,
|
.bus_id = 0,
|
||||||
.num_data_lanes = 2,
|
.num_data_lanes = 2,
|
||||||
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
|
|
||||||
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
|
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 = {
|
esp_lcd_dsi_bus_config_t bus_config = {
|
||||||
.bus_id = 0,
|
.bus_id = 0,
|
||||||
.num_data_lanes = 2,
|
.num_data_lanes = 2,
|
||||||
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
|
|
||||||
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
|
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 = {
|
esp_lcd_dsi_bus_config_t bus_config = {
|
||||||
.bus_id = 0,
|
.bus_id = 0,
|
||||||
.num_data_lanes = 2,
|
.num_data_lanes = 2,
|
||||||
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
|
|
||||||
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
|
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 = {
|
esp_lcd_dsi_bus_config_t bus_config = {
|
||||||
.bus_id = 0,
|
.bus_id = 0,
|
||||||
.num_data_lanes = 2,
|
.num_data_lanes = 2,
|
||||||
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
|
|
||||||
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
|
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 = {
|
esp_lcd_dsi_bus_config_t bus_config = {
|
||||||
.bus_id = 0,
|
.bus_id = 0,
|
||||||
.num_data_lanes = 2,
|
.num_data_lanes = 2,
|
||||||
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
|
|
||||||
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
|
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(
|
@pytest.mark.parametrize(
|
||||||
'config',
|
'config',
|
||||||
[
|
[
|
||||||
'iram_safe',
|
'cache_safe',
|
||||||
'release',
|
'release',
|
||||||
],
|
],
|
||||||
indirect=True,
|
indirect=True,
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
CONFIG_COMPILER_DUMP_RTL_FILES=y
|
CONFIG_COMPILER_DUMP_RTL_FILES=y
|
||||||
|
CONFIG_LCD_DSI_ISR_CACHE_SAFE=y
|
||||||
CONFIG_COMPILER_OPTIMIZATION_NONE=y
|
CONFIG_COMPILER_OPTIMIZATION_NONE=y
|
||||||
# silent the error check, as the error string are stored in rodata, causing RTL check failure
|
# 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_CHECKS_SILENT=y
|
||||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_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 channel Channel number
|
||||||
* @param en True to enable, false to disable
|
* @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)
|
static inline void dw_gdma_ll_channel_enable(dw_gdma_dev_t *dev, uint8_t channel, bool en)
|
||||||
{
|
{
|
||||||
if (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 channel Channel number
|
||||||
* @param addr Address of the first link list item, it must be aligned 64 bytes
|
* @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)
|
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;
|
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 channel Channel number
|
||||||
* @param port Master port
|
* @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)
|
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;
|
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_GET_BRG(bus_id) (bus_id == 0 ? &MIPI_DSI_BRIDGE : NULL)
|
||||||
#define MIPI_DSI_LL_EVENT_UNDERRUN (1 << 0)
|
#define MIPI_DSI_LL_EVENT_UNDERRUN (1 << 0)
|
||||||
|
#define MIPI_DSI_LL_EVENT_VSYNC (1 << 1)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
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;
|
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
|
* @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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "soc/hp_sys_clkrst_struct.h"
|
#include "soc/hp_sys_clkrst_struct.h"
|
||||||
#include "hal/misc.h"
|
#include "hal/misc.h"
|
||||||
|
#include "hal/config.h"
|
||||||
#include "hal/mipi_dsi_host_ll.h"
|
#include "hal/mipi_dsi_host_ll.h"
|
||||||
#include "hal/mipi_dsi_brg_ll.h"
|
#include "hal/mipi_dsi_brg_ll.h"
|
||||||
#include "hal/mipi_dsi_phy_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:
|
case MIPI_DSI_DPI_CLK_SRC_XTAL:
|
||||||
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 0;
|
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 0;
|
||||||
break;
|
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:
|
case MIPI_DSI_DPI_CLK_SRC_PLL_F160M:
|
||||||
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 2;
|
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 2;
|
||||||
break;
|
break;
|
||||||
case MIPI_DSI_DPI_CLK_SRC_PLL_F240M:
|
case MIPI_DSI_DPI_CLK_SRC_APLL:
|
||||||
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 1;
|
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_dsi_dpiclk_src_sel = 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
@@ -148,41 +152,22 @@ static inline void mipi_dsi_ll_enable_phy_config_clock(int group_id, bool enable
|
|||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable MIPI DSI PHY PLL reference clock
|
* @brief Set the clock source for the DSI PHY configuration interface
|
||||||
*
|
|
||||||
* @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
|
|
||||||
*
|
*
|
||||||
* @param group_id Group ID
|
* @param group_id Group ID
|
||||||
* @param source Clock source
|
* @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;
|
(void)group_id;
|
||||||
switch (source) {
|
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;
|
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 0;
|
||||||
break;
|
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;
|
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 1;
|
||||||
break;
|
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;
|
HP_SYS_CLKRST.peri_clk_ctrl02.reg_mipi_dsi_dphy_clk_src_sel = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
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
|
/// 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
|
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||||
#define mipi_dsi_ll_set_phy_clock_source(...) do { \
|
#define mipi_dsi_ll_set_phy_config_clock_source(...) do { \
|
||||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||||
mipi_dsi_ll_set_phy_clock_source(__VA_ARGS__); \
|
_mipi_dsi_ll_set_phy_config_clock_source(__VA_ARGS__); \
|
||||||
} while(0)
|
} 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#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,
|
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);
|
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
|
* @brief Set horizontal timing parameters for DPI
|
||||||
*
|
*
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "soc/clk_tree_defs.h"
|
#include "soc/clk_tree_defs.h"
|
||||||
#include "esp_assert.h"
|
#include "esp_assert.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -58,17 +59,25 @@ typedef enum {
|
|||||||
} mipi_dsi_pattern_type_t;
|
} mipi_dsi_pattern_type_t;
|
||||||
|
|
||||||
#if SOC_MIPI_DSI_SUPPORTED
|
#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
|
* @brief MIPI DSI DPI clock source
|
||||||
*/
|
*/
|
||||||
typedef soc_periph_mipi_dsi_dpi_clk_src_t mipi_dsi_dpi_clock_source_t;
|
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
|
#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;
|
typedef int mipi_dsi_dpi_clock_source_t;
|
||||||
#endif // SOC_MIPI_DSI_SUPPORTED
|
#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_reset(hal->host);
|
||||||
mipi_dsi_phy_ll_enable_clock_lane(hal->host, true);
|
mipi_dsi_phy_ll_enable_clock_lane(hal->host, true);
|
||||||
mipi_dsi_phy_ll_force_pll(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)
|
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);
|
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)
|
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;
|
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 */
|
CAM_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default choice */
|
||||||
} soc_periph_cam_clk_src_t;
|
} soc_periph_cam_clk_src_t;
|
||||||
|
|
||||||
/////////////////////////////////////////////////MIPI///////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////MIPI CSI///////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Array initializer for all supported clock sources of MIPI CSI PHY interface
|
* @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 */
|
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;
|
} soc_periph_mipi_csi_phy_clk_src_t;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////MIPI DSI///////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Array initializer for all supported clock sources of MIPI DSI DPI interface
|
* @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
|
* @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_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_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_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 */
|
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;
|
} soc_periph_mipi_dsi_dpi_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Array initializer for all supported clock sources of MIPI DSI PHY interface
|
* @brief Type of MIPI DSI PHY configuration clock source
|
||||||
*/
|
|
||||||
#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
|
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
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_CFG_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as MIPI DSI PHY configuration 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_CFG_CLK_SRC_PLL_F25M = SOC_MOD_CLK_PLL_F25M, /*!< Select PLL_F25M as MIPI DSI PHY configuration 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_CFG_CLK_SRC_PLL_F20M = SOC_MOD_CLK_PLL_F20M, /*!< Select PLL_F20M as MIPI DSI PHY configuration source clock */
|
||||||
MIPI_DSI_PHY_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F20M, /*!< Select PLL_F20M as default clock */
|
MIPI_DSI_PHY_CFG_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F20M, /*!< Select PLL_F20M as default clock */
|
||||||
} soc_periph_mipi_dsi_phy_clk_src_t;
|
} 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////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////I2C////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@@ -11,7 +11,6 @@ MIPI DSI Interfaced LCD
|
|||||||
esp_lcd_dsi_bus_config_t bus_config = {
|
esp_lcd_dsi_bus_config_t bus_config = {
|
||||||
.bus_id = 0, // index from 0, specify the DSI host to use
|
.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
|
.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
|
.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));
|
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 = {
|
esp_lcd_dsi_bus_config_t bus_config = {
|
||||||
.bus_id = 0, // 从 0 开始编号,指定要使用的 DSI 主机
|
.bus_id = 0, // 从 0 开始编号,指定要使用的 DSI 主机
|
||||||
.num_data_lanes = 2, // 要使用的数据通道数,不能超过芯片支持的数量
|
.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)
|
.lane_bit_rate_mbps = EXAMPLE_MIPI_DSI_LANE_BITRATE_MBPS, // 数据通道的比特率 (Mbps)
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
|
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 = {
|
esp_lcd_dsi_bus_config_t bus_config = {
|
||||||
.bus_id = 0,
|
.bus_id = 0,
|
||||||
.num_data_lanes = 2,
|
.num_data_lanes = 2,
|
||||||
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
|
|
||||||
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, mipi_dsi_bus));
|
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 = {
|
esp_lcd_dsi_bus_config_t bus_config = {
|
||||||
.bus_id = 0,
|
.bus_id = 0,
|
||||||
.num_data_lanes = EXAMPLE_MIPI_DSI_LANE_NUM,
|
.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,
|
.lane_bit_rate_mbps = EXAMPLE_MIPI_DSI_LANE_BITRATE_MBPS,
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
|
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
|
||||||
|
Reference in New Issue
Block a user