From fd5736f9bf778238fef35c6af5de7ed4ea2d22e1 Mon Sep 17 00:00:00 2001 From: morris Date: Tue, 27 Aug 2024 17:45:05 +0800 Subject: [PATCH] feat(gdma): added function to concat two link lists --- components/esp_hw_support/dma/gdma_link.c | 13 +++++++-- .../dma/include/esp_private/gdma_link.h | 27 ++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/components/esp_hw_support/dma/gdma_link.c b/components/esp_hw_support/dma/gdma_link.c index d13b62e64d..ae9d70326f 100644 --- a/components/esp_hw_support/dma/gdma_link.c +++ b/components/esp_hw_support/dma/gdma_link.c @@ -227,11 +227,20 @@ uintptr_t gdma_link_get_head_addr(gdma_link_list_handle_t list) return (uintptr_t)(list->items); } +esp_err_t gdma_link_concat(gdma_link_list_handle_t first_link, int first_link_item_index, gdma_link_list_handle_t second_link, int second_link_item_index) +{ + ESP_RETURN_ON_FALSE(first_link && second_link, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + gdma_link_list_item_t *lli_nc = NULL; + lli_nc = (gdma_link_list_item_t *)(first_link->items_nc + (first_link->num_items + first_link_item_index) % first_link->num_items * first_link->item_size); + lli_nc->next = (gdma_link_list_item_t *)(second_link->items + (second_link->num_items + second_link_item_index) % second_link->num_items * second_link->item_size); + return ESP_OK; +} + esp_err_t gdma_link_set_owner(gdma_link_list_handle_t list, int item_index, gdma_lli_owner_t owner) { ESP_RETURN_ON_FALSE_ISR(list, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE_ISR(item_index < list->num_items, ESP_ERR_INVALID_ARG, TAG, "invalid item index"); - gdma_link_list_item_t *lli = (gdma_link_list_item_t *)(list->items_nc + item_index * list->item_size); + gdma_link_list_item_t *lli = (gdma_link_list_item_t *)(list->items_nc + (list->num_items + item_index) % list->num_items * list->item_size); lli->dw0.owner = owner; return ESP_OK; } @@ -240,7 +249,7 @@ esp_err_t gdma_link_get_owner(gdma_link_list_handle_t list, int item_index, gdma { ESP_RETURN_ON_FALSE_ISR(list && owner, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE_ISR(item_index < list->num_items, ESP_ERR_INVALID_ARG, TAG, "invalid item index"); - gdma_link_list_item_t *lli = (gdma_link_list_item_t *)(list->items_nc + item_index * list->item_size); + gdma_link_list_item_t *lli = (gdma_link_list_item_t *)(list->items_nc + (list->num_items + item_index) % list->num_items * list->item_size); *owner = lli->dw0.owner; return ESP_OK; } diff --git a/components/esp_hw_support/dma/include/esp_private/gdma_link.h b/components/esp_hw_support/dma/include/esp_private/gdma_link.h index 94a13651c4..61dd0beba6 100644 --- a/components/esp_hw_support/dma/include/esp_private/gdma_link.h +++ b/components/esp_hw_support/dma/include/esp_private/gdma_link.h @@ -71,7 +71,7 @@ typedef struct { uint32_t mark_final: 1; /*!< Whether to terminate the DMA link list at this item. Note, DMA engine will stop at this item and trigger an interrupt. If `mark_final` is not set, this list item will point to the next item, and - wrap around to the head item if it's the one in the list. */ + wrap around to the head item if it's the last one in the list. */ } flags; //!< Flags for buffer mount configurations } gdma_buffer_mount_config_t; @@ -105,6 +105,27 @@ esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, uint32_t start_i */ uintptr_t gdma_link_get_head_addr(gdma_link_list_handle_t list); +/** + * @brief Concatenate two link lists as follows: + * + * Link A: A1 --> A2 --> A3 --> A4 + * | item_index + * +-----+ + * | + * v item_index + * Link B: B1 --> B2 --> B3 --> B4 + * + * @param[in] first_link First link list handle, allocated by `gdma_new_link_list` + * @param[in] first_link_item_index Index of the item in the first link list (-1 means the last item) + * @param[in] second_link Second link list handle, allocated by `gdma_new_link_list` + * @param[in] second_link_item_index Index of the item in the second link list (-1 means the last item) + * @return + * - ESP_OK: Concatenate the link lists successfully + * - ESP_ERR_INVALID_ARG: Concatenate the link lists failed because of invalid argument + * - ESP_FAIL: Concatenate the link lists failed because of other error + */ +esp_err_t gdma_link_concat(gdma_link_list_handle_t first_link, int first_link_item_index, gdma_link_list_handle_t second_link, int second_link_item_index); + /** * @brief GDMA link list item owner */ @@ -117,7 +138,7 @@ typedef enum { * @brief Set the ownership for a DMA link list item * * @param[in] list Link list handle, allocated by `gdma_new_link_list` - * @param[in] item_index Index of the link list item + * @param[in] item_index Index of the link list item (-1 means the last item) * @param[in] owner Ownership * @return * - ESP_OK: Set the ownership successfully @@ -130,7 +151,7 @@ esp_err_t gdma_link_set_owner(gdma_link_list_handle_t list, int item_index, gdma * @brief Get the ownership of a DMA link list item * * @param[in] list Link list handle, allocated by `gdma_new_link_list` - * @param[in] item_index Index of the link list item + * @param[in] item_index Index of the link list item (-1 means the last item) * @param[out] owner Ownership * @return * - ESP_OK: Get the ownership successfully