lcd: alloc framebuffer in alignment

This commit is contained in:
morris 2021-12-28 10:36:03 +08:00
parent 8ea1c12d80
commit 0e15844706
2 changed files with 13 additions and 4 deletions

View File

@ -92,6 +92,8 @@ typedef struct {
lcd_clock_source_t clk_src; /*!< Clock source for the RGB LCD peripheral */ lcd_clock_source_t clk_src; /*!< Clock source for the RGB LCD peripheral */
esp_lcd_rgb_timing_t timings; /*!< RGB timing parameters */ esp_lcd_rgb_timing_t timings; /*!< RGB timing parameters */
size_t data_width; /*!< Number of data lines */ size_t data_width; /*!< Number of data lines */
size_t sram_trans_align; /*!< Alignment for framebuffer that allocated in SRAM */
size_t psram_trans_align; /*!< Alignment for framebuffer that allocated in PSRAM */
int hsync_gpio_num; /*!< GPIO used for HSYNC signal */ int hsync_gpio_num; /*!< GPIO used for HSYNC signal */
int vsync_gpio_num; /*!< GPIO used for VSYNC signal */ int vsync_gpio_num; /*!< GPIO used for VSYNC signal */
int de_gpio_num; /*!< GPIO used for DE signal, set to -1 if it's not used */ int de_gpio_num; /*!< GPIO used for DE signal, set to -1 if it's not used */

View File

@ -65,6 +65,8 @@ struct esp_rgb_panel_t {
int panel_id; // LCD panel ID int panel_id; // LCD panel ID
lcd_hal_context_t hal; // Hal layer object lcd_hal_context_t hal; // Hal layer object
size_t data_width; // Number of data lines (e.g. for RGB565, the data width is 16) size_t data_width; // Number of data lines (e.g. for RGB565, the data width is 16)
size_t sram_trans_align; // Alignment for framebuffer that allocated in SRAM
size_t psram_trans_align; // Alignment for framebuffer that allocated in PSRAM
int disp_gpio_num; // Display control GPIO, which is used to perform action like "disp_off" int disp_gpio_num; // Display control GPIO, which is used to perform action like "disp_off"
intr_handle_t intr; // LCD peripheral interrupt handle intr_handle_t intr; // LCD peripheral interrupt handle
esp_pm_lock_handle_t pm_lock; // Power management lock esp_pm_lock_handle_t pm_lock; // Power management lock
@ -125,12 +127,17 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf
} }
#endif #endif
} }
size_t psram_trans_align = rgb_panel_config->psram_trans_align ? rgb_panel_config->psram_trans_align : 64;
size_t sram_trans_align = rgb_panel_config->sram_trans_align ? rgb_panel_config->sram_trans_align : 4;
if (alloc_from_psram) { if (alloc_from_psram) {
rgb_panel->fb = heap_caps_calloc(1, fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); // the low level malloc function will help check the validation of alignment
rgb_panel->fb = heap_caps_aligned_calloc(psram_trans_align, 1, fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
} else { } else {
rgb_panel->fb = heap_caps_calloc(1, fb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); rgb_panel->fb = heap_caps_aligned_calloc(sram_trans_align, 1, fb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
} }
ESP_GOTO_ON_FALSE(rgb_panel->fb, ESP_ERR_NO_MEM, err, TAG, "no mem for frame buffer"); ESP_GOTO_ON_FALSE(rgb_panel->fb, ESP_ERR_NO_MEM, err, TAG, "no mem for frame buffer");
rgb_panel->psram_trans_align = psram_trans_align;
rgb_panel->sram_trans_align = sram_trans_align;
rgb_panel->fb_size = fb_size; rgb_panel->fb_size = fb_size;
rgb_panel->flags.fb_in_psram = alloc_from_psram; rgb_panel->flags.fb_in_psram = alloc_from_psram;
// semaphore indicates new frame trans done // semaphore indicates new frame trans done
@ -478,8 +485,8 @@ static esp_err_t lcd_rgb_panel_create_trans_link(esp_rgb_panel_t *panel)
ESP_GOTO_ON_ERROR(ret, err, TAG, "alloc DMA channel failed"); ESP_GOTO_ON_ERROR(ret, err, TAG, "alloc DMA channel failed");
gdma_connect(panel->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_LCD, 0)); gdma_connect(panel->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_LCD, 0));
gdma_transfer_ability_t ability = { gdma_transfer_ability_t ability = {
.psram_trans_align = 64, .psram_trans_align = panel->psram_trans_align,
.sram_trans_align = 4, .sram_trans_align = panel->sram_trans_align,
}; };
gdma_set_transfer_ability(panel->dma_chan, &ability); gdma_set_transfer_ability(panel->dma_chan, &ability);
// the start of DMA should be prior to the start of LCD engine // the start of DMA should be prior to the start of LCD engine