feat(gdma_link): support to select final node link type

This commit is contained in:
laokaiyao
2025-11-27 11:36:58 +08:00
parent 7d8d166f83
commit ce84d734ef
11 changed files with 46 additions and 29 deletions
@@ -232,7 +232,7 @@ static esp_err_t mcp_cpdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *
.length = n,
.flags = {
.mark_eof = true, // mark the last item as EOF, so the RX channel can also received an EOF list item
.mark_final = true, // using singly list, so terminate the link here
.mark_final = GDMA_FINAL_LINK_TO_NULL, // using singly list, so terminate the link here
}
}
};
@@ -256,7 +256,7 @@ static esp_err_t mcp_cpdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *
.length = n,
.flags = {
.mark_eof = false, // EOF is set by TX side
.mark_final = true, // using singly list, so terminate the link here
.mark_final = GDMA_FINAL_LINK_TO_NULL, // using singly list, so terminate the link here
}
}
};
@@ -365,7 +365,7 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
.length = n,
.flags = {
.mark_eof = true, // mark the last item as EOF, so the RX channel can also received an EOF list item
.mark_final = true, // using singly list, so terminate the link here
.mark_final = GDMA_FINAL_LINK_TO_NULL, // using singly list, so terminate the link here
}
}
};
+13 -4
View File
@@ -204,10 +204,19 @@ esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, int start_item_i
// mark the EOF node
lli_nc->dw0.suc_eof = (config->flags.mark_eof == 1) && (i == num_items_need - 1);
// mark the final node
if ((config->flags.mark_final == 1) && (i == num_items_need - 1)) {
lli_nc->next = NULL;
} else {
lli_nc->next = (gdma_link_list_item_t *)(list->items + (i + begin_item_idx + 1) % list_item_capacity * item_size);
switch (config->flags.mark_final) {
case GDMA_FINAL_LINK_TO_NULL:
lli_nc->next = NULL;
break;
case GDMA_FINAL_LINK_TO_HEAD:
lli_nc->next = (gdma_link_list_item_t *)(list->items);
break;
case GDMA_FINAL_LINK_TO_START:
lli_nc->next = (gdma_link_list_item_t *)(list->items + begin_item_idx * item_size);
break;
default:
lli_nc->next = (gdma_link_list_item_t *)(list->items + (i + begin_item_idx + 1) % list_item_capacity * item_size);
break;
}
lli_nc->dw0.owner = GDMA_LLI_OWNER_DMA;
buf += max_buffer_mount_length;
@@ -56,6 +56,17 @@ esp_err_t gdma_new_link_list(const gdma_link_list_config_t *config, gdma_link_li
*/
esp_err_t gdma_del_link_list(gdma_link_list_handle_t list);
/**
* @brief Types for the next node of the final item in the DMA link list
*
*/
typedef enum {
GDMA_FINAL_LINK_TO_DEFAULT = 0, /*!< The next node is linked to the default next item in the link list */
GDMA_FINAL_LINK_TO_NULL = 1, /*!< The next node is linked to the final item in the link list */
GDMA_FINAL_LINK_TO_HEAD = 2, /*!< The next node is linked to the head item in the link list */
GDMA_FINAL_LINK_TO_START = 3, /*!< The next node is linked to the start item in the link list */
} gdma_final_node_link_type_t;
/**
* @brief DMA buffer mount configurations
*/
@@ -68,10 +79,7 @@ typedef struct {
Note, an "EOF" descriptor can be interrupted differently by peripheral.
But it doesn't mean to terminate a DMA link (use `mark_final` instead).
EOF link list item can also trigger an interrupt. */
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 last one in the list. */
gdma_final_node_link_type_t mark_final: 2; /*!< The next node of the final item in the link list */
uint32_t bypass_buffer_align_check: 1; /*!< Whether to bypass the buffer alignment check.
Only enable it when you know what you are doing. */
} flags; //!< Flags for buffer mount configurations