feat(i2s): enable dma burst size configuration

This commit is contained in:
Chen Chen
2026-08-20 16:37:37 +08:00
parent 3cd64a905d
commit bea9fd822c
7 changed files with 112 additions and 70 deletions

View File

@@ -922,12 +922,18 @@ TEST_CASE("GDMA interrupt priority configuration", "[GDMA]")
TEST_ESP_OK(gdma_del_channel(rx_chan));
}
#if SOC_HAS(AHB_GDMA)
TEST_CASE("GDMA rejects invalid AHB burst sizes", "[GDMA]")
#if SOC_HAS(AHB_GDMA) || SOC_HAS(LP_AHB_GDMA) || SOC_HAS(AXI_GDMA)
typedef esp_err_t (*gdma_new_channel_func_t)(const gdma_channel_alloc_config_t *config,
gdma_channel_handle_t *ret_tx_chan,
gdma_channel_handle_t *ret_rx_chan);
static void test_gdma_burst_size_validation(gdma_new_channel_func_t new_channel,
size_t unsupported_burst_size,
size_t invalid_psram_burst_size)
{
gdma_channel_handle_t tx_chan = NULL;
gdma_channel_alloc_config_t channel_config = {};
TEST_ESP_OK(gdma_new_ahb_channel(&channel_config, &tx_chan, NULL));
TEST_ESP_OK(new_channel(&channel_config, &tx_chan, NULL));
gdma_transfer_config_t transfer_config = {
.max_data_burst_size = 16,
@@ -935,52 +941,60 @@ TEST_CASE("GDMA rejects invalid AHB burst sizes", "[GDMA]")
};
TEST_ESP_OK(gdma_config_transfer(tx_chan, &transfer_config));
#if GDMA_LL_GET(AHB_BURST_SIZE_ADJUSTABLE)
// Non power-of-two must be rejected when the burst size is programmable.
transfer_config.max_data_burst_size = 3;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gdma_config_transfer(tx_chan, &transfer_config));
// 8 is a power of two but is outside every current AHB supported-burst mask.
transfer_config.max_data_burst_size = 8;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gdma_config_transfer(tx_chan, &transfer_config));
if (unsupported_burst_size) {
transfer_config.max_data_burst_size = unsupported_burst_size;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gdma_config_transfer(tx_chan, &transfer_config));
}
#if GDMA_LL_GET(AHB_PSRAM_CAPABLE)
transfer_config.access_ext_mem = true;
transfer_config.max_data_burst_size = GDMA_LL_MAX_BURST_SIZE_PSRAM * 2;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gdma_config_transfer(tx_chan, &transfer_config));
#endif // GDMA_LL_GET(AHB_PSRAM_CAPABLE)
#endif // GDMA_LL_GET(AHB_BURST_SIZE_ADJUSTABLE)
if (invalid_psram_burst_size) {
transfer_config.access_ext_mem = true;
transfer_config.max_data_burst_size = invalid_psram_burst_size;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gdma_config_transfer(tx_chan, &transfer_config));
}
TEST_ESP_OK(gdma_del_channel(tx_chan));
}
#endif // SOC_HAS(AHB_GDMA) || SOC_HAS(LP_AHB_GDMA) || SOC_HAS(AXI_GDMA)
#if SOC_HAS(AHB_GDMA) || SOC_HAS(LP_AHB_GDMA)
TEST_CASE("GDMA rejects invalid AHB burst sizes", "[GDMA]")
{
#if GDMA_LL_GET(AHB_BURST_SIZE_ADJUSTABLE)
const size_t unsupported_burst_size = 8;
#else
const size_t unsupported_burst_size = 0;
#endif
#if SOC_HAS(AHB_GDMA)
#if GDMA_LL_GET(AHB_PSRAM_CAPABLE)
test_gdma_burst_size_validation(gdma_new_ahb_channel, unsupported_burst_size,
GDMA_LL_MAX_BURST_SIZE_PSRAM * 2);
#else
test_gdma_burst_size_validation(gdma_new_ahb_channel, unsupported_burst_size, 0);
#endif
#endif // SOC_HAS(AHB_GDMA)
#if SOC_HAS(LP_AHB_GDMA)
#if GDMA_LL_GET(LP_AHB_PSRAM_CAPABLE)
test_gdma_burst_size_validation(gdma_new_lp_ahb_channel, unsupported_burst_size,
GDMA_LL_MAX_BURST_SIZE_PSRAM * 2);
#else
test_gdma_burst_size_validation(gdma_new_lp_ahb_channel, unsupported_burst_size, 0);
#endif
#endif // SOC_HAS(LP_AHB_GDMA)
}
#endif // SOC_HAS(AHB_GDMA) || SOC_HAS(LP_AHB_GDMA)
#if SOC_HAS(AXI_GDMA)
TEST_CASE("GDMA rejects invalid AXI burst sizes", "[GDMA]")
{
gdma_channel_handle_t tx_chan = NULL;
gdma_channel_alloc_config_t channel_config = {};
TEST_ESP_OK(gdma_new_axi_channel(&channel_config, &tx_chan, NULL));
gdma_transfer_config_t transfer_config = {
.max_data_burst_size = 16,
.access_ext_mem = false,
};
TEST_ESP_OK(gdma_config_transfer(tx_chan, &transfer_config));
transfer_config.max_data_burst_size = 3;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gdma_config_transfer(tx_chan, &transfer_config));
// 4 is a power of two but is outside the AXI supported-burst mask.
transfer_config.max_data_burst_size = 4;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gdma_config_transfer(tx_chan, &transfer_config));
#if GDMA_LL_GET(AXI_PSRAM_CAPABLE)
transfer_config.access_ext_mem = true;
transfer_config.max_data_burst_size = GDMA_LL_MAX_BURST_SIZE_PSRAM * 2;
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gdma_config_transfer(tx_chan, &transfer_config));
test_gdma_burst_size_validation(gdma_new_axi_channel, 4, GDMA_LL_MAX_BURST_SIZE_PSRAM * 2);
#else
test_gdma_burst_size_validation(gdma_new_axi_channel, 4, 0);
#endif // GDMA_LL_GET(AXI_PSRAM_CAPABLE)
TEST_ESP_OK(gdma_del_channel(tx_chan));
}
#endif // SOC_HAS(AXI_GDMA)