feat(gdma_link): support to select final node link type
This commit is contained in:
@@ -237,7 +237,7 @@ esp_err_t bitscrambler_loopback_run(bitscrambler_handle_t bs, void *buffer_in, s
|
||||
.length = length_bytes_in,
|
||||
.flags = {
|
||||
.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);
|
||||
@@ -247,7 +247,7 @@ esp_err_t bitscrambler_loopback_run(bitscrambler_handle_t bs, void *buffer_in, s
|
||||
.length = length_bytes_out,
|
||||
.flags = {
|
||||
.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);
|
||||
|
||||
@@ -481,7 +481,7 @@ static void parlio_mount_buffer(parlio_tx_unit_t *tx_unit, parlio_tx_trans_desc_
|
||||
.flags = {
|
||||
// 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_final = !t->flags.loop_transmission,
|
||||
.mark_final = !t->flags.loop_transmission ? GDMA_FINAL_LINK_TO_NULL : GDMA_FINAL_LINK_TO_DEFAULT,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ static void uhci_do_transmit(uhci_controller_handle_t uhci_ctrl, uhci_transactio
|
||||
.length = trans->buffer_size,
|
||||
.flags = {
|
||||
.mark_eof = true,
|
||||
.mark_final = true,
|
||||
.mark_final = GDMA_FINAL_LINK_TO_NULL,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -332,7 +332,7 @@ esp_err_t uhci_receive(uhci_controller_handle_t uhci_ctrl, uint8_t *read_buffer,
|
||||
.buffer_alignment = buffer_alignment,
|
||||
.length = uhci_ctrl->rx_dir.buffer_size_per_desc_node[i],
|
||||
.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]);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -278,7 +278,7 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe
|
||||
#if !SOC_DMA_CAN_ACCESS_FLASH
|
||||
.flags = {
|
||||
.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
|
||||
},
|
||||
@@ -289,7 +289,7 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe
|
||||
.length = src_string_len,
|
||||
.flags = {
|
||||
.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
|
||||
@@ -448,7 +448,7 @@ static void test_gdma_m2m_unaligned_buffer_test(uint8_t *dst_data, uint8_t *src_
|
||||
.length = data_length,
|
||||
.flags = {
|
||||
.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,
|
||||
.flags = {
|
||||
.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));
|
||||
@@ -619,7 +619,7 @@ TEST_CASE("GDMA M2M Unaligned RX Buffer Test", "[GDMA][M2M]")
|
||||
.buffer_alignment = 32,
|
||||
.length = COPY_SIZE,
|
||||
.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));
|
||||
|
||||
@@ -523,7 +523,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 = {
|
||||
.flags = {
|
||||
.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
|
||||
}
|
||||
};
|
||||
|
||||
@@ -599,7 +599,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 = {
|
||||
.flags = {
|
||||
.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
|
||||
}
|
||||
};
|
||||
|
||||
@@ -724,7 +724,7 @@ static void i2s_lcd_trigger_quick_trans_done_event(esp_lcd_i80_bus_handle_t bus)
|
||||
.length = 4,
|
||||
.flags = {
|
||||
.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);
|
||||
@@ -811,7 +811,7 @@ static IRAM_ATTR void i2s_lcd_default_isr_handler(void *args)
|
||||
.length = trans_desc->data_length,
|
||||
.flags = {
|
||||
.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);
|
||||
|
||||
@@ -500,7 +500,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,
|
||||
.flags = {
|
||||
.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);
|
||||
@@ -821,7 +821,7 @@ IRAM_ATTR static void i80_lcd_default_isr_handler(void *args)
|
||||
.length = trans_desc->data_length,
|
||||
.flags = {
|
||||
.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);
|
||||
|
||||
@@ -1013,7 +1013,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_alignment = buffer_alignment;
|
||||
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),
|
||||
TAG, "mount DMA bounce buffers failed");
|
||||
@@ -1052,7 +1052,7 @@ static esp_err_t lcd_rgb_panel_init_trans_link(esp_rgb_panel_t *rgb_panel)
|
||||
gdma_buffer_mount_config_t mount_cfg = {
|
||||
.length = rgb_panel->fb_size,
|
||||
.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,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user