mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/esp32p4_hp_spi_support' into 'master'
Feature/esp32p4 hp spi master driver support Closes IDF-7502 See merge request espressif/esp-idf!24963
This commit is contained in:
commit
f92b18053a
@ -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,19 +64,18 @@ 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
|
||||
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.
|
||||
lldesc_t *dmadesc_tx; ///< DMA descriptor array for TX
|
||||
lldesc_t *dmadesc_rx; ///< DMA descriptor array for 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
|
||||
|
@ -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;
|
||||
|
||||
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;
|
||||
}
|
||||
new_desc->buffer_to_send = send_ptr;
|
||||
#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
|
||||
}
|
||||
|
||||
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
|
||||
//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
|
||||
|
@ -146,10 +146,21 @@ components/driver/test_apps/spi/master:
|
||||
components/driver/test_apps/spi/param:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
- if: IDF_TARGET in ["esp32p4"]
|
||||
temporary: true
|
||||
reason: target(s) is not supported yet # TODO: IDF-7503
|
||||
|
||||
components/driver/test_apps/spi/slave:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
- if: IDF_TARGET in ["esp32p4"]
|
||||
temporary: true
|
||||
reason: target(s) is not supported yet # TODO: IDF-7503 slave support
|
||||
|
||||
components/driver/test_apps/spi/slave_hd:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
- if: SOC_SPI_SUPPORT_SLAVE_HD_VER2 != 1
|
||||
|
||||
components/driver/test_apps/temperature_sensor:
|
||||
disable:
|
||||
|
@ -76,7 +76,7 @@
|
||||
#define ESP_SPI_SLAVE_TV (12.5*3.5)
|
||||
#define WIRE_DELAY 12.5
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
|
||||
#define SLAVE_IOMUX_PIN_MISO -1
|
||||
#define SLAVE_IOMUX_PIN_MOSI -1
|
||||
#define SLAVE_IOMUX_PIN_SCLK -1
|
||||
|
@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
@ -11,23 +11,15 @@
|
||||
// iterator to load partition tables in `test spi bus lock, with flash` will lead memory not free
|
||||
#define TEST_MEMORY_LEAK_THRESHOLD (350)
|
||||
|
||||
static size_t before_free_8bit;
|
||||
static size_t before_free_32bit;
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
unity_utils_record_free_mem();
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
|
||||
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
printf("\n");
|
||||
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
|
||||
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
|
||||
unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -287,8 +287,8 @@ TEST_CASE("SPI Master test", "[spi]")
|
||||
success &= spi_test(handle, 4096 - 2); //multiple descs, edge case 1
|
||||
success &= spi_test(handle, 4096 - 1); //multiple descs, edge case 2
|
||||
success &= spi_test(handle, 4096 * 3); //multiple descs
|
||||
|
||||
master_free_device_bus(handle);
|
||||
TEST_ASSERT(success);
|
||||
|
||||
printf("Testing bus at 80KHz, non-DMA\n");
|
||||
handle = setup_spi_bus_loopback(80000, false);
|
||||
@ -299,19 +299,18 @@ TEST_CASE("SPI Master test", "[spi]")
|
||||
success &= spi_test(handle, 47); //small, unaligned
|
||||
success &= spi_test(handle, 63); //small
|
||||
success &= spi_test(handle, 64); //small, unaligned
|
||||
|
||||
master_free_device_bus(handle);
|
||||
TEST_ASSERT(success);
|
||||
|
||||
printf("Testing bus at 26MHz\n");
|
||||
printf("Testing bus at 20MHz\n");
|
||||
handle = setup_spi_bus_loopback(20000000, true);
|
||||
|
||||
success &= spi_test(handle, 128); //DMA, aligned
|
||||
success &= spi_test(handle, 4096 * 3); //DMA, multiple descs
|
||||
master_free_device_bus(handle);
|
||||
TEST_ASSERT(success);
|
||||
|
||||
printf("Testing bus at 900KHz\n");
|
||||
handle = setup_spi_bus_loopback(9000000, true);
|
||||
|
||||
success &= spi_test(handle, 128); //DMA, aligned
|
||||
success &= spi_test(handle, 4096 * 3); //DMA, multiple descs
|
||||
master_free_device_bus(handle);
|
||||
@ -790,11 +789,8 @@ TEST_CASE("SPI Master DMA test: length, start, not aligned", "[spi]")
|
||||
//connect MOSI to two devices breaks the output, fix it.
|
||||
spitest_gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
|
||||
|
||||
memset(rx_buf, 0x66, 320);
|
||||
|
||||
for ( int i = 0; i < 8; i ++ ) {
|
||||
memset( rx_buf, 0x66, sizeof(rx_buf));
|
||||
|
||||
spi_transaction_t t = {};
|
||||
t.length = 8 * (i + 1);
|
||||
t.rxlength = 0;
|
||||
@ -881,12 +877,12 @@ void test_cmd_addr(spi_slave_task_context_t *slave_context, bool lsb_first)
|
||||
vTaskDelay(50);
|
||||
//prepare master tx data
|
||||
int cmd_bits = (i + 1) * 2;
|
||||
int addr_bits =
|
||||
int addr_bits = 0;
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
56 - 8 * i;
|
||||
addr_bits = 56 - 8 * i;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
//ESP32S2 only supportes up to 32 bits address
|
||||
28 - 4 * i;
|
||||
addr_bits = 28 - 4 * i;
|
||||
#endif
|
||||
int round_up = (cmd_bits + addr_bits + 7) / 8 * 8;
|
||||
addr_bits = round_up - cmd_bits;
|
||||
@ -1073,6 +1069,7 @@ TEST_CASE("SPI master variable dummy test", "[spi]")
|
||||
master_free_device_bus(spi);
|
||||
}
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support
|
||||
/**
|
||||
* This test is to check when the first transaction of the HD master is to send data without receiving data via DMA,
|
||||
* then if the master could receive data correctly.
|
||||
@ -1161,8 +1158,10 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]")
|
||||
spi_slave_free(TEST_SLAVE_HOST);
|
||||
master_free_device_bus(spi);
|
||||
}
|
||||
#endif
|
||||
#endif //#if (TEST_SPI_PERIPH_NUM >= 2)
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32) //TODO: IDF-3494
|
||||
#define FD_TEST_BUF_SIZE 32
|
||||
#define TEST_NUM 4
|
||||
@ -1338,6 +1337,7 @@ static void fd_slave(void)
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("SPI Master: FD, DMA, Master Single Direction Test", "[spi_ms][test_env=generic_multi_device]", fd_master, fd_slave);
|
||||
#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32) //TODO: IDF-3494
|
||||
#endif //p4 slave support
|
||||
|
||||
|
||||
//NOTE: Explained in IDF-1445 | MR !14996
|
||||
@ -1491,6 +1491,7 @@ TEST_CASE("spi_speed", "[spi]")
|
||||
#endif // CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
|
||||
#endif // !(CONFIG_SPIRAM) || (CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL >= 16384)
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support
|
||||
//****************************************spi master add device test************************************//
|
||||
//add dummy devices first
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
@ -1601,7 +1602,7 @@ void test_add_device_slave(void)
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("SPI_Master:Test multiple devices", "[spi_ms]", test_add_device_master, test_add_device_slave);
|
||||
|
||||
#endif //p4 slave support
|
||||
|
||||
#if (SOC_CPU_CORES_NUM > 1) && (!CONFIG_FREERTOS_UNICORE)
|
||||
|
||||
@ -1661,8 +1662,8 @@ TEST_CASE("test_master_isr_pin_to_core","[spi]")
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support
|
||||
#if CONFIG_SPI_MASTER_IN_IRAM
|
||||
|
||||
#define TEST_MASTER_IRAM_TRANS_LEN 120
|
||||
static IRAM_ATTR void test_master_iram_post_trans_cbk(spi_transaction_t *trans)
|
||||
{
|
||||
@ -1767,3 +1768,4 @@ static void test_iram_slave_normal(void)
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("SPI_Master:IRAM_safe", "[spi_ms]", test_master_iram, test_iram_slave_normal);
|
||||
#endif
|
||||
#endif //p4 slave support
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -37,6 +37,8 @@
|
||||
********************************************************************************/
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define MASTER_DIN_SIGNAL HSPID_IN_IDX
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define MASTER_DIN_SIGNAL SPI2_D_PAD_IN_IDX
|
||||
#else
|
||||
#define MASTER_DIN_SIGNAL FSPID_IN_IDX
|
||||
#endif
|
||||
@ -142,7 +144,7 @@ TEST_CASE("SPI Single Board Test SIO", "[spi]")
|
||||
}
|
||||
#endif //#if (TEST_SPI_PERIPH_NUM >= 2)
|
||||
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support
|
||||
/********************************************************************************
|
||||
* Test SIO Master
|
||||
* SIO Slave is not suported, and one unit test is limited to one feature, so,,,
|
||||
@ -326,3 +328,4 @@ void test_slave_run(void)
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("SPI_Master:Test_SIO_Mode_Multi_Board", "[spi_ms][test_env=generic_multi_device]", test_master_run, test_slave_run);
|
||||
#endif //p4 slave support
|
||||
|
@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
@ -5,7 +5,11 @@ import pytest
|
||||
|
||||
|
||||
# If `test_env` is define, should not run on generic runner
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32c2
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32h2
|
||||
@pytest.mark.generic
|
||||
def test_slave_hd_single_dev(case_tester) -> None: # type: ignore
|
||||
@ -16,7 +20,11 @@ def test_slave_hd_single_dev(case_tester) -> None: # type: ignore
|
||||
|
||||
|
||||
# if `test_env` not defined, will run on `generic_multi_device` by default
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32c2
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32h2
|
||||
@pytest.mark.generic_multi_device
|
||||
@pytest.mark.parametrize('count', [2,], indirect=True)
|
||||
|
@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -127,7 +127,11 @@ void static test_isr(void*arg)
|
||||
TEST_CASE("Allocate previously freed interrupt, with different flags", "[intr_alloc]")
|
||||
{
|
||||
intr_handle_t intr;
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
int test_intr_source = ETS_GPIO_INTR0_SOURCE;
|
||||
#else
|
||||
int test_intr_source = ETS_GPIO_INTR_SOURCE;
|
||||
#endif
|
||||
int isr_flags = ESP_INTR_FLAG_LEVEL2;
|
||||
|
||||
TEST_ESP_OK(esp_intr_alloc(test_intr_source, isr_flags, test_isr, NULL, &intr));
|
||||
@ -179,7 +183,15 @@ TEST_CASE("allocate 2 handlers for a same source and remove the later one", "[in
|
||||
intr_handle_t handle1, handle2;
|
||||
|
||||
// enable SPI2
|
||||
#if CONFIG_IDF_TARGET_ESP32P4 //deprecate clk_gate_ll start from p4, others in TODO: IDF-8159
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
spi_ll_enable_bus_clock(1, true);
|
||||
spi_ll_reset_register(1);
|
||||
spi_ll_enable_clock(1, true);
|
||||
}
|
||||
#else
|
||||
periph_module_enable(spi_periph_signal[1].module);
|
||||
#endif
|
||||
|
||||
esp_err_t r;
|
||||
r = esp_intr_alloc(spi_periph_signal[1].irq, ESP_INTR_FLAG_SHARED, int_handler1, &ctx, &handle1);
|
||||
|
@ -1,4 +1,4 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
This test app is used to test LCDs with SPI interface.
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "esp_lcd_panel_vendor.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lcd_panel_commands.h"
|
||||
#include "esp_random.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "test_spi_board.h"
|
||||
|
||||
@ -92,9 +91,9 @@ static void lcd_panel_test(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_ha
|
||||
gpio_set_level(TEST_LCD_BK_LIGHT_GPIO, 1);
|
||||
|
||||
for (int i = 0; i < 200; i++) {
|
||||
uint8_t color_byte = esp_random() & 0xFF;
|
||||
int x_start = esp_random() % (TEST_LCD_H_RES - 200);
|
||||
int y_start = esp_random() % (TEST_LCD_V_RES - 200);
|
||||
uint8_t color_byte = rand() & 0xFF;
|
||||
int x_start = rand() % (TEST_LCD_H_RES - 200);
|
||||
int y_start = rand() % (TEST_LCD_V_RES - 200);
|
||||
memset(img, color_byte, TEST_IMG_SIZE);
|
||||
esp_lcd_panel_draw_bitmap(panel_handle, x_start, y_start, x_start + 200, y_start + 200, img);
|
||||
}
|
||||
@ -202,7 +201,7 @@ TEST_CASE("spi_lcd_send_colors_to_fixed_region", "[lcd]")
|
||||
size_t color_size = (x_end - x_start) * (y_end - y_start) * 2;
|
||||
void *color_data = malloc(color_size);
|
||||
TEST_ASSERT_NOT_NULL(color_data);
|
||||
uint8_t color_byte = esp_random() & 0xFF;
|
||||
uint8_t color_byte = rand() & 0xFF;
|
||||
memset(color_data, color_byte, color_size);
|
||||
|
||||
esp_lcd_panel_io_handle_t io_handle = NULL;
|
||||
@ -249,7 +248,7 @@ TEST_CASE("spi_lcd_send_colors_to_fixed_region", "[lcd]")
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
// change to another color
|
||||
color_byte = esp_random() & 0xFF;
|
||||
color_byte = rand() & 0xFF;
|
||||
memset(color_data, color_byte, color_size);
|
||||
for (int i = 0; i < steps; i++) {
|
||||
TEST_ESP_OK(esp_lcd_panel_io_tx_color(io_handle, -1, color_data + i * color_size_per_step, color_size_per_step));
|
||||
|
@ -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
|
||||
|
@ -44,12 +44,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:
|
||||
@ -125,10 +119,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:
|
||||
@ -194,10 +184,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;
|
||||
@ -247,8 +233,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
|
||||
|
||||
|
@ -391,16 +391,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
|
||||
@ -378,28 +378,28 @@
|
||||
#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_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_MEMSPI_IS_INDEPENDENT 1
|
||||
#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_MEMSPI_IS_INDEPENDENT 1
|
||||
#define SOC_SPI_MAX_PRE_DIVIDER 16
|
||||
|
||||
/*-------------------------- SPI MEM CAPS ---------------------------------------*/
|
||||
|
@ -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,
|
||||
}
|
||||
};
|
||||
|
@ -117,7 +117,6 @@ api-reference/peripherals/ana_cmpr.rst
|
||||
api-reference/peripherals/secure_element.rst
|
||||
api-reference/peripherals/ledc.rst
|
||||
api-reference/peripherals/temp_sensor.rst
|
||||
api-reference/peripherals/spi_features.rst
|
||||
api-reference/peripherals/sdio_slave.rst
|
||||
api-reference/peripherals/clk_tree.rst
|
||||
api-reference/peripherals/spi_flash/xip_from_psram.inc
|
||||
@ -136,7 +135,6 @@ api-reference/peripherals/ds.rst
|
||||
api-reference/peripherals/i2c.rst
|
||||
api-reference/peripherals/dedic_gpio.rst
|
||||
api-reference/peripherals/sd_pullup_requirements.rst
|
||||
api-reference/peripherals/spi_master.rst
|
||||
api-reference/peripherals/index.rst
|
||||
api-reference/peripherals/sdmmc_host.rst
|
||||
api-reference/peripherals/uart.rst
|
||||
|
@ -182,28 +182,28 @@ Supported line modes for {IDF_TARGET_NAME} are listed as follows, to make use of
|
||||
- 1
|
||||
- 1
|
||||
- 2
|
||||
- {SPI_TRANS_MODE_DIO}
|
||||
- {SPICOMMON_BUSFLAG_DUAL}
|
||||
- SPI_TRANS_MODE_DIO
|
||||
- SPICOMMON_BUSFLAG_DUAL
|
||||
* - Dual I/O
|
||||
- 1
|
||||
- 2
|
||||
- 2
|
||||
- * {SPI_TRANS_MODE_DIO}
|
||||
* {SPI_TRANS_MULTILINE_ADDR}
|
||||
-
|
||||
- SPI_TRANS_MODE_DIO
|
||||
SPI_TRANS_MULTILINE_ADDR
|
||||
- SPICOMMON_BUSFLAG_DUAL
|
||||
* - Quad Output
|
||||
- 1
|
||||
- 1
|
||||
- 4
|
||||
- {SPI_TRANS_MODE_QIO}
|
||||
- {SPICOMMON_BUSFLAG_QUAD}
|
||||
- SPI_TRANS_MODE_QIO
|
||||
- SPICOMMON_BUSFLAG_QUAD
|
||||
* - Quad I/O
|
||||
- 1
|
||||
- 4
|
||||
- 4
|
||||
- * {SPI_TRANS_MODE_QIO}
|
||||
* {SPI_TRANS_MULTILINE_ADDR}
|
||||
- {SPICOMMON_BUSFLAG_QUAD}
|
||||
- SPI_TRANS_MODE_QIO
|
||||
SPI_TRANS_MULTILINE_ADDR
|
||||
- SPICOMMON_BUSFLAG_QUAD
|
||||
|
||||
.. only:: SOC_SPI_SUPPORT_OCT
|
||||
|
||||
@ -227,42 +227,42 @@ Supported line modes for {IDF_TARGET_NAME} are listed as follows, to make use of
|
||||
- 1
|
||||
- 1
|
||||
- 2
|
||||
- {SPI_TRANS_MODE_DIO}
|
||||
- {SPICOMMON_BUSFLAG_DUAL}
|
||||
- SPI_TRANS_MODE_DIO
|
||||
- SPICOMMON_BUSFLAG_DUAL
|
||||
* - Dual I/O
|
||||
- 1
|
||||
- 2
|
||||
- 2
|
||||
- * {SPI_TRANS_MODE_DIO}
|
||||
* {SPI_TRANS_MULTILINE_ADDR}
|
||||
-
|
||||
- SPI_TRANS_MODE_DIO
|
||||
SPI_TRANS_MULTILINE_ADDR
|
||||
- SPICOMMON_BUSFLAG_DUAL
|
||||
* - Quad Output
|
||||
- 1
|
||||
- 1
|
||||
- 4
|
||||
- {SPI_TRANS_MODE_QIO}
|
||||
- {SPICOMMON_BUSFLAG_QUAD}
|
||||
- SPI_TRANS_MODE_QIO
|
||||
- SPICOMMON_BUSFLAG_QUAD
|
||||
* - Quad I/O
|
||||
- 1
|
||||
- 4
|
||||
- 4
|
||||
- * {SPI_TRANS_MODE_QIO}
|
||||
* {SPI_TRANS_MULTILINE_ADDR}
|
||||
- {SPICOMMON_BUSFLAG_QUAD}
|
||||
- SPI_TRANS_MODE_QIO
|
||||
SPI_TRANS_MULTILINE_ADDR
|
||||
- SPICOMMON_BUSFLAG_QUAD
|
||||
* - Octal Output
|
||||
- 1
|
||||
- 1
|
||||
- 8
|
||||
- {SPI_TRANS_MODE_OCT}
|
||||
- {SPICOMMON_BUSFLAG_OCTAL}
|
||||
- SPI_TRANS_MODE_OCT
|
||||
- SPICOMMON_BUSFLAG_OCTAL
|
||||
* - OPI
|
||||
- 8
|
||||
- 8
|
||||
- 8
|
||||
- * {SPI_TRANS_MODE_OCT}
|
||||
* {SPI_TRANS_MULTILINE_ADDR}
|
||||
* {SPI_TRANS_MULTILINE_CMD}
|
||||
- {SPICOMMON_BUSFLAG_OCTAL}
|
||||
- SPI_TRANS_MODE_OCT
|
||||
SPI_TRANS_MULTILINE_ADDR
|
||||
SPI_TRANS_MULTILINE_CMD
|
||||
- SPICOMMON_BUSFLAG_OCTAL
|
||||
|
||||
Command and Address Phases
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -292,7 +292,7 @@ If using more than one data line to transmit, please set ``SPI_DEVICE_HALFDUPLEX
|
||||
|
||||
Half-duplex transactions with both Read and Write phases are not supported when using DMA. For details and workarounds, see :ref:`spi_known_issues`.
|
||||
|
||||
.. only:: esp32s3 or esp32c3 or esp32c2 or esp32c6 or esp32h2
|
||||
.. only:: not SOC_SPI_HD_BOTH_INOUT_SUPPORTED
|
||||
|
||||
.. note::
|
||||
|
||||
@ -473,12 +473,12 @@ GPIO Matrix and IO_MUX
|
||||
|
||||
.. only:: not esp32
|
||||
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11"}
|
||||
|
||||
Most of the chip's peripheral signals have a direct connection to their dedicated IO_MUX pins. However, the signals can also be routed to any other available pins using the less direct GPIO matrix. If at least one signal is routed through the GPIO matrix, then all signals will be routed through it.
|
||||
|
||||
@ -772,8 +772,6 @@ Please note that the ISR is disabled during flash operation by default. To keep
|
||||
- 8.89
|
||||
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
.. _spi_known_issues:
|
||||
|
||||
Known Issues
|
||||
@ -802,6 +800,7 @@ Application Example
|
||||
|
||||
The code example for using the SPI master half duplex mode to read/write an AT93C46D EEPROM (8-bit mode) can be found in the :example:`peripherals/spi_master/hd_eeprom` directory of ESP-IDF examples.
|
||||
|
||||
The code example for using the SPI master full duplex mode to drive a SPI_LCD (e.g. ST7789V or ILI9341) can be found in the :example:`peripherals/spi_master/lcd` directory of ESP-IDF examples.
|
||||
|
||||
API Reference - SPI Common
|
||||
--------------------------
|
||||
|
@ -182,28 +182,28 @@ SPI 总线传输事务由五个阶段构成,详见下表(任意阶段均可
|
||||
- 1
|
||||
- 1
|
||||
- 2
|
||||
- {SPI_TRANS_MODE_DIO}
|
||||
- {SPICOMMON_BUSFLAG_DUAL}
|
||||
- SPI_TRANS_MODE_DIO
|
||||
- SPICOMMON_BUSFLAG_DUAL
|
||||
* - 双线 I/O 模式
|
||||
- 1
|
||||
- 2
|
||||
- 2
|
||||
- * {SPI_TRANS_MODE_DIO}
|
||||
* {SPI_TRANS_MULTILINE_ADDR}
|
||||
-
|
||||
- SPI_TRANS_MODE_DIO
|
||||
SPI_TRANS_MULTILINE_ADDR
|
||||
- SPICOMMON_BUSFLAG_DUAL
|
||||
* - 四线输出模式
|
||||
- 1
|
||||
- 1
|
||||
- 4
|
||||
- {SPI_TRANS_MODE_QIO}
|
||||
- {SPICOMMON_BUSFLAG_QUAD}
|
||||
- SPI_TRANS_MODE_QIO
|
||||
- SPICOMMON_BUSFLAG_QUAD
|
||||
* - 四线 I/O 模式
|
||||
- 1
|
||||
- 4
|
||||
- 4
|
||||
- * {SPI_TRANS_MODE_QIO}
|
||||
* {SPI_TRANS_MULTILINE_ADDR}
|
||||
- {SPICOMMON_BUSFLAG_QUAD}
|
||||
- SPI_TRANS_MODE_QIO
|
||||
SPI_TRANS_MULTILINE_ADDR
|
||||
- SPICOMMON_BUSFLAG_QUAD
|
||||
|
||||
.. only:: SOC_SPI_SUPPORT_OCT
|
||||
|
||||
@ -227,42 +227,42 @@ SPI 总线传输事务由五个阶段构成,详见下表(任意阶段均可
|
||||
- 1
|
||||
- 1
|
||||
- 2
|
||||
- {SPI_TRANS_MODE_DIO}
|
||||
- {SPICOMMON_BUSFLAG_DUAL}
|
||||
- SPI_TRANS_MODE_DIO
|
||||
- SPICOMMON_BUSFLAG_DUAL
|
||||
* - 双线 I/O 模式
|
||||
- 1
|
||||
- 2
|
||||
- 2
|
||||
- * {SPI_TRANS_MODE_DIO}
|
||||
* {SPI_TRANS_MULTILINE_ADDR}
|
||||
-
|
||||
- SPI_TRANS_MODE_DIO
|
||||
SPI_TRANS_MULTILINE_ADDR
|
||||
- SPICOMMON_BUSFLAG_DUAL
|
||||
* - 四线输出模式
|
||||
- 1
|
||||
- 1
|
||||
- 4
|
||||
- {SPI_TRANS_MODE_QIO}
|
||||
- {SPICOMMON_BUSFLAG_QUAD}
|
||||
- SPI_TRANS_MODE_QIO
|
||||
- SPICOMMON_BUSFLAG_QUAD
|
||||
* - 四线 I/O 模式
|
||||
- 1
|
||||
- 4
|
||||
- 4
|
||||
- * {SPI_TRANS_MODE_QIO}
|
||||
* {SPI_TRANS_MULTILINE_ADDR}
|
||||
- {SPICOMMON_BUSFLAG_QUAD}
|
||||
- SPI_TRANS_MODE_QIO
|
||||
SPI_TRANS_MULTILINE_ADDR
|
||||
- SPICOMMON_BUSFLAG_QUAD
|
||||
* - 八线输出模式
|
||||
- 1
|
||||
- 1
|
||||
- 8
|
||||
- {SPI_TRANS_MODE_OCT}
|
||||
- {SPICOMMON_BUSFLAG_OCTAL}
|
||||
- SPI_TRANS_MODE_OCT
|
||||
- SPICOMMON_BUSFLAG_OCTAL
|
||||
* - OPI 模式
|
||||
- 8
|
||||
- 8
|
||||
- 8
|
||||
- * {SPI_TRANS_MODE_OCT}
|
||||
* {SPI_TRANS_MULTILINE_ADDR}
|
||||
* {SPI_TRANS_MULTILINE_CMD}
|
||||
- {SPICOMMON_BUSFLAG_OCTAL}
|
||||
- SPI_TRANS_MODE_OCT
|
||||
SPI_TRANS_MULTILINE_ADDR
|
||||
SPI_TRANS_MULTILINE_CMD
|
||||
- SPICOMMON_BUSFLAG_OCTAL
|
||||
|
||||
命令阶段和地址阶段
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -292,7 +292,7 @@ SPI 总线传输事务由五个阶段构成,详见下表(任意阶段均可
|
||||
|
||||
当启用 DMA 时,不支持同时具有读取阶段和写入阶段的半双工传输事务。有关细节和解决方法,请参阅 :ref:`spi_known_issues`。
|
||||
|
||||
.. only:: esp32s3 or esp32c3 or esp32c2 or esp32c6 or esp32h2
|
||||
.. only:: not SOC_SPI_HD_BOTH_INOUT_SUPPORTED
|
||||
|
||||
.. note::
|
||||
|
||||
@ -473,12 +473,12 @@ GPIO 矩阵与 IO_MUX 管脚
|
||||
|
||||
.. only:: not esp32
|
||||
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6"}
|
||||
{IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11"}
|
||||
|
||||
芯片的大多数外围信号都与之专用的 IO_MUX 管脚连接,但这些信号也可以通过较不直接的 GPIO 矩阵路由到任何其他可用的管脚。只要有一个信号是通过 GPIO 矩阵路由的,那么所有的信号都将通过它路由。
|
||||
|
||||
@ -772,8 +772,6 @@ GPSPI 外设的时钟源可以通过设置 :cpp:member:`spi_device_handle_t::cfg
|
||||
- 8.89
|
||||
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
.. _spi_known_issues:
|
||||
|
||||
已知问题
|
||||
@ -802,6 +800,7 @@ GPSPI 外设的时钟源可以通过设置 :cpp:member:`spi_device_handle_t::cfg
|
||||
|
||||
查看使用 SPI 主机驱动程序在半双工模式下读取/写入 AT93C46D EEPROM(8 位模式)的示例代码,请前往 ESP-IDF 示例的 :example:`peripherals/spi_master/hd_eeprom` 目录。
|
||||
|
||||
查看使用 SPI 主机驱动程序在全双工模式下驱动 LCD 屏幕(如 ST7789V 或 ILI9341)的示例代码,请前往 ESP-IDF 示例的 :example:`peripherals/spi_master/lcd` 目录。
|
||||
|
||||
API 参考 - SPI Common
|
||||
--------------------------
|
||||
|
@ -232,13 +232,12 @@ examples/peripherals/spi_master/lcd:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
|
||||
examples/peripherals/spi_slave/receiver:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
|
||||
examples/peripherals/spi_slave/sender:
|
||||
examples/peripherals/spi_slave:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
- if: IDF_TARGET in ["esp32p4"]
|
||||
temporary: true
|
||||
reason: target(s) is not supported yet # TODO: IDF-7503 slave support
|
||||
|
||||
examples/peripherals/spi_slave_hd/append_mode/master:
|
||||
disable:
|
||||
@ -255,10 +254,16 @@ examples/peripherals/spi_slave_hd/append_mode/slave:
|
||||
examples/peripherals/spi_slave_hd/segment_mode/seg_master:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
- if: IDF_TARGET in ["esp32p4"]
|
||||
temporary: true
|
||||
reason: target(s) is not supported yet # TODO: IDF-7505 slave hd support
|
||||
|
||||
examples/peripherals/spi_slave_hd/segment_mode/seg_slave:
|
||||
disable:
|
||||
- if: IDF_TARGET == "esp32" or SOC_GPSPI_SUPPORTED != 1
|
||||
- if: IDF_TARGET in ["esp32p4"]
|
||||
temporary: true
|
||||
reason: target(s) is not supported yet # TODO: IDF-7505 slave hd support
|
||||
|
||||
examples/peripherals/temperature_sensor/temp_sensor:
|
||||
disable:
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# SPI LCD and Touch Panel Example
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
## LCD tjpgd example
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
## SPI master half duplex EEPROM example
|
||||
|
||||
|
@ -22,8 +22,11 @@
|
||||
This code demonstrates how to use the SPI master half duplex mode to read/write a AT932C46D EEPROM (8-bit mode).
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
# ifdef CONFIG_EXAMPLE_USE_SPI1_PINS
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////// Please update the following configuration according to your HardWare spec /////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
# if CONFIG_EXAMPLE_USE_SPI1_PINS
|
||||
# define EEPROM_HOST SPI1_HOST
|
||||
// Use default pins, same as the flash chip.
|
||||
# define PIN_NUM_MISO 7
|
||||
@ -35,38 +38,13 @@
|
||||
# define PIN_NUM_MOSI 23
|
||||
# define PIN_NUM_CLK 19
|
||||
# endif
|
||||
|
||||
# define PIN_NUM_CS 13
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2
|
||||
#else
|
||||
# define EEPROM_HOST SPI2_HOST
|
||||
|
||||
# define PIN_NUM_MISO 37
|
||||
# define PIN_NUM_MOSI 35
|
||||
# define PIN_NUM_CLK 36
|
||||
# define PIN_NUM_CS 34
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6
|
||||
# define EEPROM_HOST SPI2_HOST
|
||||
|
||||
# define PIN_NUM_MISO 2
|
||||
# define PIN_NUM_MOSI 7
|
||||
# define PIN_NUM_CLK 6
|
||||
# define PIN_NUM_CS 10
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
# define EEPROM_HOST SPI2_HOST
|
||||
|
||||
# define PIN_NUM_MISO 13
|
||||
# define PIN_NUM_MOSI 11
|
||||
# define PIN_NUM_CLK 12
|
||||
# define PIN_NUM_MOSI 12
|
||||
# define PIN_NUM_CLK 11
|
||||
# define PIN_NUM_CS 10
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||
# define EEPROM_HOST SPI2_HOST
|
||||
|
||||
# define PIN_NUM_MISO 0
|
||||
# define PIN_NUM_MOSI 5
|
||||
# define PIN_NUM_CLK 4
|
||||
# define PIN_NUM_CS 1
|
||||
#endif
|
||||
|
||||
static const char TAG[] = "main";
|
||||
@ -124,11 +102,10 @@ void app_main(void)
|
||||
ESP_ERROR_CHECK(ret);
|
||||
}
|
||||
ESP_LOGI(TAG, "Read: %s", test_buf);
|
||||
|
||||
ESP_LOGI(TAG, "Example finished.");
|
||||
|
||||
while (1) {
|
||||
// Add your main loop handling code here.
|
||||
vTaskDelay(1);
|
||||
vTaskDelay(100);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# SPI Host Driver Example
|
||||
|
||||
@ -15,9 +15,11 @@ If you are looking for code to drive LCDs in general, rather than code that uses
|
||||
|
||||
* An ESP development board, with SPI LCD
|
||||
|
||||
Connection :
|
||||
**Connection** :
|
||||
|
||||
Depends on boards. Refer to `spi_master_example_main.c` No wiring is required on ESP-WROVER-KIT
|
||||
Depends on boards. The GPIO number used by this example can be changed in `spi_master_example_main.c` No wiring is required on ESP-WROVER-KIT
|
||||
|
||||
Especially, please pay attention to the level used to turn on the LCD backlight, some LCD module needs a low level to turn it on, while others take a high level. You can change the backlight level macro LCD_BK_LIGHT_ON_LEVEL in `spi_master_example_main.c`.
|
||||
|
||||
### Build and Flash
|
||||
|
||||
|
@ -29,8 +29,10 @@
|
||||
before the transaction is sent, the callback will set this line to the correct state.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define LCD_HOST HSPI_HOST
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////// Please update the following configuration according to your HardWare spec /////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define LCD_HOST SPI2_HOST
|
||||
|
||||
#define PIN_NUM_MISO 25
|
||||
#define PIN_NUM_MOSI 23
|
||||
@ -40,41 +42,8 @@
|
||||
#define PIN_NUM_DC 21
|
||||
#define PIN_NUM_RST 18
|
||||
#define PIN_NUM_BCKL 5
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define LCD_HOST SPI2_HOST
|
||||
|
||||
#define PIN_NUM_MISO 37
|
||||
#define PIN_NUM_MOSI 35
|
||||
#define PIN_NUM_CLK 36
|
||||
#define PIN_NUM_CS 45
|
||||
|
||||
#define PIN_NUM_DC 4
|
||||
#define PIN_NUM_RST 5
|
||||
#define PIN_NUM_BCKL 6
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6
|
||||
#define LCD_HOST SPI2_HOST
|
||||
|
||||
#define PIN_NUM_MISO 2
|
||||
#define PIN_NUM_MOSI 7
|
||||
#define PIN_NUM_CLK 6
|
||||
#define PIN_NUM_CS 10
|
||||
|
||||
#define PIN_NUM_DC 9
|
||||
#define PIN_NUM_RST 4
|
||||
#define PIN_NUM_BCKL 5
|
||||
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32H2
|
||||
#define LCD_HOST SPI2_HOST
|
||||
|
||||
#define PIN_NUM_MISO 0
|
||||
#define PIN_NUM_MOSI 5
|
||||
#define PIN_NUM_CLK 4
|
||||
#define PIN_NUM_CS 1
|
||||
|
||||
#define PIN_NUM_DC 10
|
||||
#define PIN_NUM_RST 11
|
||||
#define PIN_NUM_BCKL 12
|
||||
#endif
|
||||
#define LCD_BK_LIGHT_ON_LEVEL 0
|
||||
|
||||
//To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many. More means more memory use,
|
||||
//but less overhead for setting up / finishing transfers. Make sure 240 is dividable by this.
|
||||
@ -328,7 +297,7 @@ void lcd_init(spi_device_handle_t spi)
|
||||
}
|
||||
|
||||
///Enable backlight
|
||||
gpio_set_level(PIN_NUM_BCKL, 0);
|
||||
gpio_set_level(PIN_NUM_BCKL, LCD_BK_LIGHT_ON_LEVEL);
|
||||
}
|
||||
|
||||
/* To send a set of lines we have to send a command, 2 data bytes, another command, 2 more data bytes and another command
|
||||
|
@ -31,52 +31,19 @@ ready to receive/send data. This code connects this line to a GPIO interrupt whi
|
||||
task waits for this semaphore to be given before queueing a transmission.
|
||||
*/
|
||||
|
||||
/*
|
||||
Pins in use. The SPI Master can use the GPIO mux, so feel free to change these if needed.
|
||||
*/
|
||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////// Please update the following configuration according to your HardWare spec /////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define GPIO_HANDSHAKE 2
|
||||
#define GPIO_MOSI 12
|
||||
#define GPIO_MISO 13
|
||||
#define GPIO_SCLK 15
|
||||
#define GPIO_CS 14
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
|
||||
#define GPIO_HANDSHAKE 3
|
||||
#define GPIO_MOSI 7
|
||||
#define GPIO_MISO 2
|
||||
#define GPIO_SCLK 6
|
||||
#define GPIO_CS 10
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
#define GPIO_HANDSHAKE 15
|
||||
#define GPIO_MOSI 19
|
||||
#define GPIO_MISO 20
|
||||
#define GPIO_SCLK 18
|
||||
#define GPIO_CS 9
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||
#define GPIO_HANDSHAKE 2
|
||||
#define GPIO_MOSI 5
|
||||
#define GPIO_MISO 0
|
||||
#define GPIO_SCLK 4
|
||||
#define GPIO_CS 1
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define GPIO_HANDSHAKE 2
|
||||
#define GPIO_MOSI 11
|
||||
#define GPIO_MISO 13
|
||||
#define GPIO_SCLK 12
|
||||
#define GPIO_CS 10
|
||||
|
||||
#endif //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define SENDER_HOST HSPI_HOST
|
||||
|
||||
#else
|
||||
#define SENDER_HOST SPI2_HOST
|
||||
|
||||
#endif
|
||||
|
||||
//The semaphore indicating the slave is ready to receive stuff.
|
||||
|
Loading…
Reference in New Issue
Block a user