mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
feat(esp_driver_dma): add dw_gdma backend for async_memcpy
This commit is contained in:
@@ -67,7 +67,7 @@ typedef struct {
|
||||
.flags = 0, \
|
||||
}
|
||||
|
||||
#if SOC_HAS(AHB_GDMA)
|
||||
#if SOC_AHB_GDMA_SUPPORTED
|
||||
/**
|
||||
* @brief Install async memcpy driver, with AHB-GDMA as the backend
|
||||
*
|
||||
@@ -80,9 +80,9 @@ typedef struct {
|
||||
* - ESP_FAIL: Install async memcpy driver failed because of other error
|
||||
*/
|
||||
esp_err_t esp_async_memcpy_install_gdma_ahb(const async_memcpy_config_t *config, async_memcpy_handle_t *mcp);
|
||||
#endif // SOC_HAS(AHB_GDMA)
|
||||
#endif // SOC_AHB_GDMA_SUPPORTED
|
||||
|
||||
#if SOC_HAS(AXI_GDMA)
|
||||
#if SOC_AXI_GDMA_SUPPORTED
|
||||
/**
|
||||
* @brief Install async memcpy driver, with AXI-GDMA as the backend
|
||||
*
|
||||
@@ -95,9 +95,9 @@ esp_err_t esp_async_memcpy_install_gdma_ahb(const async_memcpy_config_t *config,
|
||||
* - ESP_FAIL: Install async memcpy driver failed because of other error
|
||||
*/
|
||||
esp_err_t esp_async_memcpy_install_gdma_axi(const async_memcpy_config_t *config, async_memcpy_handle_t *mcp);
|
||||
#endif // SOC_HAS(AXI_GDMA)
|
||||
#endif // SOC_AXI_GDMA_SUPPORTED
|
||||
|
||||
#if SOC_HAS(LP_AHB_GDMA)
|
||||
#if SOC_LP_AHB_GDMA_SUPPORTED
|
||||
/**
|
||||
* @brief Install async memcpy driver, with LP AHB-GDMA as the backend
|
||||
*
|
||||
@@ -110,7 +110,7 @@ esp_err_t esp_async_memcpy_install_gdma_axi(const async_memcpy_config_t *config,
|
||||
* - ESP_FAIL: Install async memcpy driver failed because of other error
|
||||
*/
|
||||
esp_err_t esp_async_memcpy_install_gdma_lp_ahb(const async_memcpy_config_t *config, async_memcpy_handle_t *mcp);
|
||||
#endif // SOC_HAS(LP_AHB_GDMA)
|
||||
#endif // SOC_LP_AHB_GDMA_SUPPORTED
|
||||
|
||||
#if SOC_CP_DMA_SUPPORTED
|
||||
/**
|
||||
@@ -129,6 +129,22 @@ esp_err_t esp_async_memcpy_install_gdma_lp_ahb(const async_memcpy_config_t *conf
|
||||
esp_err_t esp_async_memcpy_install_cpdma(const async_memcpy_config_t *config, async_memcpy_handle_t *mcp);
|
||||
#endif // SOC_CP_DMA_SUPPORTED
|
||||
|
||||
#if SOC_DW_GDMA_SUPPORTED
|
||||
/**
|
||||
* @brief Install async memcpy driver, with DW_GDMA as the backend
|
||||
*
|
||||
* @param[in] config Configuration of async memcpy
|
||||
* @param[out] mcp Returned driver handle
|
||||
* @return
|
||||
* - ESP_OK: Install async memcpy driver successfully
|
||||
* - ESP_ERR_INVALID_ARG: Install async memcpy driver failed because of invalid argument
|
||||
* - ESP_ERR_NO_MEM: Install async memcpy driver failed because out of memory
|
||||
* - ESP_FAIL: Install async memcpy driver failed because of other error
|
||||
*/
|
||||
esp_err_t esp_async_memcpy_install_dw_gdma(const async_memcpy_config_t *config, async_memcpy_handle_t *mcp);
|
||||
#endif // SOC_DW_GDMA_SUPPORTED
|
||||
|
||||
/** @cond */
|
||||
/**
|
||||
* @brief Install async memcpy driver with the default DMA backend
|
||||
*
|
||||
@@ -143,12 +159,14 @@ esp_err_t esp_async_memcpy_install_cpdma(const async_memcpy_config_t *config, as
|
||||
* - ESP_ERR_NO_MEM: Install async memcpy driver failed because out of memory
|
||||
* - ESP_FAIL: Install async memcpy driver failed because of other error
|
||||
*/
|
||||
esp_err_t esp_async_memcpy_install(const async_memcpy_config_t *config, async_memcpy_handle_t *mcp);
|
||||
esp_err_t esp_async_memcpy_install(const async_memcpy_config_t *config, async_memcpy_handle_t *mcp)
|
||||
__attribute__((deprecated("Select a DMA backend explicitly with esp_async_memcpy_install_* instead")));
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* @brief Uninstall async memcpy driver
|
||||
*
|
||||
* @param[in] mcp Handle of async memcpy driver that returned from `esp_async_memcpy_install`
|
||||
* @param[in] mcp Handle of async memcpy driver returned by an install function
|
||||
* @return
|
||||
* - ESP_OK: Uninstall async memcpy driver successfully
|
||||
* - ESP_ERR_INVALID_ARG: Uninstall async memcpy driver failed because of invalid argument
|
||||
@@ -161,7 +179,7 @@ esp_err_t esp_async_memcpy_uninstall(async_memcpy_handle_t mcp);
|
||||
*
|
||||
* @note The callback function is invoked in interrupt context, never do blocking jobs in the callback.
|
||||
*
|
||||
* @param[in] mcp Handle of async memcpy driver that returned from `esp_async_memcpy_install`
|
||||
* @param[in] mcp Handle of async memcpy driver returned by an install function
|
||||
* @param[in] dst Destination address (copy to)
|
||||
* @param[in] src Source address (copy from)
|
||||
* @param[in] n Number of bytes to copy
|
||||
@@ -180,7 +198,7 @@ esp_err_t esp_async_memcpy(async_memcpy_handle_t mcp, void *dst, void *src, size
|
||||
* @note This function is blocking and should not be called from interrupt context.
|
||||
* @note Only `timeout_ms=-1` is supported, which means waiting indefinitely.
|
||||
*
|
||||
* @param[in] mcp Handle of async memcpy driver that returned from `esp_async_memcpy_install`
|
||||
* @param[in] mcp Handle of async memcpy driver returned by an install function
|
||||
* @param[in] dst Destination address (copy to)
|
||||
* @param[in] src Source address (copy from)
|
||||
* @param[in] n Number of bytes to copy
|
||||
@@ -206,7 +224,7 @@ typedef enum {
|
||||
*
|
||||
* @note The created ETM event object can be deleted later by calling `esp_etm_del_event`
|
||||
*
|
||||
* @param[in] mcp Handle of async memcpy driver that returned from `esp_async_memcpy_install`
|
||||
* @param[in] mcp Handle of async memcpy driver returned by an install function
|
||||
* @param[in] event_type ETM event type
|
||||
* @param[out] out_event Returned ETM event handle
|
||||
* @return
|
||||
|
||||
@@ -100,11 +100,46 @@ esp_err_t dw_gdma_channel_get_id(dw_gdma_channel_handle_t chan, int *channel_id)
|
||||
* @note By dynamic, we mean these channel end configurations can be changed in each transfer.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t addr; /*!< Memory address */
|
||||
dw_gdma_transfer_width_t width; /*!< Transfer width */
|
||||
dw_gdma_burst_mode_t burst_mode; /*!< Burst mode */
|
||||
dw_gdma_burst_items_t burst_items; /*!< Number of data items that are contained in one burst transaction */
|
||||
uint8_t burst_len; /*!< Burst transaction length, if set to 0, the hardware will apply a possible value as burst length */
|
||||
uint32_t addr; /*!< Memory address */
|
||||
/**
|
||||
* @brief Transfer width, i.e. the bit width of a single data item (a "beat").
|
||||
*
|
||||
* This is the atomic unit of transfer. It decides how many bytes are moved per data item,
|
||||
* and therefore the granularity of both `burst_size` / `axi_burst_len` and the address step when
|
||||
* `addr_inc_mode` is INCREMENT. E.g. with `DW_GDMA_TRANS_WIDTH_32`, one item is 4 bytes.
|
||||
*/
|
||||
dw_gdma_transfer_width_t width;
|
||||
/**
|
||||
* @brief Address increment mode: whether the transfer address advances after each data item.
|
||||
*
|
||||
* @note It controls the address behaviour item by item:
|
||||
* - `DW_GDMA_ADDR_INC_MODE_INCREMENT`: address is increased by `width` after each item
|
||||
* (normal reading/writing of a contiguous buffer).
|
||||
* - `DW_GDMA_ADDR_INC_MODE_FIXED` : address stays the same after each item
|
||||
* (used when the target is a FIFO / peripheral register, e.g. DSI/CSI/ISP).
|
||||
*/
|
||||
dw_gdma_addr_inc_mode_t addr_inc_mode;
|
||||
/**
|
||||
* @brief Burst size: number of data items contained in one (core-level) burst transaction.
|
||||
*
|
||||
* This is the "burst size" (the DW_GDMA `MSIZE` field): how many `width`-sized items the DMA
|
||||
* engine requests in a single burst. It sets the granularity of the transfer and is typically a
|
||||
* power of two (1, 4, 8, ...). The total bytes of one such burst is `burst_size * width`.
|
||||
*
|
||||
* @note To tell it apart from `axi_burst_len`: `burst_size` is the coarse, power-of-two size of
|
||||
* a burst as configured by the DMA core, while `axi_burst_len` is the fine-grained AXI
|
||||
* burst length. For most cases keep them consistent (e.g. both 4/8/16), but you may set
|
||||
* `axi_burst_len` to a value that is not a power of two and let `burst_size` stay coarse.
|
||||
*/
|
||||
dw_gdma_burst_size_t burst_size;
|
||||
/**
|
||||
* @brief AXI burst transaction length, in number of data items (beats).
|
||||
*
|
||||
* This directly programs the AXI `arlen`/`awlen` fields, i.e. how many beats the AXI master
|
||||
* puts into a single AXI burst. The total bytes transferred in one burst is `axi_burst_len * width`.
|
||||
* If set to 0, the hardware chooses a possible value for the burst length.
|
||||
*/
|
||||
uint8_t axi_burst_len;
|
||||
struct {
|
||||
uint32_t en_status_write_back: 1; /*!< Enable peripheral status write back */
|
||||
} flags;
|
||||
@@ -116,7 +151,13 @@ typedef struct {
|
||||
typedef struct {
|
||||
dw_gdma_channel_dynamic_config_t src; /*!< source configuration */
|
||||
dw_gdma_channel_dynamic_config_t dst; /*!< destination configuration */
|
||||
size_t size; /*!< Transfer size */
|
||||
/**
|
||||
* @brief Transfer size, in number of data items
|
||||
*
|
||||
* The size in bytes is `size * width` (each data item is `width` bytes). For a
|
||||
* Link-List transfer, this is the block transfer size of the corresponding LLI.
|
||||
*/
|
||||
size_t size;
|
||||
} dw_gdma_block_transfer_config_t;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user