Skip to content

Commit 0019a9f

Browse files
committed
Merge branch 'change/mipi_dsi_minor_change_v5.3' into 'release/v5.3'
feat(mipi_dsi): update low level functions to include underrun interrupt (v5.3) See merge request espressif/esp-idf!32389
2 parents a156e28 + 0417d48 commit 0019a9f

File tree

5 files changed

+78
-23
lines changed

5 files changed

+78
-23
lines changed

components/esp_lcd/dsi/esp_lcd_panel_dpi.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ struct esp_lcd_dpi_panel_t {
3232
esp_lcd_panel_t base; // Base class of generic lcd panel
3333
esp_lcd_dsi_bus_handle_t bus; // DSI bus handle
3434
uint8_t virtual_channel; // Virtual channel ID, index from 0
35-
uint8_t cur_fb_index; // Current frame buffer index
36-
uint8_t num_fbs; // Number of frame buffers
35+
uint8_t cur_fb_index; // Current frame buffer index
36+
uint8_t num_fbs; // Number of frame buffers
3737
uint8_t *fbs[DPI_PANEL_MAX_FB_NUM]; // Frame buffers
3838
uint32_t h_pixels; // Horizontal pixels
3939
uint32_t v_pixels; // Vertical pixels
40-
size_t frame_buffer_size; // Frame buffer size
40+
size_t fb_size; // Frame buffer size, in bytes
4141
size_t bits_per_pixel; // Bits per pixel
4242
lcd_color_rgb_pixel_format_t pixel_format; // RGB Pixel format
4343
dw_gdma_channel_handle_t dma_chan; // DMA channel
@@ -126,7 +126,7 @@ static esp_err_t dpi_panel_create_dma_link(esp_lcd_dpi_panel_t *dpi_panel)
126126

127127
// create DMA link lists
128128
dw_gdma_link_list_config_t link_list_config = {
129-
.num_items = DPI_PANEL_LLI_PER_FRAME,
129+
.num_items = DPI_PANEL_MIN_DMA_NODES_PER_LINK,
130130
.link_type = DW_GDMA_LINKED_LIST_TYPE_SINGLY,
131131
};
132132
for (int i = 0; i < dpi_panel->num_fbs; i++) {
@@ -191,21 +191,21 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
191191
uint32_t cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
192192
// DMA doesn't have requirement on the buffer alignment, but the cache does
193193
uint32_t alignment = cache_line_size;
194-
size_t frame_buffer_size = panel_config->video_timing.h_size * panel_config->video_timing.v_size * bits_per_pixel / 8;
194+
size_t fb_size = panel_config->video_timing.h_size * panel_config->video_timing.v_size * bits_per_pixel / 8;
195195
uint8_t *frame_buffer = NULL;
196196
for (int i = 0; i < num_fbs; i++) {
197-
frame_buffer = heap_caps_aligned_calloc(alignment, 1, frame_buffer_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
197+
frame_buffer = heap_caps_aligned_calloc(alignment, 1, fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
198198
ESP_GOTO_ON_FALSE(frame_buffer, ESP_ERR_NO_MEM, err, TAG, "no memory for frame buffer");
199199
dpi_panel->fbs[i] = frame_buffer;
200200
ESP_LOGD(TAG, "fb[%d] @%p", i, frame_buffer);
201201
// preset the frame buffer with black color
202202
// the frame buffer address alignment is ensured by `heap_caps_aligned_calloc`
203-
// while the value of the frame_buffer_size may not be aligned to the cache line size
203+
// while the value of the fb_size may not be aligned to the cache line size
204204
// 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
205-
ESP_GOTO_ON_ERROR(esp_cache_msync(frame_buffer, frame_buffer_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED),
205+
ESP_GOTO_ON_ERROR(esp_cache_msync(frame_buffer, fb_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED),
206206
err, TAG, "cache write back failed");
207207
}
208-
dpi_panel->frame_buffer_size = frame_buffer_size;
208+
dpi_panel->fb_size = fb_size;
209209
dpi_panel->bits_per_pixel = bits_per_pixel;
210210
dpi_panel->h_pixels = panel_config->video_timing.h_size;
211211
dpi_panel->v_pixels = panel_config->video_timing.v_size;
@@ -282,6 +282,7 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_
282282
mipi_dsi_brg_ll_set_underrun_discard_count(hal->bridge, panel_config->video_timing.h_size);
283283
// use the DW_GDMA as the flow controller
284284
mipi_dsi_brg_ll_set_flow_controller(hal->bridge, MIPI_DSI_LL_FLOW_CONTROLLER_DMA);
285+
mipi_dsi_brg_ll_set_multi_block_number(hal->bridge, DPI_PANEL_MIN_DMA_NODES_PER_LINK);
285286
mipi_dsi_brg_ll_set_burst_len(hal->bridge, 256);
286287
mipi_dsi_brg_ll_set_empty_threshold(hal->bridge, 1024 - 256);
287288
// enable DSI bridge
@@ -381,7 +382,7 @@ static esp_err_t dpi_panel_init(esp_lcd_panel_t *panel)
381382
.burst_len = 16,
382383
.width = DW_GDMA_TRANS_WIDTH_64,
383384
},
384-
.size = dpi_panel->frame_buffer_size * 8 / 64,
385+
.size = dpi_panel->fb_size * 8 / 64,
385386
};
386387
for (int i = 0; i < dpi_panel->num_fbs; i++) {
387388
link_list = dpi_panel->link_lists[i];
@@ -419,7 +420,7 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int
419420
uint8_t cur_fb_index = dpi_panel->cur_fb_index;
420421
uint8_t *frame_buffer = dpi_panel->fbs[cur_fb_index];
421422
uint8_t *draw_buffer = (uint8_t *)color_data;
422-
size_t frame_buffer_size = dpi_panel->frame_buffer_size;
423+
size_t fb_size = dpi_panel->fb_size;
423424
size_t bits_per_pixel = dpi_panel->bits_per_pixel;
424425

425426
// clip to boundaries
@@ -434,11 +435,11 @@ static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int
434435
uint8_t draw_buf_fb_index = 0;
435436
// check if the user draw buffer resides in any frame buffer's memory range
436437
// if so, we don't need to copy the data, just do cache write back
437-
if (draw_buffer >= dpi_panel->fbs[0] && draw_buffer < dpi_panel->fbs[0] + frame_buffer_size) {
438+
if (draw_buffer >= dpi_panel->fbs[0] && draw_buffer < dpi_panel->fbs[0] + fb_size) {
438439
draw_buf_fb_index = 0;
439-
} else if (draw_buffer >= dpi_panel->fbs[1] && draw_buffer < dpi_panel->fbs[1] + frame_buffer_size) {
440+
} else if (draw_buffer >= dpi_panel->fbs[1] && draw_buffer < dpi_panel->fbs[1] + fb_size) {
440441
draw_buf_fb_index = 1;
441-
} else if (draw_buffer >= dpi_panel->fbs[2] && draw_buffer < dpi_panel->fbs[2] + frame_buffer_size) {
442+
} else if (draw_buffer >= dpi_panel->fbs[2] && draw_buffer < dpi_panel->fbs[2] + fb_size) {
442443
draw_buf_fb_index = 2;
443444
} else {
444445
do_copy = true;

components/esp_lcd/dsi/mipi_dsi_priv.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@
2929
#define DSI_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
3030
#endif
3131

32-
#define DPI_PANEL_MAX_FB_NUM 3 // maximum number of supported frame buffers for DPI panel
33-
34-
#define DPI_PANEL_LLI_PER_FRAME 1 // NOTE: we assume ONE DMA link item can carry the WHOLE image (1920*1080)
32+
#define DPI_PANEL_MAX_FB_NUM 3 // maximum number of frame buffers that can be maintained by the driver
33+
#define DPI_PANEL_MIN_DMA_NODES_PER_LINK 1 // NOTE: we assume 1 DMA link item can carry the WHOLE image
3534

3635
#ifdef __cplusplus
3736
extern "C" {

components/esp_lcd/test_apps/mipi_dsi_lcd/main/test_mipi_dsi_panel.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,16 +222,16 @@ TEST_CASE("MIPI DSI with multiple frame buffers (ILI9881C)", "[mipi_dsi]")
222222
uint16_t *fbs[3];
223223
TEST_ESP_OK(esp_lcd_dpi_panel_get_frame_buffer(mipi_dpi_panel, 3, (void **)&fbs[0], (void **)&fbs[1], (void **)&fbs[2]));
224224

225-
for (int i = 0; i < 3; i++) {
225+
for (int i = 0; i < 9; i++) {
226226
uint16_t color_byte = rand() & 0xFFFF;
227227
int x_start = rand() % (MIPI_DSI_LCD_H_RES - 100);
228228
int y_start = rand() % (MIPI_DSI_LCD_V_RES - 100);
229229
for (int j = y_start; j < y_start + 100; j++) {
230230
for (int k = x_start; k < x_start + 100; k++) {
231-
fbs[i][j * MIPI_DSI_LCD_H_RES + k] = color_byte;
231+
fbs[i % 3][j * MIPI_DSI_LCD_H_RES + k] = color_byte;
232232
}
233233
}
234-
esp_lcd_panel_draw_bitmap(mipi_dpi_panel, x_start, y_start, x_start + 100, y_start + 100, fbs[i]);
234+
esp_lcd_panel_draw_bitmap(mipi_dpi_panel, x_start, y_start, x_start + 100, y_start + 100, fbs[i % 3]);
235235
vTaskDelay(pdMS_TO_TICKS(1000));
236236
}
237237

components/hal/esp32p4/include/hal/mipi_dsi_brg_ll.h

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "hal/lcd_types.h"
1515

1616
#define MIPI_DSI_LL_GET_BRG(bus_id) (bus_id == 0 ? &MIPI_DSI_BRIDGE : NULL)
17+
#define MIPI_DSI_LL_EVENT_UNDERRUN (1 << 0)
1718

1819
#ifdef __cplusplus
1920
extern "C" {
@@ -35,6 +36,46 @@ static inline void mipi_dsi_brg_ll_enable(dsi_brg_dev_t *dev, bool en)
3536
dev->en.dsi_en = en;
3637
}
3738

39+
/**
40+
* @brief Enable DSI bridge interrupt for specific event mask
41+
*
42+
* @param dev Pointer to the DSI bridge controller register base address
43+
* @param mask Event mask
44+
* @param enable True to enable, False to disable
45+
*/
46+
static inline void mipi_dsi_brg_ll_enable_interrupt(dsi_brg_dev_t *dev, uint32_t mask, bool enable)
47+
{
48+
if (enable) {
49+
dev->int_ena.val |= mask;
50+
} else {
51+
dev->int_ena.val &= ~mask;
52+
}
53+
}
54+
55+
/**
56+
* @brief Clear DSI bridge interrupt for specific event mask
57+
*
58+
* @param dev Pointer to the DSI bridge controller register base address
59+
* @param mask Event mask
60+
*/
61+
__attribute__((always_inline))
62+
static inline void mipi_dsi_brg_ll_clear_interrupt_status(dsi_brg_dev_t *dev, uint32_t mask)
63+
{
64+
dev->int_clr.val = mask;
65+
}
66+
67+
/**
68+
* @brief Get interrupt status for DSI bridge
69+
*
70+
* @param dev Pointer to the DSI bridge controller register base address
71+
* @return Interrupt status
72+
*/
73+
__attribute__((always_inline))
74+
static inline uint32_t mipi_dsi_brg_ll_get_interrupt_status(dsi_brg_dev_t *dev)
75+
{
76+
return dev->int_st.val;
77+
}
78+
3879
/**
3980
* @brief Set the number of 64-bit words in one dma burst transfer
4081
*
@@ -242,7 +283,7 @@ static inline void mipi_dsi_brg_ll_enable_ref_clock(dsi_brg_dev_t *dev, bool en)
242283
* @param dev Pointer to the DSI bridge controller register base address
243284
* @param controller Flow controller
244285
*/
245-
static inline void mipi_dsi_brg_ll_set_flow_controller(dsi_brg_dev_t* dev, mipi_dsi_ll_flow_controller_t controller)
286+
static inline void mipi_dsi_brg_ll_set_flow_controller(dsi_brg_dev_t *dev, mipi_dsi_ll_flow_controller_t controller)
246287
{
247288
dev->dma_flow_ctrl.dsi_dma_flow_controller = controller;
248289
}
@@ -255,9 +296,21 @@ static inline void mipi_dsi_brg_ll_set_flow_controller(dsi_brg_dev_t* dev, mipi_
255296
* @param dev Pointer to the DSI bridge controller register base address
256297
* @param number Number of blocks
257298
*/
258-
static inline void mipi_dsi_brg_ll_set_multi_block_number(dsi_brg_dev_t* dev, uint32_t number)
299+
static inline void mipi_dsi_brg_ll_set_multi_block_number(dsi_brg_dev_t *dev, uint32_t number)
259300
{
260301
dev->dma_flow_ctrl.dma_flow_multiblk_num = number;
302+
dev->dma_frame_interval.dma_multiblk_en = number > 1;
303+
}
304+
305+
/**
306+
* @brief Get the FIFO depth of the DSI bridge
307+
*
308+
* @param dev Pointer to the DSI bridge controller register base address
309+
* @return FIFO depth
310+
*/
311+
static inline uint32_t mipi_dsi_brg_ll_get_fifo_depth(dsi_brg_dev_t *dev)
312+
{
313+
return dev->fifo_flow_status.raw_buf_depth;
261314
}
262315

263316
/**
@@ -266,7 +319,7 @@ static inline void mipi_dsi_brg_ll_set_multi_block_number(dsi_brg_dev_t* dev, ui
266319
* @param dev Pointer to the DSI bridge controller register base address
267320
* @param std YUV-RGB conversion standard
268321
*/
269-
static inline void mipi_dsi_brg_ll_set_yuv_convert_std(dsi_brg_dev_t* dev, lcd_yuv_conv_std_t std)
322+
static inline void mipi_dsi_brg_ll_set_yuv_convert_std(dsi_brg_dev_t *dev, lcd_yuv_conv_std_t std)
270323
{
271324
switch (std) {
272325
case LCD_YUV_CONV_STD_BT601:

components/soc/esp32p4/include/soc/reg_base.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@
5959
#define DR_REG_DDRPHY_BASE (DR_REG_HPPERIPH0_BASE + 0x9D000)
6060
#define DR_REG_PVT_BASE (DR_REG_HPPERIPH0_BASE + 0x9E000)
6161
#define DR_REG_CSI_HOST_BASE (DR_REG_HPPERIPH0_BASE + 0x9F000)
62+
#define DR_REG_CSI_BRG_BASE (DR_REG_HPPERIPH0_BASE + 0x9F800)
6263
#define DR_REG_DSI_HOST_BASE (DR_REG_HPPERIPH0_BASE + 0xA0000)
64+
#define DR_REG_DSI_BRG_BASE (DR_REG_HPPERIPH0_BASE + 0xA0800)
6365
#define DR_REG_ISP_BASE (DR_REG_HPPERIPH0_BASE + 0xA1000)
6466
#define DR_REG_RMT_BASE (DR_REG_HPPERIPH0_BASE + 0xA2000)
6567
#define DR_REG_BITSCRAM_BASE (DR_REG_HPPERIPH0_BASE + 0xA3000)

0 commit comments

Comments
 (0)