mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
Merge branch 'refactor/lcd_i80_gpio_config_v5.2' into 'release/v5.2'
Optimize RGB LCD IRAM usage (v5.2) See merge request espressif/esp-idf!34126
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user