ESP32-P4 --- LCD 控制

 用户把需要更新的像素数据通过拷贝或者DMA搬到 frame buffer,然后刷一下CACHE

static esp_err_t dpi_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data)

frame buffer 的数据是通过DMA不停的发送到 DSI bridge(FIFO memory of peripheral: DSI),一帧搬完,在完成回调函数重新启动DMA

static esp_err_t dpi_panel_create_dma_link(esp_lcd_dpi_panel_t *dpi_panel)

DMA的源地址和目的地址在这里设置

完成回调函数即是场同步信号,可以在这里计数得到实际刷新频率(frame per second)

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 yield_needed = false;
    esp_lcd_dpi_panel_t *dpi_panel = (esp_lcd_dpi_panel_t *)user_data;
    uint8_t fb_index = dpi_panel->cur_fb_index;
    dw_gdma_link_list_handle_t link_list = dpi_panel->link_lists[fb_index];

    // restart the DMA transfer, keep refreshing the LCD
    dw_gdma_block_markers_t markers = {
        .is_valid = true,
        .is_last = true,
    };
    dw_gdma_lli_set_block_markers(dw_gdma_link_list_get_item(link_list, 0), markers);
    dw_gdma_channel_use_link_list(chan, link_list);
    dw_gdma_channel_enable_ctrl(chan, true); // 启动 DMA 搬移

    // the DMA descriptor is large enough to carry a whole frame buffer, so this event can also be treated as a fake "vsync end"
    if (dpi_panel->on_refresh_done) {
        if (dpi_panel->on_refresh_done(&dpi_panel->base, NULL, dpi_panel->user_ctx)) {
            yield_needed = true;
        }
    }
    return yield_needed;
}

 

posted @ 2024-04-23 16:53  流水灯  阅读(95)  评论(0编辑  收藏  举报