mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
46b66530ce
1. add check in the gdma driver, to prevent multiple channels connecting to the same peripheral 2. memory copy DMA ID will occupy the peripheral's DMA ID on some ESP targets (e.g. esp32c3/s3). We should search for a free one when install async memcpy driver. Closes https://github.com/espressif/esp-idf/issues/10575
81 lines
3.3 KiB
C
81 lines
3.3 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include "unity.h"
|
|
#include "esp_private/gdma.h"
|
|
#include "soc/soc_caps.h"
|
|
|
|
#if SOC_GDMA_SUPPORTED
|
|
|
|
TEST_CASE("GDMA channel allocation", "[gdma]")
|
|
{
|
|
gdma_channel_alloc_config_t channel_config = {};
|
|
gdma_channel_handle_t tx_channels[SOC_GDMA_PAIRS_PER_GROUP] = {};
|
|
gdma_channel_handle_t rx_channels[SOC_GDMA_PAIRS_PER_GROUP] = {};
|
|
channel_config.direction = GDMA_CHANNEL_DIRECTION_TX;
|
|
gdma_tx_event_callbacks_t tx_cbs = {};
|
|
gdma_rx_event_callbacks_t rx_cbs = {};
|
|
|
|
// install TX channels
|
|
for (int i = 0; i < SOC_GDMA_PAIRS_PER_GROUP; i++) {
|
|
TEST_ESP_OK(gdma_new_channel(&channel_config, &tx_channels[i]));
|
|
TEST_ESP_OK(gdma_register_tx_event_callbacks(tx_channels[i], &tx_cbs, NULL));
|
|
};
|
|
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, gdma_new_channel(&channel_config, &tx_channels[0]));
|
|
|
|
// Free interrupts before installing RX interrupts to ensure enough free interrupts
|
|
for (int i = 0; i < SOC_GDMA_PAIRS_PER_GROUP; i++) {
|
|
TEST_ESP_OK(gdma_del_channel(tx_channels[i]));
|
|
}
|
|
|
|
// install RX channels
|
|
channel_config.direction = GDMA_CHANNEL_DIRECTION_RX;
|
|
for (int i = 0; i < SOC_GDMA_PAIRS_PER_GROUP; i++) {
|
|
TEST_ESP_OK(gdma_new_channel(&channel_config, &rx_channels[i]));
|
|
TEST_ESP_OK(gdma_register_rx_event_callbacks(rx_channels[i], &rx_cbs, NULL));
|
|
}
|
|
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, gdma_new_channel(&channel_config, &rx_channels[0]));
|
|
|
|
for (int i = 0; i < SOC_GDMA_PAIRS_PER_GROUP; i++) {
|
|
TEST_ESP_OK(gdma_del_channel(rx_channels[i]));
|
|
}
|
|
|
|
// install single and paired TX/RX channels
|
|
#if SOC_GDMA_PAIRS_PER_GROUP >= 2
|
|
// single tx channel
|
|
channel_config.direction = GDMA_CHANNEL_DIRECTION_TX;
|
|
TEST_ESP_OK(gdma_new_channel(&channel_config, &tx_channels[0]));
|
|
|
|
// create tx channel and reserve sibling
|
|
channel_config.direction = GDMA_CHANNEL_DIRECTION_TX;
|
|
channel_config.flags.reserve_sibling = 1;
|
|
TEST_ESP_OK(gdma_new_channel(&channel_config, &tx_channels[1]));
|
|
// create rx channel and specify sibling channel
|
|
channel_config.flags.reserve_sibling = 0;
|
|
channel_config.sibling_chan = tx_channels[1]; // specify sibling channel
|
|
channel_config.direction = GDMA_CHANNEL_DIRECTION_RX;
|
|
TEST_ESP_OK(gdma_new_channel(&channel_config, &rx_channels[1]));
|
|
channel_config.sibling_chan = NULL;
|
|
TEST_ESP_OK(gdma_new_channel(&channel_config, &rx_channels[0]));
|
|
|
|
TEST_ESP_OK(gdma_connect(tx_channels[0], GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)));
|
|
// can't connect multiple channels to the same peripheral
|
|
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, gdma_connect(tx_channels[1], GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)));
|
|
TEST_ESP_OK(gdma_connect(tx_channels[1], GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_M2M, 0)));
|
|
|
|
TEST_ESP_OK(gdma_connect(rx_channels[0], GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)));
|
|
// but rx and tx can connect to the same peripheral
|
|
TEST_ESP_OK(gdma_connect(rx_channels[1], GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_M2M, 0)));
|
|
for (int i = 0; i < 2; i++) {
|
|
TEST_ESP_OK(gdma_disconnect(tx_channels[i]));
|
|
TEST_ESP_OK(gdma_disconnect(rx_channels[i]));
|
|
TEST_ESP_OK(gdma_del_channel(tx_channels[i]));
|
|
TEST_ESP_OK(gdma_del_channel(rx_channels[i]));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#endif
|