mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(gdma_link): support to select final node link type
This commit is contained in:
@@ -232,7 +232,7 @@ esp_err_t bitscrambler_loopback_run(bitscrambler_handle_t bs, void *buffer_in, s
|
|||||||
.length = length_bytes_in,
|
.length = length_bytes_in,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.mark_final = true,
|
.mark_final = GDMA_FINAL_LINK_TO_NULL,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
gdma_link_mount_buffers(bsl->tx_link_list, 0, &in_buf_mount_config, 1, NULL);
|
gdma_link_mount_buffers(bsl->tx_link_list, 0, &in_buf_mount_config, 1, NULL);
|
||||||
@@ -242,7 +242,7 @@ esp_err_t bitscrambler_loopback_run(bitscrambler_handle_t bs, void *buffer_in, s
|
|||||||
.length = length_bytes_out,
|
.length = length_bytes_out,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = false,
|
.mark_eof = false,
|
||||||
.mark_final = true,
|
.mark_final = GDMA_FINAL_LINK_TO_NULL,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
gdma_link_mount_buffers(bsl->rx_link_list, 0, &out_buf_mount_config, 1, NULL);
|
gdma_link_mount_buffers(bsl->rx_link_list, 0, &out_buf_mount_config, 1, NULL);
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ static void parlio_mount_buffer(parlio_tx_unit_t *tx_unit, parlio_tx_trans_desc_
|
|||||||
.flags = {
|
.flags = {
|
||||||
// if transmission is loop, we don't need to generate the EOF for 1-bit data width, DIG-559
|
// if transmission is loop, we don't need to generate the EOF for 1-bit data width, DIG-559
|
||||||
.mark_eof = tx_unit->data_width == 1 ? !t->flags.loop_transmission : true,
|
.mark_eof = tx_unit->data_width == 1 ? !t->flags.loop_transmission : true,
|
||||||
.mark_final = !t->flags.loop_transmission,
|
.mark_final = !t->flags.loop_transmission ? GDMA_FINAL_LINK_TO_NULL : GDMA_FINAL_LINK_TO_DEFAULT,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ static void uhci_do_transmit(uhci_controller_handle_t uhci_ctrl, uhci_transactio
|
|||||||
.length = trans->buffer_size,
|
.length = trans->buffer_size,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.mark_final = true,
|
.mark_final = GDMA_FINAL_LINK_TO_NULL,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -338,7 +338,7 @@ esp_err_t uhci_receive(uhci_controller_handle_t uhci_ctrl, uint8_t *read_buffer,
|
|||||||
.buffer_alignment = buffer_alignment,
|
.buffer_alignment = buffer_alignment,
|
||||||
.length = uhci_ctrl->rx_dir.buffer_size_per_desc_node[i],
|
.length = uhci_ctrl->rx_dir.buffer_size_per_desc_node[i],
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_final = false,
|
.mark_final = GDMA_FINAL_LINK_TO_DEFAULT,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ESP_LOGD(TAG, "The DMA node %d has %d byte", i, uhci_ctrl->rx_dir.buffer_size_per_desc_node[i]);
|
ESP_LOGD(TAG, "The DMA node %d has %d byte", i, uhci_ctrl->rx_dir.buffer_size_per_desc_node[i]);
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ static esp_err_t mcp_cpdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *
|
|||||||
.length = n,
|
.length = n,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true, // mark the last item as EOF, so the RX channel can also received an EOF list item
|
.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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -257,7 +257,7 @@ static esp_err_t mcp_cpdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *
|
|||||||
.length = n,
|
.length = n,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = false, // EOF is set by TX side
|
.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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -372,7 +372,7 @@ static esp_err_t mcp_gdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *s
|
|||||||
.length = n,
|
.length = n,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true, // mark the last item as EOF, so the RX channel can also received an EOF list item
|
.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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
// mark the EOF node
|
||||||
lli_nc->dw0.suc_eof = (config->flags.mark_eof == 1) && (i == num_items_need - 1);
|
lli_nc->dw0.suc_eof = (config->flags.mark_eof == 1) && (i == num_items_need - 1);
|
||||||
// mark the final node
|
// mark the final node
|
||||||
if ((config->flags.mark_final == 1) && (i == num_items_need - 1)) {
|
switch (config->flags.mark_final) {
|
||||||
lli_nc->next = NULL;
|
case GDMA_FINAL_LINK_TO_NULL:
|
||||||
} else {
|
lli_nc->next = NULL;
|
||||||
lli_nc->next = (gdma_link_list_item_t *)(list->items + (i + begin_item_idx + 1) % list_item_capacity * item_size);
|
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;
|
lli_nc->dw0.owner = GDMA_LLI_OWNER_DMA;
|
||||||
buf += max_buffer_mount_length;
|
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);
|
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
|
* @brief DMA buffer mount configurations
|
||||||
*/
|
*/
|
||||||
@@ -68,10 +79,7 @@ typedef struct {
|
|||||||
Note, an "EOF" descriptor can be interrupted differently by peripheral.
|
Note, an "EOF" descriptor can be interrupted differently by peripheral.
|
||||||
But it doesn't mean to terminate a DMA link (use `mark_final` instead).
|
But it doesn't mean to terminate a DMA link (use `mark_final` instead).
|
||||||
EOF link list item can also trigger an interrupt. */
|
EOF link list item can also trigger an interrupt. */
|
||||||
uint32_t mark_final: 1; /*!< Whether to terminate the DMA link list at this item.
|
gdma_final_node_link_type_t mark_final: 2; /*!< The next node of the final item in the link list */
|
||||||
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. */
|
|
||||||
uint32_t bypass_buffer_align_check: 1; /*!< Whether to bypass the buffer alignment check.
|
uint32_t bypass_buffer_align_check: 1; /*!< Whether to bypass the buffer alignment check.
|
||||||
Only enable it when you know what you are doing. */
|
Only enable it when you know what you are doing. */
|
||||||
} flags; //!< Flags for buffer mount configurations
|
} flags; //!< Flags for buffer mount configurations
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe
|
|||||||
#if !SOC_DMA_CAN_ACCESS_FLASH
|
#if !SOC_DMA_CAN_ACCESS_FLASH
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.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
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
@@ -289,7 +289,7 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe
|
|||||||
.length = src_string_len,
|
.length = src_string_len,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.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
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
@@ -448,7 +448,7 @@ static void test_gdma_m2m_unaligned_buffer_test(uint8_t *dst_data, uint8_t *src_
|
|||||||
.length = data_length,
|
.length = data_length,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -609,7 +609,7 @@ TEST_CASE("GDMA M2M Unaligned RX Buffer Test", "[GDMA][M2M]")
|
|||||||
.length = COPY_SIZE,
|
.length = COPY_SIZE,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(gdma_link_mount_buffers(tx_link_list, 0, &tx_buf_mount_config, 1, NULL));
|
TEST_ESP_OK(gdma_link_mount_buffers(tx_link_list, 0, &tx_buf_mount_config, 1, NULL));
|
||||||
@@ -619,7 +619,7 @@ TEST_CASE("GDMA M2M Unaligned RX Buffer Test", "[GDMA][M2M]")
|
|||||||
.buffer_alignment = 32,
|
.buffer_alignment = 32,
|
||||||
.length = COPY_SIZE,
|
.length = COPY_SIZE,
|
||||||
.flags = {
|
.flags = {
|
||||||
.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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, &rx_buf_mount_config, 1, NULL));
|
TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, &rx_buf_mount_config, 1, NULL));
|
||||||
|
|||||||
@@ -498,7 +498,7 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||||||
gdma_buffer_mount_config_t mount_config = {
|
gdma_buffer_mount_config_t mount_config = {
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.mark_final = true, // singly link list, mark final descriptor
|
.mark_final = GDMA_FINAL_LINK_TO_NULL, // singly link list, mark final descriptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -578,7 +578,7 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||||||
gdma_buffer_mount_config_t mount_config = {
|
gdma_buffer_mount_config_t mount_config = {
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.mark_final = true, // singly link list, mark final descriptor
|
.mark_final = GDMA_FINAL_LINK_TO_NULL, // singly link list, mark final descriptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -707,7 +707,7 @@ static void i2s_lcd_trigger_quick_trans_done_event(esp_lcd_i80_bus_handle_t bus)
|
|||||||
.length = 4,
|
.length = 4,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true, // mark the "EOF" flag to trigger I2S EOF interrupt
|
.mark_eof = true, // mark the "EOF" flag to trigger I2S EOF interrupt
|
||||||
.mark_final = true, // singly link list, mark final descriptor
|
.mark_final = GDMA_FINAL_LINK_TO_NULL, // singly link list, mark final descriptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL);
|
gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL);
|
||||||
@@ -796,7 +796,7 @@ static IRAM_ATTR void i2s_lcd_default_isr_handler(void *args)
|
|||||||
.length = trans_desc->data_length,
|
.length = trans_desc->data_length,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.mark_final = true, // singly link list, mark final descriptor
|
.mark_final = GDMA_FINAL_LINK_TO_NULL, // singly link list, mark final descriptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL);
|
gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL);
|
||||||
|
|||||||
@@ -473,7 +473,7 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
|||||||
.length = trans_desc->data_length,
|
.length = trans_desc->data_length,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.mark_final = true, // singly link list, mark final descriptor
|
.mark_final = GDMA_FINAL_LINK_TO_NULL, // singly link list, mark final descriptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL);
|
gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL);
|
||||||
@@ -797,7 +797,7 @@ IRAM_ATTR static void i80_lcd_default_isr_handler(void *args)
|
|||||||
.length = trans_desc->data_length,
|
.length = trans_desc->data_length,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
.mark_final = true, // singly link list, mark final descriptor
|
.mark_final = GDMA_FINAL_LINK_TO_NULL, // singly link list, mark final descriptor
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL);
|
gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL);
|
||||||
|
|||||||
@@ -1019,7 +1019,7 @@ static esp_err_t lcd_rgb_panel_init_trans_link(esp_rgb_panel_t *rgb_panel)
|
|||||||
mount_cfgs[i].buffer = rgb_panel->bounce_buffer[i];
|
mount_cfgs[i].buffer = rgb_panel->bounce_buffer[i];
|
||||||
mount_cfgs[i].buffer_alignment = buffer_alignment;
|
mount_cfgs[i].buffer_alignment = buffer_alignment;
|
||||||
mount_cfgs[i].length = rgb_panel->bb_size;
|
mount_cfgs[i].length = rgb_panel->bb_size;
|
||||||
mount_cfgs[i].flags.mark_eof = true; // we use the DMA EOF interrupt to copy the frame buffer (partially) to the bounce buffer
|
mount_cfgs[i].flags.mark_eof = GDMA_FINAL_LINK_TO_NULL; // we use the DMA EOF interrupt to copy the frame buffer (partially) to the bounce buffer
|
||||||
}
|
}
|
||||||
ESP_RETURN_ON_ERROR(gdma_link_mount_buffers(rgb_panel->dma_bb_link, 0, mount_cfgs, RGB_LCD_PANEL_BOUNCE_BUF_NUM, NULL),
|
ESP_RETURN_ON_ERROR(gdma_link_mount_buffers(rgb_panel->dma_bb_link, 0, mount_cfgs, RGB_LCD_PANEL_BOUNCE_BUF_NUM, NULL),
|
||||||
TAG, "mount DMA bounce buffers failed");
|
TAG, "mount DMA bounce buffers failed");
|
||||||
@@ -1058,7 +1058,7 @@ static esp_err_t lcd_rgb_panel_init_trans_link(esp_rgb_panel_t *rgb_panel)
|
|||||||
gdma_buffer_mount_config_t mount_cfg = {
|
gdma_buffer_mount_config_t mount_cfg = {
|
||||||
.length = rgb_panel->fb_size,
|
.length = rgb_panel->fb_size,
|
||||||
.flags = {
|
.flags = {
|
||||||
.mark_final = rgb_panel->flags.stream_mode ? false : true,
|
.mark_final = rgb_panel->flags.stream_mode ? GDMA_FINAL_LINK_TO_DEFAULT : GDMA_FINAL_LINK_TO_NULL,
|
||||||
.mark_eof = true,
|
.mark_eof = true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user