Merge branch 'feature/dma_memcpy' into 'master'

esp32s2: async memcpy

Closes IDF-1573

See merge request espressif/esp-idf!8436
This commit is contained in:
Michael (XIAO Xufeng) 2020-08-06 11:32:43 +08:00
commit bfd71ae7ec
19 changed files with 2511 additions and 746 deletions

View File

@ -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
components/esp32s2/cp_dma.c Normal file
View File

@ -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();
}
}

View File

@ -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

View File

@ -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 );

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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"

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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 \

View File

@ -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,

View File

@ -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

View File

@ -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>

View File

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