mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(spi_master): p4 add master driver supported
This commit is contained in:
parent
5306b3308f
commit
00fcdce725
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -12,6 +12,7 @@
|
||||
#include "driver/spi_common.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "hal/spi_types.h"
|
||||
#include "hal/dma_types.h"
|
||||
#include "esp_pm.h"
|
||||
#if SOC_GDMA_SUPPORTED
|
||||
#include "esp_private/gdma.h"
|
||||
@ -45,6 +46,13 @@ extern "C"
|
||||
#define BUS_LOCK_DEBUG_EXECUTE_CHECK(x)
|
||||
#endif
|
||||
|
||||
#if SOC_GPSPI_SUPPORTED && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI)
|
||||
#define DMA_DESC_MEM_ALIGN_SIZE 8
|
||||
typedef dma_descriptor_align8_t spi_dma_desc_t;
|
||||
#else
|
||||
#define DMA_DESC_MEM_ALIGN_SIZE 4
|
||||
typedef dma_descriptor_align4_t spi_dma_desc_t;
|
||||
#endif
|
||||
|
||||
struct spi_bus_lock_t;
|
||||
struct spi_bus_lock_dev_t;
|
||||
@ -56,22 +64,21 @@ typedef struct spi_bus_lock_dev_t* spi_bus_lock_dev_handle_t;
|
||||
/// Background operation control function
|
||||
typedef void (*bg_ctrl_func_t)(void*);
|
||||
|
||||
typedef struct lldesc_s lldesc_t;
|
||||
|
||||
/// Attributes of an SPI bus
|
||||
typedef struct {
|
||||
spi_bus_config_t bus_cfg; ///< Config used to initialize the bus
|
||||
uint32_t flags; ///< Flags (attributes) of the bus
|
||||
int max_transfer_sz; ///< Maximum length of bytes available to send
|
||||
bool dma_enabled; ///< To enable DMA or not
|
||||
int tx_dma_chan; ///< TX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same
|
||||
int rx_dma_chan; ///< RX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same
|
||||
int dma_desc_num; ///< DMA descriptor number of dmadesc_tx or dmadesc_rx.
|
||||
lldesc_t *dmadesc_tx; ///< DMA descriptor array for TX
|
||||
lldesc_t *dmadesc_rx; ///< DMA descriptor array for RX
|
||||
spi_bus_config_t bus_cfg; ///< Config used to initialize the bus
|
||||
uint32_t flags; ///< Flags (attributes) of the bus
|
||||
int max_transfer_sz; ///< Maximum length of bytes available to send
|
||||
bool dma_enabled; ///< To enable DMA or not
|
||||
uint16_t internal_mem_align_size; ///< Buffer align byte requirement for internal memory
|
||||
int tx_dma_chan; ///< TX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same
|
||||
int rx_dma_chan; ///< RX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same
|
||||
int dma_desc_num; ///< DMA descriptor number of dmadesc_tx or dmadesc_rx.
|
||||
spi_dma_desc_t *dmadesc_tx; ///< DMA descriptor array for TX
|
||||
spi_dma_desc_t *dmadesc_rx; ///< DMA descriptor array for RX
|
||||
spi_bus_lock_handle_t lock;
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_handle_t pm_lock; ///< Power management lock
|
||||
esp_pm_lock_handle_t pm_lock; ///< Power management lock
|
||||
#endif
|
||||
} spi_bus_attr_t;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -13,7 +13,6 @@
|
||||
#include "esp_check.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "soc/lldesc.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
@ -26,6 +25,14 @@
|
||||
#endif
|
||||
#if SOC_GDMA_SUPPORTED
|
||||
#include "esp_private/gdma.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#endif
|
||||
|
||||
#if SOC_PERIPH_CLK_CTRL_SHARED
|
||||
#define SPI_COMMON_RCC_CLOCK_ATOMIC() PERIPH_RCC_ATOMIC()
|
||||
#else
|
||||
#define SPI_COMMON_RCC_CLOCK_ATOMIC()
|
||||
#endif
|
||||
|
||||
static const char *SPI_TAG = "spi";
|
||||
@ -100,7 +107,15 @@ bool spicommon_periph_claim(spi_host_device_t host, const char* source)
|
||||
bool ret = atomic_compare_exchange_strong(&spi_periph_claimed[host], &false_var, true);
|
||||
if (ret) {
|
||||
spi_claiming_func[host] = source;
|
||||
#if CONFIG_IDF_TARGET_ESP32P4 //deprecate clk_gate_ll start from p4, others in TODO: IDF-8159
|
||||
SPI_COMMON_RCC_CLOCK_ATOMIC() {
|
||||
spi_ll_enable_bus_clock(host, true);
|
||||
spi_ll_reset_register(host);
|
||||
spi_ll_enable_clock(host, true);
|
||||
}
|
||||
#else
|
||||
periph_module_enable(spi_periph_signal[host].module);
|
||||
#endif
|
||||
} else {
|
||||
ESP_EARLY_LOGE(SPI_TAG, "SPI%d already claimed by %s.", host+1, spi_claiming_func[host]);
|
||||
}
|
||||
@ -117,7 +132,15 @@ bool spicommon_periph_free(spi_host_device_t host)
|
||||
{
|
||||
bool true_var = true;
|
||||
bool ret = atomic_compare_exchange_strong(&spi_periph_claimed[host], &true_var, false);
|
||||
if (ret) periph_module_disable(spi_periph_signal[host].module);
|
||||
if (ret) {
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
SPI_COMMON_RCC_CLOCK_ATOMIC() {
|
||||
spi_ll_enable_bus_clock(host, false);
|
||||
}
|
||||
#else
|
||||
periph_module_disable(spi_periph_signal[host].module);
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -218,6 +241,12 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch
|
||||
}
|
||||
|
||||
#else //SOC_GDMA_SUPPORTED
|
||||
|
||||
#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB)
|
||||
static esp_err_t (*spi_gdma_chan_allocator)(const gdma_channel_alloc_config_t *, gdma_channel_handle_t *) = gdma_new_ahb_channel;
|
||||
#elif (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI)
|
||||
static esp_err_t (*spi_gdma_chan_allocator)(const gdma_channel_alloc_config_t *, gdma_channel_handle_t *) = gdma_new_axi_channel;
|
||||
#endif
|
||||
static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan)
|
||||
{
|
||||
assert(is_valid_host(host_id));
|
||||
@ -231,19 +260,13 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch
|
||||
.flags.reserve_sibling = 1,
|
||||
.direction = GDMA_CHANNEL_DIRECTION_TX,
|
||||
};
|
||||
ret = gdma_new_channel(&tx_alloc_config, &ctx->tx_channel);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
ESP_RETURN_ON_ERROR(spi_gdma_chan_allocator(&tx_alloc_config, &ctx->tx_channel), SPI_TAG, "alloc gdma tx failed");
|
||||
|
||||
gdma_channel_alloc_config_t rx_alloc_config = {
|
||||
.direction = GDMA_CHANNEL_DIRECTION_RX,
|
||||
.sibling_chan = ctx->tx_channel,
|
||||
};
|
||||
ret = gdma_new_channel(&rx_alloc_config, &ctx->rx_channel);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
ESP_RETURN_ON_ERROR(spi_gdma_chan_allocator(&rx_alloc_config, &ctx->rx_channel), SPI_TAG, "alloc gdma rx failed");
|
||||
|
||||
if (host_id == SPI2_HOST) {
|
||||
gdma_connect(ctx->rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2));
|
||||
@ -802,17 +825,22 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t *
|
||||
bus_attr->tx_dma_chan = actual_tx_dma_chan;
|
||||
bus_attr->rx_dma_chan = actual_rx_dma_chan;
|
||||
|
||||
int dma_desc_ct = lldesc_get_required_num(bus_config->max_transfer_sz);
|
||||
int dma_desc_ct = (bus_config->max_transfer_sz + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED;
|
||||
if (dma_desc_ct == 0) dma_desc_ct = 1; //default to 4k when max is not given
|
||||
|
||||
bus_attr->max_transfer_sz = dma_desc_ct * LLDESC_MAX_NUM_PER_DESC;
|
||||
bus_attr->dmadesc_tx = heap_caps_malloc(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA);
|
||||
bus_attr->dmadesc_rx = heap_caps_malloc(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA);
|
||||
bus_attr->max_transfer_sz = dma_desc_ct * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED;
|
||||
bus_attr->dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA);
|
||||
bus_attr->dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA);
|
||||
if (bus_attr->dmadesc_tx == NULL || bus_attr->dmadesc_rx == NULL) {
|
||||
err = ESP_ERR_NO_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
bus_attr->dma_desc_num = dma_desc_ct;
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
bus_attr->internal_mem_align_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
||||
#else
|
||||
bus_attr->internal_mem_align_size = 4;
|
||||
#endif
|
||||
} else {
|
||||
bus_attr->dma_enabled = 0;
|
||||
bus_attr->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE;
|
||||
|
@ -112,6 +112,7 @@ We have two bits to control the interrupt:
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/spi_common_internal.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "esp_clk_tree.h"
|
||||
@ -126,6 +127,9 @@ We have two bits to control the interrupt:
|
||||
#include "hal/spi_hal.h"
|
||||
#include "hal/spi_ll.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
#include "esp_cache.h"
|
||||
#endif
|
||||
|
||||
typedef struct spi_device_t spi_device_t;
|
||||
|
||||
@ -172,6 +176,11 @@ static spi_host_t* bus_driver_ctx[SOC_SPI_PERIPH_NUM] = {};
|
||||
static const char *SPI_TAG = "spi_master";
|
||||
#define SPI_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE_ISR(a, ret_val, SPI_TAG, str)
|
||||
|
||||
#if SOC_PERIPH_CLK_CTRL_SHARED
|
||||
#define SPI_MASTER_RCC_CLOCK_ATOMIC() PERIPH_RCC_ATOMIC()
|
||||
#else
|
||||
#define SPI_MASTER_RCC_CLOCK_ATOMIC()
|
||||
#endif
|
||||
|
||||
static void spi_intr(void *arg);
|
||||
static void spi_bus_intr_enable(void *host);
|
||||
@ -547,6 +556,9 @@ static SPI_MASTER_ISR_ATTR void spi_setup_device(spi_device_t *dev)
|
||||
if (spi_bus_lock_touch(dev_lock)) {
|
||||
/* Configuration has not been applied yet. */
|
||||
spi_hal_setup_device(hal, hal_dev);
|
||||
SPI_MASTER_RCC_CLOCK_ATOMIC() {
|
||||
spi_ll_set_clk_source(hal->hw, hal_dev->timing_conf.clock_source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -680,13 +692,24 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg)
|
||||
const int cs = host->cur_cs;
|
||||
//Tell common code DMA workaround that our DMA channel is idle. If needed, the code will do a DMA reset.
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if (bus_attr->dma_enabled) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
//This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same
|
||||
spicommon_dmaworkaround_idle(bus_attr->tx_dma_chan);
|
||||
}
|
||||
#endif //#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //invalidate here to let user access rx data in post_cb if possible
|
||||
if (host->cur_trans_buf.buffer_to_rcv) {
|
||||
uint16_t alignment = bus_attr->internal_mem_align_size;
|
||||
uint32_t buffer_byte_len = (host->cur_trans_buf.trans->rxlength + 7) / 8;
|
||||
buffer_byte_len = (buffer_byte_len + alignment - 1) & (~(alignment - 1));
|
||||
// invalidate priv_trans.buffer_to_rcv anyway, only user provide aligned buffer can rcv correct data in post_cb
|
||||
esp_err_t ret = esp_cache_msync((void *)host->cur_trans_buf.buffer_to_rcv, buffer_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C);
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//cur_cs is changed to DEV_NUM_MAX here
|
||||
spi_post_trans(host);
|
||||
|
||||
@ -824,9 +847,7 @@ static SPI_MASTER_ISR_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf)
|
||||
free((void *)trans_buf->buffer_to_send); //force free, ignore const
|
||||
}
|
||||
// copy data from temporary DMA-capable buffer back to IRAM buffer and free the temporary one.
|
||||
if (trans_buf->buffer_to_rcv &&
|
||||
(void *)trans_buf->buffer_to_rcv != &trans_desc->rx_data[0] &&
|
||||
trans_buf->buffer_to_rcv != trans_desc->rx_buffer) { // NOLINT(clang-analyzer-unix.Malloc)
|
||||
if (trans_buf->buffer_to_rcv && (void *)trans_buf->buffer_to_rcv != &trans_desc->rx_data[0] && trans_buf->buffer_to_rcv != trans_desc->rx_buffer) { // NOLINT(clang-analyzer-unix.Malloc)
|
||||
if (trans_desc->flags & SPI_TRANS_USE_RXDATA) {
|
||||
memcpy((uint8_t *) & trans_desc->rx_data[0], trans_buf->buffer_to_rcv, (trans_desc->rxlength + 7) / 8);
|
||||
} else {
|
||||
@ -836,9 +857,11 @@ static SPI_MASTER_ISR_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf)
|
||||
}
|
||||
}
|
||||
|
||||
static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_transaction_t *trans_desc, spi_trans_priv_t* new_desc, bool isdma)
|
||||
static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_host_t *host, spi_trans_priv_t* priv_desc)
|
||||
{
|
||||
*new_desc = (spi_trans_priv_t) { .trans = trans_desc, };
|
||||
spi_transaction_t *trans_desc = priv_desc->trans;
|
||||
const spi_bus_attr_t *bus_attr = host->bus_attr;
|
||||
uint16_t alignment = bus_attr->internal_mem_align_size;
|
||||
|
||||
// rx memory assign
|
||||
uint32_t* rcv_ptr;
|
||||
@ -848,13 +871,6 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_transaction_t *trans_de
|
||||
//if not use RXDATA neither rx_buffer, buffer_to_rcv assigned to NULL
|
||||
rcv_ptr = trans_desc->rx_buffer;
|
||||
}
|
||||
if (rcv_ptr && isdma && (!esp_ptr_dma_capable(rcv_ptr) || ((int)rcv_ptr % 4 != 0))) {
|
||||
//if rxbuf in the desc not DMA-capable, malloc a new one. The rx buffer need to be length of multiples of 32 bits to avoid heap corruption.
|
||||
ESP_LOGD(SPI_TAG, "Allocate RX buffer for DMA" );
|
||||
rcv_ptr = heap_caps_malloc(((trans_desc->rxlength + 31) / 32) * 4, MALLOC_CAP_DMA);
|
||||
if (rcv_ptr == NULL) goto clean_up;
|
||||
}
|
||||
new_desc->buffer_to_rcv = rcv_ptr;
|
||||
|
||||
// tx memory assign
|
||||
const uint32_t *send_ptr;
|
||||
@ -864,21 +880,53 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_transaction_t *trans_de
|
||||
//if not use TXDATA neither tx_buffer, tx data assigned to NULL
|
||||
send_ptr = trans_desc->tx_buffer ;
|
||||
}
|
||||
if (send_ptr && isdma && !esp_ptr_dma_capable( send_ptr )) {
|
||||
//if txbuf in the desc not DMA-capable, malloc a new one
|
||||
ESP_LOGD(SPI_TAG, "Allocate TX buffer for DMA" );
|
||||
uint32_t *temp = heap_caps_malloc((trans_desc->length + 7) / 8, MALLOC_CAP_DMA);
|
||||
if (temp == NULL) goto clean_up;
|
||||
|
||||
memcpy( temp, send_ptr, (trans_desc->length + 7) / 8 );
|
||||
send_ptr = temp;
|
||||
uint32_t tx_byte_len = (trans_desc->length + 7) / 8;
|
||||
uint32_t rx_byte_len = (trans_desc->rxlength + 7) / 8;
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
bool tx_un_align = ((((uint32_t)send_ptr) | tx_byte_len) & (alignment - 1));
|
||||
bool rx_un_align = ((((uint32_t)rcv_ptr) | rx_byte_len) & (alignment - 1));
|
||||
#else
|
||||
bool tx_un_align = false; //tx don't need align on addr or length, for other chips
|
||||
bool rx_un_align = (((uint32_t)rcv_ptr) & (alignment - 1));
|
||||
#endif
|
||||
|
||||
if (send_ptr && bus_attr->dma_enabled) {
|
||||
if ((!esp_ptr_dma_capable(send_ptr) || tx_un_align )) {
|
||||
ESP_RETURN_ON_FALSE(!(trans_desc->flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but TX buffer addr&len not align to %d, or not dma_capable", alignment);
|
||||
//if txbuf in the desc not DMA-capable, or not bytes aligned to alignment, malloc a new one
|
||||
ESP_EARLY_LOGD(SPI_TAG, "Allocate TX buffer for DMA" );
|
||||
tx_byte_len = (tx_byte_len + alignment - 1) & (~(alignment - 1)); // up align alignment
|
||||
uint32_t *temp = heap_caps_aligned_alloc(alignment, tx_byte_len, MALLOC_CAP_DMA);
|
||||
if (temp == NULL) {
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
memcpy( temp, send_ptr, (trans_desc->length + 7) / 8 );
|
||||
send_ptr = temp;
|
||||
}
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
esp_err_t ret = esp_cache_msync((void *)send_ptr, tx_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||
assert(ret == ESP_OK);
|
||||
#endif
|
||||
}
|
||||
new_desc->buffer_to_send = send_ptr;
|
||||
|
||||
if (rcv_ptr && bus_attr->dma_enabled && (!esp_ptr_dma_capable(rcv_ptr) || rx_un_align )) {
|
||||
ESP_RETURN_ON_FALSE(!(trans_desc->flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but RX buffer addr&len not align to %d, or not dma_capable", alignment);
|
||||
//if rxbuf in the desc not DMA-capable, or not aligned to alignment, malloc a new one
|
||||
ESP_EARLY_LOGD(SPI_TAG, "Allocate RX buffer for DMA" );
|
||||
rx_byte_len = (rx_byte_len + alignment - 1) & (~(alignment - 1)); // up align alignment
|
||||
rcv_ptr = heap_caps_aligned_alloc(alignment, rx_byte_len, MALLOC_CAP_DMA);
|
||||
if (rcv_ptr == NULL) {
|
||||
goto clean_up;
|
||||
}
|
||||
}
|
||||
priv_desc->buffer_to_send = send_ptr;
|
||||
priv_desc->buffer_to_rcv = rcv_ptr;
|
||||
return ESP_OK;
|
||||
|
||||
clean_up:
|
||||
uninstall_priv_desc(new_desc);
|
||||
uninstall_priv_desc(priv_desc);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
@ -897,8 +945,8 @@ esp_err_t SPI_MASTER_ATTR spi_device_queue_trans(spi_device_handle_t handle, spi
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
spi_trans_priv_t trans_buf;
|
||||
ret = setup_priv_desc(trans_desc, &trans_buf, (host->bus_attr->dma_enabled));
|
||||
spi_trans_priv_t trans_buf = { .trans = trans_desc, };
|
||||
ret = setup_priv_desc(host, &trans_buf);
|
||||
if (ret != ESP_OK) return ret;
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
@ -935,6 +983,7 @@ esp_err_t SPI_MASTER_ATTR spi_device_get_trans_result(spi_device_handle_t handle
|
||||
BaseType_t r;
|
||||
spi_trans_priv_t trans_buf;
|
||||
SPI_CHECK(handle!=NULL, "invalid dev handle", ESP_ERR_INVALID_ARG);
|
||||
bool use_dma = handle->host->bus_attr->dma_enabled;
|
||||
|
||||
//if SPI_DEVICE_NO_RETURN_RESULT is set, ret_queue will always be empty
|
||||
SPI_CHECK(!(handle->cfg.flags & SPI_DEVICE_NO_RETURN_RESULT), "API not Supported!", ESP_ERR_NOT_SUPPORTED);
|
||||
@ -947,8 +996,10 @@ esp_err_t SPI_MASTER_ATTR spi_device_get_trans_result(spi_device_handle_t handle
|
||||
// Every in-flight transaction request occupies internal memory as DMA buffer if needed.
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
//release temporary buffers
|
||||
uninstall_priv_desc(&trans_buf);
|
||||
//release temporary buffers used by dma
|
||||
if (use_dma) {
|
||||
uninstall_priv_desc(&trans_buf);
|
||||
}
|
||||
(*trans_desc) = trans_buf.trans;
|
||||
|
||||
return ESP_OK;
|
||||
@ -1043,8 +1094,8 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_start(spi_device_handle_t handl
|
||||
SPI_CHECK(!spi_bus_device_is_polling(handle), "Cannot send polling transaction while the previous polling transaction is not terminated.", ESP_ERR_INVALID_STATE );
|
||||
|
||||
spi_host_t *host = handle->host;
|
||||
spi_trans_priv_t priv_polling_trans;
|
||||
ret = setup_priv_desc(trans_desc, &priv_polling_trans, (host->bus_attr->dma_enabled));
|
||||
spi_trans_priv_t priv_polling_trans = { .trans = trans_desc, };
|
||||
ret = setup_priv_desc(host, &priv_polling_trans);
|
||||
if (ret!=ESP_OK) return ret;
|
||||
|
||||
/* If device_acquiring_lock is set to handle, it means that the user has already
|
||||
@ -1065,6 +1116,7 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_start(spi_device_handle_t handl
|
||||
ESP_LOGE(SPI_TAG, "polling can't get buslock");
|
||||
return ret;
|
||||
}
|
||||
//After holding the buslock, common resource can be accessed !!
|
||||
|
||||
//Polling, no interrupt is used.
|
||||
host->polling = true;
|
||||
|
@ -163,6 +163,9 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
|
||||
bool use_dma = (dma_chan != SPI_DMA_DISABLED);
|
||||
spihost[host]->dma_enabled = use_dma;
|
||||
if (use_dma) {
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
abort(); //will supported in IDF-7503
|
||||
#endif
|
||||
ret = spicommon_dma_chan_alloc(host, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan);
|
||||
if (ret != ESP_OK) {
|
||||
goto cleanup;
|
||||
|
@ -115,6 +115,7 @@ typedef struct {
|
||||
#define SPI_TRANS_MULTILINE_CMD (1<<9) ///< The data lines used at command phase is the same as data phase (otherwise, only one data line is used at command phase)
|
||||
#define SPI_TRANS_MODE_OCT (1<<10) ///< Transmit/receive data in 8-bit mode
|
||||
#define SPI_TRANS_MULTILINE_ADDR SPI_TRANS_MODE_DIOQIO_ADDR ///< The data lines used at address phase is the same as data phase (otherwise, only one data line is used at address phase)
|
||||
#define SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL (1<<11) ///< By default driver will automatically re-alloc dma buffer if it doesn't meet hardware alignment or dma_capable requirements, this flag is for you to disable this feature, you will need to take care of the alignment otherwise driver will return you error ESP_ERR_INVALID_ARG
|
||||
|
||||
/**
|
||||
* This structure describes one SPI transaction. The descriptor should not be modified until the transaction finishes.
|
||||
@ -208,6 +209,7 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle);
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG if parameter is invalid. This can happen if SPI_TRANS_CS_KEEP_ACTIVE flag is specified while
|
||||
* the bus was not acquired (`spi_device_acquire_bus()` should be called first)
|
||||
* or set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but tx or rx buffer not DMA-capable, or addr&len not align to cache line size
|
||||
* - ESP_ERR_TIMEOUT if there was no room in the queue before ticks_to_wait expired
|
||||
* - ESP_ERR_NO_MEM if allocating DMA-capable temporary buffer failed
|
||||
* - ESP_ERR_INVALID_STATE if previous transactions are not finished
|
||||
@ -273,6 +275,7 @@ esp_err_t spi_device_transmit(spi_device_handle_t handle, spi_transaction_t *tra
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG if parameter is invalid. This can happen if SPI_TRANS_CS_KEEP_ACTIVE flag is specified while
|
||||
* the bus was not acquired (`spi_device_acquire_bus()` should be called first)
|
||||
* or set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but tx or rx buffer not DMA-capable, or addr&len not align to cache line size
|
||||
* - ESP_ERR_TIMEOUT if the device cannot get control of the bus before ``ticks_to_wait`` expired
|
||||
* - ESP_ERR_NO_MEM if allocating DMA-capable temporary buffer failed
|
||||
* - ESP_ERR_INVALID_STATE if previous transactions are not finished
|
||||
|
@ -63,6 +63,7 @@ typedef spi_dev_t spi_dma_dev_t;
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param clk_source clock source to select, see valid sources in type `spi_clock_source_t`
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_source)
|
||||
{
|
||||
//empty, keep this for compatibility
|
||||
|
@ -97,6 +97,7 @@ typedef enum {
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param clk_source clock source to select, see valid sources in type `spi_clock_source_t`
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_source){
|
||||
switch (clk_source)
|
||||
{
|
||||
|
@ -99,6 +99,7 @@ typedef enum {
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param clk_source clock source to select, see valid sources in type `spi_clock_source_t`
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_source){
|
||||
switch (clk_source)
|
||||
{
|
||||
|
@ -98,6 +98,7 @@ typedef enum {
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param clk_source clock source to select, see valid sources in type `spi_clock_source_t`
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_source)
|
||||
{
|
||||
switch (clk_source)
|
||||
|
@ -100,6 +100,7 @@ typedef enum {
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param clk_source clock source to select, see valid sources in type `spi_clock_source_t`
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_source)
|
||||
{
|
||||
switch (clk_source)
|
||||
|
@ -23,7 +23,7 @@ extern "C" {
|
||||
* @brief Given a L2MEM cached address, get the corresponding non-cacheable address
|
||||
* @example 0x4FF0_0000 => 0x8FF0_0000
|
||||
*/
|
||||
#define CACHE_LL_L2MEM_NON_CACHE_ADDR(addr) ((intptr_t)(addr) + 0x40000000)
|
||||
#define CACHE_LL_L2MEM_NON_CACHE_ADDR(addr) ((intptr_t)(addr) + SOC_NON_CACHEABLE_OFFSET)
|
||||
|
||||
/**
|
||||
* Cache capabilities
|
||||
|
@ -54,12 +54,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
|
||||
return HP_SYS_CLKRST_REG_TWAI1_CLK_EN;
|
||||
case PERIPH_TWAI2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_TWAI2_CLK_EN;
|
||||
case PERIPH_GPSPI_MODULE:
|
||||
return HP_SYS_CLKRST_REG_GPSPI2_HS_CLK_EN;
|
||||
case PERIPH_GPSPI2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_GPSPI2_MST_CLK_EN;
|
||||
case PERIPH_GPSPI3_MODULE:
|
||||
return HP_SYS_CLKRST_REG_GPSPI3_MST_CLK_EN;
|
||||
case PERIPH_I3C_MODULE:
|
||||
return HP_SYS_CLKRST_REG_I3C_MST_CLK_EN;
|
||||
case PERIPH_CAM_MODULE:
|
||||
@ -145,10 +139,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
|
||||
return HP_SYS_CLKRST_REG_RST_EN_CAN2;
|
||||
case PERIPH_LEDC_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_LEDC;
|
||||
case PERIPH_GPSPI2_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_SPI2;
|
||||
case PERIPH_GPSPI3_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_SPI3;
|
||||
case PERIPH_LCD_MODULE:
|
||||
return HP_SYS_CLKRST_REG_RST_EN_LCDCAM;
|
||||
case PERIPH_SARADC_MODULE:
|
||||
@ -224,10 +214,6 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
|
||||
case PERIPH_TWAI1_MODULE:
|
||||
case PERIPH_TWAI2_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL116_REG;
|
||||
case PERIPH_GPSPI_MODULE:
|
||||
case PERIPH_GPSPI2_MODULE:
|
||||
case PERIPH_GPSPI3_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL117_REG;
|
||||
case PERIPH_I3C_MODULE:
|
||||
case PERIPH_CAM_MODULE:
|
||||
return HP_SYS_CLKRST_PERI_CLK_CTRL119_REG;
|
||||
@ -282,8 +268,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
|
||||
case PERIPH_TWAI1_MODULE:
|
||||
case PERIPH_TWAI2_MODULE:
|
||||
case PERIPH_LEDC_MODULE:
|
||||
case PERIPH_GPSPI2_MODULE:
|
||||
case PERIPH_GPSPI3_MODULE:
|
||||
case PERIPH_CAM_MODULE:
|
||||
case PERIPH_SARADC_MODULE:
|
||||
case PERIPH_AES_MODULE:
|
||||
|
1279
components/hal/esp32p4/include/hal/spi_ll.h
Normal file
1279
components/hal/esp32p4/include/hal/spi_ll.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -107,6 +107,7 @@ typedef enum {
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param clk_source clock source to select, see valid sources in type `spi_clock_source_t`
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_source)
|
||||
{
|
||||
//empty, keep this for compatibility
|
||||
|
@ -99,6 +99,7 @@ typedef enum {
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param clk_source clock source to select, see valid sources in type `spi_clock_source_t`
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_source){
|
||||
switch (clk_source)
|
||||
{
|
||||
|
@ -29,9 +29,9 @@
|
||||
#include "esp_err.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/spi_types.h"
|
||||
#include "hal/dma_types.h"
|
||||
#if SOC_GPSPI_SUPPORTED
|
||||
#include "hal/spi_ll.h"
|
||||
#include "soc/lldesc.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -40,6 +40,12 @@ extern "C" {
|
||||
|
||||
#if SOC_GPSPI_SUPPORTED
|
||||
|
||||
#if SOC_GPSPI_SUPPORTED && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI)
|
||||
typedef dma_descriptor_align8_t spi_dma_desc_t;
|
||||
#else
|
||||
typedef dma_descriptor_align4_t spi_dma_desc_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Input parameters to the ``spi_hal_cal_clock_conf`` to calculate the timing configuration
|
||||
*/
|
||||
@ -76,11 +82,11 @@ typedef struct {
|
||||
spi_dma_dev_t *dma_in; ///< Input DMA(DMA -> RAM) peripheral register address
|
||||
spi_dma_dev_t *dma_out; ///< Output DMA(RAM -> DMA) peripheral register address
|
||||
bool dma_enabled; ///< Whether the DMA is enabled, do not update after initialization
|
||||
lldesc_t *dmadesc_tx; /**< Array of DMA descriptor used by the TX DMA.
|
||||
spi_dma_desc_t *dmadesc_tx; /**< Array of DMA descriptor used by the TX DMA.
|
||||
* The amount should be larger than dmadesc_n. The driver should ensure that
|
||||
* the data to be sent is shorter than the descriptors can hold.
|
||||
*/
|
||||
lldesc_t *dmadesc_rx; /**< Array of DMA descriptor used by the RX DMA.
|
||||
spi_dma_desc_t *dmadesc_rx; /**< Array of DMA descriptor used by the RX DMA.
|
||||
* The amount should be larger than dmadesc_n. The driver should ensure that
|
||||
* the data to be sent is shorter than the descriptors can hold.
|
||||
*/
|
||||
@ -112,11 +118,11 @@ typedef struct {
|
||||
*/
|
||||
typedef struct {
|
||||
/* These two need to be malloced by the driver first */
|
||||
lldesc_t *dmadesc_tx; /**< Array of DMA descriptor used by the TX DMA.
|
||||
spi_dma_desc_t *dmadesc_tx; /**< Array of DMA descriptor used by the TX DMA.
|
||||
* The amount should be larger than dmadesc_n. The driver should ensure that
|
||||
* the data to be sent is shorter than the descriptors can hold.
|
||||
*/
|
||||
lldesc_t *dmadesc_rx; /**< Array of DMA descriptor used by the RX DMA.
|
||||
spi_dma_desc_t *dmadesc_rx; /**< Array of DMA descriptor used by the RX DMA.
|
||||
* The amount should be larger than dmadesc_n. The driver should ensure that
|
||||
* the data to be sent is shorter than the descriptors can hold.
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -13,17 +13,27 @@
|
||||
#include "soc/clk_tree_defs.h"
|
||||
|
||||
//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros.
|
||||
#if SOC_AHB_GDMA_VERSION == 1
|
||||
#if SOC_GDMA_SUPPORTED
|
||||
#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) && (SOC_AHB_GDMA_VERSION == 1)
|
||||
#include "soc/gdma_struct.h"
|
||||
#include "hal/gdma_ll.h"
|
||||
|
||||
#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) gdma_ll_rx_enable_data_burst(&GDMA, chan, enable);
|
||||
#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) gdma_ll_tx_enable_data_burst(&GDMA, chan, enable);
|
||||
#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, chan, enable);
|
||||
#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, chan, enable);
|
||||
#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, chan, enable);
|
||||
#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) gdma_ll_tx_set_eof_mode(&GDMA, chan, enable);
|
||||
|
||||
#elif (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) //TODO: IDF-6152, refactor spi hal layer
|
||||
#include "hal/axi_dma_ll.h"
|
||||
#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) axi_dma_ll_rx_enable_data_burst(&AXI_DMA, chan, enable);
|
||||
#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) axi_dma_ll_tx_enable_data_burst(&AXI_DMA, chan, enable);
|
||||
#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) axi_dma_ll_rx_enable_descriptor_burst(&AXI_DMA, chan, enable);
|
||||
#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) axi_dma_ll_tx_enable_descriptor_burst(&AXI_DMA, chan, enable);
|
||||
#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) axi_dma_ll_tx_enable_auto_write_back(&AXI_DMA, chan, enable);
|
||||
#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) axi_dma_ll_tx_set_eof_mode(&AXI_DMA, chan, enable);
|
||||
#endif
|
||||
#endif //SOC_GDMA_SUPPORTED
|
||||
|
||||
/* The tag may be unused if log level is set to NONE */
|
||||
static const __attribute__((unused)) char SPI_HAL_TAG[] = "spi_hal";
|
||||
|
@ -9,13 +9,14 @@
|
||||
|
||||
#include "hal/spi_hal.h"
|
||||
#include "hal/assert.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros.
|
||||
#if SOC_AHB_GDMA_VERSION == 1
|
||||
#if SOC_GDMA_SUPPORTED
|
||||
#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) && (SOC_AHB_GDMA_VERSION == 1)
|
||||
#include "soc/gdma_struct.h"
|
||||
#include "hal/gdma_ll.h"
|
||||
|
||||
#define spi_dma_ll_rx_reset(dev, chan) gdma_ll_rx_reset_channel(&GDMA, chan)
|
||||
#define spi_dma_ll_tx_reset(dev, chan) gdma_ll_tx_reset_channel(&GDMA, chan);
|
||||
#define spi_dma_ll_rx_start(dev, chan, addr) do {\
|
||||
@ -26,7 +27,21 @@
|
||||
gdma_ll_tx_set_desc_addr(&GDMA, chan, (uint32_t)addr);\
|
||||
gdma_ll_tx_start(&GDMA, chan);\
|
||||
} while (0)
|
||||
|
||||
#elif (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) //TODO: IDF-6152, refactor spi hal layer
|
||||
#include "hal/axi_dma_ll.h"
|
||||
#define spi_dma_ll_rx_reset(dev, chan) axi_dma_ll_rx_reset_channel(&AXI_DMA, chan)
|
||||
#define spi_dma_ll_tx_reset(dev, chan) axi_dma_ll_tx_reset_channel(&AXI_DMA, chan);
|
||||
#define spi_dma_ll_rx_start(dev, chan, addr) do {\
|
||||
axi_dma_ll_rx_set_desc_addr(&AXI_DMA, chan, (uint32_t)addr);\
|
||||
axi_dma_ll_rx_start(&AXI_DMA, chan);\
|
||||
} while (0)
|
||||
#define spi_dma_ll_tx_start(dev, chan, addr) do {\
|
||||
axi_dma_ll_tx_set_desc_addr(&AXI_DMA, chan, (uint32_t)addr);\
|
||||
axi_dma_ll_tx_start(&AXI_DMA, chan);\
|
||||
} while (0)
|
||||
#endif
|
||||
#endif //SOC_GDMA_SUPPORTED
|
||||
|
||||
void spi_hal_setup_device(spi_hal_context_t *hal, const spi_hal_dev_config_t *dev)
|
||||
{
|
||||
@ -37,7 +52,6 @@ void spi_hal_setup_device(spi_hal_context_t *hal, const spi_hal_dev_config_t *de
|
||||
#endif
|
||||
spi_ll_master_set_pos_cs(hw, dev->cs_pin_id, dev->positive_cs);
|
||||
spi_ll_master_set_clock_by_reg(hw, &dev->timing_conf.clock_reg);
|
||||
spi_ll_set_clk_source(hw, dev->timing_conf.clock_source);
|
||||
//Configure bit order
|
||||
spi_ll_set_rx_lsbfirst(hw, dev->rx_lsbfirst);
|
||||
spi_ll_set_tx_lsbfirst(hw, dev->tx_lsbfirst);
|
||||
@ -131,6 +145,43 @@ void spi_hal_setup_trans(spi_hal_context_t *hal, const spi_hal_dev_config_t *dev
|
||||
memcpy(&hal->trans_config, trans, sizeof(spi_hal_trans_config_t));
|
||||
}
|
||||
|
||||
#if SOC_NON_CACHEABLE_OFFSET
|
||||
#define ADDR_DMA_2_CPU(addr) ((typeof(addr))((uint32_t)(addr) + SOC_NON_CACHEABLE_OFFSET))
|
||||
#define ADDR_CPU_2_DMA(addr) ((typeof(addr))((uint32_t)(addr) - SOC_NON_CACHEABLE_OFFSET))
|
||||
#else
|
||||
#define ADDR_DMA_2_CPU(addr) (addr)
|
||||
#define ADDR_CPU_2_DMA(addr) (addr)
|
||||
#endif
|
||||
//TODO: IDF-6152, refactor spi hal layer
|
||||
static void s_spi_hal_dma_desc_setup_link(spi_dma_desc_t *dmadesc, const void *data, int len, bool is_rx)
|
||||
{
|
||||
dmadesc = ADDR_DMA_2_CPU(dmadesc);
|
||||
int n = 0;
|
||||
while (len) {
|
||||
int dmachunklen = len;
|
||||
if (dmachunklen > DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) {
|
||||
dmachunklen = DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED;
|
||||
}
|
||||
if (is_rx) {
|
||||
//Receive needs DMA length rounded to next 32-bit boundary
|
||||
dmadesc[n].dw0.size = (dmachunklen + 3) & (~3);
|
||||
dmadesc[n].dw0.length = (dmachunklen + 3) & (~3);
|
||||
} else {
|
||||
dmadesc[n].dw0.size = dmachunklen;
|
||||
dmadesc[n].dw0.length = dmachunklen;
|
||||
}
|
||||
dmadesc[n].buffer = (uint8_t *)data;
|
||||
dmadesc[n].dw0.suc_eof = 0;
|
||||
dmadesc[n].dw0.owner = 1;
|
||||
dmadesc[n].next = ADDR_CPU_2_DMA(&dmadesc[n + 1]);
|
||||
len -= dmachunklen;
|
||||
data += dmachunklen;
|
||||
n++;
|
||||
}
|
||||
dmadesc[n - 1].dw0.suc_eof = 1; //Mark last DMA desc as end of stream.
|
||||
dmadesc[n - 1].next = NULL;
|
||||
}
|
||||
|
||||
void spi_hal_prepare_data(spi_hal_context_t *hal, const spi_hal_dev_config_t *dev, const spi_hal_trans_config_t *trans)
|
||||
{
|
||||
spi_dev_t *hw = hal->hw;
|
||||
@ -140,13 +191,13 @@ void spi_hal_prepare_data(spi_hal_context_t *hal, const spi_hal_dev_config_t *de
|
||||
if (!hal->dma_enabled) {
|
||||
//No need to setup anything; we'll copy the result out of the work registers directly later.
|
||||
} else {
|
||||
lldesc_setup_link(hal->dmadesc_rx, trans->rcv_buffer, ((trans->rx_bitlen + 7) / 8), true);
|
||||
s_spi_hal_dma_desc_setup_link(hal->dmadesc_rx, trans->rcv_buffer, ((trans->rx_bitlen + 7) / 8), true);
|
||||
|
||||
spi_dma_ll_rx_reset(hal->dma_in, hal->rx_dma_chan);
|
||||
spi_ll_dma_rx_fifo_reset(hal->hw);
|
||||
spi_ll_infifo_full_clr(hal->hw);
|
||||
spi_ll_dma_rx_enable(hal->hw, 1);
|
||||
spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, hal->dmadesc_rx);
|
||||
spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, (lldesc_t *)hal->dmadesc_rx);
|
||||
}
|
||||
|
||||
}
|
||||
@ -165,13 +216,13 @@ void spi_hal_prepare_data(spi_hal_context_t *hal, const spi_hal_dev_config_t *de
|
||||
//Need to copy data to registers manually
|
||||
spi_ll_write_buffer(hw, trans->send_buffer, trans->tx_bitlen);
|
||||
} else {
|
||||
lldesc_setup_link(hal->dmadesc_tx, trans->send_buffer, (trans->tx_bitlen + 7) / 8, false);
|
||||
s_spi_hal_dma_desc_setup_link(hal->dmadesc_tx, trans->send_buffer, (trans->tx_bitlen + 7) / 8, false);
|
||||
|
||||
spi_dma_ll_tx_reset(hal->dma_out, hal->tx_dma_chan);
|
||||
spi_ll_dma_tx_fifo_reset(hal->hw);
|
||||
spi_ll_outfifo_empty_clr(hal->hw);
|
||||
spi_ll_dma_tx_enable(hal->hw, 1);
|
||||
spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, hal->dmadesc_tx);
|
||||
spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, (lldesc_t *)hal->dmadesc_tx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,17 +3,27 @@
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros.
|
||||
#if SOC_AHB_GDMA_VERSION == 1
|
||||
#if SOC_GDMA_SUPPORTED
|
||||
#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) && (SOC_AHB_GDMA_VERSION == 1)
|
||||
#include "soc/gdma_struct.h"
|
||||
#include "hal/gdma_ll.h"
|
||||
|
||||
#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) gdma_ll_rx_enable_data_burst(&GDMA, chan, enable);
|
||||
#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) gdma_ll_tx_enable_data_burst(&GDMA, chan, enable);
|
||||
#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, chan, enable);
|
||||
#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, chan, enable);
|
||||
#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, chan, enable);
|
||||
#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) gdma_ll_tx_set_eof_mode(&GDMA, chan, enable);
|
||||
|
||||
#elif (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) //TODO: IDF-6152, refactor spi hal layer
|
||||
#include "hal/axi_dma_ll.h"
|
||||
#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) axi_dma_ll_rx_enable_data_burst(&AXI_DMA, chan, enable);
|
||||
#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) axi_dma_ll_tx_enable_data_burst(&AXI_DMA, chan, enable);
|
||||
#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) axi_dma_ll_rx_enable_descriptor_burst(&AXI_DMA, chan, enable);
|
||||
#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) axi_dma_ll_tx_enable_descriptor_burst(&AXI_DMA, chan, enable);
|
||||
#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) axi_dma_ll_tx_enable_auto_write_back(&AXI_DMA, chan, enable);
|
||||
#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) axi_dma_ll_tx_set_eof_mode(&AXI_DMA, chan, enable);
|
||||
#endif
|
||||
#endif //SOC_GDMA_SUPPORTED
|
||||
|
||||
static void s_spi_slave_hal_dma_init_config(const spi_slave_hal_context_t *hal)
|
||||
{
|
||||
|
@ -1,12 +1,13 @@
|
||||
#include "hal/spi_slave_hal.h"
|
||||
#include "hal/spi_ll.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros.
|
||||
#if SOC_AHB_GDMA_VERSION == 1
|
||||
#if SOC_GDMA_SUPPORTED
|
||||
#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) && (SOC_AHB_GDMA_VERSION == 1)
|
||||
#include "soc/gdma_struct.h"
|
||||
#include "hal/gdma_ll.h"
|
||||
|
||||
#define spi_dma_ll_rx_reset(dev, chan) gdma_ll_rx_reset_channel(&GDMA, chan)
|
||||
#define spi_dma_ll_tx_reset(dev, chan) gdma_ll_tx_reset_channel(&GDMA, chan);
|
||||
#define spi_dma_ll_rx_start(dev, chan, addr) do {\
|
||||
@ -17,7 +18,21 @@
|
||||
gdma_ll_tx_set_desc_addr(&GDMA, chan, (uint32_t)addr);\
|
||||
gdma_ll_tx_start(&GDMA, chan);\
|
||||
} while (0)
|
||||
|
||||
#elif (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) //TODO: IDF-6152, refactor spi hal layer
|
||||
#include "hal/axi_dma_ll.h"
|
||||
#define spi_dma_ll_rx_reset(dev, chan) axi_dma_ll_rx_reset_channel(&AXI_DMA, chan)
|
||||
#define spi_dma_ll_tx_reset(dev, chan) axi_dma_ll_tx_reset_channel(&AXI_DMA, chan);
|
||||
#define spi_dma_ll_rx_start(dev, chan, addr) do {\
|
||||
axi_dma_ll_rx_set_desc_addr(&AXI_DMA, chan, (uint32_t)addr);\
|
||||
axi_dma_ll_rx_start(&AXI_DMA, chan);\
|
||||
} while (0)
|
||||
#define spi_dma_ll_tx_start(dev, chan, addr) do {\
|
||||
axi_dma_ll_tx_set_desc_addr(&AXI_DMA, chan, (uint32_t)addr);\
|
||||
axi_dma_ll_tx_start(&AXI_DMA, chan);\
|
||||
} while (0)
|
||||
#endif
|
||||
#endif //SOC_GDMA_SUPPORTED
|
||||
|
||||
bool spi_slave_hal_usr_is_done(spi_slave_hal_context_t* hal)
|
||||
{
|
||||
@ -45,10 +60,11 @@ void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal)
|
||||
spi_ll_infifo_full_clr(hal->hw);
|
||||
|
||||
spi_ll_dma_rx_enable(hal->hw, 1);
|
||||
spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, &hal->dmadesc_rx[0]);
|
||||
spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, hal->dmadesc_rx);
|
||||
}
|
||||
if (hal->tx_buffer) {
|
||||
lldesc_setup_link(hal->dmadesc_tx, hal->tx_buffer, (hal->bitlen + 7) / 8, false);
|
||||
|
||||
//reset dma outlink, this should be reset before spi related reset
|
||||
spi_dma_ll_tx_reset(hal->dma_out, hal->tx_dma_chan);
|
||||
spi_ll_dma_tx_fifo_reset(hal->dma_out);
|
||||
@ -56,7 +72,7 @@ void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal)
|
||||
spi_ll_outfifo_empty_clr(hal->hw);
|
||||
|
||||
spi_ll_dma_tx_enable(hal->hw, 1);
|
||||
spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, (&hal->dmadesc_tx[0]));
|
||||
spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, hal->dmadesc_tx);
|
||||
}
|
||||
} else {
|
||||
//No DMA. Turn off SPI and copy data to transmit buffers.
|
||||
|
@ -3,3 +3,10 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
//TODO: IDF-8313 update after chips back and PLL setup
|
||||
#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 10*1000*1000
|
||||
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 1000
|
||||
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 1000
|
||||
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 1000
|
||||
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 1000
|
||||
|
@ -71,6 +71,10 @@ config SOC_I2S_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_GPSPI_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2C_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
@ -801,25 +805,21 @@ config SOC_SDM_CLK_SUPPORT_XTAL
|
||||
|
||||
config SOC_SPI_PERIPH_NUM
|
||||
int
|
||||
default 2
|
||||
default 3
|
||||
|
||||
config SOC_SPI_MAX_CS_NUM
|
||||
int
|
||||
default 6
|
||||
|
||||
config SOC_MEMSPI_IS_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_MAXIMUM_BUFFER_SIZE
|
||||
int
|
||||
default 64
|
||||
|
||||
config SOC_SPI_SUPPORT_DDRCLK
|
||||
config SOC_SPI_SLAVE_SUPPORT_SEG_TRANS
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_SLAVE_SUPPORT_SEG_TRANS
|
||||
config SOC_SPI_SUPPORT_DDRCLK
|
||||
bool
|
||||
default y
|
||||
|
||||
@ -827,23 +827,15 @@ config SOC_SPI_SUPPORT_CD_SIG
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_SUPPORT_CONTINUOUS_TRANS
|
||||
config SOC_SPI_SUPPORT_OCT
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_SUPPORT_SLAVE_HD_VER2
|
||||
bool
|
||||
default n
|
||||
|
||||
config SOC_SPI_SUPPORT_CLK_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_SUPPORT_CLK_PLL_F80M
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_SUPPORT_CLK_RC_FAST
|
||||
config SOC_MEMSPI_IS_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
||||
|
@ -370,16 +370,20 @@ typedef enum {
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of SPI
|
||||
*/
|
||||
#define SOC_SPI_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
|
||||
#define SOC_SPI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_SPLL}
|
||||
|
||||
/**
|
||||
* @brief Type of SPI clock source.
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_80M as SPI source clock */
|
||||
SPI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_80M as SPI source clock */
|
||||
SPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */
|
||||
SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as SPI source clock */
|
||||
#if SOC_CLK_TREE_SUPPORTED
|
||||
SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,
|
||||
SPI_CLK_SRC_SPLL_480 = SOC_MOD_CLK_SPLL,
|
||||
SPI_CLK_SRC_DEFAULT = SPI_CLK_SRC_SPLL_480, /*!< Select SPLL_480M as SPI source clock */
|
||||
#else
|
||||
SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */
|
||||
#endif
|
||||
} soc_periph_spi_clk_src_t;
|
||||
|
||||
/////////////////////////////////////////////////PSRAM////////////////////////////////////////////////////////////////////
|
||||
|
@ -57,6 +57,7 @@ extern "C" {
|
||||
#define SOC_MMU_FLASH_SENSITIVE BIT(13)
|
||||
#define SOC_MMU_PSRAM_SENSITIVE BIT(12)
|
||||
|
||||
#define SOC_NON_CACHEABLE_OFFSET 0x40000000
|
||||
|
||||
/**
|
||||
* MMU entry valid bit mask for mapping value.
|
||||
|
@ -52,7 +52,7 @@
|
||||
#define SOC_I2S_SUPPORTED 1
|
||||
// #define SOC_RMT_SUPPORTED 1 //TODO: IDF-7476
|
||||
// #define SOC_SDM_SUPPORTED 1 //TODO: IDF-7551
|
||||
// #define SOC_GPSPI_SUPPORTED 1 //TODO: IDF-7502, TODO: IDF-7503
|
||||
#define SOC_GPSPI_SUPPORTED 1
|
||||
// #define SOC_LEDC_SUPPORTED 1 //TODO: IDF-6510
|
||||
#define SOC_I2C_SUPPORTED 1 //TODO: IDF-6507, TODO: IDF-7491
|
||||
#define SOC_SYSTIMER_SUPPORTED 1
|
||||
@ -377,29 +377,29 @@
|
||||
#define SOC_SDM_CLK_SUPPORT_PLL_F80M 1
|
||||
#define SOC_SDM_CLK_SUPPORT_XTAL 1
|
||||
|
||||
// TODO: IDF-5334 (Copy from esp32c3, need check)
|
||||
/*-------------------------- SPI CAPS ----------------------------------------*/
|
||||
#define SOC_SPI_PERIPH_NUM 2
|
||||
#define SOC_SPI_PERIPH_CS_NUM(i) 6
|
||||
#define SOC_SPI_MAX_CS_NUM 6
|
||||
|
||||
#define SOC_MEMSPI_IS_INDEPENDENT 1
|
||||
#define SOC_SPI_PERIPH_NUM 3
|
||||
#define SOC_SPI_PERIPH_CS_NUM(i) (((i)==0)? 2: (((i)==1)? 6: 3))
|
||||
#define SOC_SPI_MAX_CS_NUM 6
|
||||
#define SOC_SPI_MAXIMUM_BUFFER_SIZE 64
|
||||
|
||||
#define SOC_SPI_SUPPORT_DDRCLK 1
|
||||
// #define SOC_SPI_SUPPORT_SLAVE_HD_VER2 1 //TODO: IDF-7505
|
||||
#define SOC_SPI_SLAVE_SUPPORT_SEG_TRANS 1
|
||||
#define SOC_SPI_SUPPORT_DDRCLK 1
|
||||
#define SOC_SPI_SUPPORT_CD_SIG 1
|
||||
#define SOC_SPI_SUPPORT_CONTINUOUS_TRANS 1
|
||||
#define SOC_SPI_SUPPORT_SLAVE_HD_VER2 0
|
||||
#define SOC_SPI_SUPPORT_OCT 1
|
||||
#define SOC_SPI_SUPPORT_CLK_XTAL 1
|
||||
#define SOC_SPI_SUPPORT_CLK_PLL_F80M 1
|
||||
#define SOC_SPI_SUPPORT_CLK_RC_FAST 1
|
||||
// #define SOC_SPI_SUPPORT_CLK_RC_FAST 1 //bellow clks are waiting for clock tree
|
||||
// #define SOC_SPI_SUPPORT_CLK_SPLL_F480M 1 //super pll
|
||||
// #define SOC_SPI_SUPPORT_CLK_SDIO 1 //sdio pll
|
||||
// #define SOC_SPI_SUPPORT_CLK_APLL 1 //audio pll
|
||||
|
||||
// Peripheral supports DIO, DOUT, QIO, or QOUT
|
||||
// host_id = 0 -> SPI0/SPI1, host_id = 1 -> SPI2,
|
||||
#define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(host_id) ({(void)host_id; 1;})
|
||||
|
||||
#define SOC_SPI_MAX_PRE_DIVIDER 16
|
||||
#define SOC_MEMSPI_IS_INDEPENDENT 1
|
||||
#define SOC_SPI_MAX_PRE_DIVIDER 16
|
||||
|
||||
/*-------------------------- SPI MEM CAPS ---------------------------------------*/
|
||||
#define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE (1)
|
||||
|
@ -5,3 +5,27 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Normal IOMUX pins
|
||||
#define SPI2_FUNC_NUM 3
|
||||
#define SPI2_IOMUX_PIN_NUM_HD 6
|
||||
#define SPI2_IOMUX_PIN_NUM_CS 7
|
||||
#define SPI2_IOMUX_PIN_NUM_MOSI 8
|
||||
#define SPI2_IOMUX_PIN_NUM_CLK 9
|
||||
#define SPI2_IOMUX_PIN_NUM_MISO 10
|
||||
#define SPI2_IOMUX_PIN_NUM_WP 11
|
||||
|
||||
// When using Octal SPI, we make use of SPI2_FUNC_NUM_OCT to route them as follows.
|
||||
#define SPI2_FUNC_NUM_OCT 2
|
||||
#define SPI2_IOMUX_PIN_NUM_HD_OCT 32
|
||||
#define SPI2_IOMUX_PIN_NUM_CS_OCT 28
|
||||
#define SPI2_IOMUX_PIN_NUM_MOSI_OCT 29
|
||||
#define SPI2_IOMUX_PIN_NUM_CLK_OCT 30
|
||||
#define SPI2_IOMUX_PIN_NUM_MISO_OCT 31
|
||||
#define SPI2_IOMUX_PIN_NUM_WP_OCT 33
|
||||
#define SPI2_IOMUX_PIN_NUM_IO4_OCT 34
|
||||
#define SPI2_IOMUX_PIN_NUM_IO5_OCT 35
|
||||
#define SPI2_IOMUX_PIN_NUM_IO6_OCT 36
|
||||
#define SPI2_IOMUX_PIN_NUM_IO7_OCT 37
|
||||
|
||||
//SPI3 have no iomux pins
|
||||
|
@ -839,198 +839,8 @@ typedef union {
|
||||
uint32_t val;
|
||||
} spi_dout_mode_reg_t;
|
||||
|
||||
|
||||
/** Group: Interrupt registers */
|
||||
/** Type of dma_int_ena register
|
||||
* SPI interrupt enable register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** dma_infifo_full_err_int_ena : R/W; bitpos: [0]; default: 0;
|
||||
* The enable bit for SPI_DMA_INFIFO_FULL_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_infifo_full_err_int_ena:1;
|
||||
/** dma_outfifo_empty_err_int_ena : R/W; bitpos: [1]; default: 0;
|
||||
* The enable bit for SPI_DMA_OUTFIFO_EMPTY_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_outfifo_empty_err_int_ena:1;
|
||||
/** slv_ex_qpi_int_ena : R/W; bitpos: [2]; default: 0;
|
||||
* The enable bit for SPI slave Ex_QPI interrupt.
|
||||
*/
|
||||
uint32_t slv_ex_qpi_int_ena:1;
|
||||
/** slv_en_qpi_int_ena : R/W; bitpos: [3]; default: 0;
|
||||
* The enable bit for SPI slave En_QPI interrupt.
|
||||
*/
|
||||
uint32_t slv_en_qpi_int_ena:1;
|
||||
/** slv_cmd7_int_ena : R/W; bitpos: [4]; default: 0;
|
||||
* The enable bit for SPI slave CMD7 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd7_int_ena:1;
|
||||
/** slv_cmd8_int_ena : R/W; bitpos: [5]; default: 0;
|
||||
* The enable bit for SPI slave CMD8 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd8_int_ena:1;
|
||||
/** slv_cmd9_int_ena : R/W; bitpos: [6]; default: 0;
|
||||
* The enable bit for SPI slave CMD9 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd9_int_ena:1;
|
||||
/** slv_cmda_int_ena : R/W; bitpos: [7]; default: 0;
|
||||
* The enable bit for SPI slave CMDA interrupt.
|
||||
*/
|
||||
uint32_t slv_cmda_int_ena:1;
|
||||
/** slv_rd_dma_done_int_ena : R/W; bitpos: [8]; default: 0;
|
||||
* The enable bit for SPI_SLV_RD_DMA_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_rd_dma_done_int_ena:1;
|
||||
/** slv_wr_dma_done_int_ena : R/W; bitpos: [9]; default: 0;
|
||||
* The enable bit for SPI_SLV_WR_DMA_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_wr_dma_done_int_ena:1;
|
||||
/** slv_rd_buf_done_int_ena : R/W; bitpos: [10]; default: 0;
|
||||
* The enable bit for SPI_SLV_RD_BUF_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_rd_buf_done_int_ena:1;
|
||||
/** slv_wr_buf_done_int_ena : R/W; bitpos: [11]; default: 0;
|
||||
* The enable bit for SPI_SLV_WR_BUF_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_wr_buf_done_int_ena:1;
|
||||
/** trans_done_int_ena : R/W; bitpos: [12]; default: 0;
|
||||
* The enable bit for SPI_TRANS_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t trans_done_int_ena:1;
|
||||
/** dma_seg_trans_done_int_ena : R/W; bitpos: [13]; default: 0;
|
||||
* The enable bit for SPI_DMA_SEG_TRANS_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_seg_trans_done_int_ena:1;
|
||||
/** seg_magic_err_int_ena : R/W; bitpos: [14]; default: 0;
|
||||
* The enable bit for SPI_SEG_MAGIC_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t seg_magic_err_int_ena:1; //this field is only for GPSPI2
|
||||
/** slv_buf_addr_err_int_ena : R/W; bitpos: [15]; default: 0;
|
||||
* The enable bit for SPI_SLV_BUF_ADDR_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_buf_addr_err_int_ena:1;
|
||||
/** slv_cmd_err_int_ena : R/W; bitpos: [16]; default: 0;
|
||||
* The enable bit for SPI_SLV_CMD_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd_err_int_ena:1;
|
||||
/** mst_rx_afifo_wfull_err_int_ena : R/W; bitpos: [17]; default: 0;
|
||||
* The enable bit for SPI_MST_RX_AFIFO_WFULL_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t mst_rx_afifo_wfull_err_int_ena:1;
|
||||
/** mst_tx_afifo_rempty_err_int_ena : R/W; bitpos: [18]; default: 0;
|
||||
* The enable bit for SPI_MST_TX_AFIFO_REMPTY_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t mst_tx_afifo_rempty_err_int_ena:1;
|
||||
/** app2_int_ena : R/W; bitpos: [19]; default: 0;
|
||||
* The enable bit for SPI_APP2_INT interrupt.
|
||||
*/
|
||||
uint32_t app2_int_ena:1;
|
||||
/** app1_int_ena : R/W; bitpos: [20]; default: 0;
|
||||
* The enable bit for SPI_APP1_INT interrupt.
|
||||
*/
|
||||
uint32_t app1_int_ena:1;
|
||||
uint32_t reserved_21:11;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_dma_int_ena_reg_t;
|
||||
|
||||
/** Type of dma_int_clr register
|
||||
* SPI interrupt clear register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** dma_infifo_full_err_int_clr : WT; bitpos: [0]; default: 0;
|
||||
* The clear bit for SPI_DMA_INFIFO_FULL_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_infifo_full_err_int_clr:1;
|
||||
/** dma_outfifo_empty_err_int_clr : WT; bitpos: [1]; default: 0;
|
||||
* The clear bit for SPI_DMA_OUTFIFO_EMPTY_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_outfifo_empty_err_int_clr:1;
|
||||
/** slv_ex_qpi_int_clr : WT; bitpos: [2]; default: 0;
|
||||
* The clear bit for SPI slave Ex_QPI interrupt.
|
||||
*/
|
||||
uint32_t slv_ex_qpi_int_clr:1;
|
||||
/** slv_en_qpi_int_clr : WT; bitpos: [3]; default: 0;
|
||||
* The clear bit for SPI slave En_QPI interrupt.
|
||||
*/
|
||||
uint32_t slv_en_qpi_int_clr:1;
|
||||
/** slv_cmd7_int_clr : WT; bitpos: [4]; default: 0;
|
||||
* The clear bit for SPI slave CMD7 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd7_int_clr:1;
|
||||
/** slv_cmd8_int_clr : WT; bitpos: [5]; default: 0;
|
||||
* The clear bit for SPI slave CMD8 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd8_int_clr:1;
|
||||
/** slv_cmd9_int_clr : WT; bitpos: [6]; default: 0;
|
||||
* The clear bit for SPI slave CMD9 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd9_int_clr:1;
|
||||
/** slv_cmda_int_clr : WT; bitpos: [7]; default: 0;
|
||||
* The clear bit for SPI slave CMDA interrupt.
|
||||
*/
|
||||
uint32_t slv_cmda_int_clr:1;
|
||||
/** slv_rd_dma_done_int_clr : WT; bitpos: [8]; default: 0;
|
||||
* The clear bit for SPI_SLV_RD_DMA_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_rd_dma_done_int_clr:1;
|
||||
/** slv_wr_dma_done_int_clr : WT; bitpos: [9]; default: 0;
|
||||
* The clear bit for SPI_SLV_WR_DMA_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_wr_dma_done_int_clr:1;
|
||||
/** slv_rd_buf_done_int_clr : WT; bitpos: [10]; default: 0;
|
||||
* The clear bit for SPI_SLV_RD_BUF_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_rd_buf_done_int_clr:1;
|
||||
/** slv_wr_buf_done_int_clr : WT; bitpos: [11]; default: 0;
|
||||
* The clear bit for SPI_SLV_WR_BUF_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_wr_buf_done_int_clr:1;
|
||||
/** trans_done_int_clr : WT; bitpos: [12]; default: 0;
|
||||
* The clear bit for SPI_TRANS_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t trans_done_int_clr:1;
|
||||
/** dma_seg_trans_done_int_clr : WT; bitpos: [13]; default: 0;
|
||||
* The clear bit for SPI_DMA_SEG_TRANS_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_seg_trans_done_int_clr:1;
|
||||
/** seg_magic_err_int_clr : WT; bitpos: [14]; default: 0;
|
||||
* The clear bit for SPI_SEG_MAGIC_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t seg_magic_err_int_clr:1; //this field is only for GPSPI2
|
||||
/** slv_buf_addr_err_int_clr : WT; bitpos: [15]; default: 0;
|
||||
* The clear bit for SPI_SLV_BUF_ADDR_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_buf_addr_err_int_clr:1;
|
||||
/** slv_cmd_err_int_clr : WT; bitpos: [16]; default: 0;
|
||||
* The clear bit for SPI_SLV_CMD_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd_err_int_clr:1;
|
||||
/** mst_rx_afifo_wfull_err_int_clr : WT; bitpos: [17]; default: 0;
|
||||
* The clear bit for SPI_MST_RX_AFIFO_WFULL_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t mst_rx_afifo_wfull_err_int_clr:1;
|
||||
/** mst_tx_afifo_rempty_err_int_clr : WT; bitpos: [18]; default: 0;
|
||||
* The clear bit for SPI_MST_TX_AFIFO_REMPTY_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t mst_tx_afifo_rempty_err_int_clr:1;
|
||||
/** app2_int_clr : WT; bitpos: [19]; default: 0;
|
||||
* The clear bit for SPI_APP2_INT interrupt.
|
||||
*/
|
||||
uint32_t app2_int_clr:1;
|
||||
/** app1_int_clr : WT; bitpos: [20]; default: 0;
|
||||
* The clear bit for SPI_APP1_INT interrupt.
|
||||
*/
|
||||
uint32_t app1_int_clr:1;
|
||||
uint32_t reserved_21:11;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_dma_int_clr_reg_t;
|
||||
|
||||
/** Type of dma_int_raw register
|
||||
* SPI interrupt raw register
|
||||
/** Type of dma_int register
|
||||
* SPI interrupt raw/ena/clr/sta/set register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
@ -1038,301 +848,112 @@ typedef union {
|
||||
* 1: The current data rate of DMA Rx is smaller than that of SPI, which will lose the
|
||||
* receive data. 0: Others.
|
||||
*/
|
||||
uint32_t dma_infifo_full_err_int_raw:1;
|
||||
uint32_t dma_infifo_full_err_int:1;
|
||||
/** dma_outfifo_empty_err_int_raw : R/WTC/SS; bitpos: [1]; default: 0;
|
||||
* 1: The current data rate of DMA TX is smaller than that of SPI. SPI will stop in
|
||||
* master mode and send out all 0 in slave mode. 0: Others.
|
||||
*/
|
||||
uint32_t dma_outfifo_empty_err_int_raw:1;
|
||||
uint32_t dma_outfifo_empty_err_int:1;
|
||||
/** slv_ex_qpi_int_raw : R/WTC/SS; bitpos: [2]; default: 0;
|
||||
* The raw bit for SPI slave Ex_QPI interrupt. 1: SPI slave mode Ex_QPI transmission
|
||||
* is ended. 0: Others.
|
||||
*/
|
||||
uint32_t slv_ex_qpi_int_raw:1;
|
||||
uint32_t slv_ex_qpi_int:1;
|
||||
/** slv_en_qpi_int_raw : R/WTC/SS; bitpos: [3]; default: 0;
|
||||
* The raw bit for SPI slave En_QPI interrupt. 1: SPI slave mode En_QPI transmission
|
||||
* is ended. 0: Others.
|
||||
*/
|
||||
uint32_t slv_en_qpi_int_raw:1;
|
||||
uint32_t slv_en_qpi_int:1;
|
||||
/** slv_cmd7_int_raw : R/WTC/SS; bitpos: [4]; default: 0;
|
||||
* The raw bit for SPI slave CMD7 interrupt. 1: SPI slave mode CMD7 transmission is
|
||||
* ended. 0: Others.
|
||||
*/
|
||||
uint32_t slv_cmd7_int_raw:1;
|
||||
uint32_t slv_cmd7_int:1;
|
||||
/** slv_cmd8_int_raw : R/WTC/SS; bitpos: [5]; default: 0;
|
||||
* The raw bit for SPI slave CMD8 interrupt. 1: SPI slave mode CMD8 transmission is
|
||||
* ended. 0: Others.
|
||||
*/
|
||||
uint32_t slv_cmd8_int_raw:1;
|
||||
uint32_t slv_cmd8_int:1;
|
||||
/** slv_cmd9_int_raw : R/WTC/SS; bitpos: [6]; default: 0;
|
||||
* The raw bit for SPI slave CMD9 interrupt. 1: SPI slave mode CMD9 transmission is
|
||||
* ended. 0: Others.
|
||||
*/
|
||||
uint32_t slv_cmd9_int_raw:1;
|
||||
uint32_t slv_cmd9_int:1;
|
||||
/** slv_cmda_int_raw : R/WTC/SS; bitpos: [7]; default: 0;
|
||||
* The raw bit for SPI slave CMDA interrupt. 1: SPI slave mode CMDA transmission is
|
||||
* ended. 0: Others.
|
||||
*/
|
||||
uint32_t slv_cmda_int_raw:1;
|
||||
uint32_t slv_cmda_int:1;
|
||||
/** slv_rd_dma_done_int_raw : R/WTC/SS; bitpos: [8]; default: 0;
|
||||
* The raw bit for SPI_SLV_RD_DMA_DONE_INT interrupt. 1: SPI slave mode Rd_DMA
|
||||
* transmission is ended. 0: Others.
|
||||
*/
|
||||
uint32_t slv_rd_dma_done_int_raw:1;
|
||||
uint32_t slv_rd_dma_done_int:1;
|
||||
/** slv_wr_dma_done_int_raw : R/WTC/SS; bitpos: [9]; default: 0;
|
||||
* The raw bit for SPI_SLV_WR_DMA_DONE_INT interrupt. 1: SPI slave mode Wr_DMA
|
||||
* transmission is ended. 0: Others.
|
||||
*/
|
||||
uint32_t slv_wr_dma_done_int_raw:1;
|
||||
uint32_t slv_wr_dma_done_int:1;
|
||||
/** slv_rd_buf_done_int_raw : R/WTC/SS; bitpos: [10]; default: 0;
|
||||
* The raw bit for SPI_SLV_RD_BUF_DONE_INT interrupt. 1: SPI slave mode Rd_BUF
|
||||
* transmission is ended. 0: Others.
|
||||
*/
|
||||
uint32_t slv_rd_buf_done_int_raw:1;
|
||||
uint32_t slv_rd_buf_done_int:1;
|
||||
/** slv_wr_buf_done_int_raw : R/WTC/SS; bitpos: [11]; default: 0;
|
||||
* The raw bit for SPI_SLV_WR_BUF_DONE_INT interrupt. 1: SPI slave mode Wr_BUF
|
||||
* transmission is ended. 0: Others.
|
||||
*/
|
||||
uint32_t slv_wr_buf_done_int_raw:1;
|
||||
uint32_t slv_wr_buf_done_int:1;
|
||||
/** trans_done_int_raw : R/WTC/SS; bitpos: [12]; default: 0;
|
||||
* The raw bit for SPI_TRANS_DONE_INT interrupt. 1: SPI master mode transmission is
|
||||
* ended. 0: others.
|
||||
*/
|
||||
uint32_t trans_done_int_raw:1;
|
||||
uint32_t trans_done_int:1;
|
||||
/** dma_seg_trans_done_int_raw : R/WTC/SS; bitpos: [13]; default: 0;
|
||||
* The raw bit for SPI_DMA_SEG_TRANS_DONE_INT interrupt. 1: spi master DMA
|
||||
* full-duplex/half-duplex seg-conf-trans ends or slave half-duplex seg-trans ends.
|
||||
* And data has been pushed to corresponding memory. 0: seg-conf-trans or seg-trans
|
||||
* is not ended or not occurred.
|
||||
*/
|
||||
uint32_t dma_seg_trans_done_int_raw:1;
|
||||
uint32_t dma_seg_trans_done_int:1;
|
||||
/** seg_magic_err_int_raw : R/WTC/SS; bitpos: [14]; default: 0;
|
||||
* The raw bit for SPI_SEG_MAGIC_ERR_INT interrupt. 1: The magic value in CONF buffer
|
||||
* is error in the DMA seg-conf-trans. 0: others.
|
||||
*/
|
||||
uint32_t seg_magic_err_int_raw:1; //this field is only for GPSPI2
|
||||
uint32_t seg_magic_err_int_raw:1; //this field is only forPI2
|
||||
/** slv_buf_addr_err_int_raw : R/WTC/SS; bitpos: [15]; default: 0;
|
||||
* The raw bit for SPI_SLV_BUF_ADDR_ERR_INT interrupt. 1: The accessing data address
|
||||
* of the current SPI slave mode CPU controlled FD, Wr_BUF or Rd_BUF transmission is
|
||||
* bigger than 63. 0: Others.
|
||||
*/
|
||||
uint32_t slv_buf_addr_err_int_raw:1;
|
||||
uint32_t slv_buf_addr_err_int:1;
|
||||
/** slv_cmd_err_int_raw : R/WTC/SS; bitpos: [16]; default: 0;
|
||||
* The raw bit for SPI_SLV_CMD_ERR_INT interrupt. 1: The slave command value in the
|
||||
* current SPI slave HD mode transmission is not supported. 0: Others.
|
||||
*/
|
||||
uint32_t slv_cmd_err_int_raw:1;
|
||||
uint32_t slv_cmd_err_int:1;
|
||||
/** mst_rx_afifo_wfull_err_int_raw : R/WTC/SS; bitpos: [17]; default: 0;
|
||||
* The raw bit for SPI_MST_RX_AFIFO_WFULL_ERR_INT interrupt. 1: There is a RX AFIFO
|
||||
* write-full error when SPI inputs data in master mode. 0: Others.
|
||||
*/
|
||||
uint32_t mst_rx_afifo_wfull_err_int_raw:1;
|
||||
uint32_t mst_rx_afifo_wfull_err_int:1;
|
||||
/** mst_tx_afifo_rempty_err_int_raw : R/WTC/SS; bitpos: [18]; default: 0;
|
||||
* The raw bit for SPI_MST_TX_AFIFO_REMPTY_ERR_INT interrupt. 1: There is a TX BUF
|
||||
* AFIFO read-empty error when SPI outputs data in master mode. 0: Others.
|
||||
*/
|
||||
uint32_t mst_tx_afifo_rempty_err_int_raw:1;
|
||||
uint32_t mst_tx_afifo_rempty_err_int:1;
|
||||
/** app2_int_raw : R/WTC/SS; bitpos: [19]; default: 0;
|
||||
* The raw bit for SPI_APP2_INT interrupt. The value is only controlled by software.
|
||||
*/
|
||||
uint32_t app2_int_raw:1;
|
||||
uint32_t app2_int:1;
|
||||
/** app1_int_raw : R/WTC/SS; bitpos: [20]; default: 0;
|
||||
* The raw bit for SPI_APP1_INT interrupt. The value is only controlled by software.
|
||||
*/
|
||||
uint32_t app1_int_raw:1;
|
||||
uint32_t app1_int:1;
|
||||
uint32_t reserved_21:11;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_dma_int_raw_reg_t;
|
||||
|
||||
/** Type of dma_int_st register
|
||||
* SPI interrupt status register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** dma_infifo_full_err_int_st : RO; bitpos: [0]; default: 0;
|
||||
* The status bit for SPI_DMA_INFIFO_FULL_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_infifo_full_err_int_st:1;
|
||||
/** dma_outfifo_empty_err_int_st : RO; bitpos: [1]; default: 0;
|
||||
* The status bit for SPI_DMA_OUTFIFO_EMPTY_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_outfifo_empty_err_int_st:1;
|
||||
/** slv_ex_qpi_int_st : RO; bitpos: [2]; default: 0;
|
||||
* The status bit for SPI slave Ex_QPI interrupt.
|
||||
*/
|
||||
uint32_t slv_ex_qpi_int_st:1;
|
||||
/** slv_en_qpi_int_st : RO; bitpos: [3]; default: 0;
|
||||
* The status bit for SPI slave En_QPI interrupt.
|
||||
*/
|
||||
uint32_t slv_en_qpi_int_st:1;
|
||||
/** slv_cmd7_int_st : RO; bitpos: [4]; default: 0;
|
||||
* The status bit for SPI slave CMD7 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd7_int_st:1;
|
||||
/** slv_cmd8_int_st : RO; bitpos: [5]; default: 0;
|
||||
* The status bit for SPI slave CMD8 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd8_int_st:1;
|
||||
/** slv_cmd9_int_st : RO; bitpos: [6]; default: 0;
|
||||
* The status bit for SPI slave CMD9 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd9_int_st:1;
|
||||
/** slv_cmda_int_st : RO; bitpos: [7]; default: 0;
|
||||
* The status bit for SPI slave CMDA interrupt.
|
||||
*/
|
||||
uint32_t slv_cmda_int_st:1;
|
||||
/** slv_rd_dma_done_int_st : RO; bitpos: [8]; default: 0;
|
||||
* The status bit for SPI_SLV_RD_DMA_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_rd_dma_done_int_st:1;
|
||||
/** slv_wr_dma_done_int_st : RO; bitpos: [9]; default: 0;
|
||||
* The status bit for SPI_SLV_WR_DMA_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_wr_dma_done_int_st:1;
|
||||
/** slv_rd_buf_done_int_st : RO; bitpos: [10]; default: 0;
|
||||
* The status bit for SPI_SLV_RD_BUF_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_rd_buf_done_int_st:1;
|
||||
/** slv_wr_buf_done_int_st : RO; bitpos: [11]; default: 0;
|
||||
* The status bit for SPI_SLV_WR_BUF_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_wr_buf_done_int_st:1;
|
||||
/** trans_done_int_st : RO; bitpos: [12]; default: 0;
|
||||
* The status bit for SPI_TRANS_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t trans_done_int_st:1;
|
||||
/** dma_seg_trans_done_int_st : RO; bitpos: [13]; default: 0;
|
||||
* The status bit for SPI_DMA_SEG_TRANS_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_seg_trans_done_int_st:1;
|
||||
/** seg_magic_err_int_st : RO; bitpos: [14]; default: 0;
|
||||
* The status bit for SPI_SEG_MAGIC_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t seg_magic_err_int_st:1; //this field is only for GPSPI2
|
||||
/** slv_buf_addr_err_int_st : RO; bitpos: [15]; default: 0;
|
||||
* The status bit for SPI_SLV_BUF_ADDR_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_buf_addr_err_int_st:1;
|
||||
/** slv_cmd_err_int_st : RO; bitpos: [16]; default: 0;
|
||||
* The status bit for SPI_SLV_CMD_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd_err_int_st:1;
|
||||
/** mst_rx_afifo_wfull_err_int_st : RO; bitpos: [17]; default: 0;
|
||||
* The status bit for SPI_MST_RX_AFIFO_WFULL_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t mst_rx_afifo_wfull_err_int_st:1;
|
||||
/** mst_tx_afifo_rempty_err_int_st : RO; bitpos: [18]; default: 0;
|
||||
* The status bit for SPI_MST_TX_AFIFO_REMPTY_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t mst_tx_afifo_rempty_err_int_st:1;
|
||||
/** app2_int_st : RO; bitpos: [19]; default: 0;
|
||||
* The status bit for SPI_APP2_INT interrupt.
|
||||
*/
|
||||
uint32_t app2_int_st:1;
|
||||
/** app1_int_st : RO; bitpos: [20]; default: 0;
|
||||
* The status bit for SPI_APP1_INT interrupt.
|
||||
*/
|
||||
uint32_t app1_int_st:1;
|
||||
uint32_t reserved_21:11;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_dma_int_st_reg_t;
|
||||
|
||||
/** Type of dma_int_set register
|
||||
* SPI interrupt software set register
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** dma_infifo_full_err_int_set : WT; bitpos: [0]; default: 0;
|
||||
* The software set bit for SPI_DMA_INFIFO_FULL_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_infifo_full_err_int_set:1;
|
||||
/** dma_outfifo_empty_err_int_set : WT; bitpos: [1]; default: 0;
|
||||
* The software set bit for SPI_DMA_OUTFIFO_EMPTY_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_outfifo_empty_err_int_set:1;
|
||||
/** slv_ex_qpi_int_set : WT; bitpos: [2]; default: 0;
|
||||
* The software set bit for SPI slave Ex_QPI interrupt.
|
||||
*/
|
||||
uint32_t slv_ex_qpi_int_set:1;
|
||||
/** slv_en_qpi_int_set : WT; bitpos: [3]; default: 0;
|
||||
* The software set bit for SPI slave En_QPI interrupt.
|
||||
*/
|
||||
uint32_t slv_en_qpi_int_set:1;
|
||||
/** slv_cmd7_int_set : WT; bitpos: [4]; default: 0;
|
||||
* The software set bit for SPI slave CMD7 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd7_int_set:1;
|
||||
/** slv_cmd8_int_set : WT; bitpos: [5]; default: 0;
|
||||
* The software set bit for SPI slave CMD8 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd8_int_set:1;
|
||||
/** slv_cmd9_int_set : WT; bitpos: [6]; default: 0;
|
||||
* The software set bit for SPI slave CMD9 interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd9_int_set:1;
|
||||
/** slv_cmda_int_set : WT; bitpos: [7]; default: 0;
|
||||
* The software set bit for SPI slave CMDA interrupt.
|
||||
*/
|
||||
uint32_t slv_cmda_int_set:1;
|
||||
/** slv_rd_dma_done_int_set : WT; bitpos: [8]; default: 0;
|
||||
* The software set bit for SPI_SLV_RD_DMA_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_rd_dma_done_int_set:1;
|
||||
/** slv_wr_dma_done_int_set : WT; bitpos: [9]; default: 0;
|
||||
* The software set bit for SPI_SLV_WR_DMA_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_wr_dma_done_int_set:1;
|
||||
/** slv_rd_buf_done_int_set : WT; bitpos: [10]; default: 0;
|
||||
* The software set bit for SPI_SLV_RD_BUF_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_rd_buf_done_int_set:1;
|
||||
/** slv_wr_buf_done_int_set : WT; bitpos: [11]; default: 0;
|
||||
* The software set bit for SPI_SLV_WR_BUF_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_wr_buf_done_int_set:1;
|
||||
/** trans_done_int_set : WT; bitpos: [12]; default: 0;
|
||||
* The software set bit for SPI_TRANS_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t trans_done_int_set:1;
|
||||
/** dma_seg_trans_done_int_set : WT; bitpos: [13]; default: 0;
|
||||
* The software set bit for SPI_DMA_SEG_TRANS_DONE_INT interrupt.
|
||||
*/
|
||||
uint32_t dma_seg_trans_done_int_set:1;
|
||||
/** seg_magic_err_int_set : WT; bitpos: [14]; default: 0;
|
||||
* The software set bit for SPI_SEG_MAGIC_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t seg_magic_err_int_set:1; //this field is only for GPSPI2
|
||||
/** slv_buf_addr_err_int_set : WT; bitpos: [15]; default: 0;
|
||||
* The software set bit for SPI_SLV_BUF_ADDR_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_buf_addr_err_int_set:1;
|
||||
/** slv_cmd_err_int_set : WT; bitpos: [16]; default: 0;
|
||||
* The software set bit for SPI_SLV_CMD_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t slv_cmd_err_int_set:1;
|
||||
/** mst_rx_afifo_wfull_err_int_set : WT; bitpos: [17]; default: 0;
|
||||
* The software set bit for SPI_MST_RX_AFIFO_WFULL_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t mst_rx_afifo_wfull_err_int_set:1;
|
||||
/** mst_tx_afifo_rempty_err_int_set : WT; bitpos: [18]; default: 0;
|
||||
* The software set bit for SPI_MST_TX_AFIFO_REMPTY_ERR_INT interrupt.
|
||||
*/
|
||||
uint32_t mst_tx_afifo_rempty_err_int_set:1;
|
||||
/** app2_int_set : WT; bitpos: [19]; default: 0;
|
||||
* The software set bit for SPI_APP2_INT interrupt.
|
||||
*/
|
||||
uint32_t app2_int_set:1;
|
||||
/** app1_int_set : WT; bitpos: [20]; default: 0;
|
||||
* The software set bit for SPI_APP1_INT interrupt.
|
||||
*/
|
||||
uint32_t app1_int_set:1;
|
||||
uint32_t reserved_21:11;
|
||||
};
|
||||
uint32_t val;
|
||||
} spi_dma_int_set_reg_t;
|
||||
|
||||
} spi_dma_int_reg_t;
|
||||
|
||||
/** Type of wn register
|
||||
* SPI CPU-controlled buffer
|
||||
@ -1378,11 +999,11 @@ typedef struct {
|
||||
volatile spi_din_num_reg_t din_num;
|
||||
volatile spi_dout_mode_reg_t dout_mode;
|
||||
volatile spi_dma_conf_reg_t dma_conf;
|
||||
volatile spi_dma_int_ena_reg_t dma_int_ena;
|
||||
volatile spi_dma_int_clr_reg_t dma_int_clr;
|
||||
volatile spi_dma_int_raw_reg_t dma_int_raw;
|
||||
volatile spi_dma_int_st_reg_t dma_int_st;
|
||||
volatile spi_dma_int_set_reg_t dma_int_set;
|
||||
volatile spi_dma_int_reg_t dma_int_ena;
|
||||
volatile spi_dma_int_reg_t dma_int_clr;
|
||||
volatile spi_dma_int_reg_t dma_int_raw;
|
||||
volatile spi_dma_int_reg_t dma_int_sta;
|
||||
volatile spi_dma_int_reg_t dma_int_set;
|
||||
uint32_t reserved_048[20];
|
||||
volatile spi_wn_reg_t data_buf[16];
|
||||
uint32_t reserved_0d8[2];
|
||||
|
@ -11,5 +11,88 @@
|
||||
Bunch of constants for every SPI peripheral: GPIO signals, irqs, hw addr of registers etc
|
||||
*/
|
||||
const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = {
|
||||
|
||||
{
|
||||
// MSPI on P4 has dedicated iomux pins
|
||||
.spiclk_out = -1,
|
||||
.spiclk_in = -1,
|
||||
.spid_out = -1,
|
||||
.spiq_out = -1,
|
||||
.spiwp_out = -1,
|
||||
.spihd_out = -1,
|
||||
.spid_in = -1,
|
||||
.spiq_in = -1,
|
||||
.spiwp_in = -1,
|
||||
.spihd_in = -1,
|
||||
.spics_out = {-1},
|
||||
.spics_in = -1,
|
||||
.spiclk_iomux_pin = -1,
|
||||
.spid_iomux_pin = -1,
|
||||
.spiq_iomux_pin = -1,
|
||||
.spiwp_iomux_pin = -1,
|
||||
.spihd_iomux_pin = -1,
|
||||
.spics0_iomux_pin = -1,
|
||||
.irq = -1,
|
||||
.irq_dma = -1,
|
||||
.module = -1,
|
||||
.hw = NULL,
|
||||
.func = -1,
|
||||
}, {
|
||||
.spiclk_out = SPI2_CK_PAD_OUT_IDX,
|
||||
.spiclk_in = SPI2_CK_PAD_IN_IDX,
|
||||
.spid_out = SPI2_D_PAD_OUT_IDX,
|
||||
.spiq_out = SPI2_Q_PAD_OUT_IDX,
|
||||
.spiwp_out = SPI2_WP_PAD_OUT_IDX,
|
||||
.spihd_out = SPI2_HOLD_PAD_OUT_IDX,
|
||||
.spid4_out = SPI2_IO4_PAD_OUT_IDX,
|
||||
.spid5_out = SPI2_IO5_PAD_OUT_IDX,
|
||||
.spid6_out = SPI2_IO6_PAD_OUT_IDX,
|
||||
.spid7_out = SPI2_IO7_PAD_OUT_IDX,
|
||||
.spid_in = SPI2_D_PAD_IN_IDX,
|
||||
.spiq_in = SPI2_Q_PAD_IN_IDX,
|
||||
.spiwp_in = SPI2_WP_PAD_IN_IDX,
|
||||
.spihd_in = SPI2_HOLD_PAD_IN_IDX,
|
||||
.spid4_in = SPI2_IO4_PAD_IN_IDX,
|
||||
.spid5_in = SPI2_IO5_PAD_IN_IDX,
|
||||
.spid6_in = SPI2_IO6_PAD_IN_IDX,
|
||||
.spid7_in = SPI2_IO7_PAD_IN_IDX,
|
||||
.spics_out = {SPI2_CS_PAD_OUT_IDX, SPI2_CS1_PAD_OUT_IDX, SPI2_CS2_PAD_OUT_IDX, SPI2_CS3_PAD_OUT_IDX, SPI2_CS4_PAD_OUT_IDX, SPI2_CS5_PAD_OUT_IDX},
|
||||
.spics_in = SPI2_CS_PAD_IN_IDX,
|
||||
.spiclk_iomux_pin = SPI2_IOMUX_PIN_NUM_CLK,
|
||||
.spid_iomux_pin = SPI2_IOMUX_PIN_NUM_MOSI,
|
||||
.spiq_iomux_pin = SPI2_IOMUX_PIN_NUM_MISO,
|
||||
.spiwp_iomux_pin = SPI2_IOMUX_PIN_NUM_WP,
|
||||
.spihd_iomux_pin = SPI2_IOMUX_PIN_NUM_HD,
|
||||
.spics0_iomux_pin = SPI2_IOMUX_PIN_NUM_CS,
|
||||
.irq = ETS_SPI2_INTR_SOURCE,
|
||||
.irq_dma = -1,
|
||||
.module = PERIPH_GPSPI2_MODULE,
|
||||
.hw = &GPSPI2,
|
||||
.func = SPI2_FUNC_NUM,
|
||||
}, {
|
||||
.spiclk_out = SPI3_CK_PAD_OUT_IDX,
|
||||
.spiclk_in = SPI3_CK_PAD_IN_IDX,
|
||||
.spid_out = SPI3_D_PAD_OUT_IDX,
|
||||
.spiq_out = SPI3_QO_PAD_OUT_IDX,
|
||||
//SPI3 doesn't have wp and hd signals
|
||||
.spiwp_out = SPI3_WP_PAD_OUT_IDX,
|
||||
.spihd_out = SPI3_HOLD_PAD_OUT_IDX,
|
||||
.spid_in = SPI3_D_PAD_IN_IDX,
|
||||
.spiq_in = SPI3_Q_PAD_IN_IDX,
|
||||
.spiwp_in = SPI3_WP_PAD_IN_IDX,
|
||||
.spihd_in = SPI3_HOLD_PAD_IN_IDX,
|
||||
.spics_out = {SPI3_CS_PAD_OUT_IDX, SPI3_CS1_PAD_OUT_IDX, SPI3_CS2_PAD_OUT_IDX},
|
||||
.spics_in = SPI3_CS_PAD_IN_IDX,
|
||||
//SPI3 doesn't have iomux pins
|
||||
.spiclk_iomux_pin = -1,
|
||||
.spid_iomux_pin = -1,
|
||||
.spiq_iomux_pin = -1,
|
||||
.spiwp_iomux_pin = -1,
|
||||
.spihd_iomux_pin = -1,
|
||||
.spics0_iomux_pin = -1,
|
||||
.irq = ETS_SPI3_INTR_SOURCE,
|
||||
.irq_dma = -1,
|
||||
.module = PERIPH_GPSPI3_MODULE,
|
||||
.hw = &GPSPI3,
|
||||
.func = -1,
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# I2S TDM Example -- ES7210 4-Ch ADC Codec
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user