feat(gdma): added function to concat two link lists

This commit is contained in:
morris
2024-08-27 17:45:05 +08:00
parent 03a0b7ace9
commit fd5736f9bf
2 changed files with 35 additions and 5 deletions

View File

@ -227,11 +227,20 @@ uintptr_t gdma_link_get_head_addr(gdma_link_list_handle_t list)
return (uintptr_t)(list->items); 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_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(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"); 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; lli->dw0.owner = owner;
return ESP_OK; 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(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"); 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; *owner = lli->dw0.owner;
return ESP_OK; return ESP_OK;
} }

View File

@ -71,7 +71,7 @@ typedef struct {
uint32_t mark_final: 1; /*!< Whether to terminate the DMA link list at this item. 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. 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 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 } flags; //!< Flags for buffer mount configurations
} gdma_buffer_mount_config_t; } 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); 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 * @brief GDMA link list item owner
*/ */
@ -117,7 +138,7 @@ typedef enum {
* @brief Set the ownership for a DMA link list item * @brief Set the ownership for a DMA link list item
* *
* @param[in] list Link list handle, allocated by `gdma_new_link_list` * @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 * @param[in] owner Ownership
* @return * @return
* - ESP_OK: Set the ownership successfully * - 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 * @brief Get the ownership of a DMA link list item
* *
* @param[in] list Link list handle, allocated by `gdma_new_link_list` * @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 * @param[out] owner Ownership
* @return * @return
* - ESP_OK: Get the ownership successfully * - ESP_OK: Get the ownership successfully