From 270ed70f3ed936b2b0ef2d5bd92974f4ffd53cb2 Mon Sep 17 00:00:00 2001 From: morris Date: Mon, 22 Mar 2021 21:58:04 +0800 Subject: [PATCH] gdma: support reset dma fifo at runtime --- components/driver/gdma.c | 19 +++++++++++++++++++ components/driver/include/esp_private/gdma.h | 13 +++++++++++++ 2 files changed, 32 insertions(+) diff --git a/components/driver/gdma.c b/components/driver/gdma.c index c1b7f497fc..dbfbb9bfbd 100644 --- a/components/driver/gdma.c +++ b/components/driver/gdma.c @@ -412,6 +412,25 @@ err: return ret; } +esp_err_t gdma_reset(gdma_channel_handle_t dma_chan) +{ + esp_err_t ret = ESP_OK; + gdma_pair_t *pair = NULL; + gdma_group_t *group = NULL; + ESP_GOTO_ON_FALSE(dma_chan, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + pair = dma_chan->pair; + group = pair->group; + + if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) { + gdma_ll_rx_reset_channel(group->hal.dev, pair->pair_id); + } else { + gdma_ll_tx_reset_channel(group->hal.dev, pair->pair_id); + } + +err: + return ret; +} + static void gdma_uninstall_group(gdma_group_t *group) { int group_id = group->group_id; diff --git a/components/driver/include/esp_private/gdma.h b/components/driver/include/esp_private/gdma.h index dc27f58269..2614a2d0fb 100644 --- a/components/driver/include/esp_private/gdma.h +++ b/components/driver/include/esp_private/gdma.h @@ -155,6 +155,7 @@ esp_err_t gdma_new_channel(const gdma_channel_alloc_config_t *config, gdma_chann * @brief Connect GDMA channel to trigger peripheral * * @note Suggest to use helper macro `GDMA_MAKE_TRIGGER` to construct parameter `trig_periph`. e.g. GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SHA,0) + * @note Connecting to a peripheral will also reset the DMA FIFO and FSM automatically * * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel` * @param[in] trig_periph GDMA trigger peripheral @@ -279,6 +280,18 @@ esp_err_t gdma_stop(gdma_channel_handle_t dma_chan); */ esp_err_t gdma_append(gdma_channel_handle_t dma_chan); +/** + * @brief Reset DMA channel FIFO and internal finite state machine + * @note Resetting a DMA channel won't break the connection with the target peripheral + * + * @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel` + * @return + * - ESP_OK: DMA channel reset successfully + * - ESP_ERR_INVALID_ARG: DMA channel reset failed due to invalid arguments + * - ESP_FAIL: DMA channel reset failed due to other errors + */ +esp_err_t gdma_reset(gdma_channel_handle_t dma_chan); + #ifdef __cplusplus } #endif