1 /*
2  * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 
11 #include <stdint.h>
12 #include <stdbool.h>
13 #include "esp_err.h"
14 #include "esp_intr_alloc.h"
15 #include "esp_etm.h"
16 #include "soc/soc_caps.h"
17 #include "hal/dma_types.h"
18 #include "freertos/FreeRTOS.h"
19 #include "esp_async_memcpy.h"
20 
21 #if SOC_CP_DMA_SUPPORTED
22 #include "hal/cp_dma_ll.h"
23 #include "hal/cp_dma_hal.h"
24 #elif SOC_GDMA_SUPPORTED
25 #include "esp_private/gdma.h"
26 #endif
27 
28 
29 /**
30  * @brief Type of async mcp implementation layer context
31  *
32  */
33 typedef struct {
34 #if SOC_CP_DMA_SUPPORTED
35     cp_dma_hal_context_t hal; // CP DMA hal
36     intr_handle_t intr; // CP DMA interrupt handle
37     portMUX_TYPE hal_lock; // CP DMA HAL level spin lock
38 #elif SOC_GDMA_SUPPORTED
39     gdma_channel_handle_t tx_channel;
40     gdma_channel_handle_t rx_channel;
41 #endif
42     intptr_t rx_eof_addr;
43     size_t sram_trans_align;
44     size_t psram_trans_align;
45     bool isr_need_yield;      // if current isr needs a yield for higher priority task
46 } async_memcpy_impl_t;
47 
48 /**
49  * @brief ISR callback function, invoked when RX done event triggered
50  *
51  * @param impl async mcp implementation layer context pointer
52  */
53 void async_memcpy_isr_on_rx_done_event(async_memcpy_impl_t *impl);
54 
55 /**
56  * @brief Initialize async mcp implementation layer
57  *
58  * @param impl async mcp implementation layer context pointer
59  * @return Always return ESP_OK
60  */
61 esp_err_t async_memcpy_impl_init(async_memcpy_impl_t *impl);
62 
63 /**
64  * @brief Deinitialize async mcp implementation layer
65  *
66  * @param impl async mcp implementation layer context pointer
67  * @return Always return ESP_OK
68  */
69 esp_err_t async_memcpy_impl_deinit(async_memcpy_impl_t *impl);
70 
71 /**
72  * @brief Start async mcp (on implementation layer)
73  *
74  * @param impl async mcp implementation layer context pointer
75  * @param outlink_base base descriptor address for TX DMA channel
76  * @param inlink_base base descriptor address for RX DMA channel
77  * @return Always return ESP_OK
78  */
79 esp_err_t async_memcpy_impl_start(async_memcpy_impl_t *impl, intptr_t outlink_base, intptr_t inlink_base);
80 
81 /**
82  * @brief Stop async mcp (on implementation layer)
83  *
84  * @param impl async mcp implementation layer context pointer
85  * @return Always return ESP_OK
86  */
87 esp_err_t async_memcpy_impl_stop(async_memcpy_impl_t *impl);
88 
89 /**
90  * @brief Restart async mcp DMA engine
91  *
92  * @param impl async mcp implementation layer context pointer
93  * @return Always return ESP_OK
94  */
95 esp_err_t async_memcpy_impl_restart(async_memcpy_impl_t *impl);
96 
97 /**
98  * @brief Get ETM Event handle
99  *
100  * @param impl async mcp implementation layer context pointer
101  * @param event_type ETM event type
102  * @param out_event Returned ETM event handle
103  * @return ESP_OK on success, ESP_ERR_NOT_SUPPORTED if not supported in hardware, otherwise failed
104  */
105 esp_err_t async_memcpy_impl_new_etm_event(async_memcpy_impl_t *impl, async_memcpy_etm_event_t event_type, esp_etm_event_handle_t *out_event);
106 
107 /**
108  * @brief check if buffer address is valid
109  * @note This is related to underlying target (e.g. on esp32-s2, only buffer located in SRAM is supported)
110  *
111  * @param impl async mcp implementation layer context pointer
112  * @param src Source buffer address
113  * @param dst Destination buffer address
114  * @return True if both address are valid
115  */
116 bool async_memcpy_impl_is_buffer_address_valid(async_memcpy_impl_t *impl, void *src, void *dst);
117 
118 #ifdef __cplusplus
119 }
120 #endif
121