Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix (esp_lcd): Don't assume panels are 16bit in VSYNC restart logic (IDFGH-11941) #13020

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions components/esp_lcd/src/esp_lcd_panel_rgb.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf

// install DMA service
rgb_panel->flags.stream_mode = !rgb_panel_config->flags.refresh_on_demand;
rgb_panel->fb_bits_per_pixel = fb_bits_per_pixel;
ret = lcd_rgb_panel_create_trans_link(rgb_panel);
ESP_GOTO_ON_ERROR(ret, err, TAG, "install DMA failed");
// configure GPIO
Expand All @@ -338,7 +339,6 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf
memcpy(rgb_panel->data_gpio_nums, rgb_panel_config->data_gpio_nums, SOC_LCD_RGB_DATA_WIDTH);
rgb_panel->timings = rgb_panel_config->timings;
rgb_panel->data_width = rgb_panel_config->data_width;
rgb_panel->fb_bits_per_pixel = fb_bits_per_pixel;
rgb_panel->output_bits_per_pixel = fb_bits_per_pixel; // by default, the output bpp is the same as the frame buffer bpp
rgb_panel->disp_gpio_num = rgb_panel_config->disp_gpio_num;
rgb_panel->flags.disp_en_level = !rgb_panel_config->flags.disp_active_low;
Expand Down Expand Up @@ -1006,7 +1006,7 @@ static esp_err_t lcd_rgb_panel_create_trans_link(esp_rgb_panel_t *panel)
// so we use a dedicated DMA node to restart the DMA transaction
// see also `lcd_rgb_panel_try_restart_transmission`
memcpy(&panel->dma_restart_node, &panel->dma_nodes[0], sizeof(panel->dma_restart_node));
int restart_skip_bytes = LCD_FIFO_PRESERVE_SIZE_PX * sizeof(uint16_t);
int restart_skip_bytes = LCD_FIFO_PRESERVE_SIZE_PX * (panel->fb_bits_per_pixel/8);
uint8_t *p = (uint8_t *)panel->dma_restart_node.buffer;
panel->dma_restart_node.buffer = &p[restart_skip_bytes];
panel->dma_restart_node.dw0.length -= restart_skip_bytes;
Expand Down Expand Up @@ -1048,6 +1048,7 @@ static esp_err_t lcd_rgb_panel_create_trans_link(esp_rgb_panel_t *panel)
// time to reset DMA.
static IRAM_ATTR void lcd_rgb_panel_try_restart_transmission(esp_rgb_panel_t *panel)
{
int bb_size_px = panel->bb_size / (panel->fb_bits_per_pixel / 8);
bool do_restart = false;
#if CONFIG_LCD_RGB_RESTART_IN_VSYNC
do_restart = true;
Expand All @@ -1070,11 +1071,11 @@ static IRAM_ATTR void lcd_rgb_panel_try_restart_transmission(esp_rgb_panel_t *pa

if (panel->bb_size) {
// Catch de-synced frame buffer and reset if needed.
if (panel->bounce_pos_px > panel->bb_size) {
if (panel->bounce_pos_px > bb_size_px*2) {
panel->bounce_pos_px = 0;
}
// Pre-fill bounce buffer 0, if the EOF ISR didn't do that already
if (panel->bounce_pos_px < panel->bb_size / 2) {
if (panel->bounce_pos_px < bb_size_px) {
lcd_rgb_panel_fill_bounce_buffer(panel, panel->bounce_buffer[0]);
}
}
Expand All @@ -1085,10 +1086,11 @@ static IRAM_ATTR void lcd_rgb_panel_try_restart_transmission(esp_rgb_panel_t *pa

if (panel->bb_size) {
// Fill 2nd bounce buffer while 1st is being sent out, if needed.
if (panel->bounce_pos_px < panel->bb_size) {
lcd_rgb_panel_fill_bounce_buffer(panel, panel->bounce_buffer[0]);
if (panel->bounce_pos_px < bb_size_px*2) {
lcd_rgb_panel_fill_bounce_buffer(panel, panel->bounce_buffer[1]);
}
}

}

static void lcd_rgb_panel_start_transmission(esp_rgb_panel_t *rgb_panel)
Expand Down
Loading