mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 18:10:57 +02:00
Merge branch 'feat/dsi_bridge_new_feat' into 'master'
feat(dsi): More DPHY Clock sources supported on ESP32-P4 ECO5 Closes IDF-13537 and IDF-13538 See merge request espressif/esp-idf!41766
This commit is contained in:
@@ -31,6 +31,7 @@ repos:
|
||||
.*.pb-c.c|
|
||||
.*.yuv|
|
||||
.*.rgb|
|
||||
.*.gray|
|
||||
.*COPYING.*|
|
||||
docs/sphinx-known-warnings\.txt
|
||||
)$
|
||||
|
@@ -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");
|
||||
|
||||
@@ -177,28 +166,42 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(num_fbs <= DPI_PANEL_MAX_FB_NUM, ESP_ERR_INVALID_ARG, TAG, "num_fbs not within [1,%d]", DPI_PANEL_MAX_FB_NUM);
|
||||
|
||||
size_t bits_per_pixel = 0;
|
||||
switch (panel_config->pixel_format) {
|
||||
case LCD_COLOR_PIXEL_FORMAT_RGB565:
|
||||
bits_per_pixel = 16;
|
||||
break;
|
||||
case LCD_COLOR_PIXEL_FORMAT_RGB666:
|
||||
// RGB data in the memory must be constructed in 6-6-6 (18 bits) for each pixel
|
||||
bits_per_pixel = 18;
|
||||
break;
|
||||
case LCD_COLOR_PIXEL_FORMAT_RGB888:
|
||||
bits_per_pixel = 24;
|
||||
break;
|
||||
// by default, use RGB888 as the input color format
|
||||
lcd_color_format_t in_color_format = LCD_COLOR_FMT_RGB888;
|
||||
size_t bits_per_pixel = 24;
|
||||
// the deprecated way to set the pixel format
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
bool has_pixel_fmt = panel_config->pixel_format != 0;
|
||||
bool has_in_fmt = panel_config->in_color_format != 0;
|
||||
ESP_RETURN_ON_FALSE(has_pixel_fmt ^ has_in_fmt, ESP_ERR_INVALID_ARG, TAG,
|
||||
"must set exactly one of pixel_format or in_color_format");
|
||||
if (panel_config->pixel_format) {
|
||||
switch (panel_config->pixel_format) {
|
||||
case LCD_COLOR_PIXEL_FORMAT_RGB565:
|
||||
bits_per_pixel = 16;
|
||||
break;
|
||||
case LCD_COLOR_PIXEL_FORMAT_RGB666:
|
||||
// RGB data in the memory must be constructed in 6-6-6 (18 bits) for each pixel
|
||||
bits_per_pixel = 18;
|
||||
break;
|
||||
case LCD_COLOR_PIXEL_FORMAT_RGB888:
|
||||
bits_per_pixel = 24;
|
||||
break;
|
||||
}
|
||||
in_color_format = COLOR_TYPE_ID(COLOR_SPACE_RGB, panel_config->pixel_format);
|
||||
}
|
||||
lcd_color_format_t in_color_format = COLOR_TYPE_ID(COLOR_SPACE_RGB, panel_config->pixel_format);
|
||||
// if user sets the in_color_format, it can override the pixel format setting
|
||||
#pragma GCC diagnostic pop
|
||||
// the recommended way to set the input color format
|
||||
if (panel_config->in_color_format) {
|
||||
in_color_format = panel_config->in_color_format;
|
||||
// if user sets the in_color_format, it can override the pixel format setting
|
||||
color_space_pixel_format_t in_color_id = {
|
||||
.color_type_id = panel_config->in_color_format,
|
||||
.color_type_id = in_color_format,
|
||||
};
|
||||
bits_per_pixel = color_hal_pixel_format_get_bit_depth(in_color_id);
|
||||
in_color_format = panel_config->in_color_format;
|
||||
}
|
||||
// by default, out_color_format is the same as in_color_format (i.e. no color format conversion)
|
||||
lcd_color_format_t out_color_format = in_color_format;
|
||||
if (panel_config->out_color_format) {
|
||||
out_color_format = panel_config->out_color_format;
|
||||
@@ -218,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");
|
||||
}
|
||||
@@ -264,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);
|
||||
@@ -283,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);
|
||||
|
||||
@@ -321,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);
|
||||
@@ -352,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
|
||||
@@ -574,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 {
|
||||
@@ -611,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");
|
||||
}
|
||||
@@ -621,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;
|
||||
|
||||
@@ -84,7 +84,6 @@ typedef struct {
|
||||
uint8_t virtual_channel; /*!< Virtual channel ID, index from 0 */
|
||||
mipi_dsi_dpi_clock_source_t dpi_clk_src; /*!< MIPI DSI DPI clock source */
|
||||
uint32_t dpi_clock_freq_mhz; /*!< DPI clock frequency in MHz */
|
||||
lcd_color_rgb_pixel_format_t pixel_format; /*!< Pixel format that used by the MIPI LCD device */
|
||||
lcd_color_format_t in_color_format; /*!< Format of the input data (color space and pixel format),
|
||||
which is the format stored in the frame buffer */
|
||||
lcd_color_format_t out_color_format; /*!< Format of the output data (color space and pixel format),
|
||||
@@ -92,6 +91,8 @@ typedef struct {
|
||||
uint8_t num_fbs; /*!< Number of screen-sized frame buffers that allocated by the driver
|
||||
By default (set to either 0 or 1) only one frame buffer will be created */
|
||||
esp_lcd_video_timing_t video_timing; /*!< Video timing */
|
||||
/** @deprecated Duplicate of in_color_format; use in_color_format instead. */
|
||||
lcd_color_rgb_pixel_format_t pixel_format __attribute__((deprecated("pixel_format is deprecated, use in_color_format instead"))); /*!< Pixel format that used by the MIPI LCD device */
|
||||
/// Extra configuration flags for MIPI DSI DPI panel
|
||||
struct extra_dpi_panel_flags {
|
||||
uint32_t use_dma2d: 1; /*!< Use DMA2D to copy user buffer to the frame buffer when necessary */
|
||||
|
@@ -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
|
@@ -9,6 +9,8 @@ project(mipi_dsi_lcd_panel_test)
|
||||
|
||||
target_add_binary_data(mipi_dsi_lcd_panel_test.elf "resources/pictures/hello.yuv" BINARY)
|
||||
target_add_binary_data(mipi_dsi_lcd_panel_test.elf "resources/pictures/world.yuv" BINARY)
|
||||
target_add_binary_data(mipi_dsi_lcd_panel_test.elf "resources/pictures/hello.gray" BINARY)
|
||||
target_add_binary_data(mipi_dsi_lcd_panel_test.elf "resources/pictures/world.gray" BINARY)
|
||||
|
||||
idf_build_get_property(elf EXECUTABLE)
|
||||
if(CONFIG_COMPILER_DUMP_RTL_FILES)
|
||||
|
@@ -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));
|
||||
@@ -89,7 +88,7 @@ TEST_CASE("MIPI DSI Pattern Generator (EK79007)", "[mipi_dsi]")
|
||||
|
||||
#define TEST_IMG_SIZE (100 * 100 * sizeof(uint16_t))
|
||||
|
||||
TEST_CASE("MIPI DSI draw bitmap (EK79007)", "[mipi_dsi]")
|
||||
TEST_CASE("MIPI DSI draw RGB bitmap (EK79007)", "[mipi_dsi]")
|
||||
{
|
||||
esp_lcd_dsi_bus_handle_t mipi_dsi_bus;
|
||||
esp_lcd_panel_io_handle_t mipi_dbi_io;
|
||||
@@ -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));
|
||||
@@ -164,7 +162,7 @@ TEST_CASE("MIPI DSI draw bitmap (EK79007)", "[mipi_dsi]")
|
||||
test_bsp_disable_dsi_phy_power();
|
||||
}
|
||||
|
||||
TEST_CASE("MIPI DSI with multiple frame buffers (EK79007)", "[mipi_dsi]")
|
||||
TEST_CASE("MIPI DSI use multiple frame buffers (EK79007)", "[mipi_dsi]")
|
||||
{
|
||||
esp_lcd_dsi_bus_handle_t mipi_dsi_bus;
|
||||
esp_lcd_panel_io_handle_t mipi_dbi_io;
|
||||
@@ -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));
|
||||
@@ -244,7 +241,7 @@ TEST_CASE("MIPI DSI with multiple frame buffers (EK79007)", "[mipi_dsi]")
|
||||
test_bsp_disable_dsi_phy_power();
|
||||
}
|
||||
|
||||
TEST_CASE("MIPI DSI draw YUV422 (EK79007)", "[mipi_dsi]")
|
||||
TEST_CASE("MIPI DSI draw YUV422 image (EK79007)", "[mipi_dsi]")
|
||||
{
|
||||
esp_lcd_dsi_bus_handle_t mipi_dsi_bus;
|
||||
esp_lcd_panel_io_handle_t mipi_dbi_io;
|
||||
@@ -252,13 +249,9 @@ TEST_CASE("MIPI DSI draw YUV422 (EK79007)", "[mipi_dsi]")
|
||||
|
||||
test_bsp_enable_dsi_phy_power();
|
||||
|
||||
uint8_t *img = malloc(TEST_IMG_SIZE);
|
||||
TEST_ASSERT_NOT_NULL(img);
|
||||
|
||||
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));
|
||||
@@ -289,10 +282,6 @@ TEST_CASE("MIPI DSI draw YUV422 (EK79007)", "[mipi_dsi]")
|
||||
.vsync_pulse_width = MIPI_DSI_LCD_VSYNC,
|
||||
.vsync_front_porch = MIPI_DSI_LCD_VFP,
|
||||
},
|
||||
|
||||
.flags = {
|
||||
.use_dma2d = true,
|
||||
}
|
||||
};
|
||||
ek79007_vendor_config_t vendor_config = {
|
||||
.mipi_config = {
|
||||
@@ -337,7 +326,84 @@ TEST_CASE("MIPI DSI draw YUV422 (EK79007)", "[mipi_dsi]")
|
||||
TEST_ESP_OK(esp_lcd_panel_del(mipi_dpi_panel));
|
||||
TEST_ESP_OK(esp_lcd_panel_io_del(mipi_dbi_io));
|
||||
TEST_ESP_OK(esp_lcd_del_dsi_bus(mipi_dsi_bus));
|
||||
free(img);
|
||||
|
||||
test_bsp_disable_dsi_phy_power();
|
||||
}
|
||||
|
||||
TEST_CASE("MIPI DSI draw Gray8 image (EK79007)", "[mipi_dsi]")
|
||||
{
|
||||
esp_lcd_dsi_bus_handle_t mipi_dsi_bus;
|
||||
esp_lcd_panel_io_handle_t mipi_dbi_io;
|
||||
esp_lcd_panel_handle_t mipi_dpi_panel;
|
||||
|
||||
test_bsp_enable_dsi_phy_power();
|
||||
|
||||
esp_lcd_dsi_bus_config_t bus_config = {
|
||||
.bus_id = 0,
|
||||
.num_data_lanes = 2,
|
||||
.lane_bit_rate_mbps = 1000, // 1000 Mbps
|
||||
};
|
||||
TEST_ESP_OK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
|
||||
|
||||
esp_lcd_dbi_io_config_t dbi_config = {
|
||||
.virtual_channel = 0,
|
||||
.lcd_cmd_bits = 8,
|
||||
.lcd_param_bits = 8,
|
||||
};
|
||||
TEST_ESP_OK(esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &mipi_dbi_io));
|
||||
|
||||
esp_lcd_dpi_panel_config_t dpi_config = {
|
||||
.dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT,
|
||||
.dpi_clock_freq_mhz = MIPI_DSI_DPI_CLK_MHZ,
|
||||
.virtual_channel = 0,
|
||||
|
||||
// Gray8 -> RGB888
|
||||
.in_color_format = LCD_COLOR_FMT_GRAY8,
|
||||
.out_color_format = LCD_COLOR_FMT_RGB888,
|
||||
|
||||
.video_timing = {
|
||||
.h_size = MIPI_DSI_LCD_H_RES,
|
||||
.v_size = MIPI_DSI_LCD_V_RES,
|
||||
.hsync_back_porch = MIPI_DSI_LCD_HBP,
|
||||
.hsync_pulse_width = MIPI_DSI_LCD_HSYNC,
|
||||
.hsync_front_porch = MIPI_DSI_LCD_HFP,
|
||||
.vsync_back_porch = MIPI_DSI_LCD_VBP,
|
||||
.vsync_pulse_width = MIPI_DSI_LCD_VSYNC,
|
||||
.vsync_front_porch = MIPI_DSI_LCD_VFP,
|
||||
},
|
||||
};
|
||||
ek79007_vendor_config_t vendor_config = {
|
||||
.mipi_config = {
|
||||
.dsi_bus = mipi_dsi_bus,
|
||||
.dpi_config = &dpi_config,
|
||||
},
|
||||
};
|
||||
esp_lcd_panel_dev_config_t lcd_dev_config = {
|
||||
.reset_gpio_num = -1,
|
||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
|
||||
.bits_per_pixel = 24,
|
||||
.vendor_config = &vendor_config,
|
||||
};
|
||||
TEST_ESP_OK(esp_lcd_new_panel_ek79007(mipi_dbi_io, &lcd_dev_config, &mipi_dpi_panel));
|
||||
|
||||
TEST_ESP_OK(esp_lcd_panel_reset(mipi_dpi_panel));
|
||||
TEST_ESP_OK(esp_lcd_panel_init(mipi_dpi_panel));
|
||||
|
||||
// YUV images are embedded in the firmware binary
|
||||
extern const uint8_t image_hello_gray_start[] asm("_binary_hello_gray_start");
|
||||
extern const uint8_t image_world_gray_start[] asm("_binary_world_gray_start");
|
||||
|
||||
printf("Draw Gray8 images\r\n");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
TEST_ESP_OK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, 320, 320, image_hello_gray_start));
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
TEST_ESP_OK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, 320, 320, image_world_gray_start));
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
|
||||
TEST_ESP_OK(esp_lcd_panel_del(mipi_dpi_panel));
|
||||
TEST_ESP_OK(esp_lcd_panel_io_del(mipi_dbi_io));
|
||||
TEST_ESP_OK(esp_lcd_del_dsi_bus(mipi_dsi_bus));
|
||||
|
||||
test_bsp_disable_dsi_phy_power();
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ from pytest_embedded_idf.utils import idf_parametrize
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'iram_safe',
|
||||
'cache_safe',
|
||||
'release',
|
||||
],
|
||||
indirect=True,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# How to generate the YUV image from the PNG image
|
||||
# How to get a YUV image from a PNG image
|
||||
|
||||
```bash
|
||||
ffmpeg -i hello.png -pix_fmt yuyv422 hello.yuv
|
||||
ffmpeg -i hello.png -pix_fmt yuyv422 -f rawvideo hello.yuv
|
||||
```
|
||||
|
||||
## Supported YUV422 packing order
|
||||
@@ -11,3 +11,9 @@ ffmpeg -i hello.png -pix_fmt yuyv422 hello.yuv
|
||||
| yuyv422 | 3 | 16 | 8-8-8 |
|
||||
| yvyu422 | 3 | 16 | 8-8-8 |
|
||||
| uyvy422 | 3 | 16 | 8-8-8 |
|
||||
|
||||
# How to get a gray8 raw image from a PNG image
|
||||
|
||||
```bash
|
||||
ffmpeg -i hello.png -vf format=gray -pix_fmt gray -f rawvideo hello.gray
|
||||
```
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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
|
@@ -29,6 +29,8 @@ uint32_t color_hal_pixel_format_get_bit_depth(color_space_pixel_format_t format)
|
||||
case COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565):
|
||||
case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422):
|
||||
return 16;
|
||||
case COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB666):
|
||||
return 18;
|
||||
case COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888):
|
||||
case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV444):
|
||||
return 24;
|
||||
|
@@ -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,161 @@ 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;
|
||||
case LCD_COLOR_FMT_GRAY8:
|
||||
dev->pixel_type.raw_type = 12;
|
||||
dev->pixel_type.data_in_type = 0;
|
||||
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
|
||||
|
@@ -32,7 +32,7 @@ typedef enum {
|
||||
} lcd_rgb_data_endian_t;
|
||||
|
||||
/**
|
||||
* @brief LCD color space
|
||||
* @brief The color space of the LCD input color data
|
||||
*/
|
||||
typedef enum {
|
||||
LCD_COLOR_SPACE_RGB = COLOR_SPACE_RGB, /*!< Color space: RGB */
|
||||
@@ -56,6 +56,7 @@ typedef enum {
|
||||
LCD_COLOR_FMT_RGB666 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB666), ///< RGB666
|
||||
LCD_COLOR_FMT_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), ///< RGB888
|
||||
LCD_COLOR_FMT_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), ///< YUV422
|
||||
LCD_COLOR_FMT_GRAY8 = COLOR_TYPE_ID(COLOR_SPACE_GRAY, COLOR_PIXEL_GRAY8), ///< 8-bit gray scale
|
||||
} lcd_color_format_t;
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
|
@@ -414,7 +414,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
|
||||
@@ -431,10 +431,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
|
||||
@@ -443,23 +445,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));
|
||||
|
@@ -173,7 +173,8 @@ LCD
|
||||
- The ``color_space`` and ``rgb_endian`` configuration options in the :cpp:type:`esp_lcd_panel_dev_config_t` structure have been replaced by the :cpp:member:`esp_lcd_panel_dev_config_t::rgb_ele_order` member, which sets the RGB element order. The corresponding types ``lcd_color_rgb_endian_t`` and ``esp_lcd_color_space_t`` have also been removed; use :cpp:type:`lcd_rgb_element_order_t` instead.
|
||||
- The ``esp_lcd_panel_disp_off`` function has been removed. Please use the :func:`esp_lcd_panel_disp_on_off` function to control display on/off.
|
||||
- The ``on_bounce_frame_finish`` member in :cpp:type:`esp_lcd_rgb_panel_event_callbacks_t` has been replaced by :cpp:member:`esp_lcd_rgb_panel_event_callbacks_t::on_frame_buf_complete`, which indicates that a complete frame buffer has been sent to the LCD controller.
|
||||
- The legacy I2C driver ``driver/i2c.h`` is deprecated since version 5.2. Starting from version 6.0, LCD driver based on legacy I2C is removed and LCD driver would only based on new I2C driver ``driver/i2c_master.h``.
|
||||
- The LCD IO layer driver for the I2C interface previously had two implementations, based on the new and legacy I2C master bus drivers. As the legacy I2C driver is being deprecated, support for it in the LCD IO layer has been removed. Only the APIs provided in ``driver/i2c_master.h`` are now used.
|
||||
- :cpp:member:`esp_lcd_dpi_panel_config_t::pixel_format` member is deprecated. It is recommended to only use :cpp:member:`esp_lcd_dpi_panel_config_t::in_color_format` to set the MIPI DSI driver's input pixel data format.
|
||||
|
||||
SPI
|
||||
---
|
||||
|
@@ -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));
|
||||
|
@@ -173,7 +173,8 @@ LCD
|
||||
- :cpp:type:`esp_lcd_panel_dev_config_t` 结构体中的 ``color_space`` 和 ``rgb_endian`` 配置均已被 :cpp:member:`esp_lcd_panel_dev_config_t::rgb_ele_order` 成员取代,用来设置 RGB 元素的排列顺序。对应的类型 ``lcd_color_rgb_endian_t`` 和 ``esp_lcd_color_space_t`` 也已被移除,请使用 :cpp:type:`lcd_rgb_element_order_t` 替代。
|
||||
- ``esp_lcd_panel_disp_off`` 函数已被移除。请使用 :func:`esp_lcd_panel_disp_on_off` 函数来控制显示内容的开关。
|
||||
- :cpp:type:`esp_lcd_rgb_panel_event_callbacks_t` 中的 ``on_bounce_frame_finish`` 成员已被 :cpp:member:`esp_lcd_rgb_panel_event_callbacks_t::on_frame_buf_complete` 成员取代,用于指示一个完整的帧缓冲区已被发送给 LCD 控制器。
|
||||
- 基于旧版 I2C 的 LCD 驱动 ``driver/lcd.h`` 在 5.2 的版本中就已经被弃用。从 6.0 版本开始,基于旧版 I2C 的 LCD 驱动被完全移除并只使用基于 ``driver/i2c_master.h`` 的新驱动。
|
||||
- I2C 接口的 LCD IO 层驱动有两套实现,分别基于新、旧 I2C Master 总线驱动。由于旧版的 I2C Master 驱动逐渐被弃用,遂 LCD 的 IO 层也移除对旧版的支持,只使用 ``driver/i2c_master.h`` 中提供的 API。
|
||||
- :cpp:member:`esp_lcd_dpi_panel_config_t::pixel_format` 成员已经被废弃。建议仅使用 :cpp:member:`esp_lcd_dpi_panel_config_t::in_color_format` 来设定 MIPI DSI 驱动输入的像素数据格式。
|
||||
|
||||
SPI
|
||||
---
|
||||
|
@@ -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