refactor(drivers): refactor the iram-safe option of the gdma peripherals

Closes https://github.com/espressif/esp-idf/issues/15771
This commit is contained in:
morris
2025-04-14 18:19:36 +08:00
parent 7bcb7248bb
commit 2c376ff99f
22 changed files with 48 additions and 37 deletions

View File

@ -10,7 +10,7 @@ menu "ADC and ADC Calibration"
depends on SOC_ADC_DMA_SUPPORTED
bool "ADC continuous mode driver ISR IRAM-Safe"
default n
select GDMA_ISR_IRAM_SAFE if SOC_ADC_DMA_SUPPORTED && SOC_GDMA_SUPPORTED
select GDMA_ISR_HANDLER_IN_IRAM if SOC_ADC_DMA_SUPPORTED && SOC_GDMA_SUPPORTED
help
Ensure the ADC continuous mode ISR is IRAM-Safe. When enabled, the ISR handler
will be available when the cache is disabled.

View File

@ -30,6 +30,9 @@ esp_err_t adc_dma_init(adc_dma_t *adc_dma)
//alloc rx gdma channel
gdma_channel_alloc_config_t rx_alloc_config = {
.direction = GDMA_CHANNEL_DIRECTION_RX,
#if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE
.flags.isr_cache_safe = true,
#endif
};
ret = gdma_new_ahb_channel(&rx_alloc_config, &(adc_dma->gdma_chan));
if (ret != ESP_OK) {

View File

@ -23,5 +23,5 @@ entries:
if SOC_ADC_CALIBRATION_V1_SUPPORTED = y:
adc_hal_common: adc_hal_set_calibration_param (noflash)
adc_hal_common: adc_hal_calibration_init (noflash)
if ADC_CONTINUOUS_ISR_IRAM_SAFE = y || GDMA_ISR_IRAM_SAFE = y:
if ADC_CONTINUOUS_ISR_IRAM_SAFE = y:
adc_hal: adc_hal_get_reading_result (noflash)

View File

@ -142,7 +142,7 @@ TEST_CASE("ADC oneshot fast work with ISR and Flash", "[adc_oneshot]")
}
#endif //#if CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM && CONFIG_GPTIMER_ISR_IRAM_SAFE
#if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE || CONFIG_GDMA_ISR_IRAM_SAFE
#if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE
#include "esp_adc/adc_continuous.h"
/*---------------------------------------------------------------
ADC continuous work with cache safe ISR
@ -249,7 +249,7 @@ TEST_CASE("ADC continuous work with ISR and Flash", "[adc_continuous]")
TEST_ESP_OK(adc_continuous_deinit(handle));
}
#endif //#if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE || CONFIG_GDMA_ISR_IRAM_SAFE
#endif //#if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE
static void IRAM_ATTR NOINLINE_ATTR s_test_cache_disable_period_us(test_adc_iram_ctx_t *ctx, uint32_t period_us)
{

View File

@ -36,17 +36,3 @@ def test_adc(dut: Dut) -> None:
)
def test_adc_esp32c2_xtal_26mhz(dut: Dut) -> None:
dut.run_all_single_board_cases(timeout=120, reset=True)
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.esp32c5
@pytest.mark.esp32p4
@pytest.mark.adc
@pytest.mark.parametrize('config', [
'gdma_iram_safe',
], indirect=True)
def test_adc_gdma_iram(dut: Dut) -> None:
dut.run_all_single_board_cases(timeout=120, reset=True)

View File

@ -1,7 +0,0 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_GDMA_ISR_IRAM_SAFE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
CONFIG_HAL_ASSERTION_SILENT=y

View File

@ -29,10 +29,8 @@ menu "ESP-Driver:Camera Controller Configurations"
bool "DVP ISR Cache-Safe"
depends on SOC_LCDCAM_CAM_SUPPORTED
default n
select DW_GDMA_ISR_IRAM_SAFE
select DW_GDMA_CTRL_FUNC_IN_IRAM
select DW_GDMA_SETTER_FUNC_IN_IRAM
select DW_GDMA_GETTER_FUNC_IN_IRAM
select GDMA_ISR_HANDLER_IN_IRAM if SOC_GDMA_SUPPORTED
select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED
help
Ensure the DVP driver ISR is Cache-Safe. When enabled, the ISR handler
will be available when the cache is disabled.

View File

@ -65,6 +65,9 @@ esp_err_t esp_cam_ctlr_dvp_dma_init(esp_cam_ctlr_dvp_dma_t *dma, uint32_t burst_
gdma_channel_alloc_config_t rx_alloc_config = {
.direction = GDMA_CHANNEL_DIRECTION_RX,
#if CONFIG_CAM_CTLR_DVP_CAM_ISR_CACHE_SAFE
.flags.isr_cache_safe = true,
#endif
};
ESP_RETURN_ON_ERROR(esp_cache_get_alignment(MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA, &alignment_size), TAG, "failed to get cache alignment");

View File

@ -3,7 +3,7 @@ menu "ESP-Driver:I2S Configurations"
config I2S_ISR_IRAM_SAFE
bool "I2S ISR IRAM-Safe"
default n
select GDMA_ISR_IRAM_SAFE if SOC_GDMA_SUPPORTED
select GDMA_ISR_HANDLER_IN_IRAM if SOC_GDMA_SUPPORTED
help
Ensure the I2S interrupt is IRAM-Safe by allowing the interrupt handler to be
executable when the cache is disabled (e.g. SPI Flash write).

View File

@ -791,7 +791,11 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag)
}
/* Set GDMA config */
gdma_channel_alloc_config_t dma_cfg = {};
gdma_channel_alloc_config_t dma_cfg = {
#if CONFIG_I2S_ISR_IRAM_SAFE
.flags.isr_cache_safe = true,
#endif
};
if (handle->dir == I2S_DIR_TX) {
dma_cfg.direction = GDMA_CHANNEL_DIRECTION_TX;
/* Register a new GDMA tx channel */

View File

@ -40,7 +40,7 @@ extern "C" {
// If ISR handler is allowed to run whilst cache is disabled,
// Make sure all the code and related variables used by the handler are in the SRAM
#if CONFIG_I2S_ISR_IRAM_SAFE || CONFIG_GDMA_ISR_IRAM_SAFE
#if CONFIG_I2S_ISR_IRAM_SAFE
#define I2S_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED)
#define I2S_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#else

View File

@ -11,6 +11,7 @@ menu "ESP-Driver:Parallel IO Configurations"
config PARLIO_ISR_IRAM_SAFE
bool "Parallel IO ISR IRAM-Safe"
default n
select GDMA_ISR_HANDLER_IN_IRAM
select GDMA_CTRL_FUNC_IN_IRAM # the driver needs to start the GDMA in the interrupt
help
Ensure the Parallel IO interrupt is IRAM-Safe by allowing the interrupt handler to be

View File

@ -1,4 +1,4 @@
[mapping:parlio_driver_gdma]
[mapping:parlio_driver_gdma_link]
archive: libesp_hw_support.a
entries:
if PARLIO_ISR_IRAM_SAFE:

View File

@ -476,6 +476,9 @@ static esp_err_t s_parlio_rx_unit_init_dma(parlio_rx_unit_handle_t rx_unit)
/* Allocate and connect the GDMA channel */
gdma_channel_alloc_config_t dma_chan_config = {
.direction = GDMA_CHANNEL_DIRECTION_RX,
#if CONFIG_PARLIO_ISR_IRAM_SAFE
.flags.isr_cache_safe = true,
#endif
};
ESP_RETURN_ON_ERROR(PARLIO_GDMA_NEW_CHANNEL(&dma_chan_config, &rx_unit->dma_chan), TAG, "allocate RX DMA channel failed");
gdma_connect(rx_unit->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_PARLIO, 0));
@ -974,7 +977,7 @@ esp_err_t parlio_rx_unit_receive(parlio_rx_unit_handle_t rx_unit,
ESP_RETURN_ON_FALSE(payload_size >= 2 * alignment, ESP_ERR_INVALID_ARG, TAG, "The payload size should greater than %"PRIu32, 2 * alignment);
}
#endif
#if CONFIG_GDMA_ISR_IRAM_SAFE
#if CONFIG_PARLIO_ISR_IRAM_SAFE
ESP_RETURN_ON_FALSE(esp_ptr_internal(payload), ESP_ERR_INVALID_ARG, TAG, "payload not in internal RAM");
#else
ESP_RETURN_ON_FALSE(recv_cfg->flags.indirect_mount || esp_ptr_internal(payload), ESP_ERR_INVALID_ARG, TAG, "payload not in internal RAM");

View File

@ -200,6 +200,9 @@ static esp_err_t parlio_tx_unit_init_dma(parlio_tx_unit_t *tx_unit, const parlio
{
gdma_channel_alloc_config_t dma_chan_config = {
.direction = GDMA_CHANNEL_DIRECTION_TX,
#if CONFIG_PARLIO_ISR_IRAM_SAFE
.flags.isr_cache_safe = true,
#endif
};
ESP_RETURN_ON_ERROR(PARLIO_GDMA_NEW_CHANNEL(&dma_chan_config, &tx_unit->dma_chan), TAG, "allocate TX DMA channel failed");
gdma_connect(tx_unit->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_PARLIO, 0));

View File

@ -3,8 +3,8 @@ menu "ESP-Driver:RMT Configurations"
config RMT_ISR_IRAM_SAFE
bool "RMT ISR IRAM-Safe"
default n
select GDMA_ISR_IRAM_SAFE if SOC_RMT_SUPPORT_DMA # RMT basic functionality relies on GDMA callback
select GDMA_CTRL_FUNC_IN_IRAM if SOC_RMT_SUPPORT_DMA # RMT needs to restart the GDMA in the interrupt
select GDMA_ISR_HANDLER_IN_IRAM if SOC_RMT_SUPPORT_DMA # RMT basic functionality relies on GDMA callback
select GDMA_CTRL_FUNC_IN_IRAM if SOC_RMT_SUPPORT_DMA # RMT needs to restart the GDMA in the interrupt
help
Ensure the RMT interrupt is IRAM-Safe by allowing the interrupt handler to be
executable when the cache is disabled (e.g. SPI Flash write).

View File

@ -57,6 +57,9 @@ static esp_err_t rmt_rx_init_dma_link(rmt_rx_channel_t *rx_channel, const rmt_rx
{
gdma_channel_alloc_config_t dma_chan_config = {
.direction = GDMA_CHANNEL_DIRECTION_RX,
#if CONFIG_RMT_ISR_IRAM_SAFE
.flags.isr_cache_safe = true,
#endif
};
ESP_RETURN_ON_ERROR(gdma_new_ahb_channel(&dma_chan_config, &rx_channel->base.dma_chan), TAG, "allocate RX DMA channel failed");
gdma_transfer_config_t transfer_cfg = {

View File

@ -52,6 +52,9 @@ static esp_err_t rmt_tx_init_dma_link(rmt_tx_channel_t *tx_channel, const rmt_tx
{
gdma_channel_alloc_config_t dma_chan_config = {
.direction = GDMA_CHANNEL_DIRECTION_TX,
#if CONFIG_RMT_ISR_IRAM_SAFE
.flags.isr_cache_safe = true,
#endif
};
ESP_RETURN_ON_ERROR(gdma_new_ahb_channel(&dma_chan_config, &tx_channel->base.dma_chan), TAG, "allocate TX DMA channel failed");
gdma_strategy_config_t gdma_strategy_conf = {

View File

@ -26,6 +26,7 @@ menu "ESP-Driver:SPI Configurations"
select HAL_SPI_MASTER_FUNC_IN_IRAM
select ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM
select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED
select GDMA_ISR_HANDLER_IN_IRAM if SOC_GDMA_SUPPORTED
help
Place the SPI master ISR in to IRAM to avoid possible cache miss.
@ -54,6 +55,7 @@ menu "ESP-Driver:SPI Configurations"
default y
select HAL_SPI_SLAVE_FUNC_IN_IRAM
select GDMA_CTRL_FUNC_IN_IRAM if SOC_GDMA_SUPPORTED
select GDMA_ISR_HANDLER_IN_IRAM if SOC_GDMA_SUPPORTED
help
Place the SPI slave ISR in to IRAM to avoid possible cache miss.

View File

@ -222,6 +222,9 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch
if (dma_chan == SPI_DMA_CH_AUTO) {
gdma_channel_alloc_config_t tx_alloc_config = {
.flags.reserve_sibling = 1,
#if CONFIG_SPI_MASTER_ISR_IN_IRAM
.flags.isr_cache_safe = true,
#endif
.direction = GDMA_CHANNEL_DIRECTION_TX,
};
ESP_RETURN_ON_ERROR(SPI_GDMA_NEW_CHANNEL(&tx_alloc_config, &dma_ctx->tx_dma_chan), SPI_TAG, "alloc gdma tx failed");
@ -229,6 +232,9 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch
gdma_channel_alloc_config_t rx_alloc_config = {
.direction = GDMA_CHANNEL_DIRECTION_RX,
.sibling_chan = dma_ctx->tx_dma_chan,
#if CONFIG_SPI_MASTER_ISR_IN_IRAM
.flags.isr_cache_safe = true,
#endif
};
ESP_RETURN_ON_ERROR(SPI_GDMA_NEW_CHANNEL(&rx_alloc_config, &dma_ctx->rx_dma_chan), SPI_TAG, "alloc gdma rx failed");

View File

@ -9,7 +9,7 @@ menu "ESP-Driver:LCD Controller Configurations"
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
select GDMA_ISR_HANDLER_IN_IRAM # 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

View File

@ -882,6 +882,9 @@ static esp_err_t lcd_rgb_create_dma_channel(esp_rgb_panel_t *rgb_panel)
// alloc DMA channel and connect to LCD peripheral
gdma_channel_alloc_config_t dma_chan_config = {
.direction = GDMA_CHANNEL_DIRECTION_TX,
#if CONFIG_LCD_RGB_ISR_IRAM_SAFE
.flags.isr_cache_safe = true,
#endif
};
ESP_RETURN_ON_ERROR(LCD_GDMA_NEW_CHANNEL(&dma_chan_config, &rgb_panel->dma_chan), TAG, "alloc DMA channel failed");
gdma_connect(rgb_panel->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_LCD, 0));