From f2d62bba7482f5b41d174437cbd1b2dac836acd2 Mon Sep 17 00:00:00 2001 From: morris Date: Tue, 31 Mar 2026 19:59:56 +0800 Subject: [PATCH] feat(gdma): expose interrupt priority as a configurable option - Add intr_priority field to gdma_channel_t structure - Add intr_bind_name field to gdma_signal_conn_t for interrupt binding - Validate intr_priority during channel allocation (must be 0-3) - Use ESP_INTR_FLAG_SHARED_PRIVATE instead of ESP_INTR_FLAG_SHARED - Use esp_intr_alloc_info() with bind_by.name for shared interrupts - Add interrupt priority configuration test case - Update all gdma_periph.c files with pair-specific bind names (gdma_gXpY) --- .../esp_driver_dma/include/esp_private/gdma.h | 1 + components/esp_driver_dma/src/dw_gdma.c | 39 +++++------ components/esp_driver_dma/src/gdma.c | 65 +++++++++++++++---- components/esp_driver_dma/src/gdma_priv.h | 1 + .../test_apps/dma/main/test_gdma.c | 49 ++++++++++++++ components/esp_driver_pcnt/src/pulse_cnt.c | 4 +- components/esp_hal_dma/esp32c2/gdma_periph.c | 1 + .../esp_hal_dma/esp32c2/include/hal/gdma_ll.h | 2 - components/esp_hal_dma/esp32c3/gdma_periph.c | 3 + .../esp_hal_dma/esp32c3/include/hal/gdma_ll.h | 2 - components/esp_hal_dma/esp32c5/gdma_periph.c | 3 + components/esp_hal_dma/esp32c6/gdma_periph.c | 3 + components/esp_hal_dma/esp32c61/gdma_periph.c | 2 + components/esp_hal_dma/esp32h2/gdma_periph.c | 3 + components/esp_hal_dma/esp32h21/gdma_periph.c | 3 + components/esp_hal_dma/esp32h4/gdma_periph.c | 5 ++ components/esp_hal_dma/esp32p4/gdma_periph.c | 6 ++ components/esp_hal_dma/esp32s3/gdma_periph.c | 5 ++ components/esp_hal_dma/esp32s31/gdma_periph.c | 10 +++ .../esp_hal_dma/include/hal/gdma_periph.h | 11 ++-- 20 files changed, 172 insertions(+), 46 deletions(-) diff --git a/components/esp_driver_dma/include/esp_private/gdma.h b/components/esp_driver_dma/include/esp_private/gdma.h index 103cd430ff..1e3b784464 100644 --- a/components/esp_driver_dma/include/esp_private/gdma.h +++ b/components/esp_driver_dma/include/esp_private/gdma.h @@ -24,6 +24,7 @@ typedef struct gdma_channel_t *gdma_channel_handle_t; * @brief Collection of configuration items that used for allocating GDMA channel */ typedef struct { + int intr_priority; /*!< DMA interrupt priority, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */ struct { int isr_cache_safe: 1; /*!< If set, DMA channel allocator would allocate interrupt in cache-safe region, and ISR is serviceable when cache is disabled */ } flags; diff --git a/components/esp_driver_dma/src/dw_gdma.c b/components/esp_driver_dma/src/dw_gdma.c index d1304e160f..a8cf6aecb8 100644 --- a/components/esp_driver_dma/src/dw_gdma.c +++ b/components/esp_driver_dma/src/dw_gdma.c @@ -76,7 +76,6 @@ typedef struct { struct dw_gdma_group_t { int group_id; // Group ID, index from 0 dw_gdma_hal_context_t hal; // HAL instance is at group level - int intr_priority; // all channels in the same group should share the same interrupt priority portMUX_TYPE spinlock; // group level spinlock, protect group level stuffs, e.g. hal object, pair handle slots and reference count of each pair dw_gdma_channel_t *channels[DW_GDMA_LL_CHANNELS_PER_GROUP]; // handles of DMA channels }; @@ -84,6 +83,7 @@ struct dw_gdma_group_t { struct dw_gdma_channel_t { int chan_id; // channel ID, index from 0 intr_handle_t intr; // per-channel interrupt handle + int intr_priority; // channel requested interrupt priority portMUX_TYPE spinlock; // channel level spinlock dw_gdma_group_t *group; // pointer to the group which the channel belongs to void *user_data; // user registered DMA event data @@ -130,7 +130,6 @@ static dw_gdma_group_t *dw_gdma_acquire_group_handle(int group_id) if (new_group) { portMUX_INITIALIZE(&group->spinlock); group->group_id = group_id; - group->intr_priority = -1; // interrupt priority not assigned yet ESP_LOGD(TAG, "new group (%d) at %p", group_id, group); } @@ -239,22 +238,11 @@ esp_err_t dw_gdma_new_channel(const dw_gdma_channel_alloc_config_t *config, dw_g ESP_GOTO_ON_ERROR(channel_register_to_group(chan), err, TAG, "register to group failed"); dw_gdma_group_t *group = chan->group; dw_gdma_hal_context_t *hal = &group->hal; - int group_id = group->group_id; int chan_id = chan->chan_id; - // all channels in the same group should use the same interrupt priority - bool intr_priority_conflict = false; - esp_os_enter_critical(&group->spinlock); - if (group->intr_priority == -1) { - group->intr_priority = config->intr_priority; - } else if (config->intr_priority != 0) { - intr_priority_conflict = (group->intr_priority != config->intr_priority); - } - esp_os_exit_critical(&group->spinlock); - ESP_GOTO_ON_FALSE(!intr_priority_conflict, ESP_ERR_INVALID_STATE, err, TAG, "intr_priority conflict, already is %d but attempt to %d", group->intr_priority, config->intr_priority); - // basic initialization portMUX_INITIALIZE(&chan->spinlock); + chan->intr_priority = config->intr_priority; chan->src_transfer_type = config->src.block_transfer_type; chan->dst_transfer_type = config->dst.block_transfer_type; // set transfer flow type @@ -284,7 +272,7 @@ esp_err_t dw_gdma_new_channel(const dw_gdma_channel_alloc_config_t *config, dw_g // enable all channel events (notes, they can't trigger an interrupt until `dw_gdma_ll_channel_enable_intr_propagation` is called) dw_gdma_ll_channel_enable_intr_generation(hal->dev, chan_id, UINT32_MAX, true); - ESP_LOGD(TAG, "new channel (%d,%d) at %p", group_id, chan_id, chan); + ESP_LOGD(TAG, "new channel (%d,%d) at %p", group->group_id, chan_id, chan); *ret_chan = chan; return ESP_OK; err: @@ -627,17 +615,24 @@ static esp_err_t dw_gdma_install_channel_interrupt(dw_gdma_channel_t *chan) dw_gdma_ll_channel_clear_intr(hal->dev, chan_id, UINT32_MAX); // pre-alloc a interrupt handle, with handler disabled - // DW_GDMA multiple channels share the same interrupt source, so we use a shared interrupt handle + // DW_GDMA channels in the same group share one private interrupt group intr_handle_t intr = NULL; - int isr_flags = DW_GDMA_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED; - if (group->intr_priority) { - isr_flags |= 1 << (group->intr_priority); + int isr_flags = DW_GDMA_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED_PRIVATE; + if (chan->intr_priority) { + isr_flags |= 1 << (chan->intr_priority); } else { isr_flags |= DW_GDMA_ALLOW_INTR_PRIORITY_MASK; } - ret = esp_intr_alloc_intrstatus(ETS_DW_GDMA_INTR_SOURCE, isr_flags, - (uint32_t)dw_gdma_ll_get_intr_status_reg(hal->dev), DW_GDMA_LL_CHANNEL_EVENT_MASK(chan_id), - dw_gdma_channel_default_isr, chan, &intr); + esp_intr_alloc_info_t intr_info = { + .source = ETS_DW_GDMA_INTR_SOURCE, + .flags = isr_flags, + .intrstatusreg = (uint32_t)dw_gdma_ll_get_intr_status_reg(hal->dev), + .intrstatusmask = DW_GDMA_LL_CHANNEL_EVENT_MASK(chan_id), + .handler = dw_gdma_channel_default_isr, + .arg = chan, + .bind_by.name = "dw_gdma0", + }; + ret = esp_intr_alloc_info(&intr_info, &intr); ESP_RETURN_ON_ERROR(ret, TAG, "alloc interrupt failed"); ESP_LOGD(TAG, "install interrupt service for channel (%d,%d)", group->group_id, chan_id); diff --git a/components/esp_driver_dma/src/gdma.c b/components/esp_driver_dma/src/gdma.c index 6da88e44c3..b248ba2bad 100644 --- a/components/esp_driver_dma/src/gdma.c +++ b/components/esp_driver_dma/src/gdma.c @@ -32,6 +32,7 @@ #define GDMA_INVALID_PERIPH_TRIG (0x3F) #define SEARCH_REQUEST_RX_CHANNEL (1 << 0) #define SEARCH_REQUEST_TX_CHANNEL (1 << 1) +#define GDMA_ALLOW_INTR_PRIORITY_MASK ESP_INTR_FLAG_LOWMED typedef struct gdma_platform_t { portMUX_TYPE spinlock; // platform level spinlock, protect the group handle slots @@ -80,6 +81,12 @@ static esp_err_t do_allocate_gdma_channel(const gdma_channel_search_info_t *sear ESP_RETURN_ON_FALSE(search_info->start_group_id < search_info->end_group_id, ESP_ERR_INVALID_ARG, TAG, "invalid group range"); ESP_RETURN_ON_FALSE(search_info->pairs_per_group > 0, ESP_ERR_INVALID_ARG, TAG, "invalid pairs_per_group"); + // Validate interrupt priority + if (config->intr_priority) { + ESP_RETURN_ON_FALSE(1 << (config->intr_priority) & GDMA_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, + TAG, "invalid interrupt priority:%d", config->intr_priority); + } + #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_GDMA_SUPPORT_SLEEP_RETENTION // retention module is per GDMA pair, before we allocate the pair object, some common registers are already configured in "hal_init" // if a light sleep happens and powers off the gdma module, those registers will get lost @@ -150,6 +157,7 @@ static esp_err_t do_allocate_gdma_channel(const gdma_channel_search_info_t *sear alloc_tx_channel->base.pair = pair; alloc_tx_channel->base.direction = GDMA_CHANNEL_DIRECTION_TX; alloc_tx_channel->base.periph_id = GDMA_INVALID_PERIPH_TRIG; + alloc_tx_channel->base.intr_priority = config->intr_priority; alloc_tx_channel->base.flags.isr_cache_safe = config->flags.isr_cache_safe; alloc_tx_channel->base.del = gdma_del_tx_channel; // set channel deletion function alloc_tx_channel->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; @@ -166,6 +174,7 @@ static esp_err_t do_allocate_gdma_channel(const gdma_channel_search_info_t *sear alloc_rx_channel->base.pair = pair; alloc_rx_channel->base.direction = GDMA_CHANNEL_DIRECTION_RX; alloc_rx_channel->base.periph_id = GDMA_INVALID_PERIPH_TRIG; + alloc_rx_channel->base.intr_priority = config->intr_priority; alloc_rx_channel->base.flags.isr_cache_safe = config->flags.isr_cache_safe; alloc_rx_channel->base.del = gdma_del_rx_channel; // set channel deletion function alloc_rx_channel->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; @@ -1003,18 +1012,32 @@ static esp_err_t gdma_install_rx_interrupt(gdma_rx_channel_t *rx_chan) gdma_group_t *group = pair->group; gdma_hal_context_t *hal = &group->hal; int pair_id = pair->pair_id; + const gdma_pair_signal_conn_t *pair_signals = &gdma_periph_signals.groups[group->group_id].pairs[pair_id]; + bool tx_rx_share_irq = pair_signals->rx_irq_id == pair_signals->tx_irq_id; // pre-alloc a interrupt handle, with handler disabled - int isr_flags = ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LOWMED; + int isr_flags = ESP_INTR_FLAG_INTRDISABLED; + if (rx_chan->base.intr_priority) { + isr_flags |= 1 << (rx_chan->base.intr_priority); + } else { + isr_flags |= ESP_INTR_FLAG_LOWMED; + } if (rx_chan->base.flags.isr_cache_safe) { isr_flags |= ESP_INTR_FLAG_IRAM; } -#if GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT - isr_flags |= ESP_INTR_FLAG_SHARED; -#endif + if (tx_rx_share_irq) { + isr_flags |= ESP_INTR_FLAG_SHARED_PRIVATE; + } + esp_intr_alloc_info_t intr_info = { + .source = pair_signals->rx_irq_id, + .flags = isr_flags, + .intrstatusreg = gdma_hal_get_intr_status_reg(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX), + .intrstatusmask = GDMA_LL_RX_EVENT_MASK, + .handler = gdma_default_rx_isr, + .arg = rx_chan, + .bind_by.name = tx_rx_share_irq ? pair_signals->name : NULL, + }; intr_handle_t intr = NULL; - ret = esp_intr_alloc_intrstatus(gdma_periph_signals.groups[group->group_id].pairs[pair_id].rx_irq_id, isr_flags, - gdma_hal_get_intr_status_reg(hal, pair_id, GDMA_CHANNEL_DIRECTION_RX), GDMA_LL_RX_EVENT_MASK, - gdma_default_rx_isr, rx_chan, &intr); + ret = esp_intr_alloc_info(&intr_info, &intr); ESP_GOTO_ON_ERROR(ret, err, TAG, "alloc interrupt failed"); rx_chan->base.intr = intr; @@ -1035,18 +1058,32 @@ static esp_err_t gdma_install_tx_interrupt(gdma_tx_channel_t *tx_chan) gdma_group_t *group = pair->group; gdma_hal_context_t *hal = &group->hal; int pair_id = pair->pair_id; + const gdma_pair_signal_conn_t *pair_signals = &gdma_periph_signals.groups[group->group_id].pairs[pair_id]; + bool tx_rx_share_irq = pair_signals->rx_irq_id == pair_signals->tx_irq_id; // pre-alloc a interrupt handle, with handler disabled - int isr_flags = ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LOWMED; + int isr_flags = ESP_INTR_FLAG_INTRDISABLED; + if (tx_chan->base.intr_priority) { + isr_flags |= 1 << (tx_chan->base.intr_priority); + } else { + isr_flags |= ESP_INTR_FLAG_LOWMED; + } if (tx_chan->base.flags.isr_cache_safe) { isr_flags |= ESP_INTR_FLAG_IRAM; } -#if GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT - isr_flags |= ESP_INTR_FLAG_SHARED; -#endif + if (tx_rx_share_irq) { + isr_flags |= ESP_INTR_FLAG_SHARED_PRIVATE; + } + esp_intr_alloc_info_t intr_info = { + .source = pair_signals->tx_irq_id, + .flags = isr_flags, + .intrstatusreg = gdma_hal_get_intr_status_reg(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX), + .intrstatusmask = GDMA_LL_TX_EVENT_MASK, + .handler = gdma_default_tx_isr, + .arg = tx_chan, + .bind_by.name = tx_rx_share_irq ? pair_signals->name : NULL, + }; intr_handle_t intr = NULL; - ret = esp_intr_alloc_intrstatus(gdma_periph_signals.groups[group->group_id].pairs[pair_id].tx_irq_id, isr_flags, - gdma_hal_get_intr_status_reg(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX), GDMA_LL_TX_EVENT_MASK, - gdma_default_tx_isr, tx_chan, &intr); + ret = esp_intr_alloc_info(&intr_info, &intr); ESP_GOTO_ON_ERROR(ret, err, TAG, "alloc interrupt failed"); tx_chan->base.intr = intr; diff --git a/components/esp_driver_dma/src/gdma_priv.h b/components/esp_driver_dma/src/gdma_priv.h index b008a95b45..a6a2a4bfcf 100644 --- a/components/esp_driver_dma/src/gdma_priv.h +++ b/components/esp_driver_dma/src/gdma_priv.h @@ -78,6 +78,7 @@ struct gdma_channel_t { portMUX_TYPE spinlock; // channel level spinlock gdma_channel_direction_t direction; // channel direction int periph_id; // Peripheral instance ID, indicates which peripheral is connected to this GDMA channel + int intr_priority; // interrupt priority, if set to 0, the driver will use the default priority size_t int_mem_alignment; // alignment for memory in internal memory size_t ext_mem_alignment; // alignment for memory in external memory esp_err_t (*del)(gdma_channel_t *channel); // channel deletion function, it's polymorphic, see `gdma_del_tx_channel` or `gdma_del_rx_channel` diff --git a/components/esp_driver_dma/test_apps/dma/main/test_gdma.c b/components/esp_driver_dma/test_apps/dma/main/test_gdma.c index 8025c72de7..46b19ad90a 100644 --- a/components/esp_driver_dma/test_apps/dma/main/test_gdma.c +++ b/components/esp_driver_dma/test_apps/dma/main/test_gdma.c @@ -849,3 +849,52 @@ TEST_CASE("GDMA memory copy SRAM->PSRAM->SRAM", "[GDMA][M2M]") #endif // SOC_HAS(LP_AHB_GDMA) } #endif // SOC_SPIRAM_SUPPORTED + +static bool test_gdma_intr_priority_tx_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + return false; +} + +static bool test_gdma_intr_priority_rx_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + return false; +} + +TEST_CASE("GDMA interrupt priority configuration", "[GDMA]") +{ + // test both TX and RX channel with the same interrupt priority + gdma_channel_handle_t tx_chan = NULL; + gdma_channel_handle_t rx_chan = NULL; + gdma_channel_alloc_config_t chan_alloc_config = { + .intr_priority = 2, + }; + + TEST_ESP_OK(gdma_new_ahb_channel(&chan_alloc_config, &tx_chan, &rx_chan)); + + gdma_tx_event_callbacks_t tx_cbs = { + .on_trans_eof = test_gdma_intr_priority_tx_callback, + }; + gdma_rx_event_callbacks_t rx_cbs = { + .on_recv_eof = test_gdma_intr_priority_rx_callback, + }; + TEST_ESP_OK(gdma_register_tx_event_callbacks(tx_chan, &tx_cbs, NULL)); + TEST_ESP_OK(gdma_register_rx_event_callbacks(rx_chan, &rx_cbs, NULL)); + TEST_ESP_OK(gdma_del_channel(tx_chan)); + TEST_ESP_OK(gdma_del_channel(rx_chan)); + + // test TX and RX channel with different interrupt priority + TEST_ESP_OK(gdma_new_ahb_channel(&chan_alloc_config, &tx_chan, NULL)); + TEST_ESP_OK(gdma_register_tx_event_callbacks(tx_chan, &tx_cbs, NULL)); + chan_alloc_config.intr_priority = 3; + TEST_ESP_OK(gdma_new_ahb_channel(&chan_alloc_config, NULL, &rx_chan)); +#if CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 + // On such targets, the TX and RX DMA interrupts are sharing the same interrupt source, + // so it's not allowed to set different interrupt priority for TX and RX channel + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gdma_register_rx_event_callbacks(rx_chan, &rx_cbs, NULL)); +#else + // on other targets, the TX and RX DMA interrupts are separate, it's allowed to set different interrupt priority for TX and RX channel + TEST_ESP_OK(gdma_register_rx_event_callbacks(rx_chan, &rx_cbs, NULL)); +#endif + TEST_ESP_OK(gdma_del_channel(tx_chan)); + TEST_ESP_OK(gdma_del_channel(rx_chan)); +} diff --git a/components/esp_driver_pcnt/src/pulse_cnt.c b/components/esp_driver_pcnt/src/pulse_cnt.c index d78ea94430..149ac4d58b 100644 --- a/components/esp_driver_pcnt/src/pulse_cnt.c +++ b/components/esp_driver_pcnt/src/pulse_cnt.c @@ -43,9 +43,9 @@ #endif #if CONFIG_PCNT_ISR_IRAM_SAFE -#define PCNT_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED_PRIVATE) +#define PCNT_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) #else -#define PCNT_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED_PRIVATE) +#define PCNT_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) #endif #define PCNT_ALLOW_INTR_PRIORITY_MASK ESP_INTR_FLAG_LOWMED diff --git a/components/esp_hal_dma/esp32c2/gdma_periph.c b/components/esp_hal_dma/esp32c2/gdma_periph.c index 51e34dcd5e..b247b8c3bc 100644 --- a/components/esp_hal_dma/esp32c2/gdma_periph.c +++ b/components/esp_hal_dma/esp32c2/gdma_periph.c @@ -13,6 +13,7 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_DMA_CH0_INTR_SOURCE, .tx_irq_id = ETS_DMA_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, } } diff --git a/components/esp_hal_dma/esp32c2/include/hal/gdma_ll.h b/components/esp_hal_dma/esp32c2/include/hal/gdma_ll.h index be5a04a0ad..9aa4aceb97 100644 --- a/components/esp_hal_dma/esp32c2/include/hal/gdma_ll.h +++ b/components/esp_hal_dma/esp32c2/include/hal/gdma_ll.h @@ -49,8 +49,6 @@ extern "C" { #define GDMA_LL_AHB_GROUP_START_ID 0 // AHB GDMA group ID starts from 0 #define GDMA_LL_AHB_NUM_GROUPS 1 // Number of AHB GDMA groups #define GDMA_LL_AHB_PAIRS_PER_GROUP 1 // Number of GDMA pairs in each AHB group -#define GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT 1 // TX and RX channel in the same pair will share the same interrupt source number - #define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x01 // pair 0 is M2M capable #define GDMA_LL_AHB_DESC_ALIGNMENT 4 diff --git a/components/esp_hal_dma/esp32c3/gdma_periph.c b/components/esp_hal_dma/esp32c3/gdma_periph.c index a38d367774..549f77803c 100644 --- a/components/esp_hal_dma/esp32c3/gdma_periph.c +++ b/components/esp_hal_dma/esp32c3/gdma_periph.c @@ -13,14 +13,17 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_DMA_CH0_INTR_SOURCE, .tx_irq_id = ETS_DMA_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, [1] = { .rx_irq_id = ETS_DMA_CH1_INTR_SOURCE, .tx_irq_id = ETS_DMA_CH1_INTR_SOURCE, + .name = "gdma_g0p1", }, [2] = { .rx_irq_id = ETS_DMA_CH2_INTR_SOURCE, .tx_irq_id = ETS_DMA_CH2_INTR_SOURCE, + .name = "gdma_g0p2", } } } diff --git a/components/esp_hal_dma/esp32c3/include/hal/gdma_ll.h b/components/esp_hal_dma/esp32c3/include/hal/gdma_ll.h index 67d575a4b5..b44a020e47 100644 --- a/components/esp_hal_dma/esp32c3/include/hal/gdma_ll.h +++ b/components/esp_hal_dma/esp32c3/include/hal/gdma_ll.h @@ -49,8 +49,6 @@ extern "C" { #define GDMA_LL_AHB_GROUP_START_ID 0 // AHB GDMA group ID starts from 0 #define GDMA_LL_AHB_NUM_GROUPS 1 // Number of AHB GDMA groups #define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group -#define GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT 1 // TX and RX channel in the same pair will share the same interrupt source number - #define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x07 // pair 0,1,2 are M2M capable #define GDMA_LL_AHB_DESC_ALIGNMENT 4 diff --git a/components/esp_hal_dma/esp32c5/gdma_periph.c b/components/esp_hal_dma/esp32c5/gdma_periph.c index 550faea38b..831387cebb 100644 --- a/components/esp_hal_dma/esp32c5/gdma_periph.c +++ b/components/esp_hal_dma/esp32c5/gdma_periph.c @@ -14,14 +14,17 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_DMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, [1] = { .rx_irq_id = ETS_DMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g0p1", }, [2] = { .rx_irq_id = ETS_DMA_IN_CH2_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH2_INTR_SOURCE, + .name = "gdma_g0p2", } } } diff --git a/components/esp_hal_dma/esp32c6/gdma_periph.c b/components/esp_hal_dma/esp32c6/gdma_periph.c index 3d6374c701..559ec806c4 100644 --- a/components/esp_hal_dma/esp32c6/gdma_periph.c +++ b/components/esp_hal_dma/esp32c6/gdma_periph.c @@ -14,14 +14,17 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_DMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, [1] = { .rx_irq_id = ETS_DMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g0p1", }, [2] = { .rx_irq_id = ETS_DMA_IN_CH2_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH2_INTR_SOURCE, + .name = "gdma_g0p2", } } } diff --git a/components/esp_hal_dma/esp32c61/gdma_periph.c b/components/esp_hal_dma/esp32c61/gdma_periph.c index 28c0b8dc74..aa9e0f5973 100644 --- a/components/esp_hal_dma/esp32c61/gdma_periph.c +++ b/components/esp_hal_dma/esp32c61/gdma_periph.c @@ -14,10 +14,12 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_DMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, [1] = { .rx_irq_id = ETS_DMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g0p1", } } } diff --git a/components/esp_hal_dma/esp32h2/gdma_periph.c b/components/esp_hal_dma/esp32h2/gdma_periph.c index 0fd9b08478..521706a645 100644 --- a/components/esp_hal_dma/esp32h2/gdma_periph.c +++ b/components/esp_hal_dma/esp32h2/gdma_periph.c @@ -14,14 +14,17 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_DMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, [1] = { .rx_irq_id = ETS_DMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g0p1", }, [2] = { .rx_irq_id = ETS_DMA_IN_CH2_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH2_INTR_SOURCE, + .name = "gdma_g0p2", } } } diff --git a/components/esp_hal_dma/esp32h21/gdma_periph.c b/components/esp_hal_dma/esp32h21/gdma_periph.c index 5a09b8ec70..d6cc76dedf 100644 --- a/components/esp_hal_dma/esp32h21/gdma_periph.c +++ b/components/esp_hal_dma/esp32h21/gdma_periph.c @@ -14,14 +14,17 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_DMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, [1] = { .rx_irq_id = ETS_DMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g0p1", }, [2] = { .rx_irq_id = ETS_DMA_IN_CH2_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH2_INTR_SOURCE, + .name = "gdma_g0p2", } } } diff --git a/components/esp_hal_dma/esp32h4/gdma_periph.c b/components/esp_hal_dma/esp32h4/gdma_periph.c index 65f111cd04..26f8c3d4cd 100644 --- a/components/esp_hal_dma/esp32h4/gdma_periph.c +++ b/components/esp_hal_dma/esp32h4/gdma_periph.c @@ -14,22 +14,27 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_DMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, [1] = { .rx_irq_id = ETS_DMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g0p1", }, [2] = { .rx_irq_id = ETS_DMA_IN_CH2_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH2_INTR_SOURCE, + .name = "gdma_g0p2", }, [3] = { .rx_irq_id = ETS_DMA_IN_CH3_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH3_INTR_SOURCE, + .name = "gdma_g0p3", }, [4] = { .rx_irq_id = ETS_DMA_IN_CH4_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH4_INTR_SOURCE, + .name = "gdma_g0p4", }, } } diff --git a/components/esp_hal_dma/esp32p4/gdma_periph.c b/components/esp_hal_dma/esp32p4/gdma_periph.c index acf6a1a735..ac33c2c5eb 100644 --- a/components/esp_hal_dma/esp32p4/gdma_periph.c +++ b/components/esp_hal_dma/esp32p4/gdma_periph.c @@ -15,14 +15,17 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_AHB_PDMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_AHB_PDMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, [1] = { .rx_irq_id = ETS_AHB_PDMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_AHB_PDMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g0p1", }, [2] = { .rx_irq_id = ETS_AHB_PDMA_IN_CH2_INTR_SOURCE, .tx_irq_id = ETS_AHB_PDMA_OUT_CH2_INTR_SOURCE, + .name = "gdma_g0p2", } } }, @@ -31,14 +34,17 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_AXI_PDMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_AXI_PDMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g1p0", }, [1] = { .rx_irq_id = ETS_AXI_PDMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_AXI_PDMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g1p1", }, [2] = { .rx_irq_id = ETS_AXI_PDMA_IN_CH2_INTR_SOURCE, .tx_irq_id = ETS_AXI_PDMA_OUT_CH2_INTR_SOURCE, + .name = "gdma_g1p2", } } } diff --git a/components/esp_hal_dma/esp32s3/gdma_periph.c b/components/esp_hal_dma/esp32s3/gdma_periph.c index 8d01ed78ab..6a7782091b 100644 --- a/components/esp_hal_dma/esp32s3/gdma_periph.c +++ b/components/esp_hal_dma/esp32s3/gdma_periph.c @@ -13,22 +13,27 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_DMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, [1] = { .rx_irq_id = ETS_DMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g0p1", }, [2] = { .rx_irq_id = ETS_DMA_IN_CH2_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH2_INTR_SOURCE, + .name = "gdma_g0p2", }, [3] = { .rx_irq_id = ETS_DMA_IN_CH3_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH3_INTR_SOURCE, + .name = "gdma_g0p3", }, [4] = { .rx_irq_id = ETS_DMA_IN_CH4_INTR_SOURCE, .tx_irq_id = ETS_DMA_OUT_CH4_INTR_SOURCE, + .name = "gdma_g0p4", } } } diff --git a/components/esp_hal_dma/esp32s31/gdma_periph.c b/components/esp_hal_dma/esp32s31/gdma_periph.c index cda0daf7c6..22e1b6deb2 100644 --- a/components/esp_hal_dma/esp32s31/gdma_periph.c +++ b/components/esp_hal_dma/esp32s31/gdma_periph.c @@ -13,22 +13,27 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_AHB_PDMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_AHB_PDMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g0p0", }, [1] = { .rx_irq_id = ETS_AHB_PDMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_AHB_PDMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g0p1", }, [2] = { .rx_irq_id = ETS_AHB_PDMA_IN_CH2_INTR_SOURCE, .tx_irq_id = ETS_AHB_PDMA_OUT_CH2_INTR_SOURCE, + .name = "gdma_g0p2", }, [3] = { .rx_irq_id = ETS_AHB_PDMA_IN_CH3_INTR_SOURCE, .tx_irq_id = ETS_AHB_PDMA_OUT_CH3_INTR_SOURCE, + .name = "gdma_g0p3", }, [4] = { .rx_irq_id = ETS_AHB_PDMA_IN_CH4_INTR_SOURCE, .tx_irq_id = ETS_AHB_PDMA_OUT_CH4_INTR_SOURCE, + .name = "gdma_g0p4", } } }, @@ -37,14 +42,17 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_AXI_PDMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_AXI_PDMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g1p0", }, [1] = { .rx_irq_id = ETS_AXI_PDMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_AXI_PDMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g1p1", }, [2] = { .rx_irq_id = ETS_AXI_PDMA_IN_CH2_INTR_SOURCE, .tx_irq_id = ETS_AXI_PDMA_OUT_CH2_INTR_SOURCE, + .name = "gdma_g1p2", } } }, @@ -53,10 +61,12 @@ const gdma_signal_conn_t gdma_periph_signals = { [0] = { .rx_irq_id = ETS_LP_AHB_PDMA_IN_CH0_INTR_SOURCE, .tx_irq_id = ETS_LP_AHB_PDMA_OUT_CH0_INTR_SOURCE, + .name = "gdma_g2p0", }, [1] = { .rx_irq_id = ETS_LP_AHB_PDMA_IN_CH1_INTR_SOURCE, .tx_irq_id = ETS_LP_AHB_PDMA_OUT_CH1_INTR_SOURCE, + .name = "gdma_g2p1", } } } diff --git a/components/esp_hal_dma/include/hal/gdma_periph.h b/components/esp_hal_dma/include/hal/gdma_periph.h index d39889a098..836b71eb5a 100644 --- a/components/esp_hal_dma/include/hal/gdma_periph.h +++ b/components/esp_hal_dma/include/hal/gdma_periph.h @@ -31,13 +31,16 @@ extern "C" { #endif #if SOC_HAS(GDMA) +typedef struct { + const int rx_irq_id; + const int tx_irq_id; + const char *name; // pair name, format: "gdma_gXpY" +} gdma_pair_signal_conn_t; + typedef struct { struct { const shared_periph_module_t module; - struct { - const int rx_irq_id; - const int tx_irq_id; - } pairs[GDMA_LL_GET(PAIRS_PER_INST)]; + gdma_pair_signal_conn_t pairs[GDMA_LL_GET(PAIRS_PER_INST)]; } groups[GDMA_LL_GET(INST_NUM)]; } gdma_signal_conn_t;