mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'feat/gdma_set_burst_size' into 'master'
feat(gdma): return alignment constraints required by the GDMA channel Closes IDF-9848 See merge request espressif/esp-idf!30748
This commit is contained in:
@@ -240,12 +240,13 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch
|
||||
gdma_connect(dma_ctx->rx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3));
|
||||
}
|
||||
#endif
|
||||
gdma_transfer_ability_t ability = {
|
||||
.psram_trans_align = 0, // fall back to use the same size of the psram data cache line size
|
||||
.sram_trans_align = 4,
|
||||
// TODO: add support to allow SPI transfer PSRAM buffer
|
||||
gdma_transfer_config_t trans_cfg = {
|
||||
.max_data_burst_size = 16,
|
||||
.access_ext_mem = false,
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(gdma_set_transfer_ability(dma_ctx->tx_dma_chan, &ability), SPI_TAG, "set gdma tx transfer ability failed");
|
||||
ESP_RETURN_ON_ERROR(gdma_set_transfer_ability(dma_ctx->rx_dma_chan, &ability), SPI_TAG, "set gdma rx transfer ability failed");
|
||||
ESP_RETURN_ON_ERROR(gdma_config_transfer(dma_ctx->tx_dma_chan, &trans_cfg), SPI_TAG, "config gdma tx transfer failed");
|
||||
ESP_RETURN_ON_ERROR(gdma_config_transfer(dma_ctx->rx_dma_chan, &trans_cfg), SPI_TAG, "config gdma rx transfer failed");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -68,13 +68,16 @@ if(NOT BOOTLOADER_BUILD)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_GDMA_SUPPORTED)
|
||||
list(APPEND srcs "dma/gdma.c")
|
||||
list(APPEND srcs "dma/gdma.c" "deprecated/gdma_legacy.c")
|
||||
if(CONFIG_SOC_GDMA_SUPPORT_SLEEP_RETENTION)
|
||||
list(APPEND srcs "dma/gdma_sleep_retention.c")
|
||||
endif()
|
||||
if(CONFIG_SOC_GDMA_SUPPORT_ETM)
|
||||
list(APPEND srcs "dma/gdma_etm.c")
|
||||
endif()
|
||||
if(CONFIG_SOC_GDMA_SUPPORT_CRC)
|
||||
list(APPEND srcs "dma/gdma_crc.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_GP_LDO_SUPPORTED)
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "../dma/gdma_priv.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
|
||||
static const char *TAG = "gdma";
|
||||
|
||||
esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(dma_chan && ability, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
gdma_pair_t *pair = dma_chan->pair;
|
||||
gdma_group_t *group = pair->group;
|
||||
gdma_hal_context_t *hal = &group->hal;
|
||||
|
||||
size_t int_mem_alignment = ability->sram_trans_align;
|
||||
size_t ext_mem_alignment = ability->psram_trans_align;
|
||||
// alignment should be 2^n
|
||||
ESP_RETURN_ON_FALSE((int_mem_alignment & (int_mem_alignment - 1)) == 0, ESP_ERR_INVALID_ARG,
|
||||
TAG, "invalid sram alignment: %zu", int_mem_alignment);
|
||||
|
||||
uint32_t ext_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
|
||||
if (ext_mem_alignment == 0) {
|
||||
// fall back to use the same size of the psram data cache line size
|
||||
ext_mem_alignment = ext_mem_cache_line_size;
|
||||
}
|
||||
if ((ext_mem_cache_line_size > 0) && (ext_mem_alignment > ext_mem_cache_line_size)) {
|
||||
ESP_RETURN_ON_FALSE(((ext_mem_alignment % ext_mem_cache_line_size) == 0), ESP_ERR_INVALID_ARG,
|
||||
TAG, "ext_mem_alignment(%d) should be multiple of the ext_mem_cache_line_size(%"PRIu32")",
|
||||
ext_mem_alignment, ext_mem_cache_line_size);
|
||||
}
|
||||
|
||||
// if the DMA can't access the PSRAM, this HAL function is no-op
|
||||
gdma_hal_set_burst_size(hal, pair->pair_id, dma_chan->direction, ext_mem_alignment);
|
||||
|
||||
// TX channel can always enable burst mode, no matter data alignment
|
||||
bool en_burst = true;
|
||||
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
// RX channel burst mode depends on specific data alignment
|
||||
en_burst = int_mem_alignment >= 4;
|
||||
}
|
||||
gdma_hal_enable_burst(hal, pair->pair_id, dma_chan->direction, en_burst, en_burst);
|
||||
|
||||
dma_chan->int_mem_alignment = int_mem_alignment;
|
||||
dma_chan->ext_mem_alignment = ext_mem_alignment;
|
||||
ESP_LOGD(TAG, "%s channel (%d,%d), (%u:%u) bytes aligned, burst %s", dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX ? "tx" : "rx",
|
||||
group->group_id, pair->pair_id, int_mem_alignment, ext_mem_alignment, en_burst ? "enabled" : "disabled");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -48,7 +48,6 @@ typedef struct async_memcpy_transaction_t {
|
||||
/// @note - Number of transaction objects are determined by the backlog parameter
|
||||
typedef struct {
|
||||
async_memcpy_context_t parent; // Parent IO interface
|
||||
size_t sram_trans_align; // DMA transfer alignment (both in size and address) for SRAM memory
|
||||
size_t max_single_dma_buffer; // max DMA buffer size by a single descriptor
|
||||
cp_dma_hal_context_t hal; // CPDMA hal
|
||||
intr_handle_t intr; // CPDMA interrupt handle
|
||||
@@ -90,7 +89,7 @@ esp_err_t esp_async_memcpy_install_cpdma(const async_memcpy_config_t *config, as
|
||||
uint32_t trans_queue_len = config->backlog ? config->backlog : DEFAULT_TRANSACTION_QUEUE_LENGTH;
|
||||
// allocate memory for transaction pool, aligned to 4 because the trans->eof_node requires that alignment
|
||||
mcp_dma->transaction_pool = heap_caps_aligned_calloc(4, trans_queue_len, sizeof(async_memcpy_transaction_t),
|
||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
ESP_GOTO_ON_FALSE(mcp_dma->transaction_pool, ESP_ERR_NO_MEM, err, TAG, "no mem for transaction pool");
|
||||
|
||||
// Init hal context
|
||||
@@ -111,8 +110,7 @@ esp_err_t esp_async_memcpy_install_cpdma(const async_memcpy_config_t *config, as
|
||||
// initialize other members
|
||||
portMUX_INITIALIZE(&mcp_dma->spin_lock);
|
||||
atomic_init(&mcp_dma->fsm, MCP_FSM_IDLE);
|
||||
mcp_dma->sram_trans_align = config->sram_trans_align;
|
||||
size_t trans_align = config->sram_trans_align;
|
||||
size_t trans_align = config->dma_burst_size;
|
||||
mcp_dma->max_single_dma_buffer = trans_align ? ALIGN_DOWN(DMA_DESCRIPTOR_BUFFER_MAX_SIZE, trans_align) : DMA_DESCRIPTOR_BUFFER_MAX_SIZE;
|
||||
mcp_dma->parent.del = mcp_cpdma_del;
|
||||
mcp_dma->parent.memcpy = mcp_cpdma_memcpy;
|
||||
@@ -240,12 +238,6 @@ static esp_err_t mcp_cpdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *
|
||||
esp_err_t ret = ESP_OK;
|
||||
async_memcpy_cpdma_context_t *mcp_dma = __containerof(ctx, async_memcpy_cpdma_context_t, parent);
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_internal(src) && esp_ptr_internal(dst), ESP_ERR_INVALID_ARG, TAG, "CP_DMA can only access SRAM");
|
||||
// alignment check
|
||||
if (mcp_dma->sram_trans_align) {
|
||||
ESP_RETURN_ON_FALSE((((intptr_t)dst & (mcp_dma->sram_trans_align - 1)) == 0), ESP_ERR_INVALID_ARG, TAG, "buffer address not aligned: %p -> %p", src, dst);
|
||||
ESP_RETURN_ON_FALSE(((n & (mcp_dma->sram_trans_align - 1)) == 0), ESP_ERR_INVALID_ARG, TAG,
|
||||
"copy size should align to %d bytes", mcp_dma->sram_trans_align);
|
||||
}
|
||||
async_memcpy_transaction_t *trans = NULL;
|
||||
// pick one transaction node from idle queue
|
||||
trans = try_pop_trans_from_idle_queue(mcp_dma);
|
||||
@@ -257,12 +249,12 @@ static esp_err_t mcp_cpdma_memcpy(async_memcpy_context_t *ctx, void *dst, void *
|
||||
uint32_t num_desc_per_path = (n + max_single_dma_buffer - 1) / max_single_dma_buffer;
|
||||
// allocate DMA descriptors, descriptors need a strict alignment
|
||||
trans->tx_desc_link = heap_caps_aligned_calloc(4, num_desc_per_path, sizeof(dma_descriptor_align4_t),
|
||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
ESP_GOTO_ON_FALSE(trans->tx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors");
|
||||
// don't have to allocate the EOF descriptor, we will use trans->eof_node as the RX EOF descriptor
|
||||
if (num_desc_per_path > 1) {
|
||||
trans->rx_desc_link = heap_caps_aligned_calloc(4, num_desc_per_path - 1, sizeof(dma_descriptor_align4_t),
|
||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA);
|
||||
ESP_GOTO_ON_FALSE(trans->rx_desc_link, ESP_ERR_NO_MEM, err, TAG, "no mem for DMA descriptors");
|
||||
} else {
|
||||
// small copy buffer, use the trans->eof_node is sufficient
|
||||
|
||||
@@ -69,8 +69,10 @@ typedef struct async_memcpy_transaction_t {
|
||||
typedef struct {
|
||||
async_memcpy_context_t parent; // Parent IO interface
|
||||
size_t descriptor_align; // DMA descriptor alignment
|
||||
size_t sram_trans_align; // DMA buffer alignment (both in size and address) for SRAM memory
|
||||
size_t psram_trans_align; // DMA buffer alignment (both in size and address) for PSRAM memory
|
||||
size_t rx_int_mem_alignment; // DMA buffer alignment (both in size and address) for internal RX memory
|
||||
size_t rx_ext_mem_alignment; // DMA buffer alignment (both in size and address) for external RX memory
|
||||
size_t tx_int_mem_alignment; // DMA buffer alignment (both in size and address) for internal TX memory
|
||||
size_t tx_ext_mem_alignment; // DMA buffer alignment (both in size and address) for external TX memory
|
||||
size_t max_single_dma_buffer; // max DMA buffer size by a single descriptor
|
||||
int gdma_bus_id; // GDMA bus id (AHB, AXI, etc.)
|
||||
gdma_channel_handle_t tx_channel; // GDMA TX channel handle
|
||||
@@ -146,12 +148,12 @@ static esp_err_t esp_async_memcpy_install_gdma_template(const async_memcpy_confi
|
||||
ESP_GOTO_ON_ERROR(gdma_connect(mcp_gdma->rx_channel, m2m_trigger), err, TAG, "GDMA rx connect failed");
|
||||
ESP_GOTO_ON_ERROR(gdma_connect(mcp_gdma->tx_channel, m2m_trigger), err, TAG, "GDMA tx connect failed");
|
||||
|
||||
gdma_transfer_ability_t transfer_ability = {
|
||||
.sram_trans_align = config->sram_trans_align,
|
||||
.psram_trans_align = config->psram_trans_align,
|
||||
gdma_transfer_config_t transfer_cfg = {
|
||||
.max_data_burst_size = config->dma_burst_size ? config->dma_burst_size : 16,
|
||||
.access_ext_mem = true, // allow to do memory copy from/to external memory
|
||||
};
|
||||
ESP_GOTO_ON_ERROR(gdma_set_transfer_ability(mcp_gdma->tx_channel, &transfer_ability), err, TAG, "set tx trans ability failed");
|
||||
ESP_GOTO_ON_ERROR(gdma_set_transfer_ability(mcp_gdma->rx_channel, &transfer_ability), err, TAG, "set rx trans ability failed");
|
||||
ESP_GOTO_ON_ERROR(gdma_config_transfer(mcp_gdma->tx_channel, &transfer_cfg), err, TAG, "config transfer for tx channel failed");
|
||||
ESP_GOTO_ON_ERROR(gdma_config_transfer(mcp_gdma->rx_channel, &transfer_cfg), err, TAG, "config transfer for rx channel failed");
|
||||
|
||||
// register rx eof callback
|
||||
gdma_rx_event_callbacks_t cbs = {
|
||||
@@ -172,15 +174,13 @@ static esp_err_t esp_async_memcpy_install_gdma_template(const async_memcpy_confi
|
||||
atomic_init(&mcp_gdma->fsm, MCP_FSM_IDLE);
|
||||
mcp_gdma->gdma_bus_id = gdma_bus_id;
|
||||
|
||||
uint32_t psram_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
|
||||
uint32_t sram_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
||||
// if the psram_trans_align is configured to zero, we should fall back to use the data cache line size
|
||||
size_t psram_trans_align = MAX(psram_cache_line_size, config->psram_trans_align);
|
||||
size_t sram_trans_align = MAX(sram_cache_line_size, config->sram_trans_align);
|
||||
size_t trans_align = MAX(sram_trans_align, psram_trans_align);
|
||||
mcp_gdma->max_single_dma_buffer = ALIGN_DOWN(DMA_DESCRIPTOR_BUFFER_MAX_SIZE, trans_align);
|
||||
mcp_gdma->psram_trans_align = psram_trans_align;
|
||||
mcp_gdma->sram_trans_align = sram_trans_align;
|
||||
// get the buffer alignment required by the GDMA channel
|
||||
gdma_get_alignment_constraints(mcp_gdma->rx_channel, &mcp_gdma->rx_int_mem_alignment, &mcp_gdma->rx_ext_mem_alignment);
|
||||
gdma_get_alignment_constraints(mcp_gdma->tx_channel, &mcp_gdma->tx_int_mem_alignment, &mcp_gdma->tx_ext_mem_alignment);
|
||||
|
||||
size_t buf_align = MAX(MAX(mcp_gdma->rx_int_mem_alignment, mcp_gdma->rx_ext_mem_alignment),
|
||||
MAX(mcp_gdma->tx_int_mem_alignment, mcp_gdma->tx_ext_mem_alignment));
|
||||
mcp_gdma->max_single_dma_buffer = ALIGN_DOWN(DMA_DESCRIPTOR_BUFFER_MAX_SIZE, buf_align);
|
||||
mcp_gdma->parent.del = mcp_gdma_del;
|
||||
mcp_gdma->parent.memcpy = mcp_gdma_memcpy;
|
||||
#if SOC_GDMA_SUPPORT_ETM
|
||||
@@ -335,29 +335,21 @@ static async_memcpy_transaction_t *try_pop_trans_from_idle_queue(async_memcpy_gd
|
||||
static bool check_buffer_alignment(async_memcpy_gdma_context_t *mcp_gdma, void *src, void *dst, size_t n)
|
||||
{
|
||||
bool valid = true;
|
||||
uint32_t psram_align_mask = 0;
|
||||
uint32_t sram_align_mask = 0;
|
||||
if (mcp_gdma->psram_trans_align) {
|
||||
psram_align_mask = mcp_gdma->psram_trans_align - 1;
|
||||
}
|
||||
if (mcp_gdma->sram_trans_align) {
|
||||
sram_align_mask = mcp_gdma->sram_trans_align - 1;
|
||||
}
|
||||
|
||||
if (esp_ptr_external_ram(dst)) {
|
||||
valid = valid && (((uint32_t)dst & psram_align_mask) == 0);
|
||||
valid = valid && ((n & psram_align_mask) == 0);
|
||||
valid = valid && (((uint32_t)dst & (mcp_gdma->rx_ext_mem_alignment - 1)) == 0);
|
||||
valid = valid && ((n & (mcp_gdma->rx_ext_mem_alignment - 1)) == 0);
|
||||
} else {
|
||||
valid = valid && (((uint32_t)dst & sram_align_mask) == 0);
|
||||
valid = valid && ((n & sram_align_mask) == 0);
|
||||
valid = valid && (((uint32_t)dst & (mcp_gdma->rx_int_mem_alignment - 1)) == 0);
|
||||
valid = valid && ((n & (mcp_gdma->rx_int_mem_alignment - 1)) == 0);
|
||||
}
|
||||
|
||||
if (esp_ptr_external_ram(src)) {
|
||||
valid = valid && (((uint32_t)src & psram_align_mask) == 0);
|
||||
valid = valid && ((n & psram_align_mask) == 0);
|
||||
valid = valid && (((uint32_t)src & (mcp_gdma->tx_ext_mem_alignment - 1)) == 0);
|
||||
valid = valid && ((n & (mcp_gdma->tx_ext_mem_alignment - 1)) == 0);
|
||||
} else {
|
||||
valid = valid && (((uint32_t)src & sram_align_mask) == 0);
|
||||
valid = valid && ((n & sram_align_mask) == 0);
|
||||
valid = valid && (((uint32_t)src & (mcp_gdma->tx_int_mem_alignment - 1)) == 0);
|
||||
valid = valid && ((n & (mcp_gdma->tx_int_mem_alignment - 1)) == 0);
|
||||
}
|
||||
|
||||
return valid;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_GDMA_ENABLE_DEBUG_LOG
|
||||
// The local log level must be defined before including esp_log.h
|
||||
@@ -42,10 +43,9 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "gdma_priv.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
|
||||
#if CONFIG_PM_ENABLE && SOC_PM_SUPPORT_TOP_PD
|
||||
#include "esp_private/gdma_sleep_retention.h"
|
||||
@@ -354,46 +354,68 @@ esp_err_t gdma_get_free_m2m_trig_id_mask(gdma_channel_handle_t dma_chan, uint32_
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability)
|
||||
esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transfer_config_t *config)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(dma_chan && ability, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
ESP_RETURN_ON_FALSE(dma_chan && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
uint32_t max_data_burst_size = config->max_data_burst_size;
|
||||
if (max_data_burst_size) {
|
||||
// burst size must be power of 2
|
||||
ESP_RETURN_ON_FALSE((max_data_burst_size & (max_data_burst_size - 1)) == 0, ESP_ERR_INVALID_ARG,
|
||||
TAG, "invalid max_data_burst_size: %"PRIu32, max_data_burst_size);
|
||||
}
|
||||
gdma_pair_t *pair = dma_chan->pair;
|
||||
gdma_group_t *group = pair->group;
|
||||
gdma_hal_context_t *hal = &group->hal;
|
||||
size_t int_mem_alignment = 1;
|
||||
size_t ext_mem_alignment = 1;
|
||||
|
||||
size_t sram_alignment = ability->sram_trans_align;
|
||||
size_t psram_alignment = ability->psram_trans_align;
|
||||
// alignment should be 2^n
|
||||
ESP_RETURN_ON_FALSE((sram_alignment & (sram_alignment - 1)) == 0, ESP_ERR_INVALID_ARG,
|
||||
TAG, "invalid sram alignment: %zu", sram_alignment);
|
||||
|
||||
uint32_t ext_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
|
||||
if (psram_alignment == 0) {
|
||||
// fall back to use the same size of the psram data cache line size
|
||||
psram_alignment = ext_mem_cache_line_size;
|
||||
}
|
||||
if (psram_alignment > ext_mem_cache_line_size) {
|
||||
ESP_RETURN_ON_FALSE(((psram_alignment % ext_mem_cache_line_size) == 0), ESP_ERR_INVALID_ARG,
|
||||
TAG, "psram_alignment(%d) should be multiple of the ext_mem_cache_line_size(%"PRIu32")",
|
||||
psram_alignment, ext_mem_cache_line_size);
|
||||
// always enable descriptor burst as the descriptor is always word aligned and is in the internal SRAM
|
||||
bool en_desc_burst = true;
|
||||
bool en_data_burst = max_data_burst_size > 0;
|
||||
gdma_hal_enable_burst(hal, pair->pair_id, dma_chan->direction, en_data_burst, en_desc_burst);
|
||||
if (en_data_burst) {
|
||||
gdma_hal_set_burst_size(hal, pair->pair_id, dma_chan->direction, max_data_burst_size);
|
||||
}
|
||||
|
||||
// if the DMA can't access the PSRAM, this HAL function is no-op
|
||||
gdma_hal_set_ext_mem_align(hal, pair->pair_id, dma_chan->direction, psram_alignment);
|
||||
|
||||
// TX channel can always enable burst mode, no matter data alignment
|
||||
bool en_burst = true;
|
||||
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
// RX channel burst mode depends on specific data alignment
|
||||
en_burst = sram_alignment >= 4;
|
||||
#if GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT
|
||||
if (en_data_burst && dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
int_mem_alignment = MAX(int_mem_alignment, 4);
|
||||
ext_mem_alignment = MAX(ext_mem_alignment, max_data_burst_size);
|
||||
}
|
||||
gdma_hal_enable_burst(hal, pair->pair_id, dma_chan->direction, en_burst, en_burst);
|
||||
#endif
|
||||
|
||||
dma_chan->sram_alignment = sram_alignment;
|
||||
dma_chan->psram_alignment = psram_alignment;
|
||||
ESP_LOGD(TAG, "%s channel (%d,%d), (%u:%u) bytes aligned, burst %s", dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX ? "tx" : "rx",
|
||||
group->group_id, pair->pair_id, sram_alignment, psram_alignment, en_burst ? "enabled" : "disabled");
|
||||
// if MSPI encryption is enabled, and DMA wants to read/write external memory
|
||||
if (esp_flash_encryption_enabled()) {
|
||||
gdma_hal_enable_access_encrypt_mem(hal, pair->pair_id, dma_chan->direction, config->access_ext_mem);
|
||||
// when DMA access the encrypted memory, extra alignment is needed, for both internal and external memory
|
||||
if (config->access_ext_mem) {
|
||||
ext_mem_alignment = MAX(ext_mem_alignment, GDMA_ACCESS_ENCRYPTION_MEM_ALIGNMENT);
|
||||
int_mem_alignment = MAX(int_mem_alignment, GDMA_ACCESS_ENCRYPTION_MEM_ALIGNMENT);
|
||||
}
|
||||
} else {
|
||||
gdma_hal_enable_access_encrypt_mem(hal, pair->pair_id, dma_chan->direction, false);
|
||||
}
|
||||
|
||||
// if the channel is not allowed to access external memory, set a super big (meaningless) alignment value
|
||||
// so when the upper layer checks the alignment with an external buffer, the check should fail
|
||||
if (!config->access_ext_mem) {
|
||||
ext_mem_alignment = BIT(31);
|
||||
}
|
||||
|
||||
dma_chan->int_mem_alignment = int_mem_alignment;
|
||||
dma_chan->ext_mem_alignment = ext_mem_alignment;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gdma_get_alignment_constraints(gdma_channel_handle_t dma_chan, size_t *int_mem_alignment, size_t *ext_mem_alignment)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(dma_chan, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
if (int_mem_alignment) {
|
||||
*int_mem_alignment = dma_chan->int_mem_alignment;
|
||||
}
|
||||
if (ext_mem_alignment) {
|
||||
*ext_mem_alignment = dma_chan->ext_mem_alignment;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -421,57 +443,6 @@ esp_err_t gdma_set_priority(gdma_channel_handle_t dma_chan, uint32_t priority)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_GDMA_SUPPORT_CRC
|
||||
esp_err_t gdma_config_crc_calculator(gdma_channel_handle_t dma_chan, const gdma_crc_calculator_config_t *config)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(dma_chan && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
gdma_pair_t *pair = dma_chan->pair;
|
||||
gdma_group_t *group = pair->group;
|
||||
gdma_hal_context_t *hal = &group->hal;
|
||||
switch (group->bus_id) {
|
||||
#if SOC_AHB_GDMA_SUPPORTED
|
||||
case SOC_GDMA_BUS_AHB:
|
||||
ESP_RETURN_ON_FALSE(config->crc_bit_width <= GDMA_LL_AHB_MAX_CRC_BIT_WIDTH, ESP_ERR_INVALID_ARG, TAG, "invalid crc bit width");
|
||||
break;
|
||||
#endif // SOC_AHB_GDMA_SUPPORTED
|
||||
#if SOC_AXI_GDMA_SUPPORTED
|
||||
case SOC_GDMA_BUS_AXI:
|
||||
ESP_RETURN_ON_FALSE(config->crc_bit_width <= GDMA_LL_AXI_MAX_CRC_BIT_WIDTH, ESP_ERR_INVALID_ARG, TAG, "invalid crc bit width");
|
||||
break;
|
||||
#endif // SOC_AXI_GDMA_SUPPORTED
|
||||
default:
|
||||
ESP_LOGE(TAG, "invalid bus id: %d", group->bus_id);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// clear the previous CRC result
|
||||
gdma_hal_clear_crc(hal, pair->pair_id, dma_chan->direction);
|
||||
|
||||
// set polynomial and initial value
|
||||
gdma_hal_crc_config_t hal_config = {
|
||||
.crc_bit_width = config->crc_bit_width,
|
||||
.poly_hex = config->poly_hex,
|
||||
.init_value = config->init_value,
|
||||
.reverse_data_mask = config->reverse_data_mask,
|
||||
};
|
||||
gdma_hal_set_crc_poly(hal, pair->pair_id, dma_chan->direction, &hal_config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gdma_crc_get_result(gdma_channel_handle_t dma_chan, uint32_t *result)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(dma_chan && result, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
gdma_pair_t *pair = dma_chan->pair;
|
||||
gdma_group_t *group = pair->group;
|
||||
gdma_hal_context_t *hal = &group->hal;
|
||||
|
||||
*result = gdma_hal_get_crc_result(hal, pair->pair_id, dma_chan->direction);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // SOC_GDMA_SUPPORT_CRC
|
||||
|
||||
esp_err_t gdma_register_tx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_tx_event_callbacks_t *cbs, void *user_data)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(dma_chan && cbs && dma_chan->direction == GDMA_CHANNEL_DIRECTION_TX, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_GDMA_ENABLE_DEBUG_LOG
|
||||
// The local log level must be defined before including esp_log.h
|
||||
// Set the maximum log level for this source file
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
#endif
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "gdma_priv.h"
|
||||
|
||||
static const char *TAG = "gdma";
|
||||
|
||||
esp_err_t gdma_config_crc_calculator(gdma_channel_handle_t dma_chan, const gdma_crc_calculator_config_t *config)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(dma_chan && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
gdma_pair_t *pair = dma_chan->pair;
|
||||
gdma_group_t *group = pair->group;
|
||||
gdma_hal_context_t *hal = &group->hal;
|
||||
switch (group->bus_id) {
|
||||
#if SOC_AHB_GDMA_SUPPORTED
|
||||
case SOC_GDMA_BUS_AHB:
|
||||
ESP_RETURN_ON_FALSE(config->crc_bit_width <= GDMA_LL_AHB_MAX_CRC_BIT_WIDTH, ESP_ERR_INVALID_ARG, TAG, "invalid crc bit width");
|
||||
break;
|
||||
#endif // SOC_AHB_GDMA_SUPPORTED
|
||||
#if SOC_AXI_GDMA_SUPPORTED
|
||||
case SOC_GDMA_BUS_AXI:
|
||||
ESP_RETURN_ON_FALSE(config->crc_bit_width <= GDMA_LL_AXI_MAX_CRC_BIT_WIDTH, ESP_ERR_INVALID_ARG, TAG, "invalid crc bit width");
|
||||
break;
|
||||
#endif // SOC_AXI_GDMA_SUPPORTED
|
||||
default:
|
||||
ESP_LOGE(TAG, "invalid bus id: %d", group->bus_id);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// clear the previous CRC result
|
||||
gdma_hal_clear_crc(hal, pair->pair_id, dma_chan->direction);
|
||||
|
||||
// set polynomial and initial value
|
||||
gdma_hal_crc_config_t hal_config = {
|
||||
.crc_bit_width = config->crc_bit_width,
|
||||
.poly_hex = config->poly_hex,
|
||||
.init_value = config->init_value,
|
||||
.reverse_data_mask = config->reverse_data_mask,
|
||||
};
|
||||
gdma_hal_set_crc_poly(hal, pair->pair_id, dma_chan->direction, &hal_config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gdma_crc_get_result(gdma_channel_handle_t dma_chan, uint32_t *result)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(dma_chan && result, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
gdma_pair_t *pair = dma_chan->pair;
|
||||
gdma_group_t *group = pair->group;
|
||||
gdma_hal_context_t *hal = &group->hal;
|
||||
|
||||
*result = gdma_hal_get_crc_result(hal, pair->pair_id, dma_chan->direction);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -32,6 +32,8 @@
|
||||
#define GDMA_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED
|
||||
#endif
|
||||
|
||||
#define GDMA_ACCESS_ENCRYPTION_MEM_ALIGNMENT 16 /*!< The alignment of the memory and size when DMA accesses the encryption memory */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -67,8 +69,8 @@ struct gdma_channel_t {
|
||||
portMUX_TYPE spinlock; // channel level spinlock
|
||||
gdma_channel_direction_t direction; // channel direction
|
||||
int periph_id; // Peripheral instance ID, indicates which peripheral is connected to this GDMA channel
|
||||
size_t sram_alignment; // alignment for memory in SRAM
|
||||
size_t psram_alignment; // alignment for memory in PSRAM
|
||||
size_t int_mem_alignment; // alignment for memory in internal memory
|
||||
size_t ext_mem_alignment; // alignment for memory in external memory
|
||||
esp_err_t (*del)(gdma_channel_t *channel); // channel deletion function, it's polymorphic, see `gdma_del_tx_channel` or `gdma_del_rx_channel`
|
||||
struct {
|
||||
uint32_t start_stop_by_etm: 1; // whether the channel is started/stopped by ETM
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// DO NOT USE THESE APIS IN ANY APPLICATIONS
|
||||
// GDMA driver is not public for end users, but for ESP-IDF developers.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
@@ -37,19 +34,6 @@ typedef struct {
|
||||
} flags;
|
||||
} gdma_channel_alloc_config_t;
|
||||
|
||||
/**
|
||||
* @brief GDMA transfer ability
|
||||
*
|
||||
* @note The alignment set in this structure is **not** a guarantee that gdma driver will take care of the nonalignment cases.
|
||||
* Actually the GDMA driver has no knowledge about the DMA buffer (address and size) used by upper layer.
|
||||
* So it's the responsibility of the **upper layer** to take care of the buffer address and size.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
size_t sram_trans_align; /*!< DMA transfer alignment for memory in SRAM, in bytes. The driver enables/disables burst mode based on this value. 0 means no alignment is required */
|
||||
size_t psram_trans_align; /*!< DMA transfer alignment for memory in PSRAM, in bytes. The driver sets proper burst block size based on the alignment value. 0 means no alignment is required */
|
||||
} gdma_transfer_ability_t;
|
||||
|
||||
/**
|
||||
* @brief Type of GDMA event data
|
||||
*/
|
||||
@@ -200,16 +184,48 @@ esp_err_t gdma_connect(gdma_channel_handle_t dma_chan, gdma_trigger_t trig_perip
|
||||
esp_err_t gdma_disconnect(gdma_channel_handle_t dma_chan);
|
||||
|
||||
/**
|
||||
* @brief Set DMA channel transfer ability
|
||||
* @brief Channel transfer configurations
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t max_data_burst_size; /*!< Set the max burst size when DMA read/write the data buffer.
|
||||
Set to 0 means to disable the data burst.
|
||||
Other value must be power of 2, e.g., 4/8/16/32/64 */
|
||||
bool access_ext_mem; /*!< Set this if the DMA transfer will access external memory */
|
||||
} gdma_transfer_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configure transfer parameters for a DMA channel
|
||||
*
|
||||
* @note It's highly recommended to enable the burst mode and set proper burst size for the DMA channel,
|
||||
* which can improve the performance in accessing external memory by a lot.
|
||||
*
|
||||
* @param[in] chan DMA channel handle, allocated by `gdma_new_channel`
|
||||
* @param[in] config Transfer configurations
|
||||
* @return
|
||||
* - ESP_OK: Configure DMA transfer parameters successfully
|
||||
* - ESP_ERR_INVALID_ARG: Configure DMA transfer parameters failed because of invalid argument
|
||||
* - ESP_FAIL: Configure DMA transfer parameters failed because of other error
|
||||
*/
|
||||
esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transfer_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Get the alignment constraints for internal and external memory
|
||||
*
|
||||
* @note You should call this function after `gdma_config_transfer`, the later one can
|
||||
* adjust the alignment constraints based on various conditions, e.g. burst size, memory encryption, etc.
|
||||
* @note You can use returned alignment value to validate if a DMA buffer provided by the upper layer meets the constraints.
|
||||
* @note The returned alignment doesn't take the cache line size into account, if you want to do aligned memory allocation,
|
||||
* you should align the buffer size to the cache line size by yourself if the DMA buffer is behind a cache.
|
||||
*
|
||||
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
|
||||
* @param[in] ability Transfer ability, e.g. alignment
|
||||
* @param[out] int_mem_alignment Internal memory alignment
|
||||
* @param[out] ext_mem_alignment External memory alignment
|
||||
* @return
|
||||
* - ESP_OK: Set DMA channel transfer ability successfully
|
||||
* - ESP_ERR_INVALID_ARG: Set DMA channel transfer ability failed because of invalid argument
|
||||
* - ESP_FAIL: Set DMA channel transfer ability failed because of other error
|
||||
* - ESP_OK: Get alignment constraints successfully
|
||||
* - ESP_ERR_INVALID_ARG: Get alignment constraints failed because of invalid argument
|
||||
* - ESP_FAIL: Get alignment constraints failed because of other error
|
||||
*/
|
||||
esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability);
|
||||
esp_err_t gdma_get_alignment_constraints(gdma_channel_handle_t dma_chan, size_t *int_mem_alignment, size_t *ext_mem_alignment);
|
||||
|
||||
/**
|
||||
* @brief Apply channel strategy for GDMA channel
|
||||
@@ -458,6 +474,36 @@ esp_err_t gdma_config_crc_calculator(gdma_channel_handle_t dma_chan, const gdma_
|
||||
esp_err_t gdma_crc_get_result(gdma_channel_handle_t dma_chan, uint32_t *result);
|
||||
#endif // SOC_GDMA_SUPPORT_CRC
|
||||
|
||||
/****************************************************************************************
|
||||
* Deprecated APIs
|
||||
****************************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief GDMA transfer ability
|
||||
*
|
||||
* @note The alignment set in this structure is **not** a guarantee that gdma driver will take care of the nonalignment cases.
|
||||
* Actually the GDMA driver has no knowledge about the DMA buffer (address and size) used by upper layer.
|
||||
* So it's the responsibility of the **upper layer** to take care of the buffer address and size.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
size_t sram_trans_align; /*!< DMA transfer alignment for memory in SRAM, in bytes. The driver enables/disables burst mode based on this value. 0 means no alignment is required */
|
||||
size_t psram_trans_align; /*!< DMA transfer alignment for memory in PSRAM, in bytes. The driver sets proper burst block size based on the alignment value. 0 means no alignment is required */
|
||||
} gdma_transfer_ability_t;
|
||||
|
||||
/**
|
||||
* @brief Set DMA channel transfer ability
|
||||
*
|
||||
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
|
||||
* @param[in] ability Transfer ability, e.g. alignment
|
||||
* @return
|
||||
* - ESP_OK: Set DMA channel transfer ability successfully
|
||||
* - ESP_ERR_INVALID_ARG: Set DMA channel transfer ability failed because of invalid argument
|
||||
* - ESP_FAIL: Set DMA channel transfer ability failed because of other error
|
||||
*/
|
||||
esp_err_t gdma_set_transfer_ability(gdma_channel_handle_t dma_chan, const gdma_transfer_ability_t *ability)
|
||||
__attribute__((deprecated("please use gdma_config_transfer instead")));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -51,8 +51,11 @@ typedef bool (*async_memcpy_isr_cb_t)(async_memcpy_handle_t mcp_hdl, async_memcp
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t backlog; /*!< Maximum number of transactions that can be prepared in the background */
|
||||
size_t sram_trans_align; /*!< DMA transfer alignment (both in size and address) for SRAM memory */
|
||||
size_t psram_trans_align; /*!< DMA transfer alignment (both in size and address) for PSRAM memory */
|
||||
size_t sram_trans_align __attribute__((deprecated)); /*!< DMA transfer alignment (both in size and address) for SRAM memory */
|
||||
union {
|
||||
size_t psram_trans_align; /*!< DMA transfer alignment (both in size and address) for PSRAM memory */
|
||||
size_t dma_burst_size; /*!< DMA transfer burst size, in bytes */
|
||||
};
|
||||
uint32_t flags; /*!< Extra flags to control async memcpy feature */
|
||||
} async_memcpy_config_t;
|
||||
|
||||
@@ -62,8 +65,7 @@ typedef struct {
|
||||
#define ASYNC_MEMCPY_DEFAULT_CONFIG() \
|
||||
{ \
|
||||
.backlog = 8, \
|
||||
.sram_trans_align = 0, \
|
||||
.psram_trans_align = 0, \
|
||||
.dma_burst_size = 16, \
|
||||
.flags = 0, \
|
||||
}
|
||||
|
||||
|
||||
@@ -302,8 +302,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
||||
|
||||
async_memcpy_config_t config = ASYNC_MEMCPY_DEFAULT_CONFIG();
|
||||
config.backlog = (buffer_size / DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1) * TEST_ASYNC_MEMCPY_BENCH_COUNTS;
|
||||
config.sram_trans_align = 4; // at least 4 bytes aligned for SRAM transfer
|
||||
config.psram_trans_align = 64; // at least 64 bytes aligned for PSRAM transfer
|
||||
config.dma_burst_size = 64; // set a big burst size for performance
|
||||
async_memcpy_handle_t driver = NULL;
|
||||
int64_t elapse_us = 0;
|
||||
float throughput = 0.0;
|
||||
@@ -311,7 +310,7 @@ static void memcpy_performance_test(uint32_t buffer_size)
|
||||
|
||||
// 1. SRAM->SRAM
|
||||
memcpy_testbench_context_t test_context = {
|
||||
.align = config.psram_trans_align,
|
||||
.align = config.dma_burst_size,
|
||||
.buffer_size = buffer_size,
|
||||
.src_in_psram = false,
|
||||
.dst_in_psram = false,
|
||||
|
||||
@@ -201,7 +201,7 @@ static void test_gdma_m2m_mode(gdma_channel_handle_t tx_chan, gdma_channel_handl
|
||||
// do write-back for the source data because it's in the cache
|
||||
TEST_ESP_OK(esp_cache_msync((void *)src_data, 128, ESP_CACHE_MSYNC_FLAG_DIR_C2M));
|
||||
}
|
||||
#if SOC_DMA_CAN_ACCESS_MSPI_MEM
|
||||
#if SOC_DMA_CAN_ACCESS_FLASH
|
||||
const char *src_string = "GDMA can fetch data from MSPI Flash";
|
||||
size_t src_string_len = strlen(src_string);
|
||||
TEST_ASSERT_TRUE(esp_ptr_in_drom(src_string));
|
||||
@@ -234,7 +234,7 @@ static void test_gdma_m2m_mode(gdma_channel_handle_t tx_chan, gdma_channel_handl
|
||||
tx_descs_nc[1].dw0.size = 64;
|
||||
tx_descs_nc[1].dw0.length = 64;
|
||||
tx_descs_nc[1].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA;
|
||||
#if !SOC_DMA_CAN_ACCESS_MSPI_MEM
|
||||
#if !SOC_DMA_CAN_ACCESS_FLASH
|
||||
tx_descs_nc[1].dw0.suc_eof = 1;
|
||||
tx_descs_nc[1].next = NULL;
|
||||
#else
|
||||
@@ -272,7 +272,7 @@ static void test_gdma_m2m_mode(gdma_channel_handle_t tx_chan, gdma_channel_handl
|
||||
for (int i = 0; i < 128; i++) {
|
||||
TEST_ASSERT_EQUAL(i, dst_data[i]);
|
||||
}
|
||||
#if SOC_DMA_CAN_ACCESS_MSPI_MEM
|
||||
#if SOC_DMA_CAN_ACCESS_FLASH
|
||||
TEST_ASSERT_TRUE(dst_data[128 + src_string_len] == 0xFF);
|
||||
dst_data[128 + src_string_len] = '\0';
|
||||
TEST_ASSERT_TRUE(strcmp(src_string, (const char *)((uint32_t)dst_data + 128)) == 0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -27,10 +27,9 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_clk_tree.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "esp_cache.h"
|
||||
#include "hal/dma_types.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "esp_private/gdma.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
@@ -38,7 +37,6 @@
|
||||
#include "soc/lcd_periph.h"
|
||||
#include "hal/lcd_ll.h"
|
||||
#include "hal/lcd_hal.h"
|
||||
#include "esp_cache.h"
|
||||
|
||||
#define ALIGN_UP(size, align) (((size) + (align) - 1) & ~((align) - 1))
|
||||
#define ALIGN_DOWN(size, align) ((size) & ~((align) - 1))
|
||||
@@ -52,7 +50,7 @@ typedef struct lcd_i80_trans_descriptor_t lcd_i80_trans_descriptor_t;
|
||||
static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, const void *param, size_t param_size);
|
||||
static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, const void *color, size_t color_size);
|
||||
static esp_err_t panel_io_i80_del(esp_lcd_panel_io_t *io);
|
||||
static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus);
|
||||
static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus, const esp_lcd_i80_bus_config_t *bus_config);
|
||||
static void lcd_periph_trigger_quick_trans_done_event(esp_lcd_i80_bus_handle_t bus);
|
||||
static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_clock_source_t clk_src);
|
||||
static esp_err_t lcd_i80_bus_configure_gpio(esp_lcd_i80_bus_handle_t bus, const esp_lcd_i80_bus_config_t *bus_config);
|
||||
@@ -72,8 +70,8 @@ struct esp_lcd_i80_bus_t {
|
||||
uint8_t *format_buffer; // The driver allocates an internal buffer for DMA to do data format transformer
|
||||
size_t resolution_hz; // LCD_CLK resolution, determined by selected clock source
|
||||
gdma_channel_handle_t dma_chan; // DMA channel handle
|
||||
size_t psram_trans_align; // DMA transfer alignment for data allocated from PSRAM
|
||||
size_t sram_trans_align; // DMA transfer alignment for data allocated from SRAM
|
||||
size_t int_mem_align; // Alignment for internal memory
|
||||
size_t ext_mem_align; // Alignment for external memory
|
||||
lcd_i80_trans_descriptor_t *cur_trans; // Current transaction
|
||||
lcd_panel_io_i80_t *cur_device; // Current working device
|
||||
LIST_HEAD(i80_device_list, lcd_panel_io_i80_t) device_list; // Head of i80 device list
|
||||
@@ -175,10 +173,8 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
|
||||
lcd_ll_enable_interrupt(bus->hal.dev, LCD_LL_EVENT_TRANS_DONE, false); // disable all interrupts
|
||||
lcd_ll_clear_interrupt_status(bus->hal.dev, UINT32_MAX); // clear pending interrupt
|
||||
// install DMA service
|
||||
bus->psram_trans_align = bus_config->psram_trans_align;
|
||||
bus->sram_trans_align = bus_config->sram_trans_align;
|
||||
bus->bus_width = bus_config->bus_width;
|
||||
ret = lcd_i80_init_dma_link(bus);
|
||||
ret = lcd_i80_init_dma_link(bus, bus_config);
|
||||
ESP_GOTO_ON_ERROR(ret, err, TAG, "install DMA failed");
|
||||
// disable RGB-LCD mode
|
||||
lcd_ll_enable_rgb_mode(bus->hal.dev, false);
|
||||
@@ -481,6 +477,18 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
||||
esp_lcd_i80_bus_t *bus = i80_device->bus;
|
||||
lcd_i80_trans_descriptor_t *trans_desc = NULL;
|
||||
assert(color_size <= (bus->num_dma_nodes * DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && "color bytes too long, enlarge max_transfer_bytes");
|
||||
if (esp_ptr_external_ram(color)) {
|
||||
// check alignment
|
||||
ESP_RETURN_ON_FALSE(((uint32_t)color & (bus->ext_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color address not aligned");
|
||||
ESP_RETURN_ON_FALSE((color_size & (bus->ext_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color size not aligned");
|
||||
// flush frame buffer from cache to the physical PSRAM
|
||||
esp_cache_msync((void *)color, color_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED);
|
||||
} else {
|
||||
// check alignment
|
||||
ESP_RETURN_ON_FALSE(((uint32_t)color & (bus->int_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color address not aligned");
|
||||
ESP_RETURN_ON_FALSE((color_size & (bus->int_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color size not aligned");
|
||||
}
|
||||
|
||||
// in case bus_width=16 and cmd_bits=8, we still need 1 cmd_cycle
|
||||
uint32_t cmd_cycles = i80_device->lcd_cmd_bits / bus->bus_width;
|
||||
if (cmd_cycles * bus->bus_width < i80_device->lcd_cmd_bits) {
|
||||
@@ -503,13 +511,6 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons
|
||||
trans_desc->trans_done_cb = i80_device->on_color_trans_done;
|
||||
trans_desc->user_ctx = i80_device->user_ctx;
|
||||
|
||||
if (esp_ptr_external_ram(color)) {
|
||||
uint32_t dcache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
|
||||
// flush frame buffer from cache to the physical PSRAM
|
||||
// note the esp_cache_msync function will check the alignment of the address and size, make sure they're aligned to current cache line size
|
||||
esp_cache_msync((void *)ALIGN_DOWN((intptr_t)color, dcache_line_size), ALIGN_UP(color_size, dcache_line_size), 0);
|
||||
}
|
||||
|
||||
// send transaction to trans_queue
|
||||
xQueueSend(i80_device->trans_queue, &trans_desc, portMAX_DELAY);
|
||||
i80_device->num_trans_inflight++;
|
||||
@@ -542,7 +543,7 @@ static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus)
|
||||
static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus, const esp_lcd_i80_bus_config_t *bus_config)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
// chain DMA descriptors
|
||||
@@ -567,12 +568,13 @@ static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus)
|
||||
.owner_check = true
|
||||
};
|
||||
gdma_apply_strategy(bus->dma_chan, &strategy_config);
|
||||
// set DMA transfer ability
|
||||
gdma_transfer_ability_t ability = {
|
||||
.psram_trans_align = bus->psram_trans_align,
|
||||
.sram_trans_align = bus->sram_trans_align,
|
||||
// config DMA transfer parameters
|
||||
gdma_transfer_config_t trans_cfg = {
|
||||
.max_data_burst_size = bus_config->dma_burst_size ? bus_config->dma_burst_size : 16, // Enable DMA burst transfer for better performance
|
||||
.access_ext_mem = true, // the LCD can carry pixel buffer from the external memory
|
||||
};
|
||||
gdma_set_transfer_ability(bus->dma_chan, &ability);
|
||||
ESP_GOTO_ON_ERROR(gdma_config_transfer(bus->dma_chan, &trans_cfg), err, TAG, "config DMA transfer failed");
|
||||
gdma_get_alignment_constraints(bus->dma_chan, &bus->int_mem_align, &bus->ext_mem_align);
|
||||
return ESP_OK;
|
||||
err:
|
||||
if (bus->dma_chan) {
|
||||
|
||||
@@ -238,8 +238,11 @@ typedef struct {
|
||||
int data_gpio_nums[ESP_LCD_I80_BUS_WIDTH_MAX]; /*!< GPIOs used for data lines */
|
||||
size_t bus_width; /*!< Number of data lines, 8 or 16 */
|
||||
size_t max_transfer_bytes; /*!< Maximum transfer size, this determines the length of internal DMA link */
|
||||
size_t psram_trans_align; /*!< DMA transfer alignment for data allocated from PSRAM */
|
||||
size_t sram_trans_align; /*!< DMA transfer alignment for data allocated from SRAM */
|
||||
union {
|
||||
size_t psram_trans_align; /*!< DMA transfer alignment for data allocated from PSRAM */
|
||||
size_t dma_burst_size; /*!< DMA burst size, in bytes */
|
||||
};
|
||||
size_t sram_trans_align __attribute__((deprecated)); /*!< DMA transfer alignment for data allocated from SRAM */
|
||||
} esp_lcd_i80_bus_config_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
#include "soc/lcd_periph.h"
|
||||
#include "hal/lcd_hal.h"
|
||||
#include "hal/lcd_ll.h"
|
||||
#include "hal/gdma_ll.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "rom/cache.h"
|
||||
#include "esp_cache.h"
|
||||
|
||||
@@ -77,7 +78,8 @@ static esp_err_t rgb_panel_swap_xy(esp_lcd_panel_t *panel, bool swap_axes);
|
||||
static esp_err_t rgb_panel_set_gap(esp_lcd_panel_t *panel, int x_gap, int y_gap);
|
||||
static esp_err_t rgb_panel_disp_on_off(esp_lcd_panel_t *panel, bool off);
|
||||
static esp_err_t lcd_rgb_panel_select_clock_src(esp_rgb_panel_t *panel, lcd_clock_source_t clk_src);
|
||||
static esp_err_t lcd_rgb_panel_create_trans_link(esp_rgb_panel_t *panel);
|
||||
static esp_err_t lcd_rgb_create_dma_channel(esp_rgb_panel_t *panel);
|
||||
static void lcd_rgb_panel_init_trans_link(esp_rgb_panel_t *panel);
|
||||
static esp_err_t lcd_rgb_panel_configure_gpio(esp_rgb_panel_t *panel, const esp_lcd_rgb_panel_config_t *panel_config);
|
||||
static void lcd_rgb_panel_start_transmission(esp_rgb_panel_t *rgb_panel);
|
||||
static void lcd_default_isr_handler(void *args);
|
||||
@@ -90,8 +92,7 @@ struct esp_rgb_panel_t {
|
||||
size_t fb_bits_per_pixel; // Frame buffer color depth, in bpp
|
||||
size_t num_fbs; // Number of frame buffers
|
||||
size_t output_bits_per_pixel; // Color depth seen from the output data line. Default to fb_bits_per_pixel, but can be changed by YUV-RGB conversion
|
||||
size_t sram_trans_align; // Alignment for framebuffer that allocated in SRAM
|
||||
size_t psram_trans_align; // Alignment for framebuffer that allocated in PSRAM
|
||||
size_t dma_burst_size; // DMA transfer burst size
|
||||
int disp_gpio_num; // Display control GPIO, which is used to perform action like "disp_off"
|
||||
intr_handle_t intr; // LCD peripheral interrupt handle
|
||||
esp_pm_lock_handle_t pm_lock; // Power management lock
|
||||
@@ -134,10 +135,20 @@ struct esp_rgb_panel_t {
|
||||
static esp_err_t lcd_rgb_panel_alloc_frame_buffers(const esp_lcd_rgb_panel_config_t *rgb_panel_config, esp_rgb_panel_t *rgb_panel)
|
||||
{
|
||||
bool fb_in_psram = false;
|
||||
size_t psram_trans_align = rgb_panel_config->psram_trans_align ? rgb_panel_config->psram_trans_align : 64;
|
||||
size_t sram_trans_align = rgb_panel_config->sram_trans_align ? rgb_panel_config->sram_trans_align : 4;
|
||||
rgb_panel->psram_trans_align = psram_trans_align;
|
||||
rgb_panel->sram_trans_align = sram_trans_align;
|
||||
size_t ext_mem_align = 0;
|
||||
size_t int_mem_align = 0;
|
||||
gdma_get_alignment_constraints(rgb_panel->dma_chan, &int_mem_align, &ext_mem_align);
|
||||
|
||||
// also take the cache line size into account when allocating the frame buffer
|
||||
uint32_t ext_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
|
||||
uint32_t int_mem_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
||||
// The buffer must be aligned to the cache line size
|
||||
if (ext_mem_cache_line_size) {
|
||||
ext_mem_align = MAX(ext_mem_align, ext_mem_cache_line_size);
|
||||
}
|
||||
if (int_mem_cache_line_size) {
|
||||
int_mem_align = MAX(int_mem_align, int_mem_cache_line_size);
|
||||
}
|
||||
|
||||
// alloc frame buffer
|
||||
if (rgb_panel->num_fbs > 0) {
|
||||
@@ -152,13 +163,13 @@ static esp_err_t lcd_rgb_panel_alloc_frame_buffers(const esp_lcd_rgb_panel_confi
|
||||
for (int i = 0; i < rgb_panel->num_fbs; i++) {
|
||||
if (fb_in_psram) {
|
||||
// the low level malloc function will help check the validation of alignment
|
||||
rgb_panel->fbs[i] = heap_caps_aligned_calloc(psram_trans_align, 1, rgb_panel->fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
rgb_panel->fbs[i] = heap_caps_aligned_calloc(ext_mem_align, 1, rgb_panel->fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
ESP_RETURN_ON_FALSE(rgb_panel->fbs[i], ESP_ERR_NO_MEM, TAG, "no mem for frame buffer");
|
||||
// calloc not only allocates but also zero's the buffer. We have to make sure this is
|
||||
// properly committed to the PSRAM, otherwise all sorts of visual corruption will happen.
|
||||
ESP_RETURN_ON_ERROR(esp_cache_msync(rgb_panel->fbs[i], rgb_panel->fb_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M), TAG, "cache write back failed");
|
||||
} else {
|
||||
rgb_panel->fbs[i] = heap_caps_aligned_calloc(sram_trans_align, 1, rgb_panel->fb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
|
||||
rgb_panel->fbs[i] = heap_caps_aligned_calloc(int_mem_align, 1, rgb_panel->fb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
|
||||
ESP_RETURN_ON_FALSE(rgb_panel->fbs[i], ESP_ERR_NO_MEM, TAG, "no mem for frame buffer");
|
||||
}
|
||||
}
|
||||
@@ -168,7 +179,7 @@ static esp_err_t lcd_rgb_panel_alloc_frame_buffers(const esp_lcd_rgb_panel_confi
|
||||
if (rgb_panel->bb_size) {
|
||||
for (int i = 0; i < RGB_LCD_PANEL_BOUNCE_BUF_NUM; i++) {
|
||||
// bounce buffer must come from SRAM
|
||||
rgb_panel->bounce_buffer[i] = heap_caps_aligned_calloc(sram_trans_align, 1, rgb_panel->bb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
|
||||
rgb_panel->bounce_buffer[i] = heap_caps_aligned_calloc(int_mem_align, 1, rgb_panel->bb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA);
|
||||
ESP_RETURN_ON_FALSE(rgb_panel->bounce_buffer[i], ESP_ERR_NO_MEM, TAG, "no mem for bounce buffer");
|
||||
}
|
||||
}
|
||||
@@ -302,9 +313,6 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf
|
||||
}
|
||||
}
|
||||
|
||||
// allocate frame buffers + bounce buffers
|
||||
ESP_GOTO_ON_ERROR(lcd_rgb_panel_alloc_frame_buffers(rgb_panel_config, rgb_panel), err, TAG, "alloc frame buffers failed");
|
||||
|
||||
// initialize HAL layer, so we can call LL APIs later
|
||||
lcd_hal_init(&rgb_panel->hal, panel_id);
|
||||
// enable clock
|
||||
@@ -334,8 +342,13 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf
|
||||
// install DMA service
|
||||
rgb_panel->flags.stream_mode = !rgb_panel_config->flags.refresh_on_demand;
|
||||
rgb_panel->fb_bits_per_pixel = fb_bits_per_pixel;
|
||||
ret = lcd_rgb_panel_create_trans_link(rgb_panel);
|
||||
ESP_GOTO_ON_ERROR(ret, err, TAG, "install DMA failed");
|
||||
rgb_panel->dma_burst_size = rgb_panel_config->dma_burst_size ? rgb_panel_config->dma_burst_size : 64;
|
||||
ESP_GOTO_ON_ERROR(lcd_rgb_create_dma_channel(rgb_panel), err, TAG, "install DMA failed");
|
||||
// allocate frame buffers + bounce buffers
|
||||
ESP_GOTO_ON_ERROR(lcd_rgb_panel_alloc_frame_buffers(rgb_panel_config, rgb_panel), err, TAG, "alloc frame buffers failed");
|
||||
// initialize DMA descriptor link
|
||||
lcd_rgb_panel_init_trans_link(rgb_panel);
|
||||
|
||||
// configure GPIO
|
||||
ret = lcd_rgb_panel_configure_gpio(rgb_panel, rgb_panel_config);
|
||||
ESP_GOTO_ON_ERROR(ret, err, TAG, "configure GPIO failed");
|
||||
@@ -959,11 +972,42 @@ static IRAM_ATTR bool lcd_rgb_panel_eof_handler(gdma_channel_handle_t dma_chan,
|
||||
return lcd_rgb_panel_fill_bounce_buffer(panel, panel->bounce_buffer[bb]);
|
||||
}
|
||||
|
||||
static esp_err_t lcd_rgb_create_dma_channel(esp_rgb_panel_t *panel)
|
||||
{
|
||||
// alloc DMA channel and connect to LCD peripheral
|
||||
gdma_channel_alloc_config_t dma_chan_config = {
|
||||
.direction = GDMA_CHANNEL_DIRECTION_TX,
|
||||
};
|
||||
#if SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AHB
|
||||
ESP_RETURN_ON_ERROR(gdma_new_ahb_channel(&dma_chan_config, &panel->dma_chan), TAG, "alloc DMA channel failed");
|
||||
#elif SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AXI
|
||||
ESP_RETURN_ON_ERROR(gdma_new_axi_channel(&dma_chan_config, &panel->dma_chan), TAG, "alloc DMA channel failed");
|
||||
#endif
|
||||
gdma_connect(panel->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_LCD, 0));
|
||||
|
||||
// configure DMA transfer parameters
|
||||
gdma_transfer_config_t trans_cfg = {
|
||||
.max_data_burst_size = panel->dma_burst_size,
|
||||
.access_ext_mem = true, // frame buffer was allocated from external memory
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(gdma_config_transfer(panel->dma_chan, &trans_cfg), TAG, "config DMA transfer failed");
|
||||
|
||||
// we need to refill the bounce buffer in the DMA EOF interrupt, so only register the callback for bounce buffer mode
|
||||
if (panel->bb_size) {
|
||||
gdma_tx_event_callbacks_t cbs = {
|
||||
.on_trans_eof = lcd_rgb_panel_eof_handler,
|
||||
};
|
||||
gdma_register_tx_event_callbacks(panel->dma_chan, &cbs, panel);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// If we restart GDMA, many pixels already have been transferred to the LCD peripheral.
|
||||
// Looks like that has 16 pixels of FIFO plus one holding register.
|
||||
#define LCD_FIFO_PRESERVE_SIZE_PX (LCD_LL_FIFO_DEPTH + 1)
|
||||
|
||||
static esp_err_t lcd_rgb_panel_create_trans_link(esp_rgb_panel_t *panel)
|
||||
static void lcd_rgb_panel_init_trans_link(esp_rgb_panel_t *panel)
|
||||
{
|
||||
for (int i = 0; i < RGB_LCD_PANEL_DMA_LINKS_REPLICA; i++) {
|
||||
panel->dma_links[i] = &panel->dma_nodes[panel->num_dma_nodes * i];
|
||||
@@ -1007,32 +1051,6 @@ static esp_err_t lcd_rgb_panel_create_trans_link(esp_rgb_panel_t *panel)
|
||||
panel->dma_restart_node.buffer = &p[restart_skip_bytes];
|
||||
panel->dma_restart_node.dw0.length -= restart_skip_bytes;
|
||||
panel->dma_restart_node.dw0.size -= restart_skip_bytes;
|
||||
|
||||
// alloc DMA channel and connect to LCD peripheral
|
||||
gdma_channel_alloc_config_t dma_chan_config = {
|
||||
.direction = GDMA_CHANNEL_DIRECTION_TX,
|
||||
};
|
||||
#if SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AHB
|
||||
ESP_RETURN_ON_ERROR(gdma_new_ahb_channel(&dma_chan_config, &panel->dma_chan), TAG, "alloc DMA channel failed");
|
||||
#elif SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AXI
|
||||
ESP_RETURN_ON_ERROR(gdma_new_axi_channel(&dma_chan_config, &panel->dma_chan), TAG, "alloc DMA channel failed");
|
||||
#endif
|
||||
gdma_connect(panel->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_LCD, 0));
|
||||
gdma_transfer_ability_t ability = {
|
||||
.psram_trans_align = panel->psram_trans_align,
|
||||
.sram_trans_align = panel->sram_trans_align,
|
||||
};
|
||||
gdma_set_transfer_ability(panel->dma_chan, &ability);
|
||||
|
||||
// we need to refill the bounce buffer in the DMA EOF interrupt, so only register the callback for bounce buffer mode
|
||||
if (panel->bb_size) {
|
||||
gdma_tx_event_callbacks_t cbs = {
|
||||
.on_trans_eof = lcd_rgb_panel_eof_handler,
|
||||
};
|
||||
gdma_register_tx_event_callbacks(panel->dma_chan, &cbs, panel);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// reset the GDMA channel every VBlank to stop permanent desyncs from happening.
|
||||
|
||||
@@ -132,8 +132,11 @@ typedef struct {
|
||||
size_t num_fbs; /*!< Number of screen-sized frame buffers that allocated by the driver. By default (set to either 0 or 1) only one frame buffer will be used. Maximum number of buffers are 3 */
|
||||
size_t bounce_buffer_size_px; /*!< If it's non-zero, the driver allocates two DRAM bounce buffers for DMA use.
|
||||
DMA fetching from DRAM bounce buffer is much faster than PSRAM frame buffer. */
|
||||
size_t sram_trans_align; /*!< Alignment of buffers (frame buffer or bounce buffer) that allocated in SRAM */
|
||||
size_t psram_trans_align; /*!< Alignment of buffers (frame buffer) that allocated in PSRAM */
|
||||
size_t sram_trans_align __attribute__((deprecated)); /*!< Alignment of buffers (frame buffer or bounce buffer) that allocated in SRAM */
|
||||
union {
|
||||
size_t psram_trans_align; /*!< Alignment of buffers (frame buffer) that allocated in PSRAM */
|
||||
size_t dma_burst_size; /*!< DMA burst size, in bytes */
|
||||
};
|
||||
int hsync_gpio_num; /*!< GPIO used for HSYNC signal */
|
||||
int vsync_gpio_num; /*!< GPIO used for VSYNC signal */
|
||||
int de_gpio_num; /*!< GPIO used for DE signal, set to -1 if it's not used */
|
||||
|
||||
@@ -31,7 +31,7 @@ static esp_lcd_panel_handle_t test_rgb_panel_initialization(size_t data_width, s
|
||||
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||
esp_lcd_rgb_panel_config_t panel_config = {
|
||||
.data_width = data_width,
|
||||
.psram_trans_align = 64,
|
||||
.dma_burst_size = 64,
|
||||
.bounce_buffer_size_px = bb_pixels,
|
||||
.bits_per_pixel = bpp,
|
||||
.clk_src = LCD_CLK_SRC_DEFAULT,
|
||||
|
||||
@@ -27,7 +27,7 @@ TEST_CASE("lcd_rgb_panel_yuv422_conversion", "[lcd]")
|
||||
esp_lcd_panel_handle_t panel_handle = NULL;
|
||||
esp_lcd_rgb_panel_config_t panel_config = {
|
||||
.data_width = 16,
|
||||
.psram_trans_align = 64,
|
||||
.dma_burst_size = 64,
|
||||
.bits_per_pixel = 16, // YUV422: 16bits per pixel
|
||||
.clk_src = LCD_CLK_SRC_DEFAULT,
|
||||
.disp_gpio_num = TEST_LCD_DISP_EN_GPIO,
|
||||
|
||||
@@ -48,6 +48,7 @@ extern "C" {
|
||||
#define GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT 1 // TX and RX channel in the same pair will share the same interrupt source number
|
||||
|
||||
#define GDMA_LL_AHB_DESC_ALIGNMENT 4
|
||||
#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1
|
||||
|
||||
///////////////////////////////////// Common /////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ extern "C" {
|
||||
#define GDMA_LL_AHB_TX_RX_SHARE_INTERRUPT 1 // TX and RX channel in the same pair will share the same interrupt source number
|
||||
|
||||
#define GDMA_LL_AHB_DESC_ALIGNMENT 4
|
||||
#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1
|
||||
|
||||
///////////////////////////////////// Common /////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "soc/gdma_struct.h"
|
||||
#include "soc/gdma_reg.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/retention_periph_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -102,25 +101,6 @@ extern "C" {
|
||||
|
||||
///////////////////////////////////// Common /////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for the DMA module
|
||||
*/
|
||||
static inline void gdma_ll_enable_bus_clock(int group_id, bool enable)
|
||||
{
|
||||
(void)group_id;
|
||||
PCR.gdma_conf.gdma_clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the DMA module
|
||||
*/
|
||||
static inline void gdma_ll_reset_register(int group_id)
|
||||
{
|
||||
(void)group_id;
|
||||
PCR.gdma_conf.gdma_rst_en = 1;
|
||||
PCR.gdma_conf.gdma_rst_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force enable register clock
|
||||
*/
|
||||
|
||||
@@ -6,8 +6,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
|
||||
#include "hal/gdma_beta3_ll.h"
|
||||
#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1
|
||||
#else
|
||||
#include "hal/ahb_dma_ll.h"
|
||||
#define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for the DMA module
|
||||
*/
|
||||
static inline void gdma_ll_enable_bus_clock(int group_id, bool enable)
|
||||
{
|
||||
(void)group_id;
|
||||
PCR.gdma_conf.gdma_clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the DMA module
|
||||
*/
|
||||
static inline void gdma_ll_reset_register(int group_id)
|
||||
{
|
||||
(void)group_id;
|
||||
PCR.gdma_conf.gdma_rst_en = 1;
|
||||
PCR.gdma_conf.gdma_rst_en = 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/gdma_types.h"
|
||||
#include "hal/assert.h"
|
||||
#include "soc/ahb_dma_struct.h"
|
||||
#include "soc/ahb_dma_reg.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/retention_periph_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -99,25 +99,6 @@ extern "C" {
|
||||
|
||||
///////////////////////////////////// Common /////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for the DMA module
|
||||
*/
|
||||
static inline void gdma_ll_enable_bus_clock(int group_id, bool enable)
|
||||
{
|
||||
(void)group_id;
|
||||
PCR.gdma_conf.gdma_clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the DMA module
|
||||
*/
|
||||
static inline void gdma_ll_reset_register(int group_id)
|
||||
{
|
||||
(void)group_id;
|
||||
PCR.gdma_conf.gdma_rst_en = 1;
|
||||
PCR.gdma_conf.gdma_rst_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force enable register clock
|
||||
*/
|
||||
@@ -212,11 +193,10 @@ static inline void ahb_dma_ll_rx_enable_owner_check(ahb_dma_dev_t *dev, uint32_t
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA RX channel burst reading data, disabled by default
|
||||
* @brief Enable DMA RX channel burst reading data, always enabled
|
||||
*/
|
||||
static inline void ahb_dma_ll_rx_enable_data_burst(ahb_dma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
// dev->channel[channel].in.in_conf0.in_data_burst_mode_sel_chn = enable; // single/incr4/incr8/incr16
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,6 +207,32 @@ static inline void ahb_dma_ll_rx_enable_descriptor_burst(ahb_dma_dev_t *dev, uin
|
||||
dev->channel[channel].in.in_conf0.indscr_burst_en_chn = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set RX channel burst size
|
||||
*/
|
||||
static inline void ahb_dma_ll_rx_set_burst_size(ahb_dma_dev_t *dev, uint32_t channel, uint32_t sz)
|
||||
{
|
||||
uint8_t burst_mode = 0;
|
||||
switch (sz) {
|
||||
case 4:
|
||||
burst_mode = 0; // single
|
||||
break;
|
||||
case 16:
|
||||
burst_mode = 1; // incr4
|
||||
break;
|
||||
case 32:
|
||||
burst_mode = 2; // incr8
|
||||
break;
|
||||
case 64:
|
||||
burst_mode = 3; // incr16
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
dev->channel[channel].in.in_conf0.in_data_burst_mode_sel_chn = burst_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset DMA RX channel FSM and FIFO pointer
|
||||
*/
|
||||
@@ -440,11 +446,10 @@ static inline void ahb_dma_ll_tx_enable_owner_check(ahb_dma_dev_t *dev, uint32_t
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA TX channel burst sending data, disabled by default
|
||||
* @brief Enable DMA TX channel burst sending data, always enabled
|
||||
*/
|
||||
static inline void ahb_dma_ll_tx_enable_data_burst(ahb_dma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
// dev->channel[channel].out.out_conf0.out_data_burst_mode_sel_chn = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -455,6 +460,32 @@ static inline void ahb_dma_ll_tx_enable_descriptor_burst(ahb_dma_dev_t *dev, uin
|
||||
dev->channel[channel].out.out_conf0.outdscr_burst_en_chn = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set TX channel burst size
|
||||
*/
|
||||
static inline void ahb_dma_ll_tx_set_burst_size(ahb_dma_dev_t *dev, uint32_t channel, uint32_t sz)
|
||||
{
|
||||
uint8_t burst_mode = 0;
|
||||
switch (sz) {
|
||||
case 4:
|
||||
burst_mode = 0; // single
|
||||
break;
|
||||
case 16:
|
||||
burst_mode = 1; // incr4
|
||||
break;
|
||||
case 32:
|
||||
burst_mode = 2; // incr8
|
||||
break;
|
||||
case 64:
|
||||
burst_mode = 3; // incr16
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
dev->channel[channel].out.out_conf0.out_data_burst_mode_sel_chn = burst_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set TX channel EOF mode
|
||||
*/
|
||||
|
||||
@@ -51,6 +51,7 @@ extern "C" {
|
||||
#define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group
|
||||
|
||||
#define GDMA_LL_AHB_DESC_ALIGNMENT 4
|
||||
#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1
|
||||
|
||||
#define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \
|
||||
(uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \
|
||||
|
||||
@@ -51,6 +51,7 @@ extern "C" {
|
||||
#define GDMA_LL_AHB_PAIRS_PER_GROUP 3 // Number of GDMA pairs in each AHB group
|
||||
|
||||
#define GDMA_LL_AHB_DESC_ALIGNMENT 4
|
||||
#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1
|
||||
|
||||
#define GDMA_LL_TX_ETM_EVENT_TABLE(group, chan, event) \
|
||||
(uint32_t[1][3][GDMA_ETM_EVENT_MAX]){{{ \
|
||||
|
||||
@@ -125,7 +125,7 @@ static inline void axi_dma_ll_rx_enable_owner_check(axi_dma_dev_t *dev, uint32_t
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA RX channel burst reading data, disabled by default
|
||||
* @brief Enable DMA RX channel burst reading data, always enabled
|
||||
*/
|
||||
static inline void axi_dma_ll_rx_enable_data_burst(axi_dma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
@@ -139,6 +139,16 @@ static inline void axi_dma_ll_rx_enable_descriptor_burst(axi_dma_dev_t *dev, uin
|
||||
dev->in[channel].conf.in_conf0.indscr_burst_en_chn = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the RX channel burst size
|
||||
*/
|
||||
static inline void axi_dma_ll_rx_set_burst_size(axi_dma_dev_t *dev, uint32_t channel, uint32_t sz)
|
||||
{
|
||||
HAL_ASSERT(sz >= 8 && sz <= 128);
|
||||
int ctz = __builtin_ctz(sz);
|
||||
dev->in[channel].conf.in_conf0.in_burst_size_sel_chn = ctz - 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset DMA RX channel FSM and FIFO pointer
|
||||
*/
|
||||
@@ -274,11 +284,11 @@ static inline void axi_dma_ll_rx_enable_etm_task(axi_dma_dev_t *dev, uint32_t ch
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether to enable the mean access ecc or aes domain
|
||||
* @brief Whether to enable access to ecc or aes memory
|
||||
*/
|
||||
static inline void axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(axi_dma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->in[channel].conf.in_conf0.in_ecc_aec_en_chn = enable;
|
||||
dev->in[channel].conf.in_conf0.in_ecc_aes_en_chn = enable;
|
||||
}
|
||||
|
||||
///////////////////////////////////// TX /////////////////////////////////////////
|
||||
@@ -333,7 +343,7 @@ static inline void axi_dma_ll_tx_enable_owner_check(axi_dma_dev_t *dev, uint32_t
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable DMA TX channel burst sending data, disabled by default
|
||||
* @brief Enable DMA TX channel burst sending data, always enabled
|
||||
*/
|
||||
static inline void axi_dma_ll_tx_enable_data_burst(axi_dma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
@@ -347,6 +357,16 @@ static inline void axi_dma_ll_tx_enable_descriptor_burst(axi_dma_dev_t *dev, uin
|
||||
dev->out[channel].conf.out_conf0.outdscr_burst_en_chn = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the TX channel burst size
|
||||
*/
|
||||
static inline void axi_dma_ll_tx_set_burst_size(axi_dma_dev_t *dev, uint32_t channel, uint32_t sz)
|
||||
{
|
||||
HAL_ASSERT(sz >= 8 && sz <= 128);
|
||||
int ctz = __builtin_ctz(sz);
|
||||
dev->out[channel].conf.out_conf0.out_burst_size_sel_chn = ctz - 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set TX channel EOF mode
|
||||
*/
|
||||
@@ -480,11 +500,11 @@ static inline void axi_dma_ll_tx_enable_etm_task(axi_dma_dev_t *dev, uint32_t ch
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Whether to enable the mean access ecc or aes domain
|
||||
* @brief Whether to enable access to ecc or aes memory
|
||||
*/
|
||||
static inline void axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(axi_dma_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->out[channel].conf.out_conf0.out_ecc_aec_en_chn = enable;
|
||||
dev->out[channel].conf.out_conf0.out_ecc_aes_en_chn = enable;
|
||||
}
|
||||
|
||||
///////////////////////////////////// CRC-TX /////////////////////////////////////////
|
||||
|
||||
@@ -62,6 +62,9 @@ extern "C" {
|
||||
|
||||
#define GDMA_LL_AHB_DESC_ALIGNMENT 4
|
||||
|
||||
#define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size
|
||||
#define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1
|
||||
|
||||
///////////////////////////////////// Common /////////////////////////////////////////
|
||||
|
||||
/**
|
||||
@@ -177,20 +180,20 @@ static inline void gdma_ll_rx_reset_channel(gdma_dev_t *dev, uint32_t channel)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set DMA RX channel memory block size based on the alignment requirement
|
||||
* @param align Supported value: 16/32/64
|
||||
* @brief Set DMA RX channel memory block size based on the burst requirement
|
||||
* @param burst_sz Supported value: 16/32/64
|
||||
*/
|
||||
static inline void gdma_ll_rx_set_ext_mem_block_size(gdma_dev_t *dev, uint32_t channel, uint8_t align)
|
||||
static inline void gdma_ll_rx_set_burst_size(gdma_dev_t *dev, uint32_t channel, uint32_t burst_sz)
|
||||
{
|
||||
uint32_t block_size = 0;
|
||||
switch (align) {
|
||||
case 64: // 64 Bytes alignment
|
||||
switch (burst_sz) {
|
||||
case 64:
|
||||
block_size = GDMA_LL_EXT_MEM_BK_SIZE_64B;
|
||||
break;
|
||||
case 32: // 32 Bytes alignment
|
||||
case 32:
|
||||
block_size = GDMA_LL_EXT_MEM_BK_SIZE_32B;
|
||||
break;
|
||||
case 16: // 16 Bytes alignment
|
||||
case 16:
|
||||
block_size = GDMA_LL_EXT_MEM_BK_SIZE_16B;
|
||||
break;
|
||||
default:
|
||||
@@ -461,20 +464,20 @@ static inline void gdma_ll_tx_reset_channel(gdma_dev_t *dev, uint32_t channel)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set DMA TX channel memory block size based on the alignment requirement
|
||||
* @param align Supported value: 16/32/64
|
||||
* @brief Set DMA TX channel memory block size based on the burst requirement
|
||||
* @param burst_sz Supported value: 16/32/64
|
||||
*/
|
||||
static inline void gdma_ll_tx_set_ext_mem_block_size(gdma_dev_t *dev, uint32_t channel, uint8_t align)
|
||||
static inline void gdma_ll_tx_set_burst_size(gdma_dev_t *dev, uint32_t channel, uint32_t burst_sz)
|
||||
{
|
||||
uint32_t block_size = 0;
|
||||
switch (align) {
|
||||
case 64: // 64 Bytes alignment
|
||||
switch (burst_sz) {
|
||||
case 64:
|
||||
block_size = GDMA_LL_EXT_MEM_BK_SIZE_64B;
|
||||
break;
|
||||
case 32: // 32 Bytes alignment
|
||||
case 32:
|
||||
block_size = GDMA_LL_EXT_MEM_BK_SIZE_32B;
|
||||
break;
|
||||
case 16: // 16 Bytes alignment
|
||||
case 16:
|
||||
block_size = GDMA_LL_EXT_MEM_BK_SIZE_16B;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -91,16 +91,16 @@ void gdma_ahb_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channe
|
||||
}
|
||||
}
|
||||
|
||||
#if SOC_AHB_GDMA_SUPPORT_PSRAM
|
||||
void gdma_ahb_hal_set_ext_mem_align(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align)
|
||||
#if GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE
|
||||
void gdma_ahb_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz)
|
||||
{
|
||||
if (dir == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
gdma_ll_rx_set_ext_mem_block_size(hal->dev, chan_id, align);
|
||||
gdma_ll_rx_set_burst_size(hal->dev, chan_id, burst_sz);
|
||||
} else {
|
||||
gdma_ll_tx_set_ext_mem_block_size(hal->dev, chan_id, align);
|
||||
gdma_ll_tx_set_burst_size(hal->dev, chan_id, burst_sz);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE
|
||||
|
||||
void gdma_ahb_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back, bool eof_till_popped)
|
||||
{
|
||||
@@ -195,8 +195,8 @@ void gdma_ahb_hal_init(gdma_hal_context_t *hal, const gdma_hal_config_t *config)
|
||||
#if SOC_GDMA_SUPPORT_ETM
|
||||
hal->enable_etm_task = gdma_ahb_hal_enable_etm_task;
|
||||
#endif
|
||||
#if SOC_AHB_GDMA_SUPPORT_PSRAM
|
||||
hal->set_ext_mem_align = gdma_ahb_hal_set_ext_mem_align;
|
||||
#endif // SOC_AHB_GDMA_SUPPORT_PSRAM
|
||||
#if GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE
|
||||
hal->set_burst_size = gdma_ahb_hal_set_burst_size;
|
||||
#endif // GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE
|
||||
hal->priv_data = &gdma_ahb_hal_priv_data;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -104,6 +104,17 @@ void gdma_ahb_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channe
|
||||
}
|
||||
}
|
||||
|
||||
#if GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE
|
||||
void gdma_ahb_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz)
|
||||
{
|
||||
if (dir == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
ahb_dma_ll_rx_set_burst_size(hal->ahb_dma_dev, chan_id, burst_sz);
|
||||
} else {
|
||||
ahb_dma_ll_tx_set_burst_size(hal->ahb_dma_dev, chan_id, burst_sz);
|
||||
}
|
||||
}
|
||||
#endif // GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE
|
||||
|
||||
void gdma_ahb_hal_enable_intr(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t intr_event_mask, bool en_or_dis)
|
||||
{
|
||||
if (dir == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
@@ -246,5 +257,8 @@ void gdma_ahb_hal_init(gdma_hal_context_t *hal, const gdma_hal_config_t *config)
|
||||
#if SOC_GDMA_SUPPORT_ETM
|
||||
hal->enable_etm_task = gdma_ahb_hal_enable_etm_task;
|
||||
#endif // SOC_GDMA_SUPPORT_ETM
|
||||
#if GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE
|
||||
hal->set_burst_size = gdma_ahb_hal_set_burst_size;
|
||||
#endif // GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE
|
||||
ahb_dma_ll_set_default_memory_range(hal->ahb_dma_dev);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -91,6 +91,15 @@ void gdma_axi_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channe
|
||||
}
|
||||
}
|
||||
|
||||
void gdma_axi_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz)
|
||||
{
|
||||
if (dir == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
axi_dma_ll_rx_set_burst_size(hal->axi_dma_dev, chan_id, burst_sz);
|
||||
} else {
|
||||
axi_dma_ll_tx_set_burst_size(hal->axi_dma_dev, chan_id, burst_sz);
|
||||
}
|
||||
}
|
||||
|
||||
void gdma_axi_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back, bool eof_till_popped)
|
||||
{
|
||||
if (dir == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
@@ -153,6 +162,15 @@ uint32_t gdma_axi_hal_get_eof_desc_addr(gdma_hal_context_t *hal, int chan_id, gd
|
||||
}
|
||||
}
|
||||
|
||||
void gdma_axi_hal_enable_access_encrypt_mem(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis)
|
||||
{
|
||||
if (dir == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(hal->axi_dma_dev, chan_id, en_or_dis);
|
||||
} else {
|
||||
axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(hal->axi_dma_dev, chan_id, en_or_dis);
|
||||
}
|
||||
}
|
||||
|
||||
#if SOC_GDMA_SUPPORT_CRC
|
||||
void gdma_axi_hal_clear_crc(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir)
|
||||
{
|
||||
@@ -238,6 +256,8 @@ void gdma_axi_hal_init(gdma_hal_context_t *hal, const gdma_hal_config_t *config)
|
||||
hal->read_intr_status = gdma_axi_hal_read_intr_status;
|
||||
hal->get_intr_status_reg = gdma_axi_hal_get_intr_status_reg;
|
||||
hal->get_eof_desc_addr = gdma_axi_hal_get_eof_desc_addr;
|
||||
hal->set_burst_size = gdma_axi_hal_set_burst_size;
|
||||
hal->enable_access_encrypt_mem = gdma_axi_hal_enable_access_encrypt_mem;
|
||||
#if SOC_GDMA_SUPPORT_CRC
|
||||
hal->clear_crc = gdma_axi_hal_clear_crc;
|
||||
hal->set_crc_poly = gdma_axi_hal_set_crc_poly;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -53,10 +53,10 @@ void gdma_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channel_di
|
||||
hal->enable_burst(hal, chan_id, dir, en_data_burst, en_desc_burst);
|
||||
}
|
||||
|
||||
void gdma_hal_set_ext_mem_align(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align)
|
||||
void gdma_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz)
|
||||
{
|
||||
if (hal->set_ext_mem_align) {
|
||||
hal->set_ext_mem_align(hal, chan_id, dir, align);
|
||||
if (hal->set_burst_size) {
|
||||
hal->set_burst_size(hal, chan_id, dir, burst_sz);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,13 @@ uint32_t gdma_hal_get_eof_desc_addr(gdma_hal_context_t *hal, int chan_id, gdma_c
|
||||
return hal->get_eof_desc_addr(hal, chan_id, dir, is_success);
|
||||
}
|
||||
|
||||
void gdma_hal_enable_access_encrypt_mem(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis)
|
||||
{
|
||||
if (hal->enable_access_encrypt_mem) {
|
||||
hal->enable_access_encrypt_mem(hal, chan_id, dir, en_or_dis);
|
||||
}
|
||||
}
|
||||
|
||||
#if SOC_GDMA_SUPPORT_CRC
|
||||
void gdma_hal_clear_crc(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir)
|
||||
{
|
||||
|
||||
@@ -80,13 +80,14 @@ struct gdma_hal_context_t {
|
||||
void (*connect_peri)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, gdma_trigger_peripheral_t periph, int periph_sub_id); /// Connect the channel to a peripheral
|
||||
void (*disconnect_peri)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir); /// Disconnect the channel from a peripheral
|
||||
void (*enable_burst)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_data_burst, bool en_desc_burst); /// Enable burst mode
|
||||
void (*set_ext_mem_align)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align); /// Set the alignment of the external memory
|
||||
void (*set_burst_size)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz); /// Set burst transfer size
|
||||
void (*set_strategy)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back, bool eof_till_popped); /// Set some misc strategy of the channel behaviour
|
||||
uint32_t (*get_intr_status_reg)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir); // Get the interrupt status register address
|
||||
void (*enable_intr)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t intr_event_mask, bool en_or_dis); /// Enable the channel interrupt
|
||||
void (*clear_intr)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t intr_event_mask); /// Clear the channel interrupt
|
||||
uint32_t (*read_intr_status)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool raw); /// Read the channel interrupt status
|
||||
uint32_t (*get_eof_desc_addr)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool is_success); /// Get the address of the descriptor with success/error EOF flag set
|
||||
void (*enable_access_encrypt_mem)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis); /// Enable the access to the encrypted memory
|
||||
#if SOC_GDMA_SUPPORT_CRC
|
||||
void (*clear_crc)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir); /// Clear the CRC interim results
|
||||
void (*set_crc_poly)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, const gdma_hal_crc_config_t *config); /// Set the CRC polynomial
|
||||
@@ -115,7 +116,7 @@ void gdma_hal_disconnect_peri(gdma_hal_context_t *hal, int chan_id, gdma_channel
|
||||
|
||||
void gdma_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_data_burst, bool en_desc_burst);
|
||||
|
||||
void gdma_hal_set_ext_mem_align(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align);
|
||||
void gdma_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz);
|
||||
|
||||
void gdma_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back, bool eof_till_popped);
|
||||
|
||||
@@ -129,6 +130,8 @@ uint32_t gdma_hal_read_intr_status(gdma_hal_context_t *hal, int chan_id, gdma_ch
|
||||
|
||||
uint32_t gdma_hal_get_eof_desc_addr(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool is_success);
|
||||
|
||||
void gdma_hal_enable_access_encrypt_mem(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis);
|
||||
|
||||
#if SOC_GDMA_SUPPORT_CRC
|
||||
void gdma_hal_build_parallel_crc_matrix(int crc_width, uint32_t crc_poly_hex, int data_width,
|
||||
uint32_t *lfsr_transform_matrix, uint32_t *data_transform_matrix);
|
||||
|
||||
@@ -28,7 +28,7 @@ void gdma_ahb_hal_disconnect_peri(gdma_hal_context_t *hal, int chan_id, gdma_cha
|
||||
|
||||
void gdma_ahb_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_data_burst, bool en_desc_burst);
|
||||
|
||||
void gdma_ahb_hal_set_ext_mem_align(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align);
|
||||
void gdma_ahb_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz);
|
||||
|
||||
void gdma_ahb_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back, bool eof_till_popped);
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ void gdma_axi_hal_disconnect_peri(gdma_hal_context_t *hal, int chan_id, gdma_cha
|
||||
|
||||
void gdma_axi_hal_enable_burst(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_data_burst, bool en_desc_burst);
|
||||
|
||||
void gdma_axi_hal_set_burst_size(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t burst_sz);
|
||||
|
||||
void gdma_axi_hal_set_ext_mem_align(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint8_t align);
|
||||
|
||||
void gdma_axi_hal_set_strategy(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_owner_check, bool en_desc_write_back, bool eof_till_popped);
|
||||
|
||||
@@ -73,12 +73,6 @@ static esp_err_t crypto_shared_gdma_init(void)
|
||||
.direction = GDMA_CHANNEL_DIRECTION_RX,
|
||||
};
|
||||
|
||||
gdma_transfer_ability_t transfer_ability = {
|
||||
.sram_trans_align = 1,
|
||||
.psram_trans_align = 16,
|
||||
};
|
||||
|
||||
|
||||
ret = crypto_shared_gdma_new_channel(&channel_config_tx, &tx_channel);
|
||||
if (ret != ESP_OK) {
|
||||
goto err;
|
||||
@@ -90,9 +84,13 @@ static esp_err_t crypto_shared_gdma_init(void)
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
gdma_set_transfer_ability(tx_channel, &transfer_ability);
|
||||
gdma_set_transfer_ability(rx_channel, &transfer_ability);
|
||||
gdma_transfer_config_t transfer_cfg = {
|
||||
.max_data_burst_size = 16,
|
||||
.access_ext_mem = true, // crypto peripheral may want to access PSRAM
|
||||
};
|
||||
gdma_config_transfer(tx_channel, &transfer_cfg);
|
||||
transfer_cfg.max_data_burst_size = 0;
|
||||
gdma_config_transfer(rx_channel, &transfer_cfg);
|
||||
|
||||
gdma_connect(rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_AES, 0));
|
||||
gdma_connect(tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_AES, 0));
|
||||
@@ -223,7 +221,7 @@ bool esp_crypto_shared_gdma_done(void)
|
||||
{
|
||||
int rx_ch_id = 0;
|
||||
gdma_get_channel_id(rx_channel, &rx_ch_id);
|
||||
while(1) {
|
||||
while (1) {
|
||||
if ((axi_dma_ll_rx_get_interrupt_status(&AXI_DMA, rx_ch_id, true) & 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ config SOC_CPU_IDRAM_SPLIT_USING_PMP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_DMA_CAN_ACCESS_MSPI_MEM
|
||||
config SOC_DMA_CAN_ACCESS_FLASH
|
||||
bool
|
||||
default y
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
// #define SOC_DS_KEY_CHECK_MAX_WAIT_US (1100)
|
||||
|
||||
/*-------------------------- DMA Common CAPS ----------------------------------------*/
|
||||
#define SOC_DMA_CAN_ACCESS_MSPI_MEM 1 /*!< DMA can access MSPI memory (e.g. Flash, PSRAM) */
|
||||
#define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */
|
||||
|
||||
/*-------------------------- GDMA CAPS -------------------------------------*/
|
||||
#define SOC_AHB_GDMA_VERSION 2
|
||||
|
||||
@@ -479,7 +479,7 @@ config SOC_DS_KEY_CHECK_MAX_WAIT_US
|
||||
int
|
||||
default 1100
|
||||
|
||||
config SOC_DMA_CAN_ACCESS_MSPI_MEM
|
||||
config SOC_DMA_CAN_ACCESS_FLASH
|
||||
bool
|
||||
default y
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -273,10 +273,10 @@ typedef union {
|
||||
* 1:mean disable cmd of this ch0
|
||||
*/
|
||||
uint32_t in_cmd_disable_chn: 1;
|
||||
/** in_ecc_aec_en_chn : R/W; bitpos: [8]; default: 0;
|
||||
/** in_ecc_aes_en_chn : R/W; bitpos: [8]; default: 0;
|
||||
* 1: mean access ecc or aes domain,0: mean not
|
||||
*/
|
||||
uint32_t in_ecc_aec_en_chn: 1;
|
||||
uint32_t in_ecc_aes_en_chn: 1;
|
||||
/** indscr_burst_en_chn : R/W; bitpos: [9]; default: 0;
|
||||
* Set this bit to 1 to enable INCR burst transfer for Rx channel 0 reading link
|
||||
* descriptor when accessing internal SRAM.
|
||||
@@ -567,7 +567,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t rx_ch_arb_weigh_chn: 4;
|
||||
/** rx_arb_weigh_opt_dir_chn : R/W; bitpos: [8]; default: 0;
|
||||
* 0: mean not optimazation weight function ,1: mean optimazation
|
||||
* 0: mean not optimization weight function ,1: mean optimization
|
||||
*/
|
||||
uint32_t rx_arb_weigh_opt_dir_chn: 1;
|
||||
uint32_t reserved_9: 23;
|
||||
@@ -952,10 +952,10 @@ typedef union {
|
||||
* 1:mean disable cmd of this chn
|
||||
*/
|
||||
uint32_t out_cmd_disable_chn: 1;
|
||||
/** out_ecc_aec_en_chn : R/W; bitpos: [9]; default: 0;
|
||||
/** out_ecc_aes_en_chn : R/W; bitpos: [9]; default: 0;
|
||||
* 1: mean access ecc or aes domain,0: mean not
|
||||
*/
|
||||
uint32_t out_ecc_aec_en_chn: 1;
|
||||
uint32_t out_ecc_aes_en_chn: 1;
|
||||
/** outdscr_burst_en_chn : R/W; bitpos: [10]; default: 0;
|
||||
* Set this bit to 1 to enable INCR burst transfer for Tx channel0 reading link
|
||||
* descriptor when accessing internal SRAM.
|
||||
@@ -1238,7 +1238,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t tx_ch_arb_weigh_chn: 4;
|
||||
/** tx_arb_weigh_opt_dir_chn : R/W; bitpos: [8]; default: 0;
|
||||
* 0: mean not optimazation weight function ,1: mean optimazation
|
||||
* 0: mean not optimization weight function ,1: mean optimization
|
||||
*/
|
||||
uint32_t tx_arb_weigh_opt_dir_chn: 1;
|
||||
uint32_t reserved_9: 23;
|
||||
@@ -1374,106 +1374,6 @@ typedef union {
|
||||
uint32_t val;
|
||||
} axi_dma_tx_crc_data_en_addr_chn_reg_t;
|
||||
|
||||
/** Type of out_conf0_ch1 register
|
||||
* Configure 0 register of Tx channel1
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** out_rst_ch1 : R/W; bitpos: [0]; default: 0;
|
||||
* This bit is used to reset AXI_DMA channel1 Tx FSM and Tx FIFO pointer.
|
||||
*/
|
||||
uint32_t out_rst_ch1: 1;
|
||||
/** out_loop_test_ch1 : R/W; bitpos: [1]; default: 0;
|
||||
* reserved
|
||||
*/
|
||||
uint32_t out_loop_test_ch1: 1;
|
||||
/** out_auto_wrback_ch1 : R/W; bitpos: [2]; default: 0;
|
||||
* Set this bit to enable automatic outlink-writeback when all the data in tx buffer
|
||||
* has been transmitted.
|
||||
*/
|
||||
uint32_t out_auto_wrback_ch1: 1;
|
||||
/** out_eof_mode_ch1 : R/W; bitpos: [3]; default: 1;
|
||||
* EOF flag generation mode when transmitting data. 1: EOF flag for Tx channel1 is
|
||||
* generated when data need to transmit has been popped from FIFO in AXI_DMA
|
||||
*/
|
||||
uint32_t out_eof_mode_ch1: 1;
|
||||
/** out_etm_en_ch1 : R/W; bitpos: [4]; default: 0;
|
||||
* Set this bit to 1 to enable etm control mode, dma Tx channel1 is triggered by etm
|
||||
* task.
|
||||
*/
|
||||
uint32_t out_etm_en_ch1: 1;
|
||||
/** out_burst_size_sel_ch1 : R/W; bitpos: [7:5]; default: 0;
|
||||
* 3'b000-3'b100:burst length 8byte~128byte
|
||||
*/
|
||||
uint32_t out_burst_size_sel_ch1: 3;
|
||||
/** out_cmd_disable_ch1 : R/W; bitpos: [8]; default: 0;
|
||||
* 1:mean disable cmd of this ch1
|
||||
*/
|
||||
uint32_t out_cmd_disable_ch1: 1;
|
||||
/** out_ecc_aec_en_ch1 : R/W; bitpos: [9]; default: 0;
|
||||
* 1: mean access ecc or aes domain,0: mean not
|
||||
*/
|
||||
uint32_t out_ecc_aec_en_ch1: 1;
|
||||
/** outdscr_burst_en_ch1 : R/W; bitpos: [10]; default: 0;
|
||||
* Set this bit to 1 to enable INCR burst transfer for Tx channel1 reading link
|
||||
* descriptor when accessing internal SRAM.
|
||||
*/
|
||||
uint32_t outdscr_burst_en_ch1: 1;
|
||||
uint32_t reserved_11: 21;
|
||||
};
|
||||
uint32_t val;
|
||||
} axi_dma_out_conf0_ch1_reg_t;
|
||||
|
||||
/** Type of out_conf0_ch2 register
|
||||
* Configure 0 register of Tx channel2
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** out_rst_ch2 : R/W; bitpos: [0]; default: 0;
|
||||
* This bit is used to reset AXI_DMA channel2 Tx FSM and Tx FIFO pointer.
|
||||
*/
|
||||
uint32_t out_rst_ch2: 1;
|
||||
/** out_loop_test_ch2 : R/W; bitpos: [1]; default: 0;
|
||||
* reserved
|
||||
*/
|
||||
uint32_t out_loop_test_ch2: 1;
|
||||
/** out_auto_wrback_ch2 : R/W; bitpos: [2]; default: 0;
|
||||
* Set this bit to enable automatic outlink-writeback when all the data in tx buffer
|
||||
* has been transmitted.
|
||||
*/
|
||||
uint32_t out_auto_wrback_ch2: 1;
|
||||
/** out_eof_mode_ch2 : R/W; bitpos: [3]; default: 1;
|
||||
* EOF flag generation mode when transmitting data. 1: EOF flag for Tx channel2 is
|
||||
* generated when data need to transmit has been popped from FIFO in AXI_DMA
|
||||
*/
|
||||
uint32_t out_eof_mode_ch2: 1;
|
||||
/** out_etm_en_ch2 : R/W; bitpos: [4]; default: 0;
|
||||
* Set this bit to 1 to enable etm control mode, dma Tx channel2 is triggered by etm
|
||||
* task.
|
||||
*/
|
||||
uint32_t out_etm_en_ch2: 1;
|
||||
/** out_burst_size_sel_ch2 : R/W; bitpos: [7:5]; default: 0;
|
||||
* 3'b000-3'b100:burst length 8byte~128byte
|
||||
*/
|
||||
uint32_t out_burst_size_sel_ch2: 3;
|
||||
/** out_cmd_disable_ch2 : R/W; bitpos: [8]; default: 0;
|
||||
* 1:mean disable cmd of this ch2
|
||||
*/
|
||||
uint32_t out_cmd_disable_ch2: 1;
|
||||
/** out_ecc_aec_en_ch2 : R/W; bitpos: [9]; default: 0;
|
||||
* 1: mean access ecc or aes domain,0: mean not
|
||||
*/
|
||||
uint32_t out_ecc_aec_en_ch2: 1;
|
||||
/** outdscr_burst_en_ch2 : R/W; bitpos: [10]; default: 0;
|
||||
* Set this bit to 1 to enable INCR burst transfer for Tx channel2 reading link
|
||||
* descriptor when accessing internal SRAM.
|
||||
*/
|
||||
uint32_t outdscr_burst_en_ch2: 1;
|
||||
uint32_t reserved_11: 21;
|
||||
};
|
||||
uint32_t val;
|
||||
} axi_dma_out_conf0_ch2_reg_t;
|
||||
|
||||
/** Group: Configuration Registers */
|
||||
/** Type of arb_timeout register
|
||||
* This retister is used to config arbiter time slice
|
||||
@@ -1705,12 +1605,12 @@ typedef union {
|
||||
|
||||
/** Group: Status Registers */
|
||||
/** Type of wresp_cnt register
|
||||
* AXI wr responce cnt register.
|
||||
* AXI wr response cnt register.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** wresp_cnt : RO; bitpos: [3:0]; default: 0;
|
||||
* axi wr responce cnt reg.
|
||||
* axi wr response cnt reg.
|
||||
*/
|
||||
uint32_t wresp_cnt: 4;
|
||||
uint32_t reserved_4: 28;
|
||||
@@ -1719,12 +1619,12 @@ typedef union {
|
||||
} axi_dma_wresp_cnt_reg_t;
|
||||
|
||||
/** Type of rresp_cnt register
|
||||
* AXI wr responce cnt register.
|
||||
* AXI wr response cnt register.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** rresp_cnt : RO; bitpos: [3:0]; default: 0;
|
||||
* axi rd responce cnt reg.
|
||||
* axi rd response cnt reg.
|
||||
*/
|
||||
uint32_t rresp_cnt: 4;
|
||||
uint32_t reserved_4: 28;
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
#define SOC_DS_KEY_CHECK_MAX_WAIT_US (1100)
|
||||
|
||||
/*-------------------------- DMA Common CAPS ----------------------------------------*/
|
||||
#define SOC_DMA_CAN_ACCESS_MSPI_MEM 1 /*!< DMA can access MSPI memory (e.g. Flash, PSRAM) */
|
||||
#define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */
|
||||
|
||||
/*-------------------------- GDMA CAPS -------------------------------------*/
|
||||
#define SOC_AHB_GDMA_VERSION 2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -37,7 +37,6 @@ TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]")
|
||||
bn = crypto_bignum_init_set(buf, 32);
|
||||
TEST_ASSERT_NOT_NULL(bn);
|
||||
|
||||
|
||||
TEST_ASSERT(crypto_bignum_to_bin(bn, buf2, 32, 0) == 32);
|
||||
|
||||
TEST_ASSERT(!memcmp(buf, buf2, 32));
|
||||
@@ -245,7 +244,6 @@ TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]")
|
||||
uint8_t buf1[32], buf2[32];
|
||||
crypto_bignum *bn1, *bn2;
|
||||
|
||||
|
||||
buf1[0] = 0xf;
|
||||
buf2[0] = 0x11;
|
||||
|
||||
@@ -277,7 +275,6 @@ TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Conversion macros for embedded constants:
|
||||
* build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
|
||||
@@ -322,30 +319,29 @@ TEST_CASE("Test crypto lib bignum apis", "[wpa_crypto]")
|
||||
* (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
|
||||
* Allocate a new memory as well so that it can be freed.
|
||||
*/
|
||||
static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len )
|
||||
static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len)
|
||||
{
|
||||
X->MBEDTLS_PRIVATE(s) = 1;
|
||||
X->MBEDTLS_PRIVATE(n) = len / sizeof( mbedtls_mpi_uint );
|
||||
X->MBEDTLS_PRIVATE(n) = len / sizeof(mbedtls_mpi_uint);
|
||||
X->MBEDTLS_PRIVATE(p) = os_zalloc(len);
|
||||
memcpy(X->MBEDTLS_PRIVATE(p), (void *)p, len);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
|
||||
{
|
||||
set_leak_threshold(600);
|
||||
set_leak_threshold(620);
|
||||
|
||||
static const mbedtls_mpi_uint secp256r1_gx[] = {
|
||||
BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
|
||||
BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
|
||||
BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
|
||||
BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
|
||||
BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4),
|
||||
BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77),
|
||||
BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8),
|
||||
BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B),
|
||||
};
|
||||
static const mbedtls_mpi_uint secp256r1_gy[] = {
|
||||
BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
|
||||
BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
|
||||
BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
|
||||
BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
|
||||
BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB),
|
||||
BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B),
|
||||
BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E),
|
||||
BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F),
|
||||
};
|
||||
|
||||
{
|
||||
@@ -393,8 +389,8 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
|
||||
TEST_ASSERT_NOT_NULL(q);
|
||||
TEST_ASSERT_NOT_NULL(r);
|
||||
|
||||
mbedtls_mpi_init( &num );
|
||||
mbedtls_mpi_lset( &num, 3 );
|
||||
mbedtls_mpi_init(&num);
|
||||
mbedtls_mpi_lset(&num, 3);
|
||||
|
||||
ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx));
|
||||
ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy));
|
||||
@@ -408,7 +404,7 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
|
||||
|
||||
TEST_ASSERT(crypto_ec_point_cmp(e, q, r) == 0);
|
||||
|
||||
mbedtls_mpi_free( &num );
|
||||
mbedtls_mpi_free(&num);
|
||||
crypto_ec_point_deinit(p, 1);
|
||||
crypto_ec_point_deinit(q, 1);
|
||||
crypto_ec_point_deinit(r, 1);
|
||||
@@ -432,8 +428,8 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
|
||||
TEST_ASSERT_NOT_NULL(q);
|
||||
TEST_ASSERT_NOT_NULL(r);
|
||||
|
||||
mbedtls_mpi_init( &num );
|
||||
mbedtls_mpi_lset( &num, 100 );
|
||||
mbedtls_mpi_init(&num);
|
||||
mbedtls_mpi_lset(&num, 100);
|
||||
|
||||
ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx));
|
||||
ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy));
|
||||
@@ -448,7 +444,7 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
|
||||
|
||||
TEST_ASSERT(crypto_ec_point_is_at_infinity(e, r));
|
||||
|
||||
mbedtls_mpi_free( &num );
|
||||
mbedtls_mpi_free(&num);
|
||||
crypto_ec_point_deinit(p, 1);
|
||||
crypto_ec_point_deinit(q, 1);
|
||||
crypto_ec_point_deinit(r, 1);
|
||||
@@ -468,8 +464,8 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
|
||||
TEST_ASSERT_NOT_NULL(p);
|
||||
TEST_ASSERT_NOT_NULL(q);
|
||||
|
||||
mbedtls_mpi_init( &num );
|
||||
mbedtls_mpi_lset( &num, 50 );
|
||||
mbedtls_mpi_init(&num);
|
||||
mbedtls_mpi_lset(&num, 50);
|
||||
|
||||
ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx));
|
||||
ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy));
|
||||
@@ -483,8 +479,7 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
|
||||
TEST_ASSERT(crypto_ec_point_mul(e, p, (crypto_bignum *) &num, q) == 0);
|
||||
TEST_ASSERT(crypto_ec_point_is_on_curve(e, q));
|
||||
|
||||
|
||||
mbedtls_mpi_free( &num );
|
||||
mbedtls_mpi_free(&num);
|
||||
crypto_ec_point_deinit(p, 1);
|
||||
crypto_ec_point_deinit(q, 1);
|
||||
crypto_ec_deinit(e);
|
||||
@@ -506,8 +501,8 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
|
||||
TEST_ASSERT_NOT_NULL(q);
|
||||
TEST_ASSERT_NOT_NULL(r);
|
||||
|
||||
mbedtls_mpi_init( &num );
|
||||
mbedtls_mpi_lset( &num, 50 );
|
||||
mbedtls_mpi_init(&num);
|
||||
mbedtls_mpi_lset(&num, 50);
|
||||
|
||||
ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(X), secp256r1_gx, sizeof(secp256r1_gx));
|
||||
ecp_mpi_load(& ((mbedtls_ecp_point *)p)->MBEDTLS_PRIVATE(Y), secp256r1_gy, sizeof(secp256r1_gy));
|
||||
@@ -532,7 +527,7 @@ TEST_CASE("Test crypto lib ECC apis", "[wpa_crypto]")
|
||||
TEST_ASSERT(crypto_ec_point_add(e, q, r, r) == 0);
|
||||
TEST_ASSERT(crypto_ec_point_is_at_infinity(e, r));
|
||||
|
||||
mbedtls_mpi_free( &num );
|
||||
mbedtls_mpi_free(&num);
|
||||
crypto_ec_point_deinit(p, 1);
|
||||
crypto_ec_point_deinit(q, 1);
|
||||
crypto_ec_point_deinit(r, 1);
|
||||
|
||||
Reference in New Issue
Block a user