瀏覽代碼

esp32s2: add CP_DMA driver

morris 5 年之前
父節點
當前提交
b30bd7a2ef

+ 1 - 0
components/esp32s2/CMakeLists.txt

@@ -14,6 +14,7 @@ else()
     set(srcs "cache_err_int.c"
              "memprot.c"
              "clk.c"
+             "cp_dma.c"
              "crosscore_int.c"
              "dport_access.c"
              "hw_random.c"

+ 235 - 0
components/esp32s2/cp_dma.c

@@ -0,0 +1,235 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include <sys/cdefs.h>
+#include <stdatomic.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/semphr.h"
+#include "esp_compiler.h"
+#include "esp_intr_alloc.h"
+#include "esp_heap_caps.h"
+#include "esp_log.h"
+#include "soc/soc_caps.h"
+#include "soc/cp_dma_caps.h"
+#include "hal/cp_dma_hal.h"
+#include "hal/cp_dma_ll.h"
+#include "cp_dma.h"
+#include "soc/periph_defs.h"
+
+static const char *TAG = "cp_dma";
+
+#define CP_DMA_CHECK(a, msg, tag, ret, ...)                                       \
+    do {                                                                          \
+        if (unlikely(!(a))) {                                                     \
+            ESP_LOGE(TAG, "%s(%d): " msg, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+            ret_code = ret;                                                       \
+            goto tag;                                                             \
+        }                                                                         \
+    } while (0)
+
+/**
+ * @brief Stream is high level abstraction over descriptor.
+ *        It combines the descriptor used by DMA and the callback function registered by user.
+ *        The benifit is, we can converter the descriptor address into stream handle.
+ */
+typedef struct {
+    cp_dma_descriptor_t tx_desc;
+    cp_dma_isr_cb_t cb;
+    void *cb_args;
+} cp_dma_out_stream_t;
+
+typedef struct {
+    cp_dma_descriptor_t rx_desc;
+    cp_dma_isr_cb_t cb;
+    void *cb_args;
+} cp_dma_in_stream_t;
+
+typedef struct cp_dma_driver_context_s {
+    uint32_t max_out_stream;
+    uint32_t max_in_stream;
+    uint32_t flags;
+    cp_dma_hal_context_t hal; // HAL context
+    intr_handle_t intr_hdl; // interrupt handle
+    portMUX_TYPE spin_lock;
+    cp_dma_out_stream_t *out_streams; // pointer to the first out stream
+    cp_dma_in_stream_t *in_streams; // pointer to the first in stream
+    uint8_t streams[0]; // stream buffer (out streams + in streams), the size if configured by user
+} cp_dma_driver_context_t;
+
+static void cp_dma_isr_default_handler(void *arg) IRAM_ATTR;
+
+esp_err_t cp_dma_driver_install(const cp_dma_config_t *config, cp_dma_driver_t *drv_hdl)
+{
+    esp_err_t ret_code = ESP_OK;
+    cp_dma_driver_context_t *cp_dma_driver = NULL;
+
+    CP_DMA_CHECK(config, "configuration can't be null", err, ESP_ERR_INVALID_ARG);
+    CP_DMA_CHECK(drv_hdl, "driver handle can't be null", err, ESP_ERR_INVALID_ARG);
+
+    size_t total_malloc_size = sizeof(cp_dma_driver_context_t) + sizeof(cp_dma_out_stream_t) * config->max_out_stream + sizeof(cp_dma_in_stream_t) * config->max_in_stream;
+    if (config->flags & CP_DMA_FLAGS_WORK_WITH_CACHE_DISABLED) {
+        // to work when cache is disabled, make sure to put driver handle in DRAM
+        cp_dma_driver = heap_caps_calloc(1, total_malloc_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
+    } else {
+        cp_dma_driver = calloc(1, total_malloc_size);
+    }
+    CP_DMA_CHECK(cp_dma_driver, "allocate driver memory failed", err, ESP_ERR_NO_MEM);
+
+    int int_flags = 0;
+    if (config->flags & CP_DMA_FLAGS_WORK_WITH_CACHE_DISABLED) {
+        int_flags |= ESP_INTR_FLAG_IRAM; // make sure interrupt can still work when cache is disabled
+    }
+    ret_code = esp_intr_alloc(ETS_DMA_COPY_INTR_SOURCE, int_flags, cp_dma_isr_default_handler, cp_dma_driver, &cp_dma_driver->intr_hdl);
+    CP_DMA_CHECK(ret_code == ESP_OK, "allocate intr failed", err, ret_code);
+
+    cp_dma_driver->out_streams = (cp_dma_out_stream_t *)cp_dma_driver->streams;
+    cp_dma_driver->in_streams = (cp_dma_in_stream_t *)(cp_dma_driver->streams + config->max_out_stream * sizeof(cp_dma_out_stream_t));
+    // HAL layer has no idea about "data stream" but TX/RX descriptors
+    // We put all descritprs' addresses into an array, HAL driver will make it a loop during initialization
+    {
+        cp_dma_descriptor_t *tx_descriptors[config->max_out_stream];
+        cp_dma_descriptor_t *rx_descriptors[config->max_in_stream];
+        for (int i = 0; i < config->max_out_stream; i++) {
+            tx_descriptors[i] = &cp_dma_driver->out_streams[i].tx_desc;
+        }
+        for (int i = 0; i < config->max_in_stream; i++) {
+            rx_descriptors[i] = &cp_dma_driver->in_streams[i].rx_desc;
+        }
+        cp_dma_hal_init(&cp_dma_driver->hal, tx_descriptors, config->max_out_stream, rx_descriptors, config->max_in_stream);
+    } // limit the scope of tx_descriptors and rx_descriptors so that goto can jump after this code block
+
+    cp_dma_driver->spin_lock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
+    cp_dma_driver->max_in_stream = config->max_in_stream;
+    cp_dma_driver->max_out_stream = config->max_out_stream;
+    *drv_hdl = cp_dma_driver;
+
+    cp_dma_hal_start(&cp_dma_driver->hal); // enable DMA and interrupt
+
+    return ESP_OK;
+err:
+    if (cp_dma_driver) {
+        if (cp_dma_driver->intr_hdl) {
+            esp_intr_free(cp_dma_driver->intr_hdl);
+        }
+        free(cp_dma_driver);
+    }
+    if (drv_hdl) {
+        *drv_hdl = NULL;
+    }
+    return ret_code;
+}
+
+esp_err_t cp_dma_driver_uninstall(cp_dma_driver_t drv_hdl)
+{
+    esp_err_t ret_code = ESP_OK;
+    CP_DMA_CHECK(drv_hdl, "driver handle can't be null", err, ESP_ERR_INVALID_ARG);
+
+    esp_intr_free(drv_hdl->intr_hdl);
+    cp_dma_hal_stop(&drv_hdl->hal);
+    cp_dma_hal_deinit(&drv_hdl->hal);
+    free(drv_hdl);
+    return ESP_OK;
+err:
+    return ret_code;
+}
+
+esp_err_t cp_dma_memcpy(cp_dma_driver_t drv_hdl, void *dst, void *src, size_t n, cp_dma_isr_cb_t cb_isr, void *cb_args)
+{
+    esp_err_t ret_code = ESP_OK;
+    cp_dma_descriptor_t *rx_start_desc = NULL;
+    cp_dma_descriptor_t *rx_end_desc = NULL;
+    cp_dma_descriptor_t *tx_start_desc = NULL;
+    cp_dma_descriptor_t *tx_end_desc = NULL;
+    int rx_prepared_size = 0;
+    int tx_prepared_size = 0;
+    CP_DMA_CHECK(drv_hdl, "driver handle can't be null", err, ESP_ERR_INVALID_ARG);
+    // CP_DMA can only access SRAM
+    CP_DMA_CHECK(esp_ptr_internal(src) && esp_ptr_internal(dst), "address not in SRAM", err, ESP_ERR_INVALID_ARG);
+    CP_DMA_CHECK(n <= SOC_CP_DMA_MAX_BUFFER_SIZE * drv_hdl->max_out_stream, "exceed max num of tx stream", err, ESP_ERR_INVALID_ARG);
+    CP_DMA_CHECK(n <= SOC_CP_DMA_MAX_BUFFER_SIZE * drv_hdl->max_in_stream, "exceed max num of rx stream", err, ESP_ERR_INVALID_ARG);
+    if (cb_isr && (drv_hdl->flags & CP_DMA_FLAGS_WORK_WITH_CACHE_DISABLED)) {
+        CP_DMA_CHECK(esp_ptr_in_iram(cb_isr), "callback(%p) not in IRAM", err, ESP_ERR_INVALID_ARG, cb_isr);
+    }
+
+    // Prepare TX and RX descriptor
+    portENTER_CRITICAL_SAFE(&drv_hdl->spin_lock);
+    // prepare functions will not change internal status of HAL until cp_dma_hal_restart_* are called
+    rx_prepared_size = cp_dma_hal_prepare_receive(&drv_hdl->hal, dst, n, &rx_start_desc, &rx_end_desc);
+    tx_prepared_size = cp_dma_hal_prepare_transmit(&drv_hdl->hal, src, n, &tx_start_desc, &tx_end_desc);
+    if ((rx_prepared_size == n) && (tx_prepared_size == n)) {
+        // register user callback to the end-of-frame descriptor (must before we restart RX)
+        cp_dma_in_stream_t *data_stream_rx = __containerof(rx_end_desc, cp_dma_in_stream_t, rx_desc);
+        data_stream_rx->cb = cb_isr;
+        data_stream_rx->cb_args = cb_args;
+        // The restart should be called with the exact returned start and end desc from previous successful prepare calls
+        cp_dma_hal_restart_rx(&drv_hdl->hal, rx_start_desc, rx_end_desc);
+        cp_dma_hal_restart_tx(&drv_hdl->hal, tx_start_desc, tx_end_desc);
+    }
+    portEXIT_CRITICAL_SAFE(&drv_hdl->spin_lock);
+
+    CP_DMA_CHECK(rx_prepared_size == n, "out of rx descriptor", err, ESP_FAIL);
+    // It's unlikely that we have space for rx descriptor but no space for tx descriptor
+    // Because in CP_DMA, both tx and rx descriptor should move in the same pace
+    CP_DMA_CHECK(tx_prepared_size == n, "out of tx descriptor", err, ESP_FAIL);
+
+    return ESP_OK;
+err:
+    return ret_code;
+}
+
+/**
+ * @brief Default ISR handler provided by ESP-IDF
+ */
+static void cp_dma_isr_default_handler(void *args)
+{
+    cp_dma_driver_context_t *cp_dma_driver = (cp_dma_driver_context_t *)args;
+    cp_dma_in_stream_t *in_stream = NULL;
+    cp_dma_descriptor_t *next_desc = NULL;
+    bool need_yield = false;
+    bool to_continue = false;
+
+    portENTER_CRITICAL_ISR(&cp_dma_driver->spin_lock);
+    uint32_t status = cp_dma_hal_get_intr_status(&cp_dma_driver->hal);
+    cp_dma_hal_clear_intr_status(&cp_dma_driver->hal, status);
+    portEXIT_CRITICAL_ISR(&cp_dma_driver->spin_lock);
+    ESP_EARLY_LOGD(TAG, "intr status=0x%x", status);
+
+    // End-Of-Frame on RX side
+    if (status & CP_DMA_LL_EVENT_RX_EOF) {
+        cp_dma_descriptor_t *eof = (cp_dma_descriptor_t *)cp_dma_ll_get_rx_eof_descriptor_address(cp_dma_driver->hal.dev);
+        // traversal all unchecked descriptors
+        do {
+            portENTER_CRITICAL_ISR(&cp_dma_driver->spin_lock);
+            // There is an assumption that the usage of rx descriptors are in the same pace as tx descriptors (this is determined by CP DMA working mechanism)
+            // And once the rx descriptor is recycled, the corresponding tx desc is guaranteed to be returned by DMA
+            to_continue = cp_dma_hal_get_next_rx_descriptor(&cp_dma_driver->hal, eof, &next_desc);
+            portEXIT_CRITICAL_ISR(&cp_dma_driver->spin_lock);
+            if (next_desc) {
+                in_stream = __containerof(next_desc, cp_dma_in_stream_t, rx_desc);
+                // invoke user registered callback if available
+                if (in_stream->cb) {
+                    cp_dma_event_t e = {.id = CP_DMA_EVENT_M2M_DONE};
+                    if (in_stream->cb(cp_dma_driver, &e, in_stream->cb_args)) {
+                        need_yield = true;
+                    }
+                    in_stream->cb = NULL;
+                    in_stream->cb_args = NULL;
+                }
+            }
+        } while (to_continue);
+    }
+
+    if (need_yield) {
+        portYIELD_FROM_ISR();
+    }
+}

+ 126 - 0
components/esp32s2/include/cp_dma.h

@@ -0,0 +1,126 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include "esp_err.h"
+
+/**
+ * @brief Handle of CP_DMA driver
+ *
+ */
+typedef struct cp_dma_driver_context_s *cp_dma_driver_t;
+
+/**
+ * @brief CP_DMA event ID
+ *
+ */
+typedef enum {
+    CP_DMA_EVENT_M2M_DONE, /*!< One or more memory copy transactions are done */
+} cp_dma_event_id_t;
+
+/**
+ * @brief Type defined for CP_DMA event object (including event ID, event data)
+ *
+ */
+typedef struct {
+    cp_dma_event_id_t id; /*!< Event ID */
+    void *data;           /*!< Event data */
+} cp_dma_event_t;
+
+/**
+ * @brief Type defined for cp_dma ISR callback function
+ *
+ * @param drv_hdl Handle of CP_DMA driver
+ * @param event Event object, which contains the event ID, event data, and so on
+ * @param cb_args User defined arguments for the callback function. It's passed in cp_dma_memcpy function
+ * @return Whether a high priority task is woken up by the callback function
+ *
+ */
+typedef bool (*cp_dma_isr_cb_t)(cp_dma_driver_t drv_hdl, cp_dma_event_t *event, void *cb_args);
+
+/**
+ * @brief Type defined for configuration of CP_DMA driver
+ *
+ */
+typedef struct {
+    uint32_t max_out_stream; /*!< maximum number of out link streams that can work simultaneously */
+    uint32_t max_in_stream;  /*!< maximum number of in link streams that can work simultaneously */
+    uint32_t flags;          /*!< Extra flags to control some special behaviour of CP_DMA, OR'ed of CP_DMA_FLAGS_xxx macros */
+} cp_dma_config_t;
+
+#define CP_DMA_FLAGS_WORK_WITH_CACHE_DISABLED (1 << 0) /*!< CP_DMA can work even when cache is diabled */
+
+/**
+ * @brief Default configuration for CP_DMA driver
+ *
+ */
+#define CP_DMA_DEFAULT_CONFIG() \
+    {                           \
+        .max_out_stream = 8,    \
+        .max_in_stream = 8,     \
+        .flags = 0,             \
+    }
+
+/**
+ * @brief Install CP_DMA driver
+ *
+ * @param[in] config Configuration of CP_DMA driver
+ * @param[out] drv_hdl Returned handle of CP_DMA driver or NULL if driver installation failed
+ * @return
+ *      - ESP_OK: Install CP_DMA driver successfully
+ *      - ESP_ERR_INVALID_ARG: Install CP_DMA driver failed because of some invalid argument
+ *      - ESP_ERR_NO_MEM: Install CP_DMA driver failed because there's no enough capable memory
+ *      - ESP_FAIL: Install CP_DMA driver failed because of other error
+ */
+esp_err_t cp_dma_driver_install(const cp_dma_config_t *config, cp_dma_driver_t *drv_hdl);
+
+/**
+ * @brief Uninstall CP_DMA driver
+ *
+ * @param[in] drv_hdl Handle of CP_DMA driver that returned from cp_dma_driver_install
+ * @return
+ *      - ESP_OK: Uninstall CP_DMA driver successfully
+ *      - ESP_ERR_INVALID_ARG: Uninstall CP_DMA driver failed because of some invalid argument
+ *      - ESP_FAIL: Uninstall CP_DMA driver failed because of other error
+ */
+esp_err_t cp_dma_driver_uninstall(cp_dma_driver_t drv_hdl);
+
+/**
+ * @brief Send an asynchronous memory copy request
+ *
+ * @param[in] drv_hdl Handle of CP_DMA driver that returned from cp_dma_driver_install
+ * @param[in] dst Destination address (copy to)
+ * @param[in] src Source address (copy from)
+ * @param[in] n Number of bytes to copy
+ * @param[in] cb_isr Callback function, which got invoked in ISR context. A NULL pointer here can bypass the callback.
+ * @param[in] cb_args User defined argument to be passed to the callback function
+ * @return
+ *      - ESP_OK: Send memcopy request successfully
+ *      - ESP_ERR_INVALID_ARG: Send memcopy request failed because of some invalid argument
+ *      - ESP_FAIL: Send memcopy request failed because of other error
+ *
+ * @note The callback function is invoked in ISR context, please never handle heavy load in the callback.
+ *       The default ISR handler is placed in IRAM, please place callback function in IRAM as well by applying IRAM_ATTR to it.
+ */
+esp_err_t cp_dma_memcpy(cp_dma_driver_t drv_hdl, void *dst, void *src, size_t n, cp_dma_isr_cb_t cb_isr, void *cb_args);
+
+#ifdef __cplusplus
+}
+#endif

+ 1 - 1
components/esp32s2/ld/esp32s2.peripherals.ld

@@ -17,7 +17,7 @@ PROVIDE ( RMTMEM = 0x3f416400 );
 PROVIDE ( PCNT = 0x3f417000 );
 PROVIDE ( SLC = 0x3f418000 );
 PROVIDE ( LEDC = 0x3f419000 );
-PROVIDE ( MCP = 0x3f4c3000 );
+PROVIDE ( CP_DMA = 0x3f4c3000 );
 PROVIDE ( TIMERG0 = 0x3f41F000 );
 PROVIDE ( TIMERG1 = 0x3f420000 );
 PROVIDE ( GPSPI2 = 0x3f424000 );

+ 184 - 0
components/esp32s2/test/test_cp_dma.c

@@ -0,0 +1,184 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include "esp_heap_caps.h"
+#include "esp_rom_sys.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/semphr.h"
+#include "unity.h"
+#include "test_utils.h"
+#include "ccomp_timer.h"
+#include "soc/cp_dma_caps.h"
+#include "cp_dma.h"
+
+#define ALIGN_UP(addr, align) (((addr) + (align)-1) & ~((align)-1))
+
+static void cp_dma_setup_testbench(uint32_t seed, uint32_t *buffer_size, uint8_t **src_buf, uint8_t **dst_buf, uint8_t **from_addr, uint8_t **to_addr, uint32_t align)
+{
+    srand(seed);
+    printf("allocating memory buffer...\r\n");
+    // memory copy from/to PSRAM is not allowed
+    *src_buf = heap_caps_malloc(*buffer_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
+    *dst_buf = heap_caps_calloc(1, *buffer_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
+
+    TEST_ASSERT_NOT_NULL_MESSAGE(*src_buf, "allocate source buffer failed");
+    TEST_ASSERT_NOT_NULL_MESSAGE(*dst_buf, "allocate destination buffer failed");
+
+    *from_addr = (uint8_t *)ALIGN_UP((uint32_t)(*src_buf), 4);
+    *to_addr = (uint8_t *)ALIGN_UP((uint32_t)(*dst_buf), 4);
+    uint8_t gap = MAX(*from_addr - *src_buf, *to_addr - *dst_buf);
+    *buffer_size -= gap;
+
+    *from_addr += align;
+    *to_addr += align;
+    *buffer_size -= align;
+
+    printf("...size %d Bytes, src@%p, dst@%p\r\n", *buffer_size, *from_addr, *to_addr);
+
+    printf("fill src buffer with random data\r\n");
+    for (int i = 0; i < *buffer_size; i++) {
+        (*from_addr)[i] = rand() % 256;
+    }
+}
+
+static void cp_dma_verify_and_clear_testbench(uint32_t seed, uint32_t buffer_size, uint8_t *src_buf, uint8_t *dst_buf, uint8_t *from_addr, uint8_t *to_addr)
+{
+    srand(seed);
+    for (int i = 0; i < buffer_size; i++) {
+        // check if source date has been copied to destination and source data not broken
+        TEST_ASSERT_EQUAL_MESSAGE(rand() % 256, to_addr[i], "destination data doesn't match generator data");
+    }
+    srand(seed);
+    for (int i = 0; i < buffer_size; i++) {
+        // check if source data has been copied to destination
+        TEST_ASSERT_EQUAL_MESSAGE(rand() % 256, to_addr[i], "destination data doesn't match source data");
+    }
+    free(src_buf);
+    free(dst_buf);
+}
+
+TEST_CASE("memory copy by DMA one by one", "[CP_DMA]")
+{
+    cp_dma_config_t config = CP_DMA_DEFAULT_CONFIG();
+    config.max_in_stream = 4;
+    config.max_out_stream = 4;
+    cp_dma_driver_t driver = NULL;
+    TEST_ESP_OK(cp_dma_driver_install(&config, &driver));
+
+    uint32_t test_buffer_len[] = {256, 512, 1024, 2048, 4096, 5011};
+    uint8_t *sbuf = NULL;
+    uint8_t *dbuf = NULL;
+    uint8_t *from = NULL;
+    uint8_t *to = NULL;
+
+    for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
+        // Test different align edge
+        for (int align = 0; align < 4; align++) {
+            cp_dma_setup_testbench(i, &test_buffer_len[i], &sbuf, &dbuf, &from, &to, align);
+            TEST_ESP_OK(cp_dma_memcpy(driver, to, from, test_buffer_len[i], NULL, NULL));
+            cp_dma_verify_and_clear_testbench(i, test_buffer_len[i], sbuf, dbuf, from, to);
+
+            vTaskDelay(pdMS_TO_TICKS(100));
+        }
+    }
+
+    TEST_ESP_OK(cp_dma_driver_uninstall(driver));
+}
+
+TEST_CASE("memory copy by DMA on the fly", "[CP_DMA]")
+{
+    cp_dma_config_t config = CP_DMA_DEFAULT_CONFIG();
+    config.max_in_stream = 4;
+    config.max_out_stream = 4;
+    cp_dma_driver_t driver = NULL;
+    TEST_ESP_OK(cp_dma_driver_install(&config, &driver));
+
+    uint32_t test_buffer_len[] = {512, 1024, 2048, 4096, 5011};
+    uint8_t *sbufs[] = {0, 0, 0, 0, 0};
+    uint8_t *dbufs[] = {0, 0, 0, 0, 0};
+    uint8_t *froms[] = {0, 0, 0, 0, 0};
+    uint8_t *tos[] = {0, 0, 0, 0, 0};
+
+    // Aligned case
+    for (int i = 0; i < sizeof(sbufs) / sizeof(sbufs[0]); i++) {
+        cp_dma_setup_testbench(i, &test_buffer_len[i], &sbufs[i], &dbufs[i], &froms[i], &tos[i], 0);
+    }
+    for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
+        TEST_ESP_OK(cp_dma_memcpy(driver, tos[i], froms[i], test_buffer_len[i], NULL, NULL));
+    }
+    for (int i = 0; i < sizeof(sbufs) / sizeof(sbufs[0]); i++) {
+        cp_dma_verify_and_clear_testbench(i, test_buffer_len[i], sbufs[i], dbufs[i], froms[i], tos[i]);
+    }
+
+    // Non-aligned case
+    for (int i = 0; i < sizeof(sbufs) / sizeof(sbufs[0]); i++) {
+        cp_dma_setup_testbench(i, &test_buffer_len[i], &sbufs[i], &dbufs[i], &froms[i], &tos[i], 3);
+    }
+    for (int i = 0; i < sizeof(test_buffer_len) / sizeof(test_buffer_len[0]); i++) {
+        TEST_ESP_OK(cp_dma_memcpy(driver, tos[i], froms[i], test_buffer_len[i], NULL, NULL));
+    }
+    for (int i = 0; i < sizeof(sbufs) / sizeof(sbufs[0]); i++) {
+        cp_dma_verify_and_clear_testbench(i, test_buffer_len[i], sbufs[i], dbufs[i], froms[i], tos[i]);
+    }
+
+    TEST_ESP_OK(cp_dma_driver_uninstall(driver));
+}
+
+#define TEST_CP_DMA_MECP_DMAY_BENCH_COUNTS (16)
+static uint32_t test_cp_dma_memcpy_bench_len = 4096;
+static int count = 0;
+
+static IRAM_ATTR bool test_cp_dma_memcpy_cb(cp_dma_driver_t drv_hdl, cp_dma_event_t *event, void *cb_args)
+{
+    SemaphoreHandle_t sem = (SemaphoreHandle_t)cb_args;
+    BaseType_t high_task_wakeup = pdFALSE;
+    switch (event->id) {
+    case CP_DMA_EVENT_M2M_DONE:
+        count++;
+        if (count == TEST_CP_DMA_MECP_DMAY_BENCH_COUNTS) {
+            xSemaphoreGiveFromISR(sem, &high_task_wakeup);
+        }
+        break;
+    default:
+        break;
+    }
+    return high_task_wakeup == pdTRUE;
+}
+
+TEST_CASE("memory copy by DMA with callback", "[CP_DMA][performance]")
+{
+    SemaphoreHandle_t sem = xSemaphoreCreateBinary();
+
+    cp_dma_config_t config = CP_DMA_DEFAULT_CONFIG();
+    cp_dma_driver_t driver = NULL;
+    TEST_ESP_OK(cp_dma_driver_install(&config, &driver));
+
+    uint8_t *sbuf = NULL;
+    uint8_t *dbuf = NULL;
+    uint8_t *from = NULL;
+    uint8_t *to = NULL;
+
+    cp_dma_setup_testbench(0, &test_cp_dma_memcpy_bench_len, &sbuf, &dbuf, &from, &to, 0);
+    count = 0;
+    ccomp_timer_start();
+    for (int i = 0; i < TEST_CP_DMA_MECP_DMAY_BENCH_COUNTS; i++) {
+        TEST_ESP_OK(cp_dma_memcpy(driver, to, from, test_cp_dma_memcpy_bench_len, test_cp_dma_memcpy_cb, sem));
+    }
+
+    // wait for done semaphore
+    TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreTake(sem, pdMS_TO_TICKS(1000)));
+    esp_rom_printf("memcpy %d Bytes data by HW costs %lldus\r\n", test_cp_dma_memcpy_bench_len, ccomp_timer_stop() / TEST_CP_DMA_MECP_DMAY_BENCH_COUNTS);
+
+    ccomp_timer_start();
+    for (int i = 0; i < TEST_CP_DMA_MECP_DMAY_BENCH_COUNTS; i++) {
+        memcpy(to, from, test_cp_dma_memcpy_bench_len);
+    }
+    esp_rom_printf("memcpy %d Bytes data by SW costs %lldus\r\n", test_cp_dma_memcpy_bench_len, ccomp_timer_stop() / TEST_CP_DMA_MECP_DMAY_BENCH_COUNTS);
+
+    cp_dma_verify_and_clear_testbench(0, test_cp_dma_memcpy_bench_len, sbuf, dbuf, from, to);
+
+    TEST_ESP_OK(cp_dma_driver_uninstall(driver));
+    vSemaphoreDelete(sem);
+}

+ 25 - 0
components/soc/soc/esp32s2/include/soc/cp_dma_caps.h

@@ -0,0 +1,25 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SOC_CP_DMA_MAX_BUFFER_SIZE (4095) /*!< Maximum size of the buffer that can be attached to descriptor */
+
+#ifdef __cplusplus
+}
+#endif

+ 698 - 0
components/soc/soc/esp32s2/include/soc/cp_dma_reg.h

@@ -0,0 +1,698 @@
+/** Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+#pragma once
+
+#include <stdint.h>
+#include "soc/soc.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** CP_DMA_INT_RAW_REG register
+ *  Raw interrupt status
+ */
+#define CP_DMA_INT_RAW_REG (DR_REG_CP_BASE + 0x0)
+/** CP_DMA_IN_DONE_INT_RAW : RO; bitpos: [0]; default: 0;
+ *  This is the interrupt raw bit. Triggered when the last data of frame is received or
+ *  the receive buffer is full indicated by inlink descriptor.
+ */
+#define CP_DMA_IN_DONE_INT_RAW    (BIT(0))
+#define CP_DMA_IN_DONE_INT_RAW_M  (CP_DMA_IN_DONE_INT_RAW_V << CP_DMA_IN_DONE_INT_RAW_S)
+#define CP_DMA_IN_DONE_INT_RAW_V  0x00000001
+#define CP_DMA_IN_DONE_INT_RAW_S  0
+/** CP_DMA_IN_SUC_EOF_INT_RAW : RO; bitpos: [1]; default: 0;
+ *  This is the interrupt raw bit. Triggered when the last data of one frame is
+ *  received.
+ */
+#define CP_DMA_IN_SUC_EOF_INT_RAW    (BIT(1))
+#define CP_DMA_IN_SUC_EOF_INT_RAW_M  (CP_DMA_IN_SUC_EOF_INT_RAW_V << CP_DMA_IN_SUC_EOF_INT_RAW_S)
+#define CP_DMA_IN_SUC_EOF_INT_RAW_V  0x00000001
+#define CP_DMA_IN_SUC_EOF_INT_RAW_S  1
+/** CP_DMA_OUT_DONE_INT_RAW : RO; bitpos: [2]; default: 0;
+ *  This is the interrupt raw bit. Triggered when all data indicated by one outlink
+ *  descriptor has been pushed into Tx FIFO.
+ */
+#define CP_DMA_OUT_DONE_INT_RAW    (BIT(2))
+#define CP_DMA_OUT_DONE_INT_RAW_M  (CP_DMA_OUT_DONE_INT_RAW_V << CP_DMA_OUT_DONE_INT_RAW_S)
+#define CP_DMA_OUT_DONE_INT_RAW_V  0x00000001
+#define CP_DMA_OUT_DONE_INT_RAW_S  2
+/** CP_DMA_OUT_EOF_INT_RAW : RO; bitpos: [3]; default: 0;
+ *  This is the interrupt raw bit. Triggered when the last data with EOF flag has been
+ *  pushed into Tx FIFO.
+ */
+#define CP_DMA_OUT_EOF_INT_RAW    (BIT(3))
+#define CP_DMA_OUT_EOF_INT_RAW_M  (CP_DMA_OUT_EOF_INT_RAW_V << CP_DMA_OUT_EOF_INT_RAW_S)
+#define CP_DMA_OUT_EOF_INT_RAW_V  0x00000001
+#define CP_DMA_OUT_EOF_INT_RAW_S  3
+/** CP_DMA_IN_DSCR_ERR_INT_RAW : RO; bitpos: [4]; default: 0;
+ *  This is the interrupt raw bit. Triggered when detecting inlink descriptor error,
+ *  including owner error, the second and third word error of inlink descriptor.
+ */
+#define CP_DMA_IN_DSCR_ERR_INT_RAW    (BIT(4))
+#define CP_DMA_IN_DSCR_ERR_INT_RAW_M  (CP_DMA_IN_DSCR_ERR_INT_RAW_V << CP_DMA_IN_DSCR_ERR_INT_RAW_S)
+#define CP_DMA_IN_DSCR_ERR_INT_RAW_V  0x00000001
+#define CP_DMA_IN_DSCR_ERR_INT_RAW_S  4
+/** CP_DMA_OUT_DSCR_ERR_INT_RAW : RO; bitpos: [5]; default: 0;
+ *  This is the interrupt raw bit. Triggered when detecting outlink descriptor error,
+ *  including owner error, the second and third word error of outlink descriptor.
+ */
+#define CP_DMA_OUT_DSCR_ERR_INT_RAW    (BIT(5))
+#define CP_DMA_OUT_DSCR_ERR_INT_RAW_M  (CP_DMA_OUT_DSCR_ERR_INT_RAW_V << CP_DMA_OUT_DSCR_ERR_INT_RAW_S)
+#define CP_DMA_OUT_DSCR_ERR_INT_RAW_V  0x00000001
+#define CP_DMA_OUT_DSCR_ERR_INT_RAW_S  5
+/** CP_DMA_IN_DSCR_EMPTY_INT_RAW : RO; bitpos: [6]; default: 0;
+ *  This is the interrupt raw bit. Triggered when receiving data is completed and no
+ *  more inlink descriptor.
+ */
+#define CP_DMA_IN_DSCR_EMPTY_INT_RAW    (BIT(6))
+#define CP_DMA_IN_DSCR_EMPTY_INT_RAW_M  (CP_DMA_IN_DSCR_EMPTY_INT_RAW_V << CP_DMA_IN_DSCR_EMPTY_INT_RAW_S)
+#define CP_DMA_IN_DSCR_EMPTY_INT_RAW_V  0x00000001
+#define CP_DMA_IN_DSCR_EMPTY_INT_RAW_S  6
+/** CP_DMA_OUT_TOTAL_EOF_INT_RAW : RO; bitpos: [7]; default: 0;
+ *  This is the interrupt raw bit. Triggered when data corresponding to all outlink
+ *  descriptor and the last descriptor with valid EOF is transmitted out.
+ */
+#define CP_DMA_OUT_TOTAL_EOF_INT_RAW    (BIT(7))
+#define CP_DMA_OUT_TOTAL_EOF_INT_RAW_M  (CP_DMA_OUT_TOTAL_EOF_INT_RAW_V << CP_DMA_OUT_TOTAL_EOF_INT_RAW_S)
+#define CP_DMA_OUT_TOTAL_EOF_INT_RAW_V  0x00000001
+#define CP_DMA_OUT_TOTAL_EOF_INT_RAW_S  7
+/** CP_DMA_CRC_DONE_INT_RAW : RO; bitpos: [8]; default: 0;
+ *  This is the interrupt raw bit. Triggered when crc calculation is done.
+ */
+#define CP_DMA_CRC_DONE_INT_RAW    (BIT(8))
+#define CP_DMA_CRC_DONE_INT_RAW_M  (CP_DMA_CRC_DONE_INT_RAW_V << CP_DMA_CRC_DONE_INT_RAW_S)
+#define CP_DMA_CRC_DONE_INT_RAW_V  0x00000001
+#define CP_DMA_CRC_DONE_INT_RAW_S  8
+
+/** CP_DMA_INT_ST_REG register
+ *  Masked interrupt status
+ */
+#define CP_DMA_INT_ST_REG (DR_REG_CP_BASE + 0x4)
+/** CP_DMA_IN_DONE_INT_ST : RO; bitpos: [0]; default: 0;
+ *  This is the masked interrupt bit for cp_in_done_int interrupt when
+ *  cp_in_done_int_ena is set to 1.
+ */
+#define CP_DMA_IN_DONE_INT_ST    (BIT(0))
+#define CP_DMA_IN_DONE_INT_ST_M  (CP_DMA_IN_DONE_INT_ST_V << CP_DMA_IN_DONE_INT_ST_S)
+#define CP_DMA_IN_DONE_INT_ST_V  0x00000001
+#define CP_DMA_IN_DONE_INT_ST_S  0
+/** CP_DMA_IN_SUC_EOF_INT_ST : RO; bitpos: [1]; default: 0;
+ *  This is the masked interrupt bit for cp_in_suc_eof_int interrupt when
+ *  cp_in_suc_eof_int_ena is set to 1.
+ */
+#define CP_DMA_IN_SUC_EOF_INT_ST    (BIT(1))
+#define CP_DMA_IN_SUC_EOF_INT_ST_M  (CP_DMA_IN_SUC_EOF_INT_ST_V << CP_DMA_IN_SUC_EOF_INT_ST_S)
+#define CP_DMA_IN_SUC_EOF_INT_ST_V  0x00000001
+#define CP_DMA_IN_SUC_EOF_INT_ST_S  1
+/** CP_DMA_OUT_DONE_INT_ST : RO; bitpos: [2]; default: 0;
+ *  This is the masked interrupt bit for cp_out_done_int interrupt when
+ *  cp_out_done_int_ena is set to 1.
+ */
+#define CP_DMA_OUT_DONE_INT_ST    (BIT(2))
+#define CP_DMA_OUT_DONE_INT_ST_M  (CP_DMA_OUT_DONE_INT_ST_V << CP_DMA_OUT_DONE_INT_ST_S)
+#define CP_DMA_OUT_DONE_INT_ST_V  0x00000001
+#define CP_DMA_OUT_DONE_INT_ST_S  2
+/** CP_DMA_OUT_EOF_INT_ST : RO; bitpos: [3]; default: 0;
+ *  This is the masked interrupt bit for cp_out_eof_int interrupt when
+ *  cp_out_eof_int_ena is set to 1.
+ */
+#define CP_DMA_OUT_EOF_INT_ST    (BIT(3))
+#define CP_DMA_OUT_EOF_INT_ST_M  (CP_DMA_OUT_EOF_INT_ST_V << CP_DMA_OUT_EOF_INT_ST_S)
+#define CP_DMA_OUT_EOF_INT_ST_V  0x00000001
+#define CP_DMA_OUT_EOF_INT_ST_S  3
+/** CP_DMA_IN_DSCR_ERR_INT_ST : RO; bitpos: [4]; default: 0;
+ *  This is the masked interrupt bit for cp_in_dscr_err_int interrupt when
+ *  cp_in_dscr_err_int_ena is set to 1.
+ */
+#define CP_DMA_IN_DSCR_ERR_INT_ST    (BIT(4))
+#define CP_DMA_IN_DSCR_ERR_INT_ST_M  (CP_DMA_IN_DSCR_ERR_INT_ST_V << CP_DMA_IN_DSCR_ERR_INT_ST_S)
+#define CP_DMA_IN_DSCR_ERR_INT_ST_V  0x00000001
+#define CP_DMA_IN_DSCR_ERR_INT_ST_S  4
+/** CP_DMA_OUT_DSCR_ERR_INT_ST : RO; bitpos: [5]; default: 0;
+ *  This is the masked interrupt bit for cp_out_dscr_err_int interrupt when
+ *  cp_out_dscr_err_int_ena is set to 1.
+ */
+#define CP_DMA_OUT_DSCR_ERR_INT_ST    (BIT(5))
+#define CP_DMA_OUT_DSCR_ERR_INT_ST_M  (CP_DMA_OUT_DSCR_ERR_INT_ST_V << CP_DMA_OUT_DSCR_ERR_INT_ST_S)
+#define CP_DMA_OUT_DSCR_ERR_INT_ST_V  0x00000001
+#define CP_DMA_OUT_DSCR_ERR_INT_ST_S  5
+/** CP_DMA_IN_DSCR_EMPTY_INT_ST : RO; bitpos: [6]; default: 0;
+ *  This is the masked interrupt bit for cp_in_dscr_empty_int interrupt when
+ *  cp_in_dscr_empty_int_ena is set to 1.
+ */
+#define CP_DMA_IN_DSCR_EMPTY_INT_ST    (BIT(6))
+#define CP_DMA_IN_DSCR_EMPTY_INT_ST_M  (CP_DMA_IN_DSCR_EMPTY_INT_ST_V << CP_DMA_IN_DSCR_EMPTY_INT_ST_S)
+#define CP_DMA_IN_DSCR_EMPTY_INT_ST_V  0x00000001
+#define CP_DMA_IN_DSCR_EMPTY_INT_ST_S  6
+/** CP_DMA_OUT_TOTAL_EOF_INT_ST : RO; bitpos: [7]; default: 0;
+ *  This is the masked interrupt bit for cp_out_total_eof_int interrupt when
+ *  cp_out_total_eof_int_ena is set to 1.
+ */
+#define CP_DMA_OUT_TOTAL_EOF_INT_ST    (BIT(7))
+#define CP_DMA_OUT_TOTAL_EOF_INT_ST_M  (CP_DMA_OUT_TOTAL_EOF_INT_ST_V << CP_DMA_OUT_TOTAL_EOF_INT_ST_S)
+#define CP_DMA_OUT_TOTAL_EOF_INT_ST_V  0x00000001
+#define CP_DMA_OUT_TOTAL_EOF_INT_ST_S  7
+/** CP_DMA_CRC_DONE_INT_ST : RO; bitpos: [8]; default: 0;
+ *  This is the masked interrupt bit for cp_crc_done_int interrupt when
+ *  cp_crc_done_int_ena is set to 1.
+ */
+#define CP_DMA_CRC_DONE_INT_ST    (BIT(8))
+#define CP_DMA_CRC_DONE_INT_ST_M  (CP_DMA_CRC_DONE_INT_ST_V << CP_DMA_CRC_DONE_INT_ST_S)
+#define CP_DMA_CRC_DONE_INT_ST_V  0x00000001
+#define CP_DMA_CRC_DONE_INT_ST_S  8
+
+/** CP_DMA_INT_ENA_REG register
+ *  Interrupt enable bits
+ */
+#define CP_DMA_INT_ENA_REG (DR_REG_CP_BASE + 0x8)
+/** CP_DMA_IN_DONE_INT_ENA : R/W; bitpos: [0]; default: 0;
+ *  This is the interrupt enable bit for cp_in_done_int interrupt.
+ */
+#define CP_DMA_IN_DONE_INT_ENA    (BIT(0))
+#define CP_DMA_IN_DONE_INT_ENA_M  (CP_DMA_IN_DONE_INT_ENA_V << CP_DMA_IN_DONE_INT_ENA_S)
+#define CP_DMA_IN_DONE_INT_ENA_V  0x00000001
+#define CP_DMA_IN_DONE_INT_ENA_S  0
+/** CP_DMA_IN_SUC_EOF_INT_ENA : R/W; bitpos: [1]; default: 0;
+ *  This is the interrupt enable bit for cp_in_suc_eof_int interrupt.
+ */
+#define CP_DMA_IN_SUC_EOF_INT_ENA    (BIT(1))
+#define CP_DMA_IN_SUC_EOF_INT_ENA_M  (CP_DMA_IN_SUC_EOF_INT_ENA_V << CP_DMA_IN_SUC_EOF_INT_ENA_S)
+#define CP_DMA_IN_SUC_EOF_INT_ENA_V  0x00000001
+#define CP_DMA_IN_SUC_EOF_INT_ENA_S  1
+/** CP_DMA_OUT_DONE_INT_ENA : R/W; bitpos: [2]; default: 0;
+ *  This is the interrupt enable bit for cp_out_done_int interrupt.
+ */
+#define CP_DMA_OUT_DONE_INT_ENA    (BIT(2))
+#define CP_DMA_OUT_DONE_INT_ENA_M  (CP_DMA_OUT_DONE_INT_ENA_V << CP_DMA_OUT_DONE_INT_ENA_S)
+#define CP_DMA_OUT_DONE_INT_ENA_V  0x00000001
+#define CP_DMA_OUT_DONE_INT_ENA_S  2
+/** CP_DMA_OUT_EOF_INT_ENA : R/W; bitpos: [3]; default: 0;
+ *  This is the interrupt enable bit for cp_out_eof_int interrupt.
+ */
+#define CP_DMA_OUT_EOF_INT_ENA    (BIT(3))
+#define CP_DMA_OUT_EOF_INT_ENA_M  (CP_DMA_OUT_EOF_INT_ENA_V << CP_DMA_OUT_EOF_INT_ENA_S)
+#define CP_DMA_OUT_EOF_INT_ENA_V  0x00000001
+#define CP_DMA_OUT_EOF_INT_ENA_S  3
+/** CP_DMA_IN_DSCR_ERR_INT_ENA : R/W; bitpos: [4]; default: 0;
+ *  This is the interrupt enable bit for cp_in_dscr_err_int interrupt.
+ */
+#define CP_DMA_IN_DSCR_ERR_INT_ENA    (BIT(4))
+#define CP_DMA_IN_DSCR_ERR_INT_ENA_M  (CP_DMA_IN_DSCR_ERR_INT_ENA_V << CP_DMA_IN_DSCR_ERR_INT_ENA_S)
+#define CP_DMA_IN_DSCR_ERR_INT_ENA_V  0x00000001
+#define CP_DMA_IN_DSCR_ERR_INT_ENA_S  4
+/** CP_DMA_OUT_DSCR_ERR_INT_ENA : R/W; bitpos: [5]; default: 0;
+ *  This is the interrupt enable bit for cp_out_dscr_err_int interrupt.
+ */
+#define CP_DMA_OUT_DSCR_ERR_INT_ENA    (BIT(5))
+#define CP_DMA_OUT_DSCR_ERR_INT_ENA_M  (CP_DMA_OUT_DSCR_ERR_INT_ENA_V << CP_DMA_OUT_DSCR_ERR_INT_ENA_S)
+#define CP_DMA_OUT_DSCR_ERR_INT_ENA_V  0x00000001
+#define CP_DMA_OUT_DSCR_ERR_INT_ENA_S  5
+/** CP_DMA_IN_DSCR_EMPTY_INT_ENA : R/W; bitpos: [6]; default: 0;
+ *  This is the interrupt enable bit for cp_in_dscr_empty_int interrupt.
+ */
+#define CP_DMA_IN_DSCR_EMPTY_INT_ENA    (BIT(6))
+#define CP_DMA_IN_DSCR_EMPTY_INT_ENA_M  (CP_DMA_IN_DSCR_EMPTY_INT_ENA_V << CP_DMA_IN_DSCR_EMPTY_INT_ENA_S)
+#define CP_DMA_IN_DSCR_EMPTY_INT_ENA_V  0x00000001
+#define CP_DMA_IN_DSCR_EMPTY_INT_ENA_S  6
+/** CP_DMA_OUT_TOTAL_EOF_INT_ENA : R/W; bitpos: [7]; default: 0;
+ *  This is the interrupt enable bit for cp_out_total_eof_int interrupt.
+ */
+#define CP_DMA_OUT_TOTAL_EOF_INT_ENA    (BIT(7))
+#define CP_DMA_OUT_TOTAL_EOF_INT_ENA_M  (CP_DMA_OUT_TOTAL_EOF_INT_ENA_V << CP_DMA_OUT_TOTAL_EOF_INT_ENA_S)
+#define CP_DMA_OUT_TOTAL_EOF_INT_ENA_V  0x00000001
+#define CP_DMA_OUT_TOTAL_EOF_INT_ENA_S  7
+/** CP_DMA_CRC_DONE_INT_ENA : R/W; bitpos: [8]; default: 0;
+ *  This is the interrupt enable bit for cp_crc_done_int interrupt.
+ */
+#define CP_DMA_CRC_DONE_INT_ENA    (BIT(8))
+#define CP_DMA_CRC_DONE_INT_ENA_M  (CP_DMA_CRC_DONE_INT_ENA_V << CP_DMA_CRC_DONE_INT_ENA_S)
+#define CP_DMA_CRC_DONE_INT_ENA_V  0x00000001
+#define CP_DMA_CRC_DONE_INT_ENA_S  8
+
+/** CP_DMA_INT_CLR_REG register
+ *  Interrupt clear bits
+ */
+#define CP_DMA_INT_CLR_REG (DR_REG_CP_BASE + 0xc)
+/** CP_DMA_IN_DONE_INT_CLR : WO; bitpos: [0]; default: 0;
+ *  Set this bit to clear cp_in_done_int interrupt.
+ */
+#define CP_DMA_IN_DONE_INT_CLR    (BIT(0))
+#define CP_DMA_IN_DONE_INT_CLR_M  (CP_DMA_IN_DONE_INT_CLR_V << CP_DMA_IN_DONE_INT_CLR_S)
+#define CP_DMA_IN_DONE_INT_CLR_V  0x00000001
+#define CP_DMA_IN_DONE_INT_CLR_S  0
+/** CP_DMA_IN_SUC_EOF_INT_CLR : WO; bitpos: [1]; default: 0;
+ *  Set this bit to clear cp_in_suc_eof_int interrupt.
+ */
+#define CP_DMA_IN_SUC_EOF_INT_CLR    (BIT(1))
+#define CP_DMA_IN_SUC_EOF_INT_CLR_M  (CP_DMA_IN_SUC_EOF_INT_CLR_V << CP_DMA_IN_SUC_EOF_INT_CLR_S)
+#define CP_DMA_IN_SUC_EOF_INT_CLR_V  0x00000001
+#define CP_DMA_IN_SUC_EOF_INT_CLR_S  1
+/** CP_DMA_OUT_DONE_INT_CLR : WO; bitpos: [2]; default: 0;
+ *  Set this bit to clear cp_out_done_int interrupt.
+ */
+#define CP_DMA_OUT_DONE_INT_CLR    (BIT(2))
+#define CP_DMA_OUT_DONE_INT_CLR_M  (CP_DMA_OUT_DONE_INT_CLR_V << CP_DMA_OUT_DONE_INT_CLR_S)
+#define CP_DMA_OUT_DONE_INT_CLR_V  0x00000001
+#define CP_DMA_OUT_DONE_INT_CLR_S  2
+/** CP_DMA_OUT_EOF_INT_CLR : WO; bitpos: [3]; default: 0;
+ *  Set this bit to clear cp_out_eof_int interrupt.
+ */
+#define CP_DMA_OUT_EOF_INT_CLR    (BIT(3))
+#define CP_DMA_OUT_EOF_INT_CLR_M  (CP_DMA_OUT_EOF_INT_CLR_V << CP_DMA_OUT_EOF_INT_CLR_S)
+#define CP_DMA_OUT_EOF_INT_CLR_V  0x00000001
+#define CP_DMA_OUT_EOF_INT_CLR_S  3
+/** CP_DMA_IN_DSCR_ERR_INT_CLR : WO; bitpos: [4]; default: 0;
+ *  Set this bit to clear cp_in_dscr_err_int interrupt.
+ */
+#define CP_DMA_IN_DSCR_ERR_INT_CLR    (BIT(4))
+#define CP_DMA_IN_DSCR_ERR_INT_CLR_M  (CP_DMA_IN_DSCR_ERR_INT_CLR_V << CP_DMA_IN_DSCR_ERR_INT_CLR_S)
+#define CP_DMA_IN_DSCR_ERR_INT_CLR_V  0x00000001
+#define CP_DMA_IN_DSCR_ERR_INT_CLR_S  4
+/** CP_DMA_OUT_DSCR_ERR_INT_CLR : WO; bitpos: [5]; default: 0;
+ *  Set this bit to clear cp_out_dscr_err_int interrupt.
+ */
+#define CP_DMA_OUT_DSCR_ERR_INT_CLR    (BIT(5))
+#define CP_DMA_OUT_DSCR_ERR_INT_CLR_M  (CP_DMA_OUT_DSCR_ERR_INT_CLR_V << CP_DMA_OUT_DSCR_ERR_INT_CLR_S)
+#define CP_DMA_OUT_DSCR_ERR_INT_CLR_V  0x00000001
+#define CP_DMA_OUT_DSCR_ERR_INT_CLR_S  5
+/** CP_DMA_IN_DSCR_EMPTY_INT_CLR : WO; bitpos: [6]; default: 0;
+ *  Set this bit to clear cp_in_dscr_empty_int interrupt.
+ */
+#define CP_DMA_IN_DSCR_EMPTY_INT_CLR    (BIT(6))
+#define CP_DMA_IN_DSCR_EMPTY_INT_CLR_M  (CP_DMA_IN_DSCR_EMPTY_INT_CLR_V << CP_DMA_IN_DSCR_EMPTY_INT_CLR_S)
+#define CP_DMA_IN_DSCR_EMPTY_INT_CLR_V  0x00000001
+#define CP_DMA_IN_DSCR_EMPTY_INT_CLR_S  6
+/** CP_DMA_OUT_TOTAL_EOF_INT_CLR : WO; bitpos: [7]; default: 0;
+ *  Set this bit to clear cp_out_total_eof_int interrupt.
+ */
+#define CP_DMA_OUT_TOTAL_EOF_INT_CLR    (BIT(7))
+#define CP_DMA_OUT_TOTAL_EOF_INT_CLR_M  (CP_DMA_OUT_TOTAL_EOF_INT_CLR_V << CP_DMA_OUT_TOTAL_EOF_INT_CLR_S)
+#define CP_DMA_OUT_TOTAL_EOF_INT_CLR_V  0x00000001
+#define CP_DMA_OUT_TOTAL_EOF_INT_CLR_S  7
+/** CP_DMA_CRC_DONE_INT_CLR : WO; bitpos: [8]; default: 0;
+ *  Set this bit to clear cp_crc_done_int interrupt.
+ */
+#define CP_DMA_CRC_DONE_INT_CLR    (BIT(8))
+#define CP_DMA_CRC_DONE_INT_CLR_M  (CP_DMA_CRC_DONE_INT_CLR_V << CP_DMA_CRC_DONE_INT_CLR_S)
+#define CP_DMA_CRC_DONE_INT_CLR_V  0x00000001
+#define CP_DMA_CRC_DONE_INT_CLR_S  8
+
+/** CP_DMA_OUT_LINK_REG register
+ *  Link descriptor address and control
+ */
+#define CP_DMA_OUT_LINK_REG (DR_REG_CP_BASE + 0x10)
+/** CP_DMA_OUTLINK_ADDR : R/W; bitpos: [19:0]; default: 0;
+ *  This register is used to specify the least significant 20 bits of the first outlink
+ *  descriptor's address.
+ */
+#define CP_DMA_OUTLINK_ADDR    0x000FFFFF
+#define CP_DMA_OUTLINK_ADDR_M  (CP_DMA_OUTLINK_ADDR_V << CP_DMA_OUTLINK_ADDR_S)
+#define CP_DMA_OUTLINK_ADDR_V  0x000FFFFF
+#define CP_DMA_OUTLINK_ADDR_S  0
+/** CP_DMA_OUTLINK_STOP : R/W; bitpos: [28]; default: 0;
+ *  Set this bit to stop dealing with the outlink descriptor.
+ */
+#define CP_DMA_OUTLINK_STOP    (BIT(28))
+#define CP_DMA_OUTLINK_STOP_M  (CP_DMA_OUTLINK_STOP_V << CP_DMA_OUTLINK_STOP_S)
+#define CP_DMA_OUTLINK_STOP_V  0x00000001
+#define CP_DMA_OUTLINK_STOP_S  28
+/** CP_DMA_OUTLINK_START : R/W; bitpos: [29]; default: 0;
+ *  Set this bit to start a new outlink descriptor.
+ */
+#define CP_DMA_OUTLINK_START    (BIT(29))
+#define CP_DMA_OUTLINK_START_M  (CP_DMA_OUTLINK_START_V << CP_DMA_OUTLINK_START_S)
+#define CP_DMA_OUTLINK_START_V  0x00000001
+#define CP_DMA_OUTLINK_START_S  29
+/** CP_DMA_OUTLINK_RESTART : R/W; bitpos: [30]; default: 0;
+ *  Set this bit to restart the outlink descriptpr from the last address.
+ */
+#define CP_DMA_OUTLINK_RESTART    (BIT(30))
+#define CP_DMA_OUTLINK_RESTART_M  (CP_DMA_OUTLINK_RESTART_V << CP_DMA_OUTLINK_RESTART_S)
+#define CP_DMA_OUTLINK_RESTART_V  0x00000001
+#define CP_DMA_OUTLINK_RESTART_S  30
+/** CP_DMA_OUTLINK_PARK : RO; bitpos: [31]; default: 0;
+ *  1: the outlink descriptor's FSM is in idle state.
+ *  0: the outlink descriptor's FSM is working.
+ */
+#define CP_DMA_OUTLINK_PARK    (BIT(31))
+#define CP_DMA_OUTLINK_PARK_M  (CP_DMA_OUTLINK_PARK_V << CP_DMA_OUTLINK_PARK_S)
+#define CP_DMA_OUTLINK_PARK_V  0x00000001
+#define CP_DMA_OUTLINK_PARK_S  31
+
+/** CP_DMA_IN_LINK_REG register
+ *  Link descriptor address and control
+ */
+#define CP_DMA_IN_LINK_REG (DR_REG_CP_BASE + 0x14)
+/** CP_DMA_INLINK_ADDR : R/W; bitpos: [19:0]; default: 0;
+ *  This register is used to specify the least significant 20 bits of the first inlink
+ *  descriptor's address.
+ */
+#define CP_DMA_INLINK_ADDR    0x000FFFFF
+#define CP_DMA_INLINK_ADDR_M  (CP_DMA_INLINK_ADDR_V << CP_DMA_INLINK_ADDR_S)
+#define CP_DMA_INLINK_ADDR_V  0x000FFFFF
+#define CP_DMA_INLINK_ADDR_S  0
+/** CP_DMA_INLINK_STOP : R/W; bitpos: [28]; default: 0;
+ *  Set this bit to stop dealing with the inlink descriptors.
+ */
+#define CP_DMA_INLINK_STOP    (BIT(28))
+#define CP_DMA_INLINK_STOP_M  (CP_DMA_INLINK_STOP_V << CP_DMA_INLINK_STOP_S)
+#define CP_DMA_INLINK_STOP_V  0x00000001
+#define CP_DMA_INLINK_STOP_S  28
+/** CP_DMA_INLINK_START : R/W; bitpos: [29]; default: 0;
+ *  Set this bit to start dealing with the inlink descriptors.
+ */
+#define CP_DMA_INLINK_START    (BIT(29))
+#define CP_DMA_INLINK_START_M  (CP_DMA_INLINK_START_V << CP_DMA_INLINK_START_S)
+#define CP_DMA_INLINK_START_V  0x00000001
+#define CP_DMA_INLINK_START_S  29
+/** CP_DMA_INLINK_RESTART : R/W; bitpos: [30]; default: 0;
+ *  Set this bit to restart new inlink descriptors.
+ */
+#define CP_DMA_INLINK_RESTART    (BIT(30))
+#define CP_DMA_INLINK_RESTART_M  (CP_DMA_INLINK_RESTART_V << CP_DMA_INLINK_RESTART_S)
+#define CP_DMA_INLINK_RESTART_V  0x00000001
+#define CP_DMA_INLINK_RESTART_S  30
+/** CP_DMA_INLINK_PARK : RO; bitpos: [31]; default: 0;
+ *  1: the inlink descriptor's FSM is in idle state.
+ *  0: the inlink descriptor's FSM is working.
+ */
+#define CP_DMA_INLINK_PARK    (BIT(31))
+#define CP_DMA_INLINK_PARK_M  (CP_DMA_INLINK_PARK_V << CP_DMA_INLINK_PARK_S)
+#define CP_DMA_INLINK_PARK_V  0x00000001
+#define CP_DMA_INLINK_PARK_S  31
+
+/** CP_DMA_OUT_EOF_DES_ADDR_REG register
+ *  Outlink descriptor address when EOF occurs
+ */
+#define CP_DMA_OUT_EOF_DES_ADDR_REG (DR_REG_CP_BASE + 0x18)
+/** CP_DMA_OUT_EOF_DES_ADDR : RO; bitpos: [31:0]; default: 0;
+ *  This register stores the address of the outlink descriptor when the EOF bit in this
+ *  descriptor is 1.
+ */
+#define CP_DMA_OUT_EOF_DES_ADDR    0xFFFFFFFF
+#define CP_DMA_OUT_EOF_DES_ADDR_M  (CP_DMA_OUT_EOF_DES_ADDR_V << CP_DMA_OUT_EOF_DES_ADDR_S)
+#define CP_DMA_OUT_EOF_DES_ADDR_V  0xFFFFFFFF
+#define CP_DMA_OUT_EOF_DES_ADDR_S  0
+
+/** CP_DMA_IN_EOF_DES_ADDR_REG register
+ *  Inlink descriptor address when EOF occurs
+ */
+#define CP_DMA_IN_EOF_DES_ADDR_REG (DR_REG_CP_BASE + 0x1c)
+/** CP_DMA_IN_SUC_EOF_DES_ADDR : RO; bitpos: [31:0]; default: 0;
+ *  This register stores the address of the inlink descriptor when received successful
+ *  EOF.
+ */
+#define CP_DMA_IN_SUC_EOF_DES_ADDR    0xFFFFFFFF
+#define CP_DMA_IN_SUC_EOF_DES_ADDR_M  (CP_DMA_IN_SUC_EOF_DES_ADDR_V << CP_DMA_IN_SUC_EOF_DES_ADDR_S)
+#define CP_DMA_IN_SUC_EOF_DES_ADDR_V  0xFFFFFFFF
+#define CP_DMA_IN_SUC_EOF_DES_ADDR_S  0
+
+/** CP_DMA_OUT_EOF_BFR_DES_ADDR_REG register
+ *  Outlink descriptor address before the last outlink descriptor
+ */
+#define CP_DMA_OUT_EOF_BFR_DES_ADDR_REG (DR_REG_CP_BASE + 0x20)
+/** CP_DMA_OUT_EOF_BFR_DES_ADDR : RO; bitpos: [31:0]; default: 0;
+ *  This register stores the address of the outlink descriptor before the last outlink
+ *  descriptor.
+ */
+#define CP_DMA_OUT_EOF_BFR_DES_ADDR    0xFFFFFFFF
+#define CP_DMA_OUT_EOF_BFR_DES_ADDR_M  (CP_DMA_OUT_EOF_BFR_DES_ADDR_V << CP_DMA_OUT_EOF_BFR_DES_ADDR_S)
+#define CP_DMA_OUT_EOF_BFR_DES_ADDR_V  0xFFFFFFFF
+#define CP_DMA_OUT_EOF_BFR_DES_ADDR_S  0
+
+/** CP_DMA_INLINK_DSCR_REG register
+ *  Address of current inlink descriptor
+ */
+#define CP_DMA_INLINK_DSCR_REG (DR_REG_CP_BASE + 0x24)
+/** CP_DMA_INLINK_DSCR : RO; bitpos: [31:0]; default: 0;
+ *  The address of the current inlink descriptor x.
+ */
+#define CP_DMA_INLINK_DSCR    0xFFFFFFFF
+#define CP_DMA_INLINK_DSCR_M  (CP_DMA_INLINK_DSCR_V << CP_DMA_INLINK_DSCR_S)
+#define CP_DMA_INLINK_DSCR_V  0xFFFFFFFF
+#define CP_DMA_INLINK_DSCR_S  0
+
+/** CP_DMA_INLINK_DSCR_BF0_REG register
+ *  Address of last inlink descriptor
+ */
+#define CP_DMA_INLINK_DSCR_BF0_REG (DR_REG_CP_BASE + 0x28)
+/** CP_DMA_INLINK_DSCR_BF0 : RO; bitpos: [31:0]; default: 0;
+ *  The address of the last inlink descriptor x-1.
+ */
+#define CP_DMA_INLINK_DSCR_BF0    0xFFFFFFFF
+#define CP_DMA_INLINK_DSCR_BF0_M  (CP_DMA_INLINK_DSCR_BF0_V << CP_DMA_INLINK_DSCR_BF0_S)
+#define CP_DMA_INLINK_DSCR_BF0_V  0xFFFFFFFF
+#define CP_DMA_INLINK_DSCR_BF0_S  0
+
+/** CP_DMA_INLINK_DSCR_BF1_REG register
+ *  Address of the second-to-last inlink descriptor
+ */
+#define CP_DMA_INLINK_DSCR_BF1_REG (DR_REG_CP_BASE + 0x2c)
+/** CP_DMA_INLINK_DSCR_BF1 : RO; bitpos: [31:0]; default: 0;
+ *  The address of the second-to-last inlink descriptor x-2.
+ */
+#define CP_DMA_INLINK_DSCR_BF1    0xFFFFFFFF
+#define CP_DMA_INLINK_DSCR_BF1_M  (CP_DMA_INLINK_DSCR_BF1_V << CP_DMA_INLINK_DSCR_BF1_S)
+#define CP_DMA_INLINK_DSCR_BF1_V  0xFFFFFFFF
+#define CP_DMA_INLINK_DSCR_BF1_S  0
+
+/** CP_DMA_OUTLINK_DSCR_REG register
+ *  Address of current outlink descriptor
+ */
+#define CP_DMA_OUTLINK_DSCR_REG (DR_REG_CP_BASE + 0x30)
+/** CP_DMA_OUTLINK_DSCR : RO; bitpos: [31:0]; default: 0;
+ *  The address of the current outlink descriptor y.
+ */
+#define CP_DMA_OUTLINK_DSCR    0xFFFFFFFF
+#define CP_DMA_OUTLINK_DSCR_M  (CP_DMA_OUTLINK_DSCR_V << CP_DMA_OUTLINK_DSCR_S)
+#define CP_DMA_OUTLINK_DSCR_V  0xFFFFFFFF
+#define CP_DMA_OUTLINK_DSCR_S  0
+
+/** CP_DMA_OUTLINK_DSCR_BF0_REG register
+ *  Address of last outlink descriptor
+ */
+#define CP_DMA_OUTLINK_DSCR_BF0_REG (DR_REG_CP_BASE + 0x34)
+/** CP_DMA_OUTLINK_DSCR_BF0 : RO; bitpos: [31:0]; default: 0;
+ *  The address of the last outlink descriptor y-1.
+ */
+#define CP_DMA_OUTLINK_DSCR_BF0    0xFFFFFFFF
+#define CP_DMA_OUTLINK_DSCR_BF0_M  (CP_DMA_OUTLINK_DSCR_BF0_V << CP_DMA_OUTLINK_DSCR_BF0_S)
+#define CP_DMA_OUTLINK_DSCR_BF0_V  0xFFFFFFFF
+#define CP_DMA_OUTLINK_DSCR_BF0_S  0
+
+/** CP_DMA_OUTLINK_DSCR_BF1_REG register
+ *  Address of the second-to-last outlink descriptor
+ */
+#define CP_DMA_OUTLINK_DSCR_BF1_REG (DR_REG_CP_BASE + 0x38)
+/** CP_DMA_OUTLINK_DSCR_BF1 : RO; bitpos: [31:0]; default: 0;
+ *  The address of the second-to-last outlink descriptor y-2.
+ */
+#define CP_DMA_OUTLINK_DSCR_BF1    0xFFFFFFFF
+#define CP_DMA_OUTLINK_DSCR_BF1_M  (CP_DMA_OUTLINK_DSCR_BF1_V << CP_DMA_OUTLINK_DSCR_BF1_S)
+#define CP_DMA_OUTLINK_DSCR_BF1_V  0xFFFFFFFF
+#define CP_DMA_OUTLINK_DSCR_BF1_S  0
+
+/** CP_DMA_CONF_REG register
+ *  Copy DMA configuration register
+ */
+#define CP_DMA_CONF_REG (DR_REG_CP_BASE + 0x3c)
+/** CP_DMA_IN_RST : R/W; bitpos: [0]; default: 0;
+ *  Set this bit to reset in_inf state machine.
+ */
+#define CP_DMA_IN_RST    (BIT(0))
+#define CP_DMA_IN_RST_M  (CP_DMA_IN_RST_V << CP_DMA_IN_RST_S)
+#define CP_DMA_IN_RST_V  0x00000001
+#define CP_DMA_IN_RST_S  0
+/** CP_DMA_OUT_RST : R/W; bitpos: [1]; default: 0;
+ *  Set this bit to reset out_inf state machine.
+ */
+#define CP_DMA_OUT_RST    (BIT(1))
+#define CP_DMA_OUT_RST_M  (CP_DMA_OUT_RST_V << CP_DMA_OUT_RST_S)
+#define CP_DMA_OUT_RST_V  0x00000001
+#define CP_DMA_OUT_RST_S  1
+/** CP_DMA_CMDFIFO_RST : R/W; bitpos: [2]; default: 0;
+ *  Set this bit to reset in_cmd fifo and out_cmd fifo.
+ */
+#define CP_DMA_CMDFIFO_RST    (BIT(2))
+#define CP_DMA_CMDFIFO_RST_M  (CP_DMA_CMDFIFO_RST_V << CP_DMA_CMDFIFO_RST_S)
+#define CP_DMA_CMDFIFO_RST_V  0x00000001
+#define CP_DMA_CMDFIFO_RST_S  2
+/** CP_DMA_FIFO_RST : R/W; bitpos: [3]; default: 0;
+ *  Set this bit to reset data in receive FIFO.
+ */
+#define CP_DMA_FIFO_RST    (BIT(3))
+#define CP_DMA_FIFO_RST_M  (CP_DMA_FIFO_RST_V << CP_DMA_FIFO_RST_S)
+#define CP_DMA_FIFO_RST_V  0x00000001
+#define CP_DMA_FIFO_RST_S  3
+/** CP_DMA_OUT_OWNER : R/W; bitpos: [4]; default: 0;
+ *  This is used to configure the owner bit in OUT descriptor. This is effective only
+ *  when you set reg_out_auto_wrback.
+ */
+#define CP_DMA_OUT_OWNER    (BIT(4))
+#define CP_DMA_OUT_OWNER_M  (CP_DMA_OUT_OWNER_V << CP_DMA_OUT_OWNER_S)
+#define CP_DMA_OUT_OWNER_V  0x00000001
+#define CP_DMA_OUT_OWNER_S  4
+/** CP_DMA_IN_OWNER : R/W; bitpos: [5]; default: 0;
+ *  This is used to configure the owner bit in IN descriptor.
+ */
+#define CP_DMA_IN_OWNER    (BIT(5))
+#define CP_DMA_IN_OWNER_M  (CP_DMA_IN_OWNER_V << CP_DMA_IN_OWNER_S)
+#define CP_DMA_IN_OWNER_V  0x00000001
+#define CP_DMA_IN_OWNER_S  5
+/** CP_DMA_OUT_AUTO_WRBACK : R/W; bitpos: [6]; default: 0;
+ *  This bit is used to write back out descriptor when hardware has already used this
+ *  descriptor.
+ */
+#define CP_DMA_OUT_AUTO_WRBACK    (BIT(6))
+#define CP_DMA_OUT_AUTO_WRBACK_M  (CP_DMA_OUT_AUTO_WRBACK_V << CP_DMA_OUT_AUTO_WRBACK_S)
+#define CP_DMA_OUT_AUTO_WRBACK_V  0x00000001
+#define CP_DMA_OUT_AUTO_WRBACK_S  6
+/** CP_DMA_CHECK_OWNER : R/W; bitpos: [7]; default: 0;
+ *  Set this bit to enable owner bit check in descriptor.
+ */
+#define CP_DMA_CHECK_OWNER    (BIT(7))
+#define CP_DMA_CHECK_OWNER_M  (CP_DMA_CHECK_OWNER_V << CP_DMA_CHECK_OWNER_S)
+#define CP_DMA_CHECK_OWNER_V  0x00000001
+#define CP_DMA_CHECK_OWNER_S  7
+/** CP_DMA_CRC_CAL_RESET : R/W; bitpos: [8]; default: 0;
+ *  Set this bit to reset crc calculation.
+ */
+#define CP_DMA_CRC_CAL_RESET    (BIT(8))
+#define CP_DMA_CRC_CAL_RESET_M  (CP_DMA_CRC_CAL_RESET_V << CP_DMA_CRC_CAL_RESET_S)
+#define CP_DMA_CRC_CAL_RESET_V  0x00000001
+#define CP_DMA_CRC_CAL_RESET_S  8
+/** CP_DMA_CRC_CAL_EN : R/W; bitpos: [9]; default: 0;
+ *  Set this bit enable crc calculation function.
+ */
+#define CP_DMA_CRC_CAL_EN    (BIT(9))
+#define CP_DMA_CRC_CAL_EN_M  (CP_DMA_CRC_CAL_EN_V << CP_DMA_CRC_CAL_EN_S)
+#define CP_DMA_CRC_CAL_EN_V  0x00000001
+#define CP_DMA_CRC_CAL_EN_S  9
+/** CP_DMA_CRC_BIG_ENDIAN_EN : R/W; bitpos: [10]; default: 0;
+ *  Set this bit to reorder the bit of data which will be send to excute crc.
+ */
+#define CP_DMA_CRC_BIG_ENDIAN_EN    (BIT(10))
+#define CP_DMA_CRC_BIG_ENDIAN_EN_M  (CP_DMA_CRC_BIG_ENDIAN_EN_V << CP_DMA_CRC_BIG_ENDIAN_EN_S)
+#define CP_DMA_CRC_BIG_ENDIAN_EN_V  0x00000001
+#define CP_DMA_CRC_BIG_ENDIAN_EN_S  10
+/** CP_DMA_CRC_OUT_REVERSE_EN : R/W; bitpos: [11]; default: 0;
+ *  Set this bit to reverse the crc calculation result.
+ */
+#define CP_DMA_CRC_OUT_REVERSE_EN    (BIT(11))
+#define CP_DMA_CRC_OUT_REVERSE_EN_M  (CP_DMA_CRC_OUT_REVERSE_EN_V << CP_DMA_CRC_OUT_REVERSE_EN_S)
+#define CP_DMA_CRC_OUT_REVERSE_EN_V  0x00000001
+#define CP_DMA_CRC_OUT_REVERSE_EN_S  11
+/** CP_DMA_CLK_EN : R/W; bitpos: [31]; default: 0;
+ *  1'b1: Force clock on for register. 1'b0: Support clock only when application writes
+ *  registers.
+ */
+#define CP_DMA_CLK_EN    (BIT(31))
+#define CP_DMA_CLK_EN_M  (CP_DMA_CLK_EN_V << CP_DMA_CLK_EN_S)
+#define CP_DMA_CLK_EN_V  0x00000001
+#define CP_DMA_CLK_EN_S  31
+
+/** CP_DMA_IN_ST_REG register
+ *  Status register of receiving data
+ */
+#define CP_DMA_IN_ST_REG (DR_REG_CP_BASE + 0x40)
+/** CP_DMA_INLINK_DSCR_ADDR : RO; bitpos: [17:0]; default: 0;
+ *  This register stores the current inlink descriptor's address.
+ */
+#define CP_DMA_INLINK_DSCR_ADDR    0x0003FFFF
+#define CP_DMA_INLINK_DSCR_ADDR_M  (CP_DMA_INLINK_DSCR_ADDR_V << CP_DMA_INLINK_DSCR_ADDR_S)
+#define CP_DMA_INLINK_DSCR_ADDR_V  0x0003FFFF
+#define CP_DMA_INLINK_DSCR_ADDR_S  0
+/** CP_DMA_IN_DSCR_STATE : RO; bitpos: [19:18]; default: 0;
+ *  Reserved.
+ */
+#define CP_DMA_IN_DSCR_STATE    0x00000003
+#define CP_DMA_IN_DSCR_STATE_M  (CP_DMA_IN_DSCR_STATE_V << CP_DMA_IN_DSCR_STATE_S)
+#define CP_DMA_IN_DSCR_STATE_V  0x00000003
+#define CP_DMA_IN_DSCR_STATE_S  18
+/** CP_DMA_IN_STATE : RO; bitpos: [22:20]; default: 0;
+ *  Reserved.
+ */
+#define CP_DMA_IN_STATE    0x00000007
+#define CP_DMA_IN_STATE_M  (CP_DMA_IN_STATE_V << CP_DMA_IN_STATE_S)
+#define CP_DMA_IN_STATE_V  0x00000007
+#define CP_DMA_IN_STATE_S  20
+/** CP_DMA_FIFO_EMPTY : RO; bitpos: [23]; default: 0;
+ *  Copy DMA FIFO empty signal.
+ */
+#define CP_DMA_FIFO_EMPTY    (BIT(23))
+#define CP_DMA_FIFO_EMPTY_M  (CP_DMA_FIFO_EMPTY_V << CP_DMA_FIFO_EMPTY_S)
+#define CP_DMA_FIFO_EMPTY_V  0x00000001
+#define CP_DMA_FIFO_EMPTY_S  23
+
+/** CP_DMA_OUT_ST_REG register
+ *  Status register of trasmitting data
+ */
+#define CP_DMA_OUT_ST_REG (DR_REG_CP_BASE + 0x44)
+/** CP_DMA_OUTLINK_DSCR_ADDR : RO; bitpos: [17:0]; default: 0;
+ *  This register stores the current outlink descriptor's address.
+ */
+#define CP_DMA_OUTLINK_DSCR_ADDR    0x0003FFFF
+#define CP_DMA_OUTLINK_DSCR_ADDR_M  (CP_DMA_OUTLINK_DSCR_ADDR_V << CP_DMA_OUTLINK_DSCR_ADDR_S)
+#define CP_DMA_OUTLINK_DSCR_ADDR_V  0x0003FFFF
+#define CP_DMA_OUTLINK_DSCR_ADDR_S  0
+/** CP_DMA_OUT_DSCR_STATE : RO; bitpos: [19:18]; default: 0;
+ *  Reserved.
+ */
+#define CP_DMA_OUT_DSCR_STATE    0x00000003
+#define CP_DMA_OUT_DSCR_STATE_M  (CP_DMA_OUT_DSCR_STATE_V << CP_DMA_OUT_DSCR_STATE_S)
+#define CP_DMA_OUT_DSCR_STATE_V  0x00000003
+#define CP_DMA_OUT_DSCR_STATE_S  18
+/** CP_DMA_OUT_STATE : RO; bitpos: [22:20]; default: 0;
+ *  Reserved.
+ */
+#define CP_DMA_OUT_STATE    0x00000007
+#define CP_DMA_OUT_STATE_M  (CP_DMA_OUT_STATE_V << CP_DMA_OUT_STATE_S)
+#define CP_DMA_OUT_STATE_V  0x00000007
+#define CP_DMA_OUT_STATE_S  20
+/** CP_DMA_FIFO_FULL : RO; bitpos: [23]; default: 0;
+ *  Copy DMA FIFO full signal.
+ */
+#define CP_DMA_FIFO_FULL    (BIT(23))
+#define CP_DMA_FIFO_FULL_M  (CP_DMA_FIFO_FULL_V << CP_DMA_FIFO_FULL_S)
+#define CP_DMA_FIFO_FULL_V  0x00000001
+#define CP_DMA_FIFO_FULL_S  23
+
+/** CP_DMA_CRC_OUT_REG register
+ *  CRC result register
+ */
+#define CP_DMA_CRC_OUT_REG (DR_REG_CP_BASE + 0x48)
+/** CP_DMA_CRC_RESULT : RO; bitpos: [31:0]; default: 0;
+ *  This register stores the result of CRC.
+ */
+#define CP_DMA_CRC_RESULT    0xFFFFFFFF
+#define CP_DMA_CRC_RESULT_M  (CP_DMA_CRC_RESULT_V << CP_DMA_CRC_RESULT_S)
+#define CP_DMA_CRC_RESULT_V  0xFFFFFFFF
+#define CP_DMA_CRC_RESULT_S  0
+
+/** CP_DMA_DATE_REG register
+ *  Copy DMA version register
+ */
+#define CP_DMA_DATE_REG (DR_REG_CP_BASE + 0xfc)
+/** CP_DMA_DMA_DATE : R/W; bitpos: [31:0]; default: 403185664;
+ *  This is the version register.
+ */
+#define CP_DMA_DMA_DATE    0xFFFFFFFF
+#define CP_DMA_DMA_DATE_M  (CP_DMA_DMA_DATE_V << CP_DMA_DMA_DATE_S)
+#define CP_DMA_DMA_DATE_V  0xFFFFFFFF
+#define CP_DMA_DMA_DATE_S  0
+
+#ifdef __cplusplus
+}
+#endif

+ 623 - 0
components/soc/soc/esp32s2/include/soc/cp_dma_struct.h

@@ -0,0 +1,623 @@
+/** Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+#pragma once
+
+#include <stdint.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Interrupt Registers */
+/** Type of dma_int_raw register
+ *  Raw interrupt status
+ */
+typedef union {
+    struct {
+        /** dma_in_done_int_raw : RO; bitpos: [0]; default: 0;
+         *  This is the interrupt raw bit. Triggered when the last data of frame is received or
+         *  the receive buffer is full indicated by inlink descriptor.
+         */
+        uint32_t dma_in_done_int_raw: 1;
+        /** dma_in_suc_eof_int_raw : RO; bitpos: [1]; default: 0;
+         *  This is the interrupt raw bit. Triggered when the last data of one frame is
+         *  received.
+         */
+        uint32_t dma_in_suc_eof_int_raw: 1;
+        /** dma_out_done_int_raw : RO; bitpos: [2]; default: 0;
+         *  This is the interrupt raw bit. Triggered when all data indicated by one outlink
+         *  descriptor has been pushed into Tx FIFO.
+         */
+        uint32_t dma_out_done_int_raw: 1;
+        /** dma_out_eof_int_raw : RO; bitpos: [3]; default: 0;
+         *  This is the interrupt raw bit. Triggered when the last data with EOF flag has been
+         *  pushed into Tx FIFO.
+         */
+        uint32_t dma_out_eof_int_raw: 1;
+        /** dma_in_dscr_err_int_raw : RO; bitpos: [4]; default: 0;
+         *  This is the interrupt raw bit. Triggered when detecting inlink descriptor error,
+         *  including owner error, the second and third word error of inlink descriptor.
+         */
+        uint32_t dma_in_dscr_err_int_raw: 1;
+        /** dma_out_dscr_err_int_raw : RO; bitpos: [5]; default: 0;
+         *  This is the interrupt raw bit. Triggered when detecting outlink descriptor error,
+         *  including owner error, the second and third word error of outlink descriptor.
+         */
+        uint32_t dma_out_dscr_err_int_raw: 1;
+        /** dma_in_dscr_empty_int_raw : RO; bitpos: [6]; default: 0;
+         *  This is the interrupt raw bit. Triggered when receiving data is completed and no
+         *  more inlink descriptor.
+         */
+        uint32_t dma_in_dscr_empty_int_raw: 1;
+        /** dma_out_total_eof_int_raw : RO; bitpos: [7]; default: 0;
+         *  This is the interrupt raw bit. Triggered when data corresponding to all outlink
+         *  descriptor and the last descriptor with valid EOF is transmitted out.
+         */
+        uint32_t dma_out_total_eof_int_raw: 1;
+        /** dma_crc_done_int_raw : RO; bitpos: [8]; default: 0;
+         *  This is the interrupt raw bit. Triggered when crc calculation is done.
+         */
+        uint32_t dma_crc_done_int_raw: 1;
+    };
+    uint32_t val;
+} cp_dma_int_raw_reg_t;
+
+/** Type of dma_int_st register
+ *  Masked interrupt status
+ */
+typedef union {
+    struct {
+        /** dma_in_done_int_st : RO; bitpos: [0]; default: 0;
+         *  This is the masked interrupt bit for cp_in_done_int interrupt when
+         *  cp_in_done_int_ena is set to 1.
+         */
+        uint32_t dma_in_done_int_st: 1;
+        /** dma_in_suc_eof_int_st : RO; bitpos: [1]; default: 0;
+         *  This is the masked interrupt bit for cp_in_suc_eof_int interrupt when
+         *  cp_in_suc_eof_int_ena is set to 1.
+         */
+        uint32_t dma_in_suc_eof_int_st: 1;
+        /** dma_out_done_int_st : RO; bitpos: [2]; default: 0;
+         *  This is the masked interrupt bit for cp_out_done_int interrupt when
+         *  cp_out_done_int_ena is set to 1.
+         */
+        uint32_t dma_out_done_int_st: 1;
+        /** dma_out_eof_int_st : RO; bitpos: [3]; default: 0;
+         *  This is the masked interrupt bit for cp_out_eof_int interrupt when
+         *  cp_out_eof_int_ena is set to 1.
+         */
+        uint32_t dma_out_eof_int_st: 1;
+        /** dma_in_dscr_err_int_st : RO; bitpos: [4]; default: 0;
+         *  This is the masked interrupt bit for cp_in_dscr_err_int interrupt when
+         *  cp_in_dscr_err_int_ena is set to 1.
+         */
+        uint32_t dma_in_dscr_err_int_st: 1;
+        /** dma_out_dscr_err_int_st : RO; bitpos: [5]; default: 0;
+         *  This is the masked interrupt bit for cp_out_dscr_err_int interrupt when
+         *  cp_out_dscr_err_int_ena is set to 1.
+         */
+        uint32_t dma_out_dscr_err_int_st: 1;
+        /** dma_in_dscr_empty_int_st : RO; bitpos: [6]; default: 0;
+         *  This is the masked interrupt bit for cp_in_dscr_empty_int interrupt when
+         *  cp_in_dscr_empty_int_ena is set to 1.
+         */
+        uint32_t dma_in_dscr_empty_int_st: 1;
+        /** dma_out_total_eof_int_st : RO; bitpos: [7]; default: 0;
+         *  This is the masked interrupt bit for cp_out_total_eof_int interrupt when
+         *  cp_out_total_eof_int_ena is set to 1.
+         */
+        uint32_t dma_out_total_eof_int_st: 1;
+        /** dma_crc_done_int_st : RO; bitpos: [8]; default: 0;
+         *  This is the masked interrupt bit for cp_crc_done_int interrupt when
+         *  cp_crc_done_int_ena is set to 1.
+         */
+        uint32_t dma_crc_done_int_st: 1;
+    };
+    uint32_t val;
+} cp_dma_int_st_reg_t;
+
+/** Type of dma_int_ena register
+ *  Interrupt enable bits
+ */
+typedef union {
+    struct {
+        /** dma_in_done_int_ena : R/W; bitpos: [0]; default: 0;
+         *  This is the interrupt enable bit for cp_in_done_int interrupt.
+         */
+        uint32_t dma_in_done_int_ena: 1;
+        /** dma_in_suc_eof_int_ena : R/W; bitpos: [1]; default: 0;
+         *  This is the interrupt enable bit for cp_in_suc_eof_int interrupt.
+         */
+        uint32_t dma_in_suc_eof_int_ena: 1;
+        /** dma_out_done_int_ena : R/W; bitpos: [2]; default: 0;
+         *  This is the interrupt enable bit for cp_out_done_int interrupt.
+         */
+        uint32_t dma_out_done_int_ena: 1;
+        /** dma_out_eof_int_ena : R/W; bitpos: [3]; default: 0;
+         *  This is the interrupt enable bit for cp_out_eof_int interrupt.
+         */
+        uint32_t dma_out_eof_int_ena: 1;
+        /** dma_in_dscr_err_int_ena : R/W; bitpos: [4]; default: 0;
+         *  This is the interrupt enable bit for cp_in_dscr_err_int interrupt.
+         */
+        uint32_t dma_in_dscr_err_int_ena: 1;
+        /** dma_out_dscr_err_int_ena : R/W; bitpos: [5]; default: 0;
+         *  This is the interrupt enable bit for cp_out_dscr_err_int interrupt.
+         */
+        uint32_t dma_out_dscr_err_int_ena: 1;
+        /** dma_in_dscr_empty_int_ena : R/W; bitpos: [6]; default: 0;
+         *  This is the interrupt enable bit for cp_in_dscr_empty_int interrupt.
+         */
+        uint32_t dma_in_dscr_empty_int_ena: 1;
+        /** dma_out_total_eof_int_ena : R/W; bitpos: [7]; default: 0;
+         *  This is the interrupt enable bit for cp_out_total_eof_int interrupt.
+         */
+        uint32_t dma_out_total_eof_int_ena: 1;
+        /** dma_crc_done_int_ena : R/W; bitpos: [8]; default: 0;
+         *  This is the interrupt enable bit for cp_crc_done_int interrupt.
+         */
+        uint32_t dma_crc_done_int_ena: 1;
+    };
+    uint32_t val;
+} cp_dma_int_ena_reg_t;
+
+/** Type of dma_int_clr register
+ *  Interrupt clear bits
+ */
+typedef union {
+    struct {
+        /** dma_in_done_int_clr : WO; bitpos: [0]; default: 0;
+         *  Set this bit to clear cp_in_done_int interrupt.
+         */
+        uint32_t dma_in_done_int_clr: 1;
+        /** dma_in_suc_eof_int_clr : WO; bitpos: [1]; default: 0;
+         *  Set this bit to clear cp_in_suc_eof_int interrupt.
+         */
+        uint32_t dma_in_suc_eof_int_clr: 1;
+        /** dma_out_done_int_clr : WO; bitpos: [2]; default: 0;
+         *  Set this bit to clear cp_out_done_int interrupt.
+         */
+        uint32_t dma_out_done_int_clr: 1;
+        /** dma_out_eof_int_clr : WO; bitpos: [3]; default: 0;
+         *  Set this bit to clear cp_out_eof_int interrupt.
+         */
+        uint32_t dma_out_eof_int_clr: 1;
+        /** dma_in_dscr_err_int_clr : WO; bitpos: [4]; default: 0;
+         *  Set this bit to clear cp_in_dscr_err_int interrupt.
+         */
+        uint32_t dma_in_dscr_err_int_clr: 1;
+        /** dma_out_dscr_err_int_clr : WO; bitpos: [5]; default: 0;
+         *  Set this bit to clear cp_out_dscr_err_int interrupt.
+         */
+        uint32_t dma_out_dscr_err_int_clr: 1;
+        /** dma_in_dscr_empty_int_clr : WO; bitpos: [6]; default: 0;
+         *  Set this bit to clear cp_in_dscr_empty_int interrupt.
+         */
+        uint32_t dma_in_dscr_empty_int_clr: 1;
+        /** dma_out_total_eof_int_clr : WO; bitpos: [7]; default: 0;
+         *  Set this bit to clear cp_out_total_eof_int interrupt.
+         */
+        uint32_t dma_out_total_eof_int_clr: 1;
+        /** dma_crc_done_int_clr : WO; bitpos: [8]; default: 0;
+         *  Set this bit to clear cp_crc_done_int interrupt.
+         */
+        uint32_t dma_crc_done_int_clr: 1;
+    };
+    uint32_t val;
+} cp_dma_int_clr_reg_t;
+
+
+/** Configuration Registers */
+/** Type of dma_out_link register
+ *  Link descriptor address and control
+ */
+typedef union {
+    struct {
+        /** dma_outlink_addr : R/W; bitpos: [19:0]; default: 0;
+         *  This register is used to specify the least significant 20 bits of the first outlink
+         *  descriptor's address.
+         */
+        uint32_t dma_outlink_addr: 20;
+        uint32_t reserved_20: 8;
+        /** dma_outlink_stop : R/W; bitpos: [28]; default: 0;
+         *  Set this bit to stop dealing with the outlink descriptor.
+         */
+        uint32_t dma_outlink_stop: 1;
+        /** dma_outlink_start : R/W; bitpos: [29]; default: 0;
+         *  Set this bit to start a new outlink descriptor.
+         */
+        uint32_t dma_outlink_start: 1;
+        /** dma_outlink_restart : R/W; bitpos: [30]; default: 0;
+         *  Set this bit to restart the outlink descriptpr from the last address.
+         */
+        uint32_t dma_outlink_restart: 1;
+        /** dma_outlink_park : RO; bitpos: [31]; default: 0;
+         *  1: the outlink descriptor's FSM is in idle state.
+         *  0: the outlink descriptor's FSM is working.
+         */
+        uint32_t dma_outlink_park: 1;
+    };
+    uint32_t val;
+} cp_dma_out_link_reg_t;
+
+/** Type of dma_in_link register
+ *  Link descriptor address and control
+ */
+typedef union {
+    struct {
+        /** dma_inlink_addr : R/W; bitpos: [19:0]; default: 0;
+         *  This register is used to specify the least significant 20 bits of the first inlink
+         *  descriptor's address.
+         */
+        uint32_t dma_inlink_addr: 20;
+        uint32_t reserved_20: 8;
+        /** dma_inlink_stop : R/W; bitpos: [28]; default: 0;
+         *  Set this bit to stop dealing with the inlink descriptors.
+         */
+        uint32_t dma_inlink_stop: 1;
+        /** dma_inlink_start : R/W; bitpos: [29]; default: 0;
+         *  Set this bit to start dealing with the inlink descriptors.
+         */
+        uint32_t dma_inlink_start: 1;
+        /** dma_inlink_restart : R/W; bitpos: [30]; default: 0;
+         *  Set this bit to restart new inlink descriptors.
+         */
+        uint32_t dma_inlink_restart: 1;
+        /** dma_inlink_park : RO; bitpos: [31]; default: 0;
+         *  1: the inlink descriptor's FSM is in idle state.
+         *  0: the inlink descriptor's FSM is working.
+         */
+        uint32_t dma_inlink_park: 1;
+    };
+    uint32_t val;
+} cp_dma_in_link_reg_t;
+
+/** Type of dma_conf register
+ *  Copy DMA configuration register
+ */
+typedef union {
+    struct {
+        /** dma_in_rst : R/W; bitpos: [0]; default: 0;
+         *  Set this bit to reset in_inf state machine.
+         */
+        uint32_t dma_in_rst: 1;
+        /** dma_out_rst : R/W; bitpos: [1]; default: 0;
+         *  Set this bit to reset out_inf state machine.
+         */
+        uint32_t dma_out_rst: 1;
+        /** dma_cmdfifo_rst : R/W; bitpos: [2]; default: 0;
+         *  Set this bit to reset in_cmd fifo and out_cmd fifo.
+         */
+        uint32_t dma_cmdfifo_rst: 1;
+        /** dma_fifo_rst : R/W; bitpos: [3]; default: 0;
+         *  Set this bit to reset data in receive FIFO.
+         */
+        uint32_t dma_fifo_rst: 1;
+        /** dma_out_owner : R/W; bitpos: [4]; default: 0;
+         *  This is used to configure the owner bit in OUT descriptor. This is effective only
+         *  when you set reg_out_auto_wrback.
+         */
+        uint32_t dma_out_owner: 1;
+        /** dma_in_owner : R/W; bitpos: [5]; default: 0;
+         *  This is used to configure the owner bit in IN descriptor.
+         */
+        uint32_t dma_in_owner: 1;
+        /** dma_out_auto_wrback : R/W; bitpos: [6]; default: 0;
+         *  This bit is used to write back out descriptor when hardware has already used this
+         *  descriptor.
+         */
+        uint32_t dma_out_auto_wrback: 1;
+        /** dma_check_owner : R/W; bitpos: [7]; default: 0;
+         *  Set this bit to enable owner bit check in descriptor.
+         */
+        uint32_t dma_check_owner: 1;
+        /** dma_crc_cal_reset : R/W; bitpos: [8]; default: 0;
+         *  Set this bit to reset crc calculation.
+         */
+        uint32_t dma_crc_cal_reset: 1;
+        /** dma_crc_cal_en : R/W; bitpos: [9]; default: 0;
+         *  Set this bit enable crc calculation function.
+         */
+        uint32_t dma_crc_cal_en: 1;
+        /** dma_crc_big_endian_en : R/W; bitpos: [10]; default: 0;
+         *  Set this bit to reorder the bit of data which will be send to excute crc.
+         */
+        uint32_t dma_crc_big_endian_en: 1;
+        /** dma_crc_out_reverse_en : R/W; bitpos: [11]; default: 0;
+         *  Set this bit to reverse the crc calculation result.
+         */
+        uint32_t dma_crc_out_reverse_en: 1;
+        uint32_t reserved_12: 19;
+        /** dma_clk_en : R/W; bitpos: [31]; default: 0;
+         *  1'b1: Force clock on for register. 1'b0: Support clock only when application writes
+         *  registers.
+         */
+        uint32_t dma_clk_en: 1;
+    };
+    uint32_t val;
+} cp_dma_conf_reg_t;
+
+
+/** Status Registers */
+/** Type of dma_out_eof_des_addr register
+ *  Outlink descriptor address when EOF occurs
+ */
+typedef union {
+    struct {
+        /** dma_out_eof_des_addr : RO; bitpos: [31:0]; default: 0;
+         *  This register stores the address of the outlink descriptor when the EOF bit in this
+         *  descriptor is 1.
+         */
+        uint32_t dma_out_eof_des_addr: 32;
+    };
+    uint32_t val;
+} cp_dma_out_eof_des_addr_reg_t;
+
+/** Type of dma_in_eof_des_addr register
+ *  Inlink descriptor address when EOF occurs
+ */
+typedef union {
+    struct {
+        /** dma_in_suc_eof_des_addr : RO; bitpos: [31:0]; default: 0;
+         *  This register stores the address of the inlink descriptor when received successful
+         *  EOF.
+         */
+        uint32_t dma_in_suc_eof_des_addr: 32;
+    };
+    uint32_t val;
+} cp_dma_in_eof_des_addr_reg_t;
+
+/** Type of dma_out_eof_bfr_des_addr register
+ *  Outlink descriptor address before the last outlink descriptor
+ */
+typedef union {
+    struct {
+        /** dma_out_eof_bfr_des_addr : RO; bitpos: [31:0]; default: 0;
+         *  This register stores the address of the outlink descriptor before the last outlink
+         *  descriptor.
+         */
+        uint32_t dma_out_eof_bfr_des_addr: 32;
+    };
+    uint32_t val;
+} cp_dma_out_eof_bfr_des_addr_reg_t;
+
+/** Type of dma_inlink_dscr register
+ *  Address of current inlink descriptor
+ */
+typedef union {
+    struct {
+        /** dma_inlink_dscr : RO; bitpos: [31:0]; default: 0;
+         *  The address of the current inlink descriptor x.
+         */
+        uint32_t dma_inlink_dscr: 32;
+    };
+    uint32_t val;
+} cp_dma_inlink_dscr_reg_t;
+
+/** Type of dma_inlink_dscr_bf0 register
+ *  Address of last inlink descriptor
+ */
+typedef union {
+    struct {
+        /** dma_inlink_dscr_bf0 : RO; bitpos: [31:0]; default: 0;
+         *  The address of the last inlink descriptor x-1.
+         */
+        uint32_t dma_inlink_dscr_bf0: 32;
+    };
+    uint32_t val;
+} cp_dma_inlink_dscr_bf0_reg_t;
+
+/** Type of dma_inlink_dscr_bf1 register
+ *  Address of the second-to-last inlink descriptor
+ */
+typedef union {
+    struct {
+        /** dma_inlink_dscr_bf1 : RO; bitpos: [31:0]; default: 0;
+         *  The address of the second-to-last inlink descriptor x-2.
+         */
+        uint32_t dma_inlink_dscr_bf1: 32;
+    };
+    uint32_t val;
+} cp_dma_inlink_dscr_bf1_reg_t;
+
+/** Type of dma_outlink_dscr register
+ *  Address of current outlink descriptor
+ */
+typedef union {
+    struct {
+        /** dma_outlink_dscr : RO; bitpos: [31:0]; default: 0;
+         *  The address of the current outlink descriptor y.
+         */
+        uint32_t dma_outlink_dscr: 32;
+    };
+    uint32_t val;
+} cp_dma_outlink_dscr_reg_t;
+
+/** Type of dma_outlink_dscr_bf0 register
+ *  Address of last outlink descriptor
+ */
+typedef union {
+    struct {
+        /** dma_outlink_dscr_bf0 : RO; bitpos: [31:0]; default: 0;
+         *  The address of the last outlink descriptor y-1.
+         */
+        uint32_t dma_outlink_dscr_bf0: 32;
+    };
+    uint32_t val;
+} cp_dma_outlink_dscr_bf0_reg_t;
+
+/** Type of dma_outlink_dscr_bf1 register
+ *  Address of the second-to-last outlink descriptor
+ */
+typedef union {
+    struct {
+        /** dma_outlink_dscr_bf1 : RO; bitpos: [31:0]; default: 0;
+         *  The address of the second-to-last outlink descriptor y-2.
+         */
+        uint32_t dma_outlink_dscr_bf1: 32;
+    };
+    uint32_t val;
+} cp_dma_outlink_dscr_bf1_reg_t;
+
+/** Type of dma_in_st register
+ *  Status register of receiving data
+ */
+typedef union {
+    struct {
+        /** dma_inlink_dscr_addr : RO; bitpos: [17:0]; default: 0;
+         *  This register stores the current inlink descriptor's address.
+         */
+        uint32_t dma_inlink_dscr_addr: 18;
+        /** dma_in_dscr_state : RO; bitpos: [19:18]; default: 0;
+         *  Reserved.
+         */
+        uint32_t dma_in_dscr_state: 2;
+        /** dma_in_state : RO; bitpos: [22:20]; default: 0;
+         *  Reserved.
+         */
+        uint32_t dma_in_state: 3;
+        /** dma_fifo_empty : RO; bitpos: [23]; default: 0;
+         *  Copy DMA FIFO empty signal.
+         */
+        uint32_t dma_fifo_empty: 1;
+    };
+    uint32_t val;
+} cp_dma_in_st_reg_t;
+
+/** Type of dma_out_st register
+ *  Status register of transmitting data
+ */
+typedef union {
+    struct {
+        /** dma_outlink_dscr_addr : RO; bitpos: [17:0]; default: 0;
+         *  This register stores the current outlink descriptor's address.
+         */
+        uint32_t dma_outlink_dscr_addr: 18;
+        /** dma_out_dscr_state : RO; bitpos: [19:18]; default: 0;
+         *  Reserved.
+         */
+        uint32_t dma_out_dscr_state: 2;
+        /** dma_out_state : RO; bitpos: [22:20]; default: 0;
+         *  Reserved.
+         */
+        uint32_t dma_out_state: 3;
+        /** dma_fifo_full : RO; bitpos: [23]; default: 0;
+         *  Copy DMA FIFO full signal.
+         */
+        uint32_t dma_fifo_full: 1;
+    };
+    uint32_t val;
+} cp_dma_out_st_reg_t;
+
+/** Type of dma_crc_out register
+ *  CRC result register
+ */
+typedef union {
+    struct {
+        /** dma_crc_result : RO; bitpos: [31:0]; default: 0;
+         *  This register stores the result of CRC.
+         */
+        uint32_t dma_crc_result: 32;
+    };
+    uint32_t val;
+} cp_dma_crc_out_reg_t;
+
+/** Type of dma_date register
+ *  Copy DMA version register
+ */
+typedef union {
+    struct {
+        /** dma_dma_date : R/W; bitpos: [31:0]; default: 403185664;
+         *  This is the version register.
+         */
+        uint32_t dma_dma_date: 32;
+    };
+    uint32_t val;
+} cp_dma_date_reg_t;
+
+
+typedef struct {
+    volatile cp_dma_int_raw_reg_t dma_int_raw;
+    volatile cp_dma_int_st_reg_t dma_int_st;
+    volatile cp_dma_int_ena_reg_t dma_int_ena;
+    volatile cp_dma_int_clr_reg_t dma_int_clr;
+    volatile cp_dma_out_link_reg_t dma_out_link;
+    volatile cp_dma_in_link_reg_t dma_in_link;
+    volatile cp_dma_out_eof_des_addr_reg_t dma_out_eof_des_addr;
+    volatile cp_dma_in_eof_des_addr_reg_t dma_in_eof_des_addr;
+    volatile cp_dma_out_eof_bfr_des_addr_reg_t dma_out_eof_bfr_des_addr;
+    volatile cp_dma_inlink_dscr_reg_t dma_inlink_dscr;
+    volatile cp_dma_inlink_dscr_bf0_reg_t dma_inlink_dscr_bf0;
+    volatile cp_dma_inlink_dscr_bf1_reg_t dma_inlink_dscr_bf1;
+    volatile cp_dma_outlink_dscr_reg_t dma_outlink_dscr;
+    volatile cp_dma_outlink_dscr_bf0_reg_t dma_outlink_dscr_bf0;
+    volatile cp_dma_outlink_dscr_bf1_reg_t dma_outlink_dscr_bf1;
+    volatile cp_dma_conf_reg_t dma_conf;
+    volatile cp_dma_in_st_reg_t dma_in_st;
+    volatile cp_dma_out_st_reg_t dma_out_st;
+    volatile cp_dma_crc_out_reg_t dma_crc_out;
+    uint32_t reserved_04c;
+    uint32_t reserved_050;
+    uint32_t reserved_054;
+    uint32_t reserved_058;
+    uint32_t reserved_05c;
+    uint32_t reserved_060;
+    uint32_t reserved_064;
+    uint32_t reserved_068;
+    uint32_t reserved_06c;
+    uint32_t reserved_070;
+    uint32_t reserved_074;
+    uint32_t reserved_078;
+    uint32_t reserved_07c;
+    uint32_t reserved_080;
+    uint32_t reserved_084;
+    uint32_t reserved_088;
+    uint32_t reserved_08c;
+    uint32_t reserved_090;
+    uint32_t reserved_094;
+    uint32_t reserved_098;
+    uint32_t reserved_09c;
+    uint32_t reserved_0a0;
+    uint32_t reserved_0a4;
+    uint32_t reserved_0a8;
+    uint32_t reserved_0ac;
+    uint32_t reserved_0b0;
+    uint32_t reserved_0b4;
+    uint32_t reserved_0b8;
+    uint32_t reserved_0bc;
+    uint32_t reserved_0c0;
+    uint32_t reserved_0c4;
+    uint32_t reserved_0c8;
+    uint32_t reserved_0cc;
+    uint32_t reserved_0d0;
+    uint32_t reserved_0d4;
+    uint32_t reserved_0d8;
+    uint32_t reserved_0dc;
+    uint32_t reserved_0e0;
+    uint32_t reserved_0e4;
+    uint32_t reserved_0e8;
+    uint32_t reserved_0ec;
+    uint32_t reserved_0f0;
+    uint32_t reserved_0f4;
+    uint32_t reserved_0f8;
+    volatile cp_dma_date_reg_t dma_date;
+} cp_dma_dev_t;
+
+_Static_assert(sizeof(cp_dma_dev_t) == 0x100, "cp_dma_dev_t should occupy 0x100 bytes in memory");
+
+extern cp_dma_dev_t CP_DMA;
+
+#ifdef __cplusplus
+}
+#endif

+ 0 - 540
components/soc/soc/esp32s2/include/soc/mcp_reg.h

@@ -1,540 +0,0 @@
-// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-#ifndef _SOC_MCP_REG_H_
-#define _SOC_MCP_REG_H_
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "soc.h"
-#define MCP_INT_RAW_REG          (DR_REG_MCP_BASE + 0x0000)
-/* MCP_CRC_DONE_INT_RAW : RO ;bitpos:[8] ;default: 1'b0 ; */
-/*description: */
-#define MCP_CRC_DONE_INT_RAW  (BIT(8))
-#define MCP_CRC_DONE_INT_RAW_M  (BIT(8))
-#define MCP_CRC_DONE_INT_RAW_V  0x1
-#define MCP_CRC_DONE_INT_RAW_S  8
-/* MCP_OUT_TOTAL_EOF_INT_RAW : RO ;bitpos:[7] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_TOTAL_EOF_INT_RAW  (BIT(7))
-#define MCP_OUT_TOTAL_EOF_INT_RAW_M  (BIT(7))
-#define MCP_OUT_TOTAL_EOF_INT_RAW_V  0x1
-#define MCP_OUT_TOTAL_EOF_INT_RAW_S  7
-/* MCP_IN_DSCR_EMPTY_INT_RAW : RO ;bitpos:[6] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DSCR_EMPTY_INT_RAW  (BIT(6))
-#define MCP_IN_DSCR_EMPTY_INT_RAW_M  (BIT(6))
-#define MCP_IN_DSCR_EMPTY_INT_RAW_V  0x1
-#define MCP_IN_DSCR_EMPTY_INT_RAW_S  6
-/* MCP_OUT_DSCR_ERR_INT_RAW : RO ;bitpos:[5] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_DSCR_ERR_INT_RAW  (BIT(5))
-#define MCP_OUT_DSCR_ERR_INT_RAW_M  (BIT(5))
-#define MCP_OUT_DSCR_ERR_INT_RAW_V  0x1
-#define MCP_OUT_DSCR_ERR_INT_RAW_S  5
-/* MCP_IN_DSCR_ERR_INT_RAW : RO ;bitpos:[4] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DSCR_ERR_INT_RAW  (BIT(4))
-#define MCP_IN_DSCR_ERR_INT_RAW_M  (BIT(4))
-#define MCP_IN_DSCR_ERR_INT_RAW_V  0x1
-#define MCP_IN_DSCR_ERR_INT_RAW_S  4
-/* MCP_OUT_EOF_INT_RAW : RO ;bitpos:[3] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_EOF_INT_RAW  (BIT(3))
-#define MCP_OUT_EOF_INT_RAW_M  (BIT(3))
-#define MCP_OUT_EOF_INT_RAW_V  0x1
-#define MCP_OUT_EOF_INT_RAW_S  3
-/* MCP_OUT_DONE_INT_RAW : RO ;bitpos:[2] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_DONE_INT_RAW  (BIT(2))
-#define MCP_OUT_DONE_INT_RAW_M  (BIT(2))
-#define MCP_OUT_DONE_INT_RAW_V  0x1
-#define MCP_OUT_DONE_INT_RAW_S  2
-/* MCP_IN_SUC_EOF_INT_RAW : RO ;bitpos:[1] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_SUC_EOF_INT_RAW  (BIT(1))
-#define MCP_IN_SUC_EOF_INT_RAW_M  (BIT(1))
-#define MCP_IN_SUC_EOF_INT_RAW_V  0x1
-#define MCP_IN_SUC_EOF_INT_RAW_S  1
-/* MCP_IN_DONE_INT_RAW : RO ;bitpos:[0] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DONE_INT_RAW  (BIT(0))
-#define MCP_IN_DONE_INT_RAW_M  (BIT(0))
-#define MCP_IN_DONE_INT_RAW_V  0x1
-#define MCP_IN_DONE_INT_RAW_S  0
-
-#define MCP_INT_ST_REG          (DR_REG_MCP_BASE + 0x0004)
-/* MCP_CRC_DONE_INT_ST : RO ;bitpos:[8] ;default: 1'b0 ; */
-/*description: */
-#define MCP_CRC_DONE_INT_ST  (BIT(8))
-#define MCP_CRC_DONE_INT_ST_M  (BIT(8))
-#define MCP_CRC_DONE_INT_ST_V  0x1
-#define MCP_CRC_DONE_INT_ST_S  8
-/* MCP_OUT_TOTAL_EOF_INT_ST : RO ;bitpos:[7] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_TOTAL_EOF_INT_ST  (BIT(7))
-#define MCP_OUT_TOTAL_EOF_INT_ST_M  (BIT(7))
-#define MCP_OUT_TOTAL_EOF_INT_ST_V  0x1
-#define MCP_OUT_TOTAL_EOF_INT_ST_S  7
-/* MCP_IN_DSCR_EMPTY_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DSCR_EMPTY_INT_ST  (BIT(6))
-#define MCP_IN_DSCR_EMPTY_INT_ST_M  (BIT(6))
-#define MCP_IN_DSCR_EMPTY_INT_ST_V  0x1
-#define MCP_IN_DSCR_EMPTY_INT_ST_S  6
-/* MCP_OUT_DSCR_ERR_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_DSCR_ERR_INT_ST  (BIT(5))
-#define MCP_OUT_DSCR_ERR_INT_ST_M  (BIT(5))
-#define MCP_OUT_DSCR_ERR_INT_ST_V  0x1
-#define MCP_OUT_DSCR_ERR_INT_ST_S  5
-/* MCP_IN_DSCR_ERR_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DSCR_ERR_INT_ST  (BIT(4))
-#define MCP_IN_DSCR_ERR_INT_ST_M  (BIT(4))
-#define MCP_IN_DSCR_ERR_INT_ST_V  0x1
-#define MCP_IN_DSCR_ERR_INT_ST_S  4
-/* MCP_OUT_EOF_INT_ST : RO ;bitpos:[3] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_EOF_INT_ST  (BIT(3))
-#define MCP_OUT_EOF_INT_ST_M  (BIT(3))
-#define MCP_OUT_EOF_INT_ST_V  0x1
-#define MCP_OUT_EOF_INT_ST_S  3
-/* MCP_OUT_DONE_INT_ST : RO ;bitpos:[2] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_DONE_INT_ST  (BIT(2))
-#define MCP_OUT_DONE_INT_ST_M  (BIT(2))
-#define MCP_OUT_DONE_INT_ST_V  0x1
-#define MCP_OUT_DONE_INT_ST_S  2
-/* MCP_IN_SUC_EOF_INT_ST : RO ;bitpos:[1] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_SUC_EOF_INT_ST  (BIT(1))
-#define MCP_IN_SUC_EOF_INT_ST_M  (BIT(1))
-#define MCP_IN_SUC_EOF_INT_ST_V  0x1
-#define MCP_IN_SUC_EOF_INT_ST_S  1
-/* MCP_IN_DONE_INT_ST : RO ;bitpos:[0] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DONE_INT_ST  (BIT(0))
-#define MCP_IN_DONE_INT_ST_M  (BIT(0))
-#define MCP_IN_DONE_INT_ST_V  0x1
-#define MCP_IN_DONE_INT_ST_S  0
-
-#define MCP_INT_ENA_REG          (DR_REG_MCP_BASE + 0x008)
-/* MCP_CRC_DONE_INT_ENA : R/W ;bitpos:[8] ;default: 1'b0 ; */
-/*description: */
-#define MCP_CRC_DONE_INT_ENA  (BIT(8))
-#define MCP_CRC_DONE_INT_ENA_M  (BIT(8))
-#define MCP_CRC_DONE_INT_ENA_V  0x1
-#define MCP_CRC_DONE_INT_ENA_S  8
-/* MCP_OUT_TOTAL_EOF_INT_ENA : R/W ;bitpos:[7] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_TOTAL_EOF_INT_ENA  (BIT(7))
-#define MCP_OUT_TOTAL_EOF_INT_ENA_M  (BIT(7))
-#define MCP_OUT_TOTAL_EOF_INT_ENA_V  0x1
-#define MCP_OUT_TOTAL_EOF_INT_ENA_S  7
-/* MCP_IN_DSCR_EMPTY_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DSCR_EMPTY_INT_ENA  (BIT(6))
-#define MCP_IN_DSCR_EMPTY_INT_ENA_M  (BIT(6))
-#define MCP_IN_DSCR_EMPTY_INT_ENA_V  0x1
-#define MCP_IN_DSCR_EMPTY_INT_ENA_S  6
-/* MCP_OUT_DSCR_ERR_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_DSCR_ERR_INT_ENA  (BIT(5))
-#define MCP_OUT_DSCR_ERR_INT_ENA_M  (BIT(5))
-#define MCP_OUT_DSCR_ERR_INT_ENA_V  0x1
-#define MCP_OUT_DSCR_ERR_INT_ENA_S  5
-/* MCP_IN_DSCR_ERR_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DSCR_ERR_INT_ENA  (BIT(4))
-#define MCP_IN_DSCR_ERR_INT_ENA_M  (BIT(4))
-#define MCP_IN_DSCR_ERR_INT_ENA_V  0x1
-#define MCP_IN_DSCR_ERR_INT_ENA_S  4
-/* MCP_OUT_EOF_INT_ENA : R/W ;bitpos:[3] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_EOF_INT_ENA  (BIT(3))
-#define MCP_OUT_EOF_INT_ENA_M  (BIT(3))
-#define MCP_OUT_EOF_INT_ENA_V  0x1
-#define MCP_OUT_EOF_INT_ENA_S  3
-/* MCP_OUT_DONE_INT_ENA : R/W ;bitpos:[2] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_DONE_INT_ENA  (BIT(2))
-#define MCP_OUT_DONE_INT_ENA_M  (BIT(2))
-#define MCP_OUT_DONE_INT_ENA_V  0x1
-#define MCP_OUT_DONE_INT_ENA_S  2
-/* MCP_IN_SUC_EOF_INT_ENA : R/W ;bitpos:[1] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_SUC_EOF_INT_ENA  (BIT(1))
-#define MCP_IN_SUC_EOF_INT_ENA_M  (BIT(1))
-#define MCP_IN_SUC_EOF_INT_ENA_V  0x1
-#define MCP_IN_SUC_EOF_INT_ENA_S  1
-/* MCP_IN_DONE_INT_ENA : R/W ;bitpos:[0] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DONE_INT_ENA  (BIT(0))
-#define MCP_IN_DONE_INT_ENA_M  (BIT(0))
-#define MCP_IN_DONE_INT_ENA_V  0x1
-#define MCP_IN_DONE_INT_ENA_S  0
-
-#define MCP_INT_CLR_REG          (DR_REG_MCP_BASE + 0x000c)
-/* MCP_CRC_DONE_INT_CLR : WO ;bitpos:[8] ;default: 1'b0 ; */
-/*description: */
-#define MCP_CRC_DONE_INT_CLR  (BIT(8))
-#define MCP_CRC_DONE_INT_CLR_M  (BIT(8))
-#define MCP_CRC_DONE_INT_CLR_V  0x1
-#define MCP_CRC_DONE_INT_CLR_S  8
-/* MCP_OUT_TOTAL_EOF_INT_CLR : WO ;bitpos:[7] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_TOTAL_EOF_INT_CLR  (BIT(7))
-#define MCP_OUT_TOTAL_EOF_INT_CLR_M  (BIT(7))
-#define MCP_OUT_TOTAL_EOF_INT_CLR_V  0x1
-#define MCP_OUT_TOTAL_EOF_INT_CLR_S  7
-/* MCP_IN_DSCR_EMPTY_INT_CLR : WO ;bitpos:[6] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DSCR_EMPTY_INT_CLR  (BIT(6))
-#define MCP_IN_DSCR_EMPTY_INT_CLR_M  (BIT(6))
-#define MCP_IN_DSCR_EMPTY_INT_CLR_V  0x1
-#define MCP_IN_DSCR_EMPTY_INT_CLR_S  6
-/* MCP_OUT_DSCR_ERR_INT_CLR : WO ;bitpos:[5] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_DSCR_ERR_INT_CLR  (BIT(5))
-#define MCP_OUT_DSCR_ERR_INT_CLR_M  (BIT(5))
-#define MCP_OUT_DSCR_ERR_INT_CLR_V  0x1
-#define MCP_OUT_DSCR_ERR_INT_CLR_S  5
-/* MCP_IN_DSCR_ERR_INT_CLR : WO ;bitpos:[4] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DSCR_ERR_INT_CLR  (BIT(4))
-#define MCP_IN_DSCR_ERR_INT_CLR_M  (BIT(4))
-#define MCP_IN_DSCR_ERR_INT_CLR_V  0x1
-#define MCP_IN_DSCR_ERR_INT_CLR_S  4
-/* MCP_OUT_EOF_INT_CLR : WO ;bitpos:[3] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_EOF_INT_CLR  (BIT(3))
-#define MCP_OUT_EOF_INT_CLR_M  (BIT(3))
-#define MCP_OUT_EOF_INT_CLR_V  0x1
-#define MCP_OUT_EOF_INT_CLR_S  3
-/* MCP_OUT_DONE_INT_CLR : WO ;bitpos:[2] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUT_DONE_INT_CLR  (BIT(2))
-#define MCP_OUT_DONE_INT_CLR_M  (BIT(2))
-#define MCP_OUT_DONE_INT_CLR_V  0x1
-#define MCP_OUT_DONE_INT_CLR_S  2
-/* MCP_IN_SUC_EOF_INT_CLR : WO ;bitpos:[1] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_SUC_EOF_INT_CLR  (BIT(1))
-#define MCP_IN_SUC_EOF_INT_CLR_M  (BIT(1))
-#define MCP_IN_SUC_EOF_INT_CLR_V  0x1
-#define MCP_IN_SUC_EOF_INT_CLR_S  1
-/* MCP_IN_DONE_INT_CLR : WO ;bitpos:[0] ;default: 1'b0 ; */
-/*description: */
-#define MCP_IN_DONE_INT_CLR  (BIT(0))
-#define MCP_IN_DONE_INT_CLR_M  (BIT(0))
-#define MCP_IN_DONE_INT_CLR_V  0x1
-#define MCP_IN_DONE_INT_CLR_S  0
-
-#define MCP_OUT_LINK_REG          (DR_REG_MCP_BASE + 0x0010)
-/* MCP_OUTLINK_PARK : RO ;bitpos:[31] ;default: 1'h0 ; */
-/*description: */
-#define MCP_OUTLINK_PARK  (BIT(31))
-#define MCP_OUTLINK_PARK_M  (BIT(31))
-#define MCP_OUTLINK_PARK_V  0x1
-#define MCP_OUTLINK_PARK_S  31
-/* MCP_OUTLINK_RESTART : R/W ;bitpos:[30] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUTLINK_RESTART  (BIT(30))
-#define MCP_OUTLINK_RESTART_M  (BIT(30))
-#define MCP_OUTLINK_RESTART_V  0x1
-#define MCP_OUTLINK_RESTART_S  30
-/* MCP_OUTLINK_START : R/W ;bitpos:[29] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUTLINK_START  (BIT(29))
-#define MCP_OUTLINK_START_M  (BIT(29))
-#define MCP_OUTLINK_START_V  0x1
-#define MCP_OUTLINK_START_S  29
-/* MCP_OUTLINK_STOP : R/W ;bitpos:[28] ;default: 1'b0 ; */
-/*description: */
-#define MCP_OUTLINK_STOP  (BIT(28))
-#define MCP_OUTLINK_STOP_M  (BIT(28))
-#define MCP_OUTLINK_STOP_V  0x1
-#define MCP_OUTLINK_STOP_S  28
-/* MCP_OUTLINK_ADDR : R/W ;bitpos:[19:0] ;default: 20'h0 ; */
-/*description: */
-#define MCP_OUTLINK_ADDR  0x000FFFFF
-#define MCP_OUTLINK_ADDR_M  ((MCP_OUTLINK_ADDR_V)<<(MCP_OUTLINK_ADDR_S))
-#define MCP_OUTLINK_ADDR_V  0xFFFFF
-#define MCP_OUTLINK_ADDR_S  0
-
-#define MCP_IN_LINK_REG          (DR_REG_MCP_BASE + 0x0014)
-/* MCP_INLINK_PARK : RO ;bitpos:[31] ;default: 1'h0 ; */
-/*description: */
-#define MCP_INLINK_PARK  (BIT(31))
-#define MCP_INLINK_PARK_M  (BIT(31))
-#define MCP_INLINK_PARK_V  0x1
-#define MCP_INLINK_PARK_S  31
-/* MCP_INLINK_RESTART : R/W ;bitpos:[30] ;default: 1'b0 ; */
-/*description: */
-#define MCP_INLINK_RESTART  (BIT(30))
-#define MCP_INLINK_RESTART_M  (BIT(30))
-#define MCP_INLINK_RESTART_V  0x1
-#define MCP_INLINK_RESTART_S  30
-/* MCP_INLINK_START : R/W ;bitpos:[29] ;default: 1'b0 ; */
-/*description: */
-#define MCP_INLINK_START  (BIT(29))
-#define MCP_INLINK_START_M  (BIT(29))
-#define MCP_INLINK_START_V  0x1
-#define MCP_INLINK_START_S  29
-/* MCP_INLINK_STOP : R/W ;bitpos:[28] ;default: 1'b0 ; */
-/*description: */
-#define MCP_INLINK_STOP  (BIT(28))
-#define MCP_INLINK_STOP_M  (BIT(28))
-#define MCP_INLINK_STOP_V  0x1
-#define MCP_INLINK_STOP_S  28
-/* MCP_INLINK_ADDR : R/W ;bitpos:[19:0] ;default: 20'h0 ; */
-/*description: */
-#define MCP_INLINK_ADDR  0x000FFFFF
-#define MCP_INLINK_ADDR_M  ((MCP_INLINK_ADDR_V)<<(MCP_INLINK_ADDR_S))
-#define MCP_INLINK_ADDR_V  0xFFFFF
-#define MCP_INLINK_ADDR_S  0
-
-#define MCP_OUT_EOF_DES_ADDR_REG          (DR_REG_MCP_BASE + 0x0018)
-/* MCP_OUT_EOF_DES_ADDR : RO ;bitpos:[31:0] ;default: 32'h0 ; */
-/*description: */
-#define MCP_OUT_EOF_DES_ADDR  0xFFFFFFFF
-#define MCP_OUT_EOF_DES_ADDR_M  ((MCP_OUT_EOF_DES_ADDR_V)<<(MCP_OUT_EOF_DES_ADDR_S))
-#define MCP_OUT_EOF_DES_ADDR_V  0xFFFFFFFF
-#define MCP_OUT_EOF_DES_ADDR_S  0
-
-#define MCP_IN_EOF_DES_ADDR_REG          (DR_REG_MCP_BASE + 0x001c)
-/* MCP_IN_SUC_EOF_DES_ADDR : RO ;bitpos:[31:0] ;default: 32'h0 ; */
-/*description: */
-#define MCP_IN_SUC_EOF_DES_ADDR  0xFFFFFFFF
-#define MCP_IN_SUC_EOF_DES_ADDR_M  ((MCP_IN_SUC_EOF_DES_ADDR_V)<<(MCP_IN_SUC_EOF_DES_ADDR_S))
-#define MCP_IN_SUC_EOF_DES_ADDR_V  0xFFFFFFFF
-#define MCP_IN_SUC_EOF_DES_ADDR_S  0
-
-#define MCP_OUT_EOF_BFR_DES_ADDR_REG          (DR_REG_MCP_BASE + 0x0020)
-/* MCP_OUT_EOF_BFR_DES_ADDR : RO ;bitpos:[31:0] ;default: 32'h0 ; */
-/*description: */
-#define MCP_OUT_EOF_BFR_DES_ADDR  0xFFFFFFFF
-#define MCP_OUT_EOF_BFR_DES_ADDR_M  ((MCP_OUT_EOF_BFR_DES_ADDR_V)<<(MCP_OUT_EOF_BFR_DES_ADDR_S))
-#define MCP_OUT_EOF_BFR_DES_ADDR_V  0xFFFFFFFF
-#define MCP_OUT_EOF_BFR_DES_ADDR_S  0
-
-#define MCP_INLINK_DSCR_REG          (DR_REG_MCP_BASE + 0x0024)
-/* MCP_INLINK_DSCR : RO ;bitpos:[31:0] ;default: 32'b0 ; */
-/*description: */
-#define MCP_INLINK_DSCR  0xFFFFFFFF
-#define MCP_INLINK_DSCR_M  ((MCP_INLINK_DSCR_V)<<(MCP_INLINK_DSCR_S))
-#define MCP_INLINK_DSCR_V  0xFFFFFFFF
-#define MCP_INLINK_DSCR_S  0
-
-#define MCP_INLINK_DSCR_BF0_REG          (DR_REG_MCP_BASE + 0x0028)
-/* MCP_INLINK_DSCR_BF0 : RO ;bitpos:[31:0] ;default: 32'b0 ; */
-/*description: */
-#define MCP_INLINK_DSCR_BF0  0xFFFFFFFF
-#define MCP_INLINK_DSCR_BF0_M  ((MCP_INLINK_DSCR_BF0_V)<<(MCP_INLINK_DSCR_BF0_S))
-#define MCP_INLINK_DSCR_BF0_V  0xFFFFFFFF
-#define MCP_INLINK_DSCR_BF0_S  0
-
-#define MCP_INLINK_DSCR_BF1_REG          (DR_REG_MCP_BASE + 0x002c)
-/* MCP_INLINK_DSCR_BF1 : RO ;bitpos:[31:0] ;default: 32'b0 ; */
-/*description: */
-#define MCP_INLINK_DSCR_BF1  0xFFFFFFFF
-#define MCP_INLINK_DSCR_BF1_M  ((MCP_INLINK_DSCR_BF1_V)<<(MCP_INLINK_DSCR_BF1_S))
-#define MCP_INLINK_DSCR_BF1_V  0xFFFFFFFF
-#define MCP_INLINK_DSCR_BF1_S  0
-
-#define MCP_OUTLINK_DSCR_REG          (DR_REG_MCP_BASE + 0x0030)
-/* MCP_OUTLINK_DSCR : RO ;bitpos:[31:0] ;default: 32'b0 ; */
-/*description: */
-#define MCP_OUTLINK_DSCR  0xFFFFFFFF
-#define MCP_OUTLINK_DSCR_M  ((MCP_OUTLINK_DSCR_V)<<(MCP_OUTLINK_DSCR_S))
-#define MCP_OUTLINK_DSCR_V  0xFFFFFFFF
-#define MCP_OUTLINK_DSCR_S  0
-
-#define MCP_OUTLINK_DSCR_BF0_REG          (DR_REG_MCP_BASE + 0x0034)
-/* MCP_OUTLINK_DSCR_BF0 : RO ;bitpos:[31:0] ;default: 32'b0 ; */
-/*description: */
-#define MCP_OUTLINK_DSCR_BF0  0xFFFFFFFF
-#define MCP_OUTLINK_DSCR_BF0_M  ((MCP_OUTLINK_DSCR_BF0_V)<<(MCP_OUTLINK_DSCR_BF0_S))
-#define MCP_OUTLINK_DSCR_BF0_V  0xFFFFFFFF
-#define MCP_OUTLINK_DSCR_BF0_S  0
-
-#define MCP_OUTLINK_DSCR_BF1_REG          (DR_REG_MCP_BASE + 0x0038)
-/* MCP_OUTLINK_DSCR_BF1 : RO ;bitpos:[31:0] ;default: 32'b0 ; */
-/*description: */
-#define MCP_OUTLINK_DSCR_BF1  0xFFFFFFFF
-#define MCP_OUTLINK_DSCR_BF1_M  ((MCP_OUTLINK_DSCR_BF1_V)<<(MCP_OUTLINK_DSCR_BF1_S))
-#define MCP_OUTLINK_DSCR_BF1_V  0xFFFFFFFF
-#define MCP_OUTLINK_DSCR_BF1_S  0
-
-#define MCP_CONF_REG          (DR_REG_MCP_BASE + 0x003c)
-/* MCP_CLK_EN : R/W ;bitpos:[31] ;default: 1'h0 ; */
-/*description: */
-#define MCP_CLK_EN  (BIT(31))
-#define MCP_CLK_EN_M  (BIT(31))
-#define MCP_CLK_EN_V  0x1
-#define MCP_CLK_EN_S  31
-/* MCP_CRC_OUT_REVERSE_EN : R/W ;bitpos:[11] ;default: 1'b0 ; */
-/*description: */
-#define MCP_CRC_OUT_REVERSE_EN  (BIT(11))
-#define MCP_CRC_OUT_REVERSE_EN_M  (BIT(11))
-#define MCP_CRC_OUT_REVERSE_EN_V  0x1
-#define MCP_CRC_OUT_REVERSE_EN_S  11
-/* MCP_CRC_BIG_ENDIAN_EN : R/W ;bitpos:[10] ;default: 1'b0 ; */
-/*description: Set this bit to reorder the bit of data which will be send to excute crc.*/
-#define MCP_CRC_BIG_ENDIAN_EN  (BIT(10))
-#define MCP_CRC_BIG_ENDIAN_EN_M  (BIT(10))
-#define MCP_CRC_BIG_ENDIAN_EN_V  0x1
-#define MCP_CRC_BIG_ENDIAN_EN_S  10
-/* MCP_CRC_CAL_EN : R/W ;bitpos:[9] ;default: 1'b0 ; */
-/*description: Set this bit enable crc calculation function.*/
-#define MCP_CRC_CAL_EN  (BIT(9))
-#define MCP_CRC_CAL_EN_M  (BIT(9))
-#define MCP_CRC_CAL_EN_V  0x1
-#define MCP_CRC_CAL_EN_S  9
-/* MCP_CRC_CAL_RESET : R/W ;bitpos:[8] ;default: 1'b0 ; */
-/*description: Set this bit to reset crc calculation.*/
-#define MCP_CRC_CAL_RESET  (BIT(8))
-#define MCP_CRC_CAL_RESET_M  (BIT(8))
-#define MCP_CRC_CAL_RESET_V  0x1
-#define MCP_CRC_CAL_RESET_S  8
-/* MCP_CHECK_OWNER : R/W ;bitpos:[7] ;default: 1'b0 ; */
-/*description: Set this bit to enable owner bit check in descriptor.*/
-#define MCP_CHECK_OWNER  (BIT(7))
-#define MCP_CHECK_OWNER_M  (BIT(7))
-#define MCP_CHECK_OWNER_V  0x1
-#define MCP_CHECK_OWNER_S  7
-/* MCP_OUT_AUTO_WRBACK : R/W ;bitpos:[6] ;default: 1'b0 ; */
-/*description: this bit is used to write back out descriptor when hardware has
- already used this descriptor.*/
-#define MCP_OUT_AUTO_WRBACK  (BIT(6))
-#define MCP_OUT_AUTO_WRBACK_M  (BIT(6))
-#define MCP_OUT_AUTO_WRBACK_V  0x1
-#define MCP_OUT_AUTO_WRBACK_S  6
-/* MCP_IN_OWNER : R/W ;bitpos:[5] ;default: 1'b0 ; */
-/*description: This is used to configure the owner bit in IN descriptor.*/
-#define MCP_IN_OWNER  (BIT(5))
-#define MCP_IN_OWNER_M  (BIT(5))
-#define MCP_IN_OWNER_V  0x1
-#define MCP_IN_OWNER_S  5
-/* MCP_OUT_OWNER : R/W ;bitpos:[4] ;default: 1'b0 ; */
-/*description: This is used to configure the owner bit in OUT descriptor. This
- is effective only when you set reg_out_auto_wrback.*/
-#define MCP_OUT_OWNER  (BIT(4))
-#define MCP_OUT_OWNER_M  (BIT(4))
-#define MCP_OUT_OWNER_V  0x1
-#define MCP_OUT_OWNER_S  4
-/* MCP_FIFO_RST : R/W ;bitpos:[3] ;default: 1'b0 ; */
-/*description: */
-#define MCP_FIFO_RST  (BIT(3))
-#define MCP_FIFO_RST_M  (BIT(3))
-#define MCP_FIFO_RST_V  0x1
-#define MCP_FIFO_RST_S  3
-/* MCP_CMDFIFO_RST : R/W ;bitpos:[2] ;default: 1'b0 ; */
-/*description: set this bit to reset in_cmdfifo and out_cmdfifo.*/
-#define MCP_CMDFIFO_RST  (BIT(2))
-#define MCP_CMDFIFO_RST_M  (BIT(2))
-#define MCP_CMDFIFO_RST_V  0x1
-#define MCP_CMDFIFO_RST_S  2
-/* MCP_OUT_RST : R/W ;bitpos:[1] ;default: 1'b0 ; */
-/*description: set this bit to reset out_inf state machine.*/
-#define MCP_OUT_RST  (BIT(1))
-#define MCP_OUT_RST_M  (BIT(1))
-#define MCP_OUT_RST_V  0x1
-#define MCP_OUT_RST_S  1
-/* MCP_IN_RST : R/W ;bitpos:[0] ;default: 1'h0 ; */
-/*description: set this bit to reset in_inf state machine.*/
-#define MCP_IN_RST  (BIT(0))
-#define MCP_IN_RST_M  (BIT(0))
-#define MCP_IN_RST_V  0x1
-#define MCP_IN_RST_S  0
-
-#define MCP_IN_ST_REG          (DR_REG_MCP_BASE + 0x0040)
-/* MCP_FIFO_EMPTY : RO ;bitpos:[23] ;default: 1'b0 ; */
-/*description: */
-#define MCP_FIFO_EMPTY  (BIT(23))
-#define MCP_FIFO_EMPTY_M  (BIT(23))
-#define MCP_FIFO_EMPTY_V  0x1
-#define MCP_FIFO_EMPTY_S  23
-/* MCP_IN_STATE : RO ;bitpos:[22:20] ;default: 3'b0 ; */
-/*description: */
-#define MCP_IN_STATE  0x00000007
-#define MCP_IN_STATE_M  ((MCP_IN_STATE_V)<<(MCP_IN_STATE_S))
-#define MCP_IN_STATE_V  0x7
-#define MCP_IN_STATE_S  20
-/* MCP_IN_DSCR_STATE : RO ;bitpos:[19:18] ;default: 2'b0 ; */
-/*description: */
-#define MCP_IN_DSCR_STATE  0x00000003
-#define MCP_IN_DSCR_STATE_M  ((MCP_IN_DSCR_STATE_V)<<(MCP_IN_DSCR_STATE_S))
-#define MCP_IN_DSCR_STATE_V  0x3
-#define MCP_IN_DSCR_STATE_S  18
-/* MCP_INLINK_DSCR_ADDR : RO ;bitpos:[17:0] ;default: 18'b0 ; */
-/*description: */
-#define MCP_INLINK_DSCR_ADDR  0x0003FFFF
-#define MCP_INLINK_DSCR_ADDR_M  ((MCP_INLINK_DSCR_ADDR_V)<<(MCP_INLINK_DSCR_ADDR_S))
-#define MCP_INLINK_DSCR_ADDR_V  0x3FFFF
-#define MCP_INLINK_DSCR_ADDR_S  0
-
-#define MCP_OUT_ST_REG          (DR_REG_MCP_BASE + 0x0044)
-/* MCP_FIFO_FULL : RO ;bitpos:[23] ;default: 1'b0 ; */
-/*description: */
-#define MCP_FIFO_FULL  (BIT(23))
-#define MCP_FIFO_FULL_M  (BIT(23))
-#define MCP_FIFO_FULL_V  0x1
-#define MCP_FIFO_FULL_S  23
-/* MCP_OUT_STATE : RO ;bitpos:[22:20] ;default: 3'b0 ; */
-/*description: */
-#define MCP_OUT_STATE  0x00000007
-#define MCP_OUT_STATE_M  ((MCP_OUT_STATE_V)<<(MCP_OUT_STATE_S))
-#define MCP_OUT_STATE_V  0x7
-#define MCP_OUT_STATE_S  20
-/* MCP_OUT_DSCR_STATE : RO ;bitpos:[19:18] ;default: 2'b0 ; */
-/*description: */
-#define MCP_OUT_DSCR_STATE  0x00000003
-#define MCP_OUT_DSCR_STATE_M  ((MCP_OUT_DSCR_STATE_V)<<(MCP_OUT_DSCR_STATE_S))
-#define MCP_OUT_DSCR_STATE_V  0x3
-#define MCP_OUT_DSCR_STATE_S  18
-/* MCP_OUTLINK_DSCR_ADDR : RO ;bitpos:[17:0] ;default: 18'b0 ; */
-/*description: */
-#define MCP_OUTLINK_DSCR_ADDR  0x0003FFFF
-#define MCP_OUTLINK_DSCR_ADDR_M  ((MCP_OUTLINK_DSCR_ADDR_V)<<(MCP_OUTLINK_DSCR_ADDR_S))
-#define MCP_OUTLINK_DSCR_ADDR_V  0x3FFFF
-#define MCP_OUTLINK_DSCR_ADDR_S  0
-
-#define MCP_CRC_OUT_REG          (DR_REG_MCP_BASE + 0x0048)
-/* MCP_CRC_RESULT : RO ;bitpos:[31:0] ;default: 32'h0 ; */
-/*description: */
-#define MCP_CRC_RESULT  0xFFFFFFFF
-#define MCP_CRC_RESULT_M  ((MCP_CRC_RESULT_V)<<(MCP_CRC_RESULT_S))
-#define MCP_CRC_RESULT_V  0xFFFFFFFF
-#define MCP_CRC_RESULT_S  0
-
-#define MCP_DATE_REG          (DR_REG_MCP_BASE + 0x00fc)
-/* MCP_DMA_DATE : R/W ;bitpos:[31:0] ;default: 32'h18082000 ; */
-/*description: */
-#define MCP_DMA_DATE  0xFFFFFFFF
-#define MCP_DMA_DATE_M  ((MCP_DMA_DATE_V)<<(MCP_DMA_DATE_S))
-#define MCP_DMA_DATE_V  0xFFFFFFFF
-#define MCP_DMA_DATE_S  0
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-#endif /*_SOC_MCP_REG_H_ */
-
-

+ 0 - 203
components/soc/soc/esp32s2/include/soc/mcp_struct.h

@@ -1,203 +0,0 @@
-// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-#ifndef _SOC_MCP_STRUCT_H_
-#define _SOC_MCP_STRUCT_H_
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef volatile struct {
-    union {
-        struct {
-            uint32_t in_done:                  1;
-            uint32_t in_suc_eof:               1;
-            uint32_t out_done:                 1;
-            uint32_t out_eof:                  1;
-            uint32_t in_dscr_err:              1;
-            uint32_t out_dscr_err:             1;
-            uint32_t in_dscr_empty:            1;
-            uint32_t out_total_eof:            1;
-            uint32_t crc_done:                 1;
-            uint32_t reserved9:               23;
-        };
-        uint32_t val;
-    } int_raw;
-    union {
-        struct {
-            uint32_t in_done:                 1;
-            uint32_t in_suc_eof:              1;
-            uint32_t out_done:                1;
-            uint32_t out_eof:                 1;
-            uint32_t in_dscr_err:             1;
-            uint32_t out_dscr_err:            1;
-            uint32_t in_dscr_empty:           1;
-            uint32_t out_total_eof:           1;
-            uint32_t crc_done:                1;
-            uint32_t reserved9:              23;
-        };
-        uint32_t val;
-    } int_st;
-    union {
-        struct {
-            uint32_t in_done:                  1;
-            uint32_t in_suc_eof:               1;
-            uint32_t out_done:                 1;
-            uint32_t out_eof:                  1;
-            uint32_t in_dscr_err:              1;
-            uint32_t out_dscr_err:             1;
-            uint32_t in_dscr_empty:            1;
-            uint32_t out_total_eof:            1;
-            uint32_t crc_done:                 1;
-            uint32_t reserved9:               23;
-        };
-        uint32_t val;
-    } int_ena;
-    union {
-        struct {
-            uint32_t in_done:                  1;
-            uint32_t in_suc_eof:               1;
-            uint32_t out_done:                 1;
-            uint32_t out_eof:                  1;
-            uint32_t in_dscr_err:              1;
-            uint32_t out_dscr_err:             1;
-            uint32_t in_dscr_empty:            1;
-            uint32_t out_total_eof:            1;
-            uint32_t crc_done:                 1;
-            uint32_t reserved9:               23;
-        };
-        uint32_t val;
-    } int_clr;
-    union {
-        struct {
-            uint32_t addr:              20;
-            uint32_t reserved20:         8;
-            uint32_t stop:               1;
-            uint32_t start:              1;
-            uint32_t restart:            1;
-            uint32_t park:               1;
-        };
-        uint32_t val;
-    } out_link;
-    union {
-        struct {
-            uint32_t addr:             20;
-            uint32_t reserved20:        8;
-            uint32_t stop:              1;
-            uint32_t start:             1;
-            uint32_t restart:           1;
-            uint32_t park:              1;
-        };
-        uint32_t val;
-    } in_link;
-    uint32_t out_eof_des_addr;                   /**/
-    uint32_t in_eof_des_addr;                    /**/
-    uint32_t out_eof_bfr_des_addr;               /**/
-    uint32_t inlink_dscr;                        /**/
-    uint32_t inlink_dscr_bf0;                    /**/
-    uint32_t inlink_dscr_bf1;                    /**/
-    uint32_t outlink_dscr;                       /**/
-    uint32_t outlink_dscr_bf0;                   /**/
-    uint32_t outlink_dscr_bf1;                   /**/
-    union {
-        struct {
-            uint32_t in_rst:             1;         /*set this bit to reset in_inf state machine.*/
-            uint32_t out_rst:            1;         /*set this bit to reset out_inf state machine.*/
-            uint32_t cmdfifo_rst:        1;         /*set this bit to reset in_cmdfifo and out_cmdfifo.*/
-            uint32_t fifo_rst:           1;
-            uint32_t out_owner:          1;         /*This is used to configure the owner bit in OUT descriptor. This is effective only when you set reg_out_auto_wrback.*/
-            uint32_t in_owner:           1;         /*This is used to configure the owner bit in IN descriptor.*/
-            uint32_t out_auto_wrback:    1;         /*this bit is used to write back out descriptor when hardware has already used this descriptor.*/
-            uint32_t check_owner:        1;         /*Set this bit to enable owner bit check in descriptor.*/
-            uint32_t crc_cal_reset:      1;         /*Set this bit to reset crc calculation.*/
-            uint32_t crc_cal_en:         1;         /*Set this bit enable crc calculation function.*/
-            uint32_t crc_big_endian_en:  1;         /*Set this bit to reorder the bit of data which will be send to excute crc.*/
-            uint32_t crc_out_reverse_en: 1;
-            uint32_t reserved12:        19;
-            uint32_t clk_en:             1;
-        };
-        uint32_t val;
-    } conf;
-    union {
-        struct {
-            uint32_t dscr_addr:       18;
-            uint32_t dscr_state:       2;
-            uint32_t state:            3;
-            uint32_t fifo_empty:       1;
-            uint32_t reserved24:       8;
-        };
-        uint32_t val;
-    } in_st;
-    union {
-        struct {
-            uint32_t dscr_addr:        18;
-            uint32_t dscr_state:        2;
-            uint32_t state:             3;
-            uint32_t fifo_full:         1;
-            uint32_t reserved24:        8;
-        };
-        uint32_t val;
-    } out_st;
-    uint32_t crc_out;                            /**/
-    uint32_t reserved_4c;
-    uint32_t reserved_50;
-    uint32_t reserved_54;
-    uint32_t reserved_58;
-    uint32_t reserved_5c;
-    uint32_t reserved_60;
-    uint32_t reserved_64;
-    uint32_t reserved_68;
-    uint32_t reserved_6c;
-    uint32_t reserved_70;
-    uint32_t reserved_74;
-    uint32_t reserved_78;
-    uint32_t reserved_7c;
-    uint32_t reserved_80;
-    uint32_t reserved_84;
-    uint32_t reserved_88;
-    uint32_t reserved_8c;
-    uint32_t reserved_90;
-    uint32_t reserved_94;
-    uint32_t reserved_98;
-    uint32_t reserved_9c;
-    uint32_t reserved_a0;
-    uint32_t reserved_a4;
-    uint32_t reserved_a8;
-    uint32_t reserved_ac;
-    uint32_t reserved_b0;
-    uint32_t reserved_b4;
-    uint32_t reserved_b8;
-    uint32_t reserved_bc;
-    uint32_t reserved_c0;
-    uint32_t reserved_c4;
-    uint32_t reserved_c8;
-    uint32_t reserved_cc;
-    uint32_t reserved_d0;
-    uint32_t reserved_d4;
-    uint32_t reserved_d8;
-    uint32_t reserved_dc;
-    uint32_t reserved_e0;
-    uint32_t reserved_e4;
-    uint32_t reserved_e8;
-    uint32_t reserved_ec;
-    uint32_t reserved_f0;
-    uint32_t reserved_f4;
-    uint32_t reserved_f8;
-    uint32_t date;                               /**/
-} mcp_dev_t;
-extern mcp_dev_t MCP;
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* _SOC_MCP_STRUCT_H_ */

+ 1 - 0
components/soc/src/esp32s2/CMakeLists.txt

@@ -1,5 +1,6 @@
 set(srcs "adc_hal.c"
         "brownout_hal.c"
+        "cp_dma_hal.c"
         "rtc_clk.c"
         "rtc_clk_init.c"
         "rtc_init.c"

+ 218 - 0
components/soc/src/esp32s2/cp_dma_hal.c

@@ -0,0 +1,218 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "hal/cp_dma_hal.h"
+#include "hal/cp_dma_ll.h"
+#include "soc/cp_dma_caps.h"
+
+#define MCP_DESCRIPTOR_BUFFER_OWNER_DMA (1)
+#define MCP_DESCRIPTOR_BUFFER_OWNER_CPU (0)
+
+void cp_dma_hal_init(cp_dma_hal_context_t *hal, cp_dma_descriptor_t *tx_descriptors[], uint32_t tx_desc_num, cp_dma_descriptor_t *rx_descriptors[], uint32_t rx_desc_num)
+{
+    hal->dev = &CP_DMA;
+    cp_dma_ll_enable_clock(hal->dev, true);
+    cp_dma_ll_reset_in_link(hal->dev);
+    cp_dma_ll_reset_out_link(hal->dev);
+    cp_dma_ll_reset_cmd_fifo(hal->dev);
+    cp_dma_ll_reset_fifo(hal->dev);
+    cp_dma_ll_enable_intr(hal->dev, UINT32_MAX, false);
+    cp_dma_ll_clear_intr_status(hal->dev, UINT32_MAX);
+    cp_dma_ll_enable_owner_check(hal->dev, true);
+
+    // circle TX descriptors
+    for (int i = 0; i < tx_desc_num; i++) {
+        tx_descriptors[i]->dw0.owner = MCP_DESCRIPTOR_BUFFER_OWNER_CPU;
+        tx_descriptors[i]->next = tx_descriptors[i + 1];
+    }
+    tx_descriptors[tx_desc_num - 1]->next = tx_descriptors[0];
+
+    // circle RX descriptors
+    for (int i = 0; i < rx_desc_num; i++) {
+        rx_descriptors[i]->dw0.owner = MCP_DESCRIPTOR_BUFFER_OWNER_CPU;
+        rx_descriptors[i]->next = rx_descriptors[i + 1];
+    }
+    rx_descriptors[rx_desc_num - 1]->next = rx_descriptors[0];
+
+    // set the start of each descriptor chain
+    hal->tx_desc = tx_descriptors[0];
+    hal->rx_desc = rx_descriptors[0];
+
+    /* set base address of the first descriptor */
+    cp_dma_ll_tx_set_descriptor_base_addr(hal->dev, (uint32_t)hal->tx_desc);
+    cp_dma_ll_rx_set_descriptor_base_addr(hal->dev, (uint32_t)hal->rx_desc);
+
+    hal->next_rx_desc_to_check = rx_descriptors[0];
+}
+
+void cp_dma_hal_deinit(cp_dma_hal_context_t *hal)
+{
+    cp_dma_ll_enable_clock(hal->dev, false);
+    hal->dev = NULL;
+    hal->tx_desc = NULL;
+    hal->rx_desc = NULL;
+}
+
+void cp_dma_hal_start(cp_dma_hal_context_t *hal)
+{
+    // enable DMA engine
+    cp_dma_ll_start_rx(hal->dev, true);
+    cp_dma_ll_start_tx(hal->dev, true);
+    // enable RX EOF interrupt
+    cp_dma_ll_enable_intr(hal->dev, CP_DMA_LL_EVENT_RX_EOF, true);
+}
+
+void cp_dma_hal_stop(cp_dma_hal_context_t *hal)
+{
+    // disable interrupt
+    cp_dma_ll_enable_intr(hal->dev, CP_DMA_LL_EVENT_RX_EOF, false);
+    cp_dma_ll_enable_intr(hal->dev, CP_DMA_LL_EVENT_TX_EOF, false);
+
+    // disable DMA
+    cp_dma_ll_start_rx(hal->dev, false);
+    cp_dma_ll_start_tx(hal->dev, false);
+}
+
+uint32_t cp_dma_hal_get_intr_status(cp_dma_hal_context_t *hal)
+{
+    return cp_dma_ll_get_intr_status(hal->dev);
+}
+
+void cp_dma_hal_clear_intr_status(cp_dma_hal_context_t *hal, uint32_t mask)
+{
+    cp_dma_ll_clear_intr_status(hal->dev, mask);
+}
+
+int cp_dma_hal_prepare_transmit(cp_dma_hal_context_t *hal, void *buffer, size_t len, cp_dma_descriptor_t **start_desc, cp_dma_descriptor_t **end_desc)
+{
+    uint32_t prepared_length = 0;
+    uint8_t *buf = (uint8_t *)buffer;
+    cp_dma_descriptor_t *desc = hal->tx_desc; // descriptor iterator
+    cp_dma_descriptor_t *start = desc;
+    cp_dma_descriptor_t *end = desc;
+
+    while (len > SOC_CP_DMA_MAX_BUFFER_SIZE) {
+        if (desc->dw0.owner != MCP_DESCRIPTOR_BUFFER_OWNER_DMA) {
+            desc->dw0.eof = 0; // not the end of the transaction
+            desc->dw0.size = SOC_CP_DMA_MAX_BUFFER_SIZE;
+            desc->dw0.length = SOC_CP_DMA_MAX_BUFFER_SIZE;
+            desc->buffer = &buf[prepared_length];
+            desc = desc->next; // move to next descriptor
+            prepared_length += SOC_CP_DMA_MAX_BUFFER_SIZE;
+            len -= SOC_CP_DMA_MAX_BUFFER_SIZE;
+        } else {
+            // out of TX descriptors
+            goto _exit;
+        }
+    }
+    if (len) {
+        if (desc->dw0.owner != MCP_DESCRIPTOR_BUFFER_OWNER_DMA) {
+            end = desc; // the last descriptor used
+            desc->dw0.eof = 1; // end of the transaction
+            desc->dw0.size = len;
+            desc->dw0.length = len;
+            desc->buffer = &buf[prepared_length];
+            desc = desc->next; // move to next descriptor
+            prepared_length += len;
+        } else {
+            // out of TX descriptors
+            goto _exit;
+        }
+    }
+
+    *start_desc = start;
+    *end_desc = end;
+_exit:
+    return prepared_length;
+}
+
+int cp_dma_hal_prepare_receive(cp_dma_hal_context_t *hal, void *buffer, size_t size, cp_dma_descriptor_t **start_desc, cp_dma_descriptor_t **end_desc)
+{
+    uint32_t prepared_length = 0;
+    uint8_t *buf = (uint8_t *)buffer;
+    cp_dma_descriptor_t *desc = hal->rx_desc; // descriptor iterator
+    cp_dma_descriptor_t *start = desc;
+    cp_dma_descriptor_t *end = desc;
+
+    while (size > SOC_CP_DMA_MAX_BUFFER_SIZE) {
+        if (desc->dw0.owner != MCP_DESCRIPTOR_BUFFER_OWNER_DMA) {
+            desc->dw0.size = SOC_CP_DMA_MAX_BUFFER_SIZE;
+            desc->buffer = &buf[prepared_length];
+            desc = desc->next; // move to next descriptor
+            prepared_length += SOC_CP_DMA_MAX_BUFFER_SIZE;
+            size -= SOC_CP_DMA_MAX_BUFFER_SIZE;
+        } else {
+            // out of TX descriptors
+            goto _exit;
+        }
+    }
+    if (size) {
+        if (desc->dw0.owner != MCP_DESCRIPTOR_BUFFER_OWNER_DMA) {
+            end = desc; // the last descriptor used
+            desc->dw0.size = size;
+            desc->buffer = &buf[prepared_length];
+            desc = desc->next; // move to next descriptor
+            prepared_length += size;
+        } else {
+            // out of TX descriptors
+            goto _exit;
+        }
+    }
+
+    *start_desc = start;
+    *end_desc = end;
+_exit:
+    return prepared_length;
+}
+
+void cp_dma_hal_restart_tx(cp_dma_hal_context_t *hal, cp_dma_descriptor_t *start_desc, cp_dma_descriptor_t *end_desc)
+{
+    // Give descriptor owner to DMA
+    cp_dma_descriptor_t *desc = start_desc;
+    while (desc != end_desc) {
+        desc->dw0.owner = MCP_DESCRIPTOR_BUFFER_OWNER_DMA;
+        desc = desc->next;
+    }
+    desc->dw0.owner = MCP_DESCRIPTOR_BUFFER_OWNER_DMA;
+    hal->tx_desc = end_desc->next; // update the next available descriptor in HAL
+    cp_dma_ll_restart_tx(hal->dev);
+}
+
+void cp_dma_hal_restart_rx(cp_dma_hal_context_t *hal, cp_dma_descriptor_t *start_desc, cp_dma_descriptor_t *end_desc)
+{
+    // Give descriptor owner to DMA
+    cp_dma_descriptor_t *desc = start_desc;
+    while (desc != end_desc) {
+        desc->dw0.owner = MCP_DESCRIPTOR_BUFFER_OWNER_DMA;
+        desc = desc->next;
+    }
+    desc->dw0.owner = MCP_DESCRIPTOR_BUFFER_OWNER_DMA;
+    hal->rx_desc = end_desc->next; // update the next available descriptor in HAL
+    cp_dma_ll_restart_rx(hal->dev);
+}
+
+bool cp_dma_hal_get_next_rx_descriptor(cp_dma_hal_context_t *hal, cp_dma_descriptor_t *eof_desc, cp_dma_descriptor_t **next_desc)
+{
+    cp_dma_descriptor_t *next = hal->next_rx_desc_to_check;
+    // additional check, to avoid potential interrupt got triggered by mistake
+    if (next->dw0.owner == MCP_DESCRIPTOR_BUFFER_OWNER_CPU) {
+        hal->next_rx_desc_to_check = hal->next_rx_desc_to_check->next;
+        *next_desc = next;
+        // return if we need to continue
+        return eof_desc == next ? false : true;
+    } else {
+        *next_desc = NULL;
+        return false;
+    }
+}

+ 155 - 0
components/soc/src/esp32s2/include/hal/cp_dma_hal.h

@@ -0,0 +1,155 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*******************************************************************************
+ * NOTICE
+ * The HAL is not public api, don't use in application code.
+ * See readme.md in soc/README.md
+ ******************************************************************************/
+
+// CP DMA HAL usages:
+// 1. Initialize HAL layer by cp_dma_hal_init, pass in the allocated descriptors for TX and RX
+// 2. Enable DMA and interrupt by cp_dma_hal_start
+// 3. Prepare descriptors used for TX and RX
+// 4. Restart the DMA engine in case it's not in working
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdbool.h>
+#include "esp_attr.h"
+#include "soc/cp_dma_struct.h"
+
+typedef struct cp_dma_descriptor {
+    struct {
+        uint32_t size : 12;         /*!< buffer size */
+        uint32_t length : 12;       /*!< specify number of valid bytes in the buffer */
+        uint32_t reversed24_27 : 4; /*!< reserved */
+        uint32_t err : 1;           /*!< specify whether a received buffer contains error */
+        uint32_t reserved29 : 1;    /*!< reserved */
+        uint32_t eof : 1;           /*!< if this dma link is the last one, you shoule set this bit 1 */
+        uint32_t owner : 1;         /*!< specify the owner of buffer that this descriptor points to, 1=DMA, 0=CPU. DMA will clear it after use. */
+    } dw0;                          /*!< descriptor word 0 */
+    void *buffer;                   /*!< pointer to the buffer */
+    struct cp_dma_descriptor *next; /*!< pointer to the next descriptor or NULL if this descriptor is the last one */
+} cp_dma_descriptor_t;
+
+_Static_assert(sizeof(cp_dma_descriptor_t) == 12, "cp_dma_descriptor_t should occupy 12 bytes in memory");
+
+/**
+ * @brief HAL context
+ *
+ * @note `tx_desc` and `rx_desc` are internal state of the HAL, will be modified during the operations.
+ * Upper layer of HAL should keep the buffer address themselves and make sure the buffers are freed when the HAL is no longer used.
+ *
+ */
+typedef struct {
+    cp_dma_dev_t *dev;
+    cp_dma_descriptor_t *tx_desc;
+    cp_dma_descriptor_t *rx_desc;
+    cp_dma_descriptor_t *next_rx_desc_to_check;
+} cp_dma_hal_context_t;
+
+/**
+ * @brief Initialize HAL layer context
+ *
+ * @param hal HAL layer context, memroy should be allocated at driver layer
+ * @param tx_descriptors out link descriptor pool
+ * @param tx_desc_num number of out link descriptors
+ * @param rx_descriptors in line descriptor pool
+ * @param rx_desc_num  number of in link descriptors
+ */
+void cp_dma_hal_init(cp_dma_hal_context_t *hal, cp_dma_descriptor_t *tx_descriptors[], uint32_t tx_desc_num, cp_dma_descriptor_t *rx_descriptors[], uint32_t rx_desc_num);
+
+/**
+ * @brief Deinitialize HAL layer context
+ */
+void cp_dma_hal_deinit(cp_dma_hal_context_t *hal);
+
+/**
+ * @brief Start mem2mem DMA state machine
+ */
+void cp_dma_hal_start(cp_dma_hal_context_t *hal);
+
+/**
+ * @brief Stop mem2mem DMA state machine
+ */
+void cp_dma_hal_stop(cp_dma_hal_context_t *hal);
+
+/**
+ * @brief Get interrupt status word
+ *
+ * @return uint32_t Interrupt status
+ */
+uint32_t cp_dma_hal_get_intr_status(cp_dma_hal_context_t *hal) IRAM_ATTR;
+
+/**
+ * @brief Clear interrupt mask
+ *
+ * @param mask interrupt mask
+ */
+void cp_dma_hal_clear_intr_status(cp_dma_hal_context_t *hal, uint32_t mask) IRAM_ATTR;
+
+/**
+ * @brief Get next RX descriptor that needs recycling
+ *
+ * @param eof_desc EOF descriptor for this iteration
+ * @param[out] next_desc Next descriptor needs to check
+ * @return Whether to continue
+ */
+bool cp_dma_hal_get_next_rx_descriptor(cp_dma_hal_context_t *hal, cp_dma_descriptor_t *eof_desc, cp_dma_descriptor_t **next_desc);
+
+/**
+ * @brief Prepare buffer to be transmitted
+ *
+ * @param hal HAL layer context
+ * @param buffer buffer address
+ * @param len buffer size
+ * @param[out] start_desc The first descriptor that carry the TX transaction
+ * @param[out] end_desc The last descriptor that carry the TX transaction
+ * @return Number of bytes has been parepared to transmit
+ */
+int cp_dma_hal_prepare_transmit(cp_dma_hal_context_t *hal, void *buffer, size_t len, cp_dma_descriptor_t **start_desc, cp_dma_descriptor_t **end_desc);
+
+/**
+ * @brief Prepare buffer to receive
+ *
+ * @param hal HAL layer context
+ * @param buffer buffer address
+ * @param size buffer size
+ * @param[out] start_desc The first descriptor that carries the RX transaction
+ * @param[out] end_desc The last descriptor that carries the RX transaction
+ * @return Number of bytes has been parepared to receive
+ */
+int cp_dma_hal_prepare_receive(cp_dma_hal_context_t *hal, void *buffer, size_t size, cp_dma_descriptor_t **start_desc, cp_dma_descriptor_t **end_desc);
+
+/**@{*/
+/**
+ * @brief Give the owner of descriptors between [start_desc, end_desc] to DMA, and restart DMA HW engine
+ *
+ * @param hal HAL layer context
+ * @param start_desc The first descriptor that carries one transaction
+ * @param end_desc The last descriptor that carries one transaction
+ */
+void cp_dma_hal_restart_tx(cp_dma_hal_context_t *hal, cp_dma_descriptor_t *start_desc, cp_dma_descriptor_t *end_desc);
+void cp_dma_hal_restart_rx(cp_dma_hal_context_t *hal, cp_dma_descriptor_t *start_desc, cp_dma_descriptor_t *end_desc);
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif

+ 159 - 0
components/soc/src/esp32s2/include/hal/cp_dma_ll.h

@@ -0,0 +1,159 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "soc/cp_dma_struct.h"
+
+#define CP_DMA_LL_EVENT_RX_DONE       (1 << 0)
+#define CP_DMA_LL_EVENT_RX_EOF        (1 << 1)
+#define CP_DMA_LL_EVENT_TX_DONE       (1 << 2)
+#define CP_DMA_LL_EVENT_TX_EOF        (1 << 3)
+#define CP_DMA_LL_EVENT_RX_DESC_ERR   (1 << 4)
+#define CP_DMA_LL_EVENT_TX_DESC_ERR   (1 << 5)
+#define CP_DMA_LL_EVENT_RX_DESC_EMPTY (1 << 6)
+#define CP_DMA_LL_EVENT_TX_TOTAL_EOF  (1 << 7)
+#define CP_DMA_LL_EVENT_ALL           (0xFF)
+
+/**
+ * Copy DMA firstly reads data to be transferred from internal RAM,
+ * stores the data into DMA FIFO via an outlink,
+ * and then writes the data to the destination internal RAM via an inlink.
+ */
+
+static inline void cp_dma_ll_reset_in_link(cp_dma_dev_t *dev)
+{
+    dev->dma_conf.dma_in_rst = 1;
+    dev->dma_conf.dma_in_rst = 0;
+}
+
+static inline void cp_dma_ll_reset_out_link(cp_dma_dev_t *dev)
+{
+    dev->dma_conf.dma_out_rst = 1;
+    dev->dma_conf.dma_out_rst = 0;
+}
+
+static inline void cp_dma_ll_reset_fifo(cp_dma_dev_t *dev)
+{
+    dev->dma_conf.dma_fifo_rst = 1;
+    dev->dma_conf.dma_fifo_rst = 0;
+}
+
+static inline void cp_dma_ll_reset_cmd_fifo(cp_dma_dev_t *dev)
+{
+    dev->dma_conf.dma_cmdfifo_rst = 1;
+    dev->dma_conf.dma_cmdfifo_rst = 0;
+}
+
+static inline void cp_dma_ll_enable_owner_check(cp_dma_dev_t *dev, bool enable)
+{
+    dev->dma_conf.dma_check_owner = enable;
+    dev->dma_conf.dma_out_auto_wrback = 1;
+    dev->dma_conf.dma_out_owner = 0;
+    dev->dma_conf.dma_in_owner = 0;
+}
+
+static inline void cp_dma_ll_enable_clock(cp_dma_dev_t *dev, bool enable)
+{
+    dev->dma_conf.dma_clk_en = enable;
+}
+
+static inline void cp_dma_ll_enable_intr(cp_dma_dev_t *dev, uint32_t mask, bool enable)
+{
+    if (enable) {
+        dev->dma_int_ena.val |= mask;
+    } else {
+        dev->dma_int_ena.val &= ~mask;
+    }
+}
+
+static inline __attribute__((always_inline)) uint32_t cp_dma_ll_get_intr_status(cp_dma_dev_t *dev)
+{
+    return dev->dma_int_st.val;
+}
+
+static inline __attribute__((always_inline)) void cp_dma_ll_clear_intr_status(cp_dma_dev_t *dev, uint32_t mask)
+{
+    dev->dma_int_clr.val = mask;
+}
+
+static inline void cp_dma_ll_tx_set_descriptor_base_addr(cp_dma_dev_t *dev, uint32_t address)
+{
+    dev->dma_out_link.dma_outlink_addr = address;
+}
+
+static inline void cp_dma_ll_rx_set_descriptor_base_addr(cp_dma_dev_t *dev, uint32_t address)
+{
+    dev->dma_in_link.dma_inlink_addr = address;
+}
+
+static inline void cp_dma_ll_start_tx(cp_dma_dev_t *dev, bool enable)
+{
+    if (enable) {
+        dev->dma_out_link.dma_outlink_start = 1; // cleared automatically by HW
+    } else {
+        dev->dma_out_link.dma_outlink_stop = 1; // cleared automatically by HW
+    }
+}
+
+static inline void cp_dma_ll_start_rx(cp_dma_dev_t *dev, bool enable)
+{
+    if (enable) {
+        dev->dma_in_link.dma_inlink_start = 1; // cleared automatically by HW
+    } else {
+        dev->dma_in_link.dma_inlink_stop = 1; // cleared automatically by HW
+    }
+}
+
+static inline void cp_dma_ll_restart_tx(cp_dma_dev_t *dev)
+{
+    dev->dma_out_link.dma_outlink_restart = 1; // cleared automatically by HW
+}
+
+static inline void cp_dma_ll_restart_rx(cp_dma_dev_t *dev)
+{
+    dev->dma_in_link.dma_inlink_restart = 1; // cleared automatically by HW
+}
+
+// get the address of last rx descriptor
+static inline uint32_t cp_dma_ll_get_rx_eof_descriptor_address(cp_dma_dev_t *dev)
+{
+    return dev->dma_in_eof_des_addr.dma_in_suc_eof_des_addr;
+}
+
+// get the address of last tx descriptor
+static inline uint32_t cp_dma_ll_get_tx_eof_descriptor_address(cp_dma_dev_t *dev)
+{
+    return dev->dma_out_eof_des_addr.dma_out_eof_des_addr;
+}
+
+static inline uint32_t cp_dma_ll_get_tx_status(cp_dma_dev_t *dev)
+{
+    return dev->dma_out_st.val;
+}
+
+static inline uint32_t cp_dma_ll_get_rx_status(cp_dma_dev_t *dev)
+{
+    return dev->dma_in_st.val;
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 1 - 0
docs/Doxyfile

@@ -110,6 +110,7 @@ INPUT = \
     $(IDF_PATH)/components/driver/include/driver/adc_common.h \
     $(IDF_PATH)/components/driver/include/driver/uart.h \
     $(IDF_PATH)/components/esp_adc_cal/include/esp_adc_cal.h \
+    $(IDF_PATH)/components/esp32s2/include/cp_dma.h \
     $(IDF_PATH)/components/esp32s2/include/esp_hmac.h \
     $(IDF_PATH)/components/esp32s2/include/esp_ds.h \
     $(IDF_PATH)/components/soc/include/hal/rmt_types.h \

+ 2 - 2
docs/conf_common.py

@@ -166,8 +166,8 @@ ESP32S2_DOCS = ['esp32s2.rst',
                 'api-reference/peripherals/hmac.rst',
                 'api-reference/peripherals/ds.rst',
                 'api-reference/peripherals/spi_slave_hd.rst',
-                'api-reference/peripherals/temp_sensor.rst'
-                '']
+                'api-reference/peripherals/temp_sensor.rst',
+                'api-reference/system/async_memcpy.rst']
 
 # format: {tag needed to include: documents to included}, tags are parsed from sdkconfig and peripheral_caps.h headers
 conditional_include_dict = {'SOC_BT_SUPPORTED':BT_DOCS,

+ 80 - 0
docs/en/api-reference/system/async_memcpy.rst

@@ -0,0 +1,80 @@
+The Async memcpy API
+====================
+
+Overview
+--------
+
+ESP32-S2 features a dedicated DMA (a.k.a `CP_DMA`) which aims to offload internal memory copy operations from the CPU. When using 160MHz CPU, copying 4KB of data via memcpy() takes 14us, copying via cp_dma_memcpy can complete in 7us.
+
+The async memcpy API wraps all DMA configurations and operations, the signature of :cpp:func:`cp_dma_memcpy` is almost the same to the standard libc one.
+
+Thanks to the benefit of the DMA, we don't have to wait for each memory copy to be done before we issue another memcpy request. By providing a user defined callback, it's still possible to know when memcpy has finished.
+
+.. note::
+    Memory copy with external PSRAM is not supported on ESP32-S2, :cpp:func:`cp_dma_memcpy` will abort returning an error if memory address does not reside in SRAM.
+
+Configure and Install driver
+----------------------------
+
+:cpp:func:`cp_dma_driver_install` is used to install `CP_DMA` driver with user's configuration. Please note that async memcpy has to be called with the handle returned by :cpp:func:`cp_dma_driver_install`.
+
+Driver configuration is described in :cpp:type:`cp_dma_config_t`:
+:cpp:member:`max_out_stream` and :cpp:member:`max_in_stream`: You can increase/decrease the number if you want to support more/less memcpy operations to be pending in background.
+:cpp:member:`flags`: Control special behavior of `CP_DMA`. If `CP_DMA_FLAGS_WORK_WITH_CACHE_DISABLE` is set in the flags, then `CP_DMA` driver can work even when cache is disabled. Please note, it would increase the consumption of SRAM.
+
+:c:macro:`CP_DMA_DEFAULT_CONFIG` provides a default configuration, which specifies the maximum data streams used by underlay DMA engine to 8.
+
+.. highlight:: c
+
+::
+
+    cp_dma_config_t config = CP_DMA_DEFAULT_CONFIG();
+    config.max_in_stream = 4; // update the maximum data stream supported by DMA
+    config.max_out_stream = 4;
+    config.flags = CP_DMA_FLAGS_WORK_WITH_CACHE_DISABLE; // the driver can work even when cache is disabled
+    cp_dma_driver_t driver = NULL;
+    ESP_ERROR_CHECK(cp_dma_driver_install(&config, &driver)); // install driver, return driver handle
+
+Send memory copy request
+------------------------
+
+:cpp:func:`cp_dma_memcpy` is the API to send memory copy request to DMA engine. It must be called after `CP_DMA` driver is installed successfully. This API is thread safe, so it can be called from different tasks.
+
+Different from the libc version of `memcpy`, user can pass a callback to :cpp:func:`cp_dma_memcpy` when it's necessary. The callback is executed in the ISR context, make sure you won't violate the the restriction applied to ISR handler.
+
+Besides that, the callback function should reside in IRAM space by applying `IRAM_ATTR` attribute. The prototype of the callback function is :cpp:type:`cp_dma_isr_cb_t`, please note that, the callback function should return true if there's a high priority task woken up due to any operations done in the callback.
+
+.. highlight:: c
+
+::
+
+    Semphr_Handle_t semphr; //already initialized in somewhere
+
+    // Callback implementation, running in ISR context
+    static IRAM_ATTR bool memcpy_cb(cp_dma_driver_t drv_hdl, cp_dma_event_t *event, void *cb_args)
+    {
+        BaseType_t high_task_wakeup = pdFALSE;
+        switch (event->id) {
+        case CP_DMA_EVENT_M2M_DONE:
+            SemphrGiveInISR(semphr, &high_task_wakeup); // high_task_wakeup set to pdTRUE if some high priority task unblocked
+            break;
+        default:
+            break;
+        }
+        return high_task_wakeup == pdTRUE;
+    }
+
+    // Called from user's context
+    ESP_ERROR_CHECK(cp_dma_memcpy(driver, to, from, copy_len, memcpy_cb, cb_args));
+    //Do something else here
+    SemphrTake(semphr, ...); //wait until the buffer copy is done
+
+Uninstall driver (optional)
+---------------------------
+
+:cpp:func:`cp_dma_driver_uninstall` is used to uninstall `CP_DMA` driver. It's not necessary to uninstall the driver after each memcpy operation. If your application won't use `CP_DMA` anymore, then this API can recycle the memory used by driver.
+
+API Reference
+-------------
+
+.. include-build-file:: inc/cp_dma.inc

+ 1 - 0
docs/en/api-reference/system/index.rst

@@ -6,6 +6,7 @@ System API
 
     App image format <app_image_format>
     Application Level Tracing <app_trace>
+    :esp32s2: Async Memory Copy <async_memcpy>
     Console Component <console>
     eFuse Manager <efuse>
     Error Codes and Helper Functions <esp_err>

+ 1 - 0
docs/zh_CN/api-reference/system/async_memcpy.rst

@@ -0,0 +1 @@
+.. include:: ../../../en/api-reference/system/async_memcpy.rst