Skip to content

Commit 713a63f

Browse files
committed
Merge branch 'feat/gdma_weight_based_arbitration' into 'master'
feat(gdma): support gdma weighted arbitration on C5 ECO2 Closes IDF-8007 See merge request espressif/esp-idf!32826
2 parents adf1c5b + 16d25b4 commit 713a63f

File tree

15 files changed

+317
-17
lines changed

15 files changed

+317
-17
lines changed

Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,3 +704,4 @@ mainmenu "Espressif IoT Development Framework Configuration"
704704
- CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
705705
- CONFIG_USB_HOST_EXT_PORT_RESET_ATTEMPTS
706706
- CONFIG_LIBC_PICOLIBC
707+
- CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION

components/esp_hw_support/dma/Kconfig.dma

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ menu "GDMA Configurations"
4343
If this option is enabled, ALL GDMA channel's ISR handlers should be placed in IRAM, which is a overkill.
4444
It's recommend to set the "isr_cache_safe" in the "gdma_channel_alloc_config_t".
4545
Then other GDMA channels won't be influenced.
46+
47+
config GDMA_ENABLE_WEIGHTED_ARBITRATION
48+
depends on SOC_GDMA_SUPPORT_WEIGHTED_ARBITRATION && IDF_EXPERIMENTAL_FEATURES
49+
bool "GDMA enable weighted arbitration (Experimental)"
50+
default n
51+
help
52+
Whether to enable the weighted arbitration for GDMA driver.
53+
The default weight of each channel is 1. You need to set weight for each channel before transmissions.
54+
If this option is enabled, the buffer should be aligned to the burst size.
55+
56+
4657
endmenu # GDMA Configurations
4758

4859
menu "DW_GDMA Configurations"

components/esp_hw_support/dma/async_memcpy_gdma.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,12 @@ static esp_err_t esp_async_memcpy_install_gdma_template(const async_memcpy_confi
145145
gdma_apply_strategy(mcp_gdma->tx_channel, &strategy_cfg);
146146
gdma_apply_strategy(mcp_gdma->rx_channel, &strategy_cfg);
147147

148+
#if SOC_GDMA_SUPPORT_WEIGHTED_ARBITRATION
149+
if(config->weight){
150+
ESP_GOTO_ON_ERROR(gdma_set_weight(mcp_gdma->rx_channel, config->weight), err, TAG, "Set GDMA rx channel weight failed");
151+
ESP_GOTO_ON_ERROR(gdma_set_weight(mcp_gdma->tx_channel, config->weight), err, TAG, "Set GDMA tx channel weight failed");
152+
}
153+
#endif
148154
gdma_transfer_config_t transfer_cfg = {
149155
.max_data_burst_size = config->dma_burst_size,
150156
.access_ext_mem = true, // allow to do memory copy from/to external memory

components/esp_hw_support/dma/gdma.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,10 @@ static esp_err_t do_allocate_gdma_channel(const gdma_channel_search_info_t *sear
173173
alloc_rx_channel->base.del = gdma_del_rx_channel; // set channel deletion function
174174
*ret_chan = &alloc_rx_channel->base; // return the installed channel
175175
}
176-
176+
#if SOC_GDMA_SUPPORT_WEIGHTED_ARBITRATION
177+
// set 1 as default weight, can be overwritten by user
178+
gdma_set_weight(*ret_chan, 1);
179+
#endif
177180
(*ret_chan)->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
178181
ESP_LOGD(TAG, "new %s channel (%d,%d) at %p", (config->direction == GDMA_CHANNEL_DIRECTION_TX) ? "tx" : "rx",
179182
group->group_id, pair->pair_id, *ret_chan);
@@ -370,6 +373,11 @@ esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transf
370373
gdma_hal_enable_burst(hal, pair->pair_id, dma_chan->direction, en_data_burst, en_desc_burst);
371374
if (en_data_burst) {
372375
gdma_hal_set_burst_size(hal, pair->pair_id, dma_chan->direction, max_data_burst_size);
376+
#if CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION
377+
// due to hardware limitation, if weighted arbitration is enabled, the data must be aligned to burst size
378+
int_mem_alignment = MAX(int_mem_alignment, max_data_burst_size);
379+
ext_mem_alignment = MAX(ext_mem_alignment, max_data_burst_size);
380+
#endif
373381
}
374382

375383
#if GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT
@@ -437,6 +445,20 @@ esp_err_t gdma_set_priority(gdma_channel_handle_t dma_chan, uint32_t priority)
437445
return ESP_OK;
438446
}
439447

448+
#if SOC_GDMA_SUPPORT_WEIGHTED_ARBITRATION
449+
esp_err_t gdma_set_weight(gdma_channel_handle_t dma_chan, uint32_t weight)
450+
{
451+
ESP_RETURN_ON_FALSE(dma_chan && weight <= GDMA_LL_CHANNEL_MAX_WEIGHT, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
452+
gdma_pair_t *pair = dma_chan->pair;
453+
gdma_group_t *group = pair->group;
454+
gdma_hal_context_t *hal = &group->hal;
455+
456+
gdma_hal_set_weight(hal, pair->pair_id, dma_chan->direction, weight);
457+
458+
return ESP_OK;
459+
}
460+
# endif
461+
440462
esp_err_t gdma_register_tx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_tx_event_callbacks_t *cbs, void *user_data)
441463
{
442464
ESP_RETURN_ON_FALSE(dma_chan && cbs && dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
@@ -636,6 +658,9 @@ static gdma_group_t *gdma_acquire_group_handle(int group_id, void (*hal_init)(gd
636658
}
637659
gdma_hal_config_t config = {
638660
.group_id = group_id,
661+
#if CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION
662+
.flags.enable_weighted_arbitration = true,
663+
#endif
639664
};
640665
hal_init(&group->hal, &config);
641666
ESP_LOGD(TAG, "new group (%d) at %p", group_id, group);

components/esp_hw_support/dma/include/esp_private/gdma.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -462,6 +462,28 @@ esp_err_t gdma_config_crc_calculator(gdma_channel_handle_t dma_chan, const gdma_
462462
esp_err_t gdma_crc_get_result(gdma_channel_handle_t dma_chan, uint32_t *result);
463463
#endif // SOC_GDMA_SUPPORT_CRC
464464

465+
#if SOC_GDMA_SUPPORT_WEIGHTED_ARBITRATION
466+
/**
467+
* @brief Set GDMA channel weight (0 ~ 15), default weight is 1
468+
*
469+
* @note Once weight arbitration is enabled, The arbitrator will allocate the corresponding number of tokens based on the weight of each channel.
470+
* You need to set weights for each channel. If the weight is 0, the channel requests will no longer be responded to.
471+
* @note If channels have different weights, the channel with a larger weight can get a larger bandwidth.
472+
* e.g. if channel A has weight 2, channel B has weight 3 and channel C has weight 4, the percentage of bandwidth allocated to channel A is 2/9,
473+
* the percentage of bandwidth allocated to channel B is 3/9, and the percentage of bandwidth allocated to channel C is 4/9.
474+
* @note Weighted arbitration is different from priority arbitration. "Weight" is used after comparing "priority"
475+
* After the priority comparison, then arbitrator checks whether there are still unused tokens in the channel.
476+
*
477+
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
478+
* @param[in] weight Weight of GDMA channel, higher value means higher priority in weighted arbitration.
479+
* @return
480+
* - ESP_OK: Set GDMA channel weight successfully
481+
* - ESP_ERR_INVALID_ARG: Set GDMA channel weight failed because of invalid argument. e.g. weight out of range [0,GDMA_LL_CHANNEL_MAX_WEIGHT]
482+
* - ESP_FAIL: Set GDMA channel weight failed because of other error
483+
*/
484+
esp_err_t gdma_set_weight(gdma_channel_handle_t dma_chan, uint32_t weight);
485+
#endif // SOC_GDMA_SUPPORT_WEIGHTED_ARBITRATION
486+
465487
/****************************************************************************************
466488
* Deprecated APIs (will be removed in esp-idf 6.0)
467489
****************************************************************************************/

components/esp_hw_support/include/esp_async_memcpy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ typedef bool (*async_memcpy_isr_cb_t)(async_memcpy_handle_t mcp_hdl, async_memcp
5151
*/
5252
typedef struct {
5353
uint32_t backlog; /*!< Maximum number of transactions that can be prepared in the background */
54+
uint32_t weight; /*!< Weight of async memcpy dma channel, higher weight means higher average bandwidth */
5455
size_t sram_trans_align __attribute__((deprecated)); /*!< DMA transfer alignment (both in size and address) for SRAM memory */
5556
union {
5657
size_t psram_trans_align __attribute__((deprecated)); /*!< DMA transfer alignment (both in size and address) for PSRAM memory */

components/esp_hw_support/test_apps/dma/main/test_async_memcpy.c

Lines changed: 130 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ typedef struct {
3636
uint32_t dst_offset;
3737
bool src_in_psram;
3838
bool dst_in_psram;
39+
bool src_dst_same;
3940
} memcpy_testbench_context_t;
4041

4142
static void async_memcpy_setup_testbench(memcpy_testbench_context_t *test_context)
@@ -51,10 +52,13 @@ static void async_memcpy_setup_testbench(memcpy_testbench_context_t *test_contex
5152
uint32_t mem_caps = test_context->src_in_psram ? MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_8BIT : MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT ;
5253
src_buf = heap_caps_aligned_calloc(test_context->align, 1, buffer_size, mem_caps);
5354
TEST_ASSERT_NOT_NULL(src_buf);
54-
55-
mem_caps = test_context->dst_in_psram ? MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_8BIT : MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT ;
56-
dst_buf = heap_caps_aligned_calloc(test_context->align, 1, buffer_size, mem_caps);
57-
TEST_ASSERT_NOT_NULL(dst_buf);
55+
if(test_context->src_dst_same) {
56+
dst_buf = src_buf;
57+
} else {
58+
mem_caps = test_context->dst_in_psram ? MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA | MALLOC_CAP_8BIT : MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT ;
59+
dst_buf = heap_caps_aligned_calloc(test_context->align, 1, buffer_size, mem_caps);
60+
TEST_ASSERT_NOT_NULL(dst_buf);
61+
}
5862

5963
// adding extra offset
6064
from_addr = src_buf + test_context->src_offset;
@@ -87,10 +91,10 @@ static void async_memcpy_verify_and_clear_testbench(uint32_t copy_size, uint8_t
8791
free(dst_buf);
8892
}
8993

90-
static void test_memory_copy_with_same_buffer(async_memcpy_handle_t driver)
94+
static void test_memory_copy_with_same_buffer(async_memcpy_handle_t driver, async_memcpy_config_t *config)
9195
{
92-
uint8_t *sbuf = heap_caps_calloc(1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
93-
uint8_t *dbuf = heap_caps_calloc(1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
96+
uint8_t *sbuf = heap_caps_aligned_calloc(config->dma_burst_size, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
97+
uint8_t *dbuf = heap_caps_aligned_calloc(config->dma_burst_size, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
9498
TEST_ASSERT_NOT_NULL(sbuf);
9599
TEST_ASSERT_NOT_NULL(dbuf);
96100

@@ -118,21 +122,21 @@ TEST_CASE("memory copy the same buffer with different content", "[async mcp]")
118122
#if SOC_AHB_GDMA_SUPPORTED
119123
printf("Testing memcpy by AHB GDMA\r\n");
120124
TEST_ESP_OK(esp_async_memcpy_install_gdma_ahb(&config, &driver));
121-
test_memory_copy_with_same_buffer(driver);
125+
test_memory_copy_with_same_buffer(driver, &config);
122126
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
123127
#endif // SOC_AHB_GDMA_SUPPORTED
124128

125129
#if SOC_AXI_GDMA_SUPPORTED
126130
printf("Testing memcpy by AXI GDMA\r\n");
127131
TEST_ESP_OK(esp_async_memcpy_install_gdma_axi(&config, &driver));
128-
test_memory_copy_with_same_buffer(driver);
132+
test_memory_copy_with_same_buffer(driver, &config);
129133
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
130134
#endif // SOC_AXI_GDMA_SUPPORTED
131135

132136
#if SOC_CP_DMA_SUPPORTED
133137
printf("Testing memcpy by CP DMA\r\n");
134138
TEST_ESP_OK(esp_async_memcpy_install_cpdma(&config, &driver));
135-
test_memory_copy_with_same_buffer(driver);
139+
test_memory_copy_with_same_buffer(driver, &config);
136140
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
137141
#endif // SOC_CP_DMA_SUPPORTED
138142
}
@@ -243,7 +247,7 @@ TEST_CASE("memory copy with dest address unaligned", "[async mcp]")
243247
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
244248
#endif // SOC_CP_DMA_SUPPORTED
245249

246-
#if SOC_AHB_GDMA_SUPPORTED && !GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT
250+
#if SOC_AHB_GDMA_SUPPORTED && !GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT && !CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION
247251
printf("Testing memcpy by AHB GDMA\r\n");
248252
TEST_ESP_OK(esp_async_memcpy_install_gdma_ahb(&driver_config, &driver));
249253
test_memcpy_with_dest_addr_unaligned(driver, false, false);
@@ -253,7 +257,7 @@ TEST_CASE("memory copy with dest address unaligned", "[async mcp]")
253257
TEST_ESP_OK(esp_async_memcpy_uninstall(driver));
254258
#endif // SOC_AHB_GDMA_SUPPORTED
255259

256-
#if SOC_AXI_GDMA_SUPPORTED
260+
#if SOC_AXI_GDMA_SUPPORTED && !CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION
257261
printf("Testing memcpy by AXI GDMA\r\n");
258262
TEST_ESP_OK(esp_async_memcpy_install_gdma_axi(&driver_config, &driver));
259263
test_memcpy_with_dest_addr_unaligned(driver, false, false);
@@ -377,3 +381,117 @@ TEST_CASE("memory copy performance 40KB: PSRAM->PSRAM", "[async mcp]")
377381
#endif // SOC_AXI_GDMA_SUPPORTED && SOC_AXI_GDMA_SUPPORT_PSRAM
378382
}
379383
#endif
384+
385+
#if CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION
386+
typedef struct {
387+
SemaphoreHandle_t sem;
388+
int64_t elapse_us;
389+
} test_weighted_arb_context_t;
390+
static IRAM_ATTR bool test_weighted_arb_isr_cb(async_memcpy_handle_t mcp_hdl, async_memcpy_event_t *event, void *cb_args)
391+
{
392+
test_weighted_arb_context_t *ctx = (test_weighted_arb_context_t *)cb_args;
393+
BaseType_t high_task_wakeup = pdFALSE;
394+
ctx->elapse_us = ccomp_timer_get_time();
395+
xSemaphoreGiveFromISR(ctx->sem, &high_task_wakeup);
396+
return high_task_wakeup == pdTRUE;
397+
}
398+
399+
static void memcpy_weighted_arb_test(async_memcpy_handle_t driver[2], size_t burst_size, uint32_t buffer_size, bool buffer_in_psram)
400+
{
401+
SemaphoreHandle_t sem[2] = {xSemaphoreCreateBinary(),xSemaphoreCreateBinary()};
402+
int64_t elapse_us[2] = {0};
403+
float throughput[2] = {0.0};
404+
405+
memcpy_testbench_context_t test_context = {
406+
.align = burst_size,
407+
.buffer_size = buffer_size,
408+
.src_dst_same = !buffer_in_psram, // if buffer is in PSRAM, no memory size limitation
409+
.src_in_psram = buffer_in_psram,
410+
.dst_in_psram = buffer_in_psram,
411+
};
412+
async_memcpy_setup_testbench(&test_context);
413+
test_weighted_arb_context_t ctx[2] = {
414+
[0] = {
415+
.sem = sem[0],
416+
},
417+
[1] = {
418+
.sem = sem[1],
419+
}
420+
};
421+
422+
ccomp_timer_start();
423+
TEST_ESP_OK(esp_async_memcpy(driver[0], test_context.to_addr, test_context.from_addr, test_context.copy_size, test_weighted_arb_isr_cb, &ctx[0]));
424+
TEST_ESP_OK(esp_async_memcpy(driver[1], test_context.to_addr, test_context.from_addr, test_context.copy_size, test_weighted_arb_isr_cb, &ctx[1]));
425+
426+
// get channel_1 spent time
427+
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem[1], pdMS_TO_TICKS(1000)));
428+
elapse_us[1] = ctx[1].elapse_us;
429+
430+
// wait for channel_0 done, keep channel_1 busy to do arbitration
431+
while(xSemaphoreTake(sem[0], 0) == pdFALSE) {
432+
TEST_ESP_OK(esp_async_memcpy(driver[1], test_context.to_addr, test_context.from_addr, test_context.copy_size, test_weighted_arb_isr_cb, &ctx[1]));
433+
TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem[1], pdMS_TO_TICKS(1000)));
434+
}
435+
// get channel_0 spent time
436+
elapse_us[0] = ctx[0].elapse_us;
437+
438+
ccomp_timer_stop();
439+
throughput[0] = (float)test_context.buffer_size * 1e6 / 1024 / 1024 / elapse_us[0];
440+
IDF_LOG_PERFORMANCE("DMA0_COPY", "%.2f MB/s, size: %zu Bytes", throughput[0], test_context.buffer_size);
441+
442+
throughput[1] = (float)test_context.buffer_size * 1e6 / 1024 / 1024 / elapse_us[1];
443+
IDF_LOG_PERFORMANCE("DMA1_COPY", "%.2f MB/s, size: %zu Bytes", throughput[1], test_context.buffer_size);
444+
445+
// the bandwidth of channel_1 should be at least 10 times of channel_0
446+
TEST_ASSERT_EQUAL(throughput[1] / throughput[0] > 10, true);
447+
448+
async_memcpy_verify_and_clear_testbench(test_context.copy_size, test_context.src_buf, buffer_in_psram ? test_context.dst_buf : NULL,
449+
test_context.from_addr, test_context.to_addr);
450+
451+
vSemaphoreDelete(sem[0]);
452+
vSemaphoreDelete(sem[1]);
453+
}
454+
455+
TEST_CASE("GDMA M2M Weighted Arbitration Test SRAM->SRAM", "[GDMA][M2M][async mcp]")
456+
{
457+
async_memcpy_config_t driver_config = {
458+
.backlog = TEST_ASYNC_MEMCPY_BENCH_COUNTS,
459+
.dma_burst_size = 64,
460+
};
461+
462+
async_memcpy_handle_t driver[2] = {NULL};
463+
464+
#if SOC_AHB_GDMA_SUPPORTED
465+
driver_config.weight = 1;
466+
TEST_ESP_OK(esp_async_memcpy_install_gdma_ahb(&driver_config, &driver[0]));
467+
driver_config.weight = 15;
468+
TEST_ESP_OK(esp_async_memcpy_install_gdma_ahb(&driver_config, &driver[1]));
469+
memcpy_weighted_arb_test(driver, driver_config.dma_burst_size, 200 * 1024, false);
470+
TEST_ESP_OK(esp_async_memcpy_uninstall(driver[0]));
471+
TEST_ESP_OK(esp_async_memcpy_uninstall(driver[1]));
472+
#endif // SOC_AHB_GDMA_SUPPORTED
473+
}
474+
475+
#if SOC_SPIRAM_SUPPORTED
476+
TEST_CASE("GDMA M2M Weighted Arbitration Test PSRAM->PSRAM", "[GDMA][M2M][async mcp]")
477+
{
478+
[[maybe_unused]] async_memcpy_config_t driver_config = {
479+
.backlog = TEST_ASYNC_MEMCPY_BENCH_COUNTS,
480+
.dma_burst_size = 32, // PSRAM bandwidth may be not enough if burst size is 64
481+
};
482+
483+
[[maybe_unused]] async_memcpy_handle_t driver[2] = {NULL};
484+
485+
#if SOC_AHB_GDMA_SUPPORTED && SOC_AHB_GDMA_SUPPORT_PSRAM
486+
driver_config.weight = 1;
487+
TEST_ESP_OK(esp_async_memcpy_install_gdma_ahb(&driver_config, &driver[0]));
488+
driver_config.weight = 15;
489+
TEST_ESP_OK(esp_async_memcpy_install_gdma_ahb(&driver_config, &driver[1]));
490+
memcpy_weighted_arb_test(driver, driver_config.dma_burst_size, 200 * 1024, true);
491+
TEST_ESP_OK(esp_async_memcpy_uninstall(driver[0]));
492+
TEST_ESP_OK(esp_async_memcpy_uninstall(driver[1]));
493+
#endif // SOC_AHB_GDMA_SUPPORTED && SOC_AHB_GDMA_SUPPORT_PSRAM
494+
}
495+
#endif // SOC_SPIRAM_SUPPORTED
496+
497+
#endif // CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION

components/esp_hw_support/test_apps/dma/pytest_dma.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import pytest
44
from pytest_embedded import Dut
55
from pytest_embedded_idf.utils import idf_parametrize
6+
from pytest_embedded_idf.utils import soc_filtered_targets
67

78

89
@pytest.mark.generic
@@ -33,3 +34,16 @@ def test_dma(dut: Dut) -> None:
3334
@idf_parametrize('target', ['esp32s3'], indirect=['target'])
3435
def test_dma_psram(dut: Dut) -> None:
3536
dut.run_all_single_board_cases(reset=True)
37+
38+
39+
@pytest.mark.generic
40+
@pytest.mark.parametrize(
41+
'config',
42+
[
43+
'weighted_arbitration',
44+
],
45+
indirect=True,
46+
)
47+
@idf_parametrize('target', soc_filtered_targets('SOC_GDMA_SUPPORT_WEIGHTED_ARBITRATION == 1'), indirect=['target'])
48+
def test_dma_weighted_arbitration(dut: Dut) -> None:
49+
dut.run_all_single_board_cases(reset=True)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION=y
2+
CONFIG_IDF_EXPERIMENTAL_FEATURES=y

0 commit comments

Comments
 (0)