diff --git a/components/esp_lcd/Kconfig b/components/esp_lcd/Kconfig index 25a77c8376..84f2df704b 100644 --- a/components/esp_lcd/Kconfig +++ b/components/esp_lcd/Kconfig @@ -19,6 +19,7 @@ menu "LCD and Touch Panel" if SOC_LCD_RGB_SUPPORTED config LCD_RGB_ISR_IRAM_SAFE bool "RGB LCD ISR IRAM-Safe" + select GDMA_ISR_IRAM_SAFE # bounce buffer mode relies on GDMA EOF interrupt default n help Ensure the LCD interrupt is IRAM-Safe by allowing the interrupt handler to be @@ -29,7 +30,6 @@ menu "LCD and Touch Panel" config LCD_RGB_RESTART_IN_VSYNC bool "Restart transmission in VSYNC" default n - select GDMA_CTRL_FUNC_IN_IRAM # need to restart GDMA in the LCD ISR help Reset the GDMA channel every VBlank to stop permanent desyncs from happening. Only need to enable it when in your application, the DMA can't deliver data diff --git a/components/esp_lcd/linker.lf b/components/esp_lcd/linker.lf index 6e3aa0d3cd..513429d536 100644 --- a/components/esp_lcd/linker.lf +++ b/components/esp_lcd/linker.lf @@ -1,8 +1,9 @@ -[mapping:esp_lcd_driver] -archive: libesp_lcd.a +[mapping:esp_lcd_gdma] +archive: libesp_hw_support.a entries: if LCD_RGB_ISR_IRAM_SAFE = y: - esp_lcd_common: lcd_com_mount_dma_data (noflash) + gdma: gdma_reset (noflash) + gdma: gdma_start (noflash) [mapping:esp_lcd_hal] archive: libhal.a diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c index a835f26558..416d949a9d 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c @@ -58,7 +58,7 @@ static esp_err_t i2s_lcd_init_dma_link(esp_lcd_i80_bus_handle_t bus); static esp_err_t i2s_lcd_configure_gpio(esp_lcd_i80_bus_handle_t bus, const esp_lcd_i80_bus_config_t *bus_config); static void i2s_lcd_trigger_quick_trans_done_event(esp_lcd_i80_bus_handle_t bus); static void lcd_i80_switch_devices(lcd_panel_io_i80_t *cur_device, lcd_panel_io_i80_t *next_device); -static void lcd_default_isr_handler(void *args); +static void i2s_lcd_default_isr_handler(void *args); static esp_err_t panel_io_i80_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx); struct esp_lcd_i80_bus_t { @@ -175,7 +175,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc int isr_flags = LCD_I80_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED; ret = esp_intr_alloc_intrstatus(lcd_periph_signals.buses[bus->bus_id].irq_id, isr_flags, (uint32_t)i2s_ll_get_intr_status_reg(bus->hal.dev), - I2S_LL_EVENT_TX_EOF, lcd_default_isr_handler, bus, &bus->intr); + I2S_LL_EVENT_TX_EOF, i2s_lcd_default_isr_handler, bus, &bus->intr); ESP_GOTO_ON_ERROR(ret, err, TAG, "install interrupt failed"); i2s_ll_enable_intr(bus->hal.dev, I2S_LL_EVENT_TX_EOF, false); // disable interrupt temporarily i2s_ll_clear_intr_status(bus->hal.dev, I2S_LL_EVENT_TX_EOF); // clear pending interrupt @@ -604,7 +604,7 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons xQueueSend(next_device->trans_queue, &trans_desc, portMAX_DELAY); next_device->num_trans_inflight++; // enable interrupt and go into isr handler, where we fetch the transactions from trans_queue and start it - // we will go into `lcd_default_isr_handler` almost at once, because the "trans done" event is active at the moment + // we will go into `i2s_lcd_default_isr_handler` almost at once, because the "trans done" event is active at the moment esp_intr_enable(bus->intr); return ESP_OK; } @@ -709,7 +709,7 @@ static void lcd_i80_switch_devices(lcd_panel_io_i80_t *cur_device, lcd_panel_io_ bus->cur_device = next_device; } -static IRAM_ATTR void lcd_default_isr_handler(void *args) +static IRAM_ATTR void i2s_lcd_default_isr_handler(void *args) { esp_lcd_i80_bus_t *bus = (esp_lcd_i80_bus_t *)args; lcd_i80_trans_descriptor_t *trans_desc = NULL; diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i80.c b/components/esp_lcd/src/esp_lcd_panel_io_i80.c index 8164455419..27cca1cb0c 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i80.c @@ -58,7 +58,7 @@ static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c static esp_err_t lcd_i80_bus_configure_gpio(esp_lcd_i80_bus_handle_t bus, const esp_lcd_i80_bus_config_t *bus_config); static void lcd_i80_switch_devices(lcd_panel_io_i80_t *cur_device, lcd_panel_io_i80_t *next_device); static void lcd_start_transaction(esp_lcd_i80_bus_t *bus, lcd_i80_trans_descriptor_t *trans_desc); -static void lcd_default_isr_handler(void *args); +static void i80_lcd_default_isr_handler(void *args); static esp_err_t panel_io_i80_register_event_callbacks(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_io_callbacks_t *cbs, void *user_ctx); struct esp_lcd_i80_bus_t { @@ -165,7 +165,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc int isr_flags = LCD_I80_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED; ret = esp_intr_alloc_intrstatus(lcd_periph_signals.buses[bus_id].irq_id, isr_flags, (uint32_t)lcd_ll_get_interrupt_status_reg(bus->hal.dev), - LCD_LL_EVENT_TRANS_DONE, lcd_default_isr_handler, bus, &bus->intr); + LCD_LL_EVENT_TRANS_DONE, i80_lcd_default_isr_handler, bus, &bus->intr); ESP_GOTO_ON_ERROR(ret, err, TAG, "install interrupt failed"); lcd_ll_enable_interrupt(bus->hal.dev, LCD_LL_EVENT_TRANS_DONE, false); // disable all interrupts lcd_ll_clear_interrupt_status(bus->hal.dev, UINT32_MAX); // clear pending interrupt @@ -503,7 +503,7 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons xQueueSend(i80_device->trans_queue, &trans_desc, portMAX_DELAY); i80_device->num_trans_inflight++; // enable interrupt and go into isr handler, where we fetch the transactions from trans_queue and start it - // we will go into `lcd_default_isr_handler` almost at once, because the "trans done" event is active at the moment + // we will go into `i80_lcd_default_isr_handler` almost at once, because the "trans done" event is active at the moment esp_intr_enable(bus->intr); return ESP_OK; } @@ -650,7 +650,7 @@ static void lcd_i80_switch_devices(lcd_panel_io_i80_t *cur_device, lcd_panel_io_ } } -IRAM_ATTR static void lcd_default_isr_handler(void *args) +IRAM_ATTR static void i80_lcd_default_isr_handler(void *args) { esp_lcd_i80_bus_t *bus = (esp_lcd_i80_bus_t *)args; lcd_i80_trans_descriptor_t *trans_desc = NULL; diff --git a/components/esp_lcd/src/esp_lcd_panel_rgb.c b/components/esp_lcd/src/esp_lcd_panel_rgb.c index e0c8ffb32f..25440360a1 100644 --- a/components/esp_lcd/src/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/src/esp_lcd_panel_rgb.c @@ -79,7 +79,7 @@ static esp_err_t lcd_rgb_panel_select_clock_src(esp_rgb_panel_t *panel, lcd_cloc static esp_err_t lcd_rgb_panel_create_trans_link(esp_rgb_panel_t *panel); static esp_err_t lcd_rgb_panel_configure_gpio(esp_rgb_panel_t *panel, const esp_lcd_rgb_panel_config_t *panel_config); static void lcd_rgb_panel_start_transmission(esp_rgb_panel_t *rgb_panel); -static void lcd_default_isr_handler(void *args); +static void rgb_lcd_default_isr_handler(void *args); struct esp_rgb_panel_t { esp_lcd_panel_t base; // Base class of generic lcd panel @@ -317,7 +317,7 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf int isr_flags = LCD_RGB_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED; ret = esp_intr_alloc_intrstatus(lcd_periph_signals.panels[panel_id].irq_id, isr_flags, (uint32_t)lcd_ll_get_interrupt_status_reg(rgb_panel->hal.dev), - LCD_LL_EVENT_VSYNC_END, lcd_default_isr_handler, rgb_panel, &rgb_panel->intr); + LCD_LL_EVENT_VSYNC_END, rgb_lcd_default_isr_handler, rgb_panel, &rgb_panel->intr); ESP_GOTO_ON_ERROR(ret, err, TAG, "install interrupt failed"); lcd_ll_enable_interrupt(rgb_panel->hal.dev, LCD_LL_EVENT_VSYNC_END, false); // disable all interrupts lcd_ll_clear_interrupt_status(rgb_panel->hal.dev, UINT32_MAX); // clear pending interrupt @@ -1105,7 +1105,7 @@ IRAM_ATTR static void lcd_rgb_panel_try_update_pclk(esp_rgb_panel_t *rgb_panel) portEXIT_CRITICAL_ISR(&rgb_panel->spinlock); } -IRAM_ATTR static void lcd_default_isr_handler(void *args) +IRAM_ATTR static void rgb_lcd_default_isr_handler(void *args) { esp_rgb_panel_t *rgb_panel = (esp_rgb_panel_t *)args; bool need_yield = false; diff --git a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.ci.iram_safe b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.ci.iram_safe index 8800405f61..40f8204e3c 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.ci.iram_safe +++ b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.ci.iram_safe @@ -1,8 +1,5 @@ CONFIG_COMPILER_DUMP_RTL_FILES=y CONFIG_LCD_RGB_ISR_IRAM_SAFE=y -CONFIG_GDMA_CTRL_FUNC_IN_IRAM=y -# bounce buffer mode relies on GDMA EOF interrupt to be service-able -CONFIG_GDMA_ISR_IRAM_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