mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
arch/risc-v/espressif: Add LPSPI and SPI3 support
Add LPSPI and SPI3 support for esp32[-p4] Signed-off-by: Eren Terzioglu <eren.terzioglu@espressif.com>
This commit is contained in:
parent
f47e5394b5
commit
6497d57c30
6 changed files with 582 additions and 146 deletions
|
|
@ -1793,6 +1793,22 @@ config ESPRESSIF_SPI2
|
|||
select SPI
|
||||
select ESPRESSIF_SPI_PERIPH
|
||||
|
||||
config ESPRESSIF_SPI3
|
||||
bool "SPI 3"
|
||||
depends on ARCH_CHIP_ESP32P4
|
||||
default n
|
||||
select ESPRESSIF_SPI
|
||||
select SPI
|
||||
select ESPRESSIF_SPI_PERIPH
|
||||
|
||||
config ESPRESSIF_LPSPI0
|
||||
bool "LP SPI"
|
||||
depends on ARCH_CHIP_ESP32P4
|
||||
default n
|
||||
select ESPRESSIF_SPI
|
||||
select SPI
|
||||
select ESPRESSIF_SPI_PERIPH
|
||||
|
||||
config ESPRESSIF_SPI_BITBANG
|
||||
bool "SPI Bitbang"
|
||||
default n
|
||||
|
|
@ -3388,6 +3404,104 @@ config ESPRESSIF_SPI2_MISOPIN
|
|||
|
||||
endif # ESPRESSIF_SPI2
|
||||
|
||||
if ESPRESSIF_SPI3
|
||||
|
||||
config ESPRESSIF_SPI3_DMA
|
||||
bool "SPI3 use GDMA"
|
||||
default n
|
||||
depends on ESPRESSIF_DMA
|
||||
---help---
|
||||
Enable support for transfers using the GDMA engine.
|
||||
|
||||
config ESPRESSIF_SPI3_DMADESC_NUM
|
||||
int "SPI3 Master GDMA maximum number of descriptors"
|
||||
default 2
|
||||
depends on ESPRESSIF_SPI3_DMA
|
||||
---help---
|
||||
Configure the maximum number of out-link/in-link descriptors to
|
||||
be chained for a GDMA transfer.
|
||||
|
||||
config ESPRESSIF_SPI3_DMATHRESHOLD
|
||||
int "SPI3 GDMA threshold"
|
||||
default 64
|
||||
depends on ESPRESSIF_SPI3_DMA
|
||||
---help---
|
||||
When SPI GDMA is enabled, GDMA transfers whose size are below the
|
||||
defined threshold will be performed by polling logic.
|
||||
|
||||
choice ESPRESSIF_SPI3_MODE
|
||||
prompt "SPI3 mode"
|
||||
default ESPRESSIF_SPI3_MODE_MASTER
|
||||
|
||||
config ESPRESSIF_SPI3_MODE_MASTER
|
||||
bool "SPI3 Master mode"
|
||||
depends on SPI_DRIVER
|
||||
---help---
|
||||
Configure SPI3 to operate in Master mode.
|
||||
|
||||
config ESPRESSIF_SPI3_SLAVE
|
||||
bool "SPI3 Slave mode"
|
||||
depends on SPI_SLAVE
|
||||
select ESPRESSIF_GPIO_IRQ
|
||||
select ESPRESSIF_SPI_SLAVE
|
||||
---help---
|
||||
Configure SPI3 to operate in Slave mode.
|
||||
|
||||
endchoice # ESPRESSIF_SPI3_MODE
|
||||
|
||||
config ESPRESSIF_SPI3_SLAVE_BUFSIZE
|
||||
int "SPI3 Slave buffer size"
|
||||
default 2048
|
||||
depends on ESPRESSIF_SPI3_SLAVE
|
||||
---help---
|
||||
Configure the size of SPI3 Slave controller's internal buffers.
|
||||
|
||||
config ESPRESSIF_SPI3_CSPIN
|
||||
int "SPI3 CS Pin"
|
||||
default 20 if ARCH_CHIP_ESP32P4
|
||||
range 0 54 if ARCH_CHIP_ESP32P4
|
||||
|
||||
config ESPRESSIF_SPI3_CLKPIN
|
||||
int "SPI3 CLK Pin"
|
||||
default 22 if ARCH_CHIP_ESP32P4
|
||||
range 0 54 if ARCH_CHIP_ESP32P4
|
||||
|
||||
config ESPRESSIF_SPI3_MOSIPIN
|
||||
int "SPI3 MOSI Pin"
|
||||
default 21 if ARCH_CHIP_ESP32P4
|
||||
range 0 54 if ARCH_CHIP_ESP32P4
|
||||
|
||||
config ESPRESSIF_SPI3_MISOPIN
|
||||
int "SPI3 MISO Pin"
|
||||
default 27 if ARCH_CHIP_ESP32P4
|
||||
range 0 54 if ARCH_CHIP_ESP32P4
|
||||
|
||||
endif # ESPRESSIF_SPI3
|
||||
|
||||
if ESPRESSIF_LPSPI0
|
||||
|
||||
config ESPRESSIF_LPSPI0_CSPIN
|
||||
int "LP SPI CS Pin"
|
||||
default 4 if ARCH_CHIP_ESP32P4
|
||||
range 0 15 if ARCH_CHIP_ESP32P4
|
||||
|
||||
config ESPRESSIF_LPSPI0_CLKPIN
|
||||
int "LP SPI CLK Pin"
|
||||
default 8 if ARCH_CHIP_ESP32P4
|
||||
range 0 15 if ARCH_CHIP_ESP32P4
|
||||
|
||||
config ESPRESSIF_LPSPI0_MOSIPIN
|
||||
int "LP SPI MOSI Pin"
|
||||
default 7 if ARCH_CHIP_ESP32P4
|
||||
range 0 15 if ARCH_CHIP_ESP32P4
|
||||
|
||||
config ESPRESSIF_LPSPI0_MISOPIN
|
||||
int "LP SPI MISO Pin"
|
||||
default 6 if ARCH_CHIP_ESP32P4
|
||||
range 0 15 if ARCH_CHIP_ESP32P4
|
||||
|
||||
endif # ESPRESSIF_LPSPI0
|
||||
|
||||
if ESPRESSIF_SPI_BITBANG
|
||||
|
||||
choice ESPRESSIF_SPI_BITBANG_OPERATION_MODE
|
||||
|
|
|
|||
|
|
@ -77,6 +77,10 @@
|
|||
# include "include/esp_pm.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_LPSPI0
|
||||
# include "lp_core_spi.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
|
@ -114,7 +118,7 @@
|
|||
# define SPI_HAVE_SWCS 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
|
||||
/* SPI DMA RX/TX number of descriptors */
|
||||
|
||||
|
|
@ -216,12 +220,15 @@ struct esp_spi_priv_s
|
|||
const struct esp_spi_config_s *config;
|
||||
int refs; /* Reference count */
|
||||
mutex_t lock; /* Held while chip is selected for mutual exclusion */
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
sem_t sem_isr; /* Interrupt wait semaphore */
|
||||
int cpuint; /* SPI interrupt ID */
|
||||
gdma_channel_handle_t dma_channel_tx; /* I2S DMA TX channel being used */
|
||||
gdma_channel_handle_t dma_channel_rx; /* I2S DMA RX channel being used */
|
||||
gdma_channel_handle_t dma_channel_tx; /* SPI DMA TX channel being used */
|
||||
gdma_channel_handle_t dma_channel_rx; /* SPI DMA RX channel being used */
|
||||
int32_t dma_channel; /* Channel assigned by the GDMA driver */
|
||||
spi_dma_desc_t *dma_rxdesc; /* DMA RX description */
|
||||
spi_dma_desc_t *dma_txdesc; /* DMA TX description */
|
||||
int dma_thld; /* DMA threshold value */
|
||||
#endif
|
||||
uint8_t nbits; /* Actual SPI send/receive bits once transmission */
|
||||
uint8_t id; /* ID number of SPI interface */
|
||||
|
|
@ -242,7 +249,7 @@ static uint32_t spi_find_clock_src_pre_div(uint32_t src_freq,
|
|||
uint32_t target_freq);
|
||||
#endif //SPI_LL_SUPPORT_CLK_SRC_PRE_DIV
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
static uint32_t spi_common_dma_setup(int chan, bool tx,
|
||||
spi_dma_desc_t *dmadesc, uint32_t num,
|
||||
uint8_t *pbuf, uint32_t len);
|
||||
|
|
@ -265,7 +272,7 @@ static uint32_t esp_spi_send(struct spi_dev_s *dev, uint32_t wd);
|
|||
static void esp_spi_exchange(struct spi_dev_s *dev,
|
||||
const void *txbuffer,
|
||||
void *rxbuffer, size_t nwords);
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
static int esp_spi_interrupt(int irq, void *context, void *arg);
|
||||
static int esp_spi_sem_waitdone(struct esp_spi_priv_s *priv);
|
||||
static void esp_spi_dma_exchange(struct esp_spi_priv_s *priv,
|
||||
|
|
@ -289,7 +296,7 @@ static void esp_spi_recvblock(struct spi_dev_s *dev,
|
|||
#ifdef CONFIG_SPI_TRIGGER
|
||||
static int esp_spi_trigger(struct spi_dev_s *dev);
|
||||
#endif
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
static void esp_spi_dma_init(struct spi_dev_s *dev);
|
||||
#endif
|
||||
static void esp_spi_init(struct spi_dev_s *dev);
|
||||
|
|
@ -301,6 +308,15 @@ static void esp_spi_deinit(struct spi_dev_s *dev);
|
|||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2
|
||||
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
|
||||
/* SPI DMA RX/TX description */
|
||||
|
||||
static spi_dma_desc_t dma_rxdesc[CONFIG_ESPRESSIF_SPI2_DMADESC_NUM];
|
||||
static spi_dma_desc_t dma_txdesc[CONFIG_ESPRESSIF_SPI2_DMADESC_NUM];
|
||||
|
||||
#endif
|
||||
|
||||
static spi_hal_context_t ctx =
|
||||
{
|
||||
0
|
||||
|
|
@ -390,9 +406,13 @@ static struct esp_spi_priv_s esp_spi2_priv =
|
|||
.dev_cfg = &dev_cfg,
|
||||
.ctx = &ctx,
|
||||
.timing_param = &timing_param,
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
.sem_isr = SEM_INITIALIZER(0),
|
||||
.cpuint = -ENOMEM,
|
||||
.dma_channel = CONFIG_ESPRESSIF_SPI2_DMADESC_NUM,
|
||||
.dma_rxdesc = dma_rxdesc,
|
||||
.dma_txdesc = dma_txdesc,
|
||||
.dma_thld = CONFIG_ESPRESSIF_SPI2_DMATHRESHOLD,
|
||||
#endif
|
||||
#ifdef CONFIG_PM
|
||||
.pm_lock = NULL,
|
||||
|
|
@ -400,12 +420,151 @@ static struct esp_spi_priv_s esp_spi2_priv =
|
|||
};
|
||||
#endif /* CONFIG_ESPRESSIF_SPI2 */
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef CONFIG_ESPRESSIF_SPI3
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI3_DMA
|
||||
|
||||
/* SPI DMA RX/TX description */
|
||||
|
||||
static spi_dma_desc_t dma_rxdesc[SPI_DMA_DESC_NUM];
|
||||
static spi_dma_desc_t dma_txdesc[SPI_DMA_DESC_NUM];
|
||||
static spi_dma_desc_t spi3_dma_rxdesc[CONFIG_ESPRESSIF_SPI3_DMADESC_NUM];
|
||||
static spi_dma_desc_t spi3_dma_txdesc[CONFIG_ESPRESSIF_SPI3_DMADESC_NUM];
|
||||
|
||||
#endif
|
||||
|
||||
static spi_hal_context_t spi3_ctx =
|
||||
{
|
||||
0
|
||||
};
|
||||
|
||||
static spi_hal_dev_config_t spi3_dev_cfg =
|
||||
{
|
||||
.mode = SPI_DEFAULT_MODE,
|
||||
.cs_setup = 0,
|
||||
.cs_hold = 0,
|
||||
.cs_pin_id = 0,
|
||||
.timing_conf =
|
||||
{
|
||||
0
|
||||
},
|
||||
{
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
static spi_hal_timing_param_t spi3_timing_param =
|
||||
{
|
||||
.no_compensate = 0,
|
||||
.half_duplex = 0,
|
||||
.input_delay_ns = 0,
|
||||
.use_gpio = 1,
|
||||
.duty_cycle = 128,
|
||||
.clk_src_hz = 0,
|
||||
.expected_freq = SPI_DEFAULT_FREQ,
|
||||
};
|
||||
|
||||
static const struct esp_spi_config_s esp_spi3_config =
|
||||
{
|
||||
.width = SPI_DEFAULT_WIDTH,
|
||||
.cs_pin = CONFIG_ESPRESSIF_SPI3_CSPIN,
|
||||
.mosi_pin = CONFIG_ESPRESSIF_SPI3_MOSIPIN,
|
||||
.miso_pin = CONFIG_ESPRESSIF_SPI3_MISOPIN,
|
||||
.clk_pin = CONFIG_ESPRESSIF_SPI3_CLKPIN,
|
||||
};
|
||||
|
||||
static const struct spi_ops_s esp_spi3_ops =
|
||||
{
|
||||
.lock = esp_spi_lock,
|
||||
#ifdef CONFIG_ESPRESSIF_SPI_UDCS
|
||||
.select = esp_spi3_select,
|
||||
#else
|
||||
.select = esp_spi_select,
|
||||
#endif
|
||||
.setfrequency = esp_spi_setfrequency,
|
||||
.setmode = esp_spi_setmode,
|
||||
.setbits = esp_spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = esp_spi_hwfeatures,
|
||||
#endif
|
||||
.status = esp_spi3_status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = esp_spi3_cmddata,
|
||||
#endif
|
||||
.send = esp_spi_send,
|
||||
#ifdef CONFIG_SPI_EXCHANGE
|
||||
.exchange = esp_spi_exchange,
|
||||
#else
|
||||
.sndblock = esp_spi_sndblock,
|
||||
.recvblock = esp_spi_recvblock,
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_TRIGGER
|
||||
.trigger = esp_spi_trigger,
|
||||
#endif
|
||||
.registercallback = NULL,
|
||||
};
|
||||
|
||||
static struct esp_spi_priv_s esp_spi3_priv =
|
||||
{
|
||||
.spi_dev =
|
||||
{
|
||||
.ops = &esp_spi3_ops
|
||||
},
|
||||
.config = &esp_spi3_config,
|
||||
.refs = 0,
|
||||
.lock = NXMUTEX_INITIALIZER,
|
||||
.id = SPI3_HOST,
|
||||
.nbits = 0,
|
||||
.dev_cfg = &spi3_dev_cfg,
|
||||
.ctx = &spi3_ctx,
|
||||
.timing_param = &spi3_timing_param,
|
||||
#ifdef CONFIG_ESPRESSIF_SPI3_DMA
|
||||
.sem_isr = SEM_INITIALIZER(0),
|
||||
.cpuint = -ENOMEM,
|
||||
.dma_channel = CONFIG_ESPRESSIF_SPI3_DMADESC_NUM,
|
||||
.dma_rxdesc = spi3_dma_rxdesc,
|
||||
.dma_txdesc = spi3_dma_txdesc,
|
||||
.dma_thld = CONFIG_ESPRESSIF_SPI3_DMATHRESHOLD,
|
||||
#endif
|
||||
#ifdef CONFIG_PM
|
||||
.pm_lock = NULL,
|
||||
#endif
|
||||
};
|
||||
#endif /* CONFIG_ESPRESSIF_SPI3 */
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_LPSPI0
|
||||
static const struct esp_spi_config_s esp_lpspi_config =
|
||||
{
|
||||
.width = SPI_DEFAULT_WIDTH,
|
||||
.cs_pin = CONFIG_ESPRESSIF_LPSPI0_CSPIN,
|
||||
.mosi_pin = CONFIG_ESPRESSIF_LPSPI0_MOSIPIN,
|
||||
.miso_pin = CONFIG_ESPRESSIF_LPSPI0_MISOPIN,
|
||||
.clk_pin = CONFIG_ESPRESSIF_LPSPI0_CLKPIN,
|
||||
};
|
||||
|
||||
static struct esp_spi_priv_s esp_lpspi_priv =
|
||||
{
|
||||
.spi_dev =
|
||||
{
|
||||
.ops = NULL
|
||||
},
|
||||
.config = &esp_lpspi_config,
|
||||
.refs = 0,
|
||||
.lock = NXMUTEX_INITIALIZER,
|
||||
.id = 0,
|
||||
.nbits = 0,
|
||||
.dev_cfg = NULL,
|
||||
.ctx = NULL,
|
||||
.timing_param = NULL,
|
||||
#ifdef CONFIG_PM
|
||||
.pm_lock = NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
static lp_spi_device_config_t esp_lpspi_device_config =
|
||||
{
|
||||
.cs_io_num = CONFIG_ESPRESSIF_LPSPI0_CSPIN,
|
||||
.clock_speed_hz = SPI_DEFAULT_FREQ / 4,
|
||||
.duty_cycle = 128,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -469,7 +628,7 @@ static uint32_t spi_find_clock_src_pre_div(uint32_t src_freq,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
static uint32_t spi_common_dma_setup(int chan, bool tx,
|
||||
spi_dma_desc_t *dmadesc, uint32_t num,
|
||||
uint8_t *pbuf, uint32_t len)
|
||||
|
|
@ -580,7 +739,7 @@ static int esp_spi_lock(struct spi_dev_s *dev, bool lock)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
static int esp_spi_sem_waitdone(struct esp_spi_priv_s *priv)
|
||||
{
|
||||
return nxsem_tickwait_uninterruptible(&priv->sem_isr, SEC2TICK(10));
|
||||
|
|
@ -815,7 +974,7 @@ static int esp_spi_hwfeatures(struct spi_dev_s *dev,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
static void esp_spi_dma_exchange(struct esp_spi_priv_s *priv,
|
||||
const void *txbuffer,
|
||||
void *rxbuffer,
|
||||
|
|
@ -826,7 +985,6 @@ static void esp_spi_dma_exchange(struct esp_spi_priv_s *priv,
|
|||
uint32_t rx_byte_len;
|
||||
int tx_dma_channel_id;
|
||||
int rx_dma_channel_id;
|
||||
spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(SPI2_HOST);
|
||||
uint32_t n;
|
||||
uint16_t alignment;
|
||||
uint32_t bytes = total;
|
||||
|
|
@ -953,8 +1111,8 @@ static void esp_spi_dma_exchange(struct esp_spi_priv_s *priv,
|
|||
|
||||
while (bytes != 0)
|
||||
{
|
||||
n = spi_common_dma_setup(tx_dma_channel_id, true, dma_txdesc,
|
||||
SPI_DMA_DESC_NUM, tp, bytes);
|
||||
n = spi_common_dma_setup(tx_dma_channel_id, true, priv->dma_txdesc,
|
||||
priv->dma_channel, tp, bytes);
|
||||
|
||||
trans.tx_bitlen = n * 8;
|
||||
trans.rx_bitlen = n * 8;
|
||||
|
|
@ -971,7 +1129,7 @@ static void esp_spi_dma_exchange(struct esp_spi_priv_s *priv,
|
|||
|
||||
spi_hal_hw_prepare_tx(priv->ctx->hw);
|
||||
|
||||
spi_dma_start(priv->dma_channel_tx, dma_txdesc);
|
||||
spi_dma_start(priv->dma_channel_tx, priv->dma_txdesc);
|
||||
|
||||
spi_ll_enable_mosi(priv->ctx->hw, true);
|
||||
|
||||
|
|
@ -981,14 +1139,14 @@ static void esp_spi_dma_exchange(struct esp_spi_priv_s *priv,
|
|||
{
|
||||
/* Enable SPI DMA RX */
|
||||
|
||||
spi_common_dma_setup(rx_dma_channel_id, false, dma_rxdesc,
|
||||
SPI_DMA_DESC_NUM, rp, bytes);
|
||||
spi_common_dma_setup(rx_dma_channel_id, false, priv->dma_rxdesc,
|
||||
priv->dma_channel, rp, bytes);
|
||||
|
||||
spi_dma_reset(priv->dma_channel_rx);
|
||||
|
||||
spi_hal_hw_prepare_rx(priv->ctx->hw);
|
||||
|
||||
spi_dma_start(priv->dma_channel_rx, dma_rxdesc);
|
||||
spi_dma_start(priv->dma_channel_rx, priv->dma_rxdesc);
|
||||
|
||||
spi_ll_enable_miso(priv->ctx->hw, true);
|
||||
|
||||
|
|
@ -1236,8 +1394,8 @@ static void esp_spi_exchange(struct spi_dev_s *dev,
|
|||
#ifdef CONFIG_PM
|
||||
esp_pm_lock_acquire(priv->pm_lock);
|
||||
#endif
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
size_t thld = CONFIG_ESPRESSIF_SPI2_DMATHRESHOLD;
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
size_t thld = priv->dma_thld;
|
||||
|
||||
if (nwords > thld)
|
||||
{
|
||||
|
|
@ -1352,7 +1510,7 @@ static int esp_spi_trigger(struct spi_dev_s *dev)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
void esp_spi_dma_init(struct spi_dev_s *dev)
|
||||
{
|
||||
struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev;
|
||||
|
|
@ -1366,15 +1524,31 @@ void esp_spi_dma_init(struct spi_dev_s *dev)
|
|||
0
|
||||
};
|
||||
|
||||
gdma_trigger_t periph_trigger;
|
||||
|
||||
/* Request a GDMA channel for SPI peripheral */
|
||||
|
||||
if (priv->id == SPI2_HOST)
|
||||
{
|
||||
periph_trigger = GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2);
|
||||
}
|
||||
#if defined(SOC_GDMA_TRIG_PERIPH_SPI3)
|
||||
else if (priv->id == SPI3_HOST)
|
||||
{
|
||||
periph_trigger = GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
DEBUGASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
SPI_GDMA_NEW_CHANNEL(&tx_handle, &priv->dma_channel_tx, NULL);
|
||||
gdma_connect(priv->dma_channel_tx,
|
||||
GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2));
|
||||
gdma_connect(priv->dma_channel_tx, periph_trigger);
|
||||
|
||||
SPI_GDMA_NEW_CHANNEL(&rx_handle, NULL, &priv->dma_channel_rx);
|
||||
gdma_connect(priv->dma_channel_rx,
|
||||
GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2));
|
||||
gdma_connect(priv->dma_channel_rx, periph_trigger);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1401,76 +1575,93 @@ static void esp_spi_init(struct spi_dev_s *dev)
|
|||
# if !SPI_HAVE_SWCS
|
||||
int cs_id = 0;
|
||||
# endif
|
||||
#endif
|
||||
#ifdef CONFIG_ESPRESSIF_LPSPI0
|
||||
lp_spi_bus_config_t bus_config;
|
||||
#endif
|
||||
|
||||
esp_gpiowrite(config->cs_pin, true);
|
||||
esp_gpiowrite(config->mosi_pin, true);
|
||||
esp_gpiowrite(config->miso_pin, true);
|
||||
esp_gpiowrite(config->clk_pin, true);
|
||||
if (priv->id != ESPRESSIF_LPSPI0)
|
||||
{
|
||||
esp_gpiowrite(config->cs_pin, true);
|
||||
esp_gpiowrite(config->mosi_pin, true);
|
||||
esp_gpiowrite(config->miso_pin, true);
|
||||
esp_gpiowrite(config->clk_pin, true);
|
||||
|
||||
#if SPI_HAVE_SWCS
|
||||
esp_configgpio(config->cs_pin, OUTPUT_FUNCTION_2);
|
||||
esp_gpio_matrix_out(config->cs_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
esp_configgpio(config->cs_pin, OUTPUT_FUNCTION_2);
|
||||
esp_gpio_matrix_out(config->cs_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
#endif
|
||||
|
||||
#if SPI_VIA_IOMUX
|
||||
#if !SPI_HAVE_SWCS
|
||||
esp_configgpio(config->cs_pin, OUTPUT_FUNCTION_3);
|
||||
esp_gpio_matrix_out(config->cs_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
esp_configgpio(config->cs_pin, OUTPUT_FUNCTION_3);
|
||||
esp_gpio_matrix_out(config->cs_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
#endif
|
||||
esp_configgpio(config->mosi_pin, OUTPUT_FUNCTION_3);
|
||||
esp_gpio_matrix_out(config->mosi_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
esp_configgpio(config->mosi_pin, OUTPUT_FUNCTION_3);
|
||||
esp_gpio_matrix_out(config->mosi_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
|
||||
esp_configgpio(config->miso_pin, INPUT_FUNCTION_3 | PULLUP);
|
||||
esp_gpio_matrix_out(config->miso_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
esp_configgpio(config->miso_pin, INPUT_FUNCTION_3 | PULLUP);
|
||||
esp_gpio_matrix_out(config->miso_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
|
||||
esp_configgpio(config->clk_pin, OUTPUT_FUNCTION_3);
|
||||
esp_gpio_matrix_out(config->clk_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
esp_configgpio(config->clk_pin, OUTPUT_FUNCTION_3);
|
||||
esp_gpio_matrix_out(config->clk_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
#else
|
||||
#if !SPI_HAVE_SWCS
|
||||
esp_configgpio(config->cs_pin, OUTPUT_FUNCTION_2);
|
||||
esp_gpio_matrix_out(config->cs_pin,
|
||||
spi_periph_signal[priv->id].spics_out[cs_id], 0, 0);
|
||||
#if !SPI_HAVE_SWCS
|
||||
esp_configgpio(config->cs_pin, OUTPUT_FUNCTION_2);
|
||||
esp_gpio_matrix_out(config->cs_pin,
|
||||
spi_periph_signal[priv->id].spics_out[cs_id],
|
||||
0, 0);
|
||||
#endif
|
||||
esp_configgpio(config->mosi_pin, MOSI_PIN_ATTR);
|
||||
esp_gpio_matrix_out(config->mosi_pin,
|
||||
spi_periph_signal[priv->id].spid_out, 0, 0);
|
||||
esp_configgpio(config->mosi_pin, MOSI_PIN_ATTR);
|
||||
esp_gpio_matrix_out(config->mosi_pin,
|
||||
spi_periph_signal[priv->id].spid_out, 0, 0);
|
||||
|
||||
esp_configgpio(config->miso_pin, MISO_PIN_ATTR);
|
||||
esp_gpio_matrix_in(config->miso_pin,
|
||||
spi_periph_signal[priv->id].spiq_in, 0);
|
||||
esp_configgpio(config->miso_pin, MISO_PIN_ATTR);
|
||||
esp_gpio_matrix_in(config->miso_pin,
|
||||
spi_periph_signal[priv->id].spiq_in, 0);
|
||||
|
||||
esp_configgpio(config->clk_pin, OUTPUT_FUNCTION_2);
|
||||
esp_gpio_matrix_out(config->clk_pin,
|
||||
spi_periph_signal[priv->id].spiclk_out, 0, 0);
|
||||
esp_configgpio(config->clk_pin, OUTPUT_FUNCTION_2);
|
||||
esp_gpio_matrix_out(config->clk_pin,
|
||||
spi_periph_signal[priv->id].spiclk_out, 0, 0);
|
||||
#endif
|
||||
|
||||
PERIPH_RCC_ATOMIC()
|
||||
{
|
||||
spi_ll_enable_bus_clock(priv->id, true);
|
||||
spi_ll_reset_register(priv->id);
|
||||
}
|
||||
PERIPH_RCC_ATOMIC()
|
||||
{
|
||||
spi_ll_enable_bus_clock(priv->id, true);
|
||||
spi_ll_reset_register(priv->id);
|
||||
}
|
||||
|
||||
SPI_MASTER_PERI_CLOCK_ATOMIC()
|
||||
{
|
||||
spi_ll_enable_clock(priv->id, true);
|
||||
}
|
||||
SPI_MASTER_PERI_CLOCK_ATOMIC()
|
||||
{
|
||||
spi_ll_enable_clock(priv->id, true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
esp_spi_dma_init(dev);
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
esp_spi_dma_init(dev);
|
||||
|
||||
priv->ctx->hw = SPI_LL_GET_HW(priv->id);
|
||||
priv->ctx->hw = SPI_LL_GET_HW(priv->id);
|
||||
|
||||
spi_ll_master_init(priv->ctx->hw);
|
||||
spi_ll_enable_int(priv->ctx->hw);
|
||||
spi_ll_set_mosi_delay(priv->ctx->hw, 0, 0);
|
||||
spi_ll_master_init(priv->ctx->hw);
|
||||
spi_ll_enable_int(priv->ctx->hw);
|
||||
spi_ll_set_mosi_delay(priv->ctx->hw, 0, 0);
|
||||
#else
|
||||
spi_hal_init(priv->ctx, priv->id);
|
||||
spi_hal_init(priv->ctx, priv->id);
|
||||
#endif
|
||||
|
||||
esp_spi_setbits(dev, config->width);
|
||||
esp_spi_setmode(dev, priv->dev_cfg->mode);
|
||||
esp_spi_setfrequency(dev, priv->timing_param->expected_freq);
|
||||
esp_spi_setbits(dev, config->width);
|
||||
esp_spi_setmode(dev, priv->dev_cfg->mode);
|
||||
esp_spi_setfrequency(dev, priv->timing_param->expected_freq);
|
||||
}
|
||||
#ifdef CONFIG_ESPRESSIF_LPSPI0
|
||||
else
|
||||
{
|
||||
bus_config.miso_io_num = config->miso_pin;
|
||||
bus_config.mosi_io_num = config->mosi_pin;
|
||||
bus_config.sclk_io_num = config->clk_pin;
|
||||
lp_core_lp_spi_bus_initialize(priv->id, &bus_config);
|
||||
lp_core_lp_spi_bus_add_device(priv->id, &esp_lpspi_device_config);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -1496,7 +1687,8 @@ static void esp_spi_deinit(struct spi_dev_s *dev)
|
|||
spi_hal_deinit(priv->ctx);
|
||||
|
||||
#if SOC_GDMA_SUPPORTED
|
||||
# ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
# if defined(CONFIG_ESPRESSIF_SPI2_DMA) || \
|
||||
defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
if (priv->dma_channel_rx)
|
||||
{
|
||||
gdma_disconnect(priv->dma_channel_rx);
|
||||
|
|
@ -1535,7 +1727,7 @@ static void esp_spi_deinit(struct spi_dev_s *dev)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
static int esp_spi_interrupt(int irq, void *context, void *arg)
|
||||
{
|
||||
struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)arg;
|
||||
|
|
@ -1575,6 +1767,16 @@ struct spi_dev_s *esp_spibus_initialize(int port)
|
|||
case ESPRESSIF_SPI2:
|
||||
priv = &esp_spi2_priv;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_ESPRESSIF_SPI3
|
||||
case ESPRESSIF_SPI3:
|
||||
priv = &esp_spi3_priv;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_ESPRESSIF_LPSPI0
|
||||
case ESPRESSIF_LPSPI0:
|
||||
priv = &esp_lpspi_priv;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return NULL;
|
||||
|
|
@ -1606,36 +1808,39 @@ struct spi_dev_s *esp_spibus_initialize(int port)
|
|||
|
||||
/* Initialize the blank array */
|
||||
|
||||
for (int i = 0; i < SPI_BLANK_ARRAY_SIZE; i++)
|
||||
if (priv->id != ESPRESSIF_LPSPI0)
|
||||
{
|
||||
blank_arr[i] = UINT32_MAX;
|
||||
}
|
||||
for (int i = 0; i < SPI_BLANK_ARRAY_SIZE; i++)
|
||||
{
|
||||
blank_arr[i] = UINT32_MAX;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
if (priv->cpuint != -ENOMEM)
|
||||
{
|
||||
/* Disable the provided CPU Interrupt to configure it. */
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
if (priv->cpuint != -ENOMEM)
|
||||
{
|
||||
/* Disable the provided CPU Interrupt to configure it. */
|
||||
|
||||
up_disable_irq(ESP_SOURCE2IRQ(spi_periph_signal[priv->id].irq));
|
||||
}
|
||||
up_disable_irq(ESP_SOURCE2IRQ(spi_periph_signal[priv->id].irq));
|
||||
}
|
||||
|
||||
priv->cpuint = esp_setup_irq(spi_periph_signal[priv->id].irq,
|
||||
ESP_IRQ_PRIORITY_DEFAULT,
|
||||
ESP_IRQ_TRIGGER_LEVEL,
|
||||
esp_spi_interrupt,
|
||||
priv);
|
||||
if (priv->cpuint < 0)
|
||||
{
|
||||
/* Failed to allocate a CPU interrupt of this type. */
|
||||
priv->cpuint = esp_setup_irq(spi_periph_signal[priv->id].irq,
|
||||
ESP_IRQ_PRIORITY_DEFAULT,
|
||||
ESP_IRQ_TRIGGER_LEVEL,
|
||||
esp_spi_interrupt,
|
||||
priv);
|
||||
if (priv->cpuint < 0)
|
||||
{
|
||||
/* Failed to allocate a CPU interrupt of this type. */
|
||||
|
||||
nxmutex_unlock(&priv->lock);
|
||||
return NULL;
|
||||
}
|
||||
nxmutex_unlock(&priv->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Enable the CPU interrupt that is linked to the SPI device. */
|
||||
/* Enable the CPU interrupt that is linked to the SPI device. */
|
||||
|
||||
up_enable_irq(ESP_SOURCE2IRQ(spi_periph_signal[priv->id].irq));
|
||||
up_enable_irq(ESP_SOURCE2IRQ(spi_periph_signal[priv->id].irq));
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_spi_init(spi_dev);
|
||||
priv->refs++;
|
||||
|
|
@ -1676,7 +1881,7 @@ int esp_spibus_uninitialize(struct spi_dev_s *dev)
|
|||
return OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
up_disable_irq(ESP_SOURCE2IRQ(spi_periph_signal[priv->id].irq));
|
||||
esp_teardown_irq(spi_periph_signal[priv->id].irq, priv->cpuint);
|
||||
priv->cpuint = -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ extern "C"
|
|||
#include <nuttx/spi/spi.h>
|
||||
|
||||
#define ESPRESSIF_SPI2 2
|
||||
#define ESPRESSIF_SPI3 3
|
||||
#define ESPRESSIF_LPSPI0 0
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
|
|
@ -71,25 +73,25 @@ extern "C"
|
|||
struct spi_dev_s *esp_spibus_initialize(int port);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp_spi[2]_select and esp_spi[2]_status
|
||||
* Name: esp_spi[2|3]_select and esp_spi[2|3]_status
|
||||
*
|
||||
* Description:
|
||||
* The external functions, esp_spi[2]_select,
|
||||
* esp_spi[2]_status, and esp_spi[2]_cmddata must be provided
|
||||
* The external functions, esp_spi[2|3]_select,
|
||||
* esp_spi[2|3]_status, and esp_spi[2|3]_cmddata must be provided
|
||||
* by board-specific logic.
|
||||
* These are implementations of the select, status, and cmddata methods of
|
||||
* the SPI interface defined by struct spi_ops_s (include/nuttx/spi/spi.h).
|
||||
* All other methods (including esp_spibus_initialize()) are provided
|
||||
* by common ESP32-S3 logic. To use this common SPI logic on your board:
|
||||
* by common ESP logic. To use this common SPI logic on your board:
|
||||
*
|
||||
* 1. Provide logic in esp_board_initialize() to configure SPI chip
|
||||
* select pins.
|
||||
* 2. Provide esp_spi[2]_select() and esp_spi[2]_status()
|
||||
* 2. Provide esp_spi[2|3]_select() and esp_spi[2|3]_status()
|
||||
* functions in your board-specific logic. These functions will perform
|
||||
* chip selection and status operations using GPIOs in the way your
|
||||
* board is configured.
|
||||
* 3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file,
|
||||
* then provide esp_spi[2]_cmddata() functions in your
|
||||
* then provide esp_spi[2|3]_cmddata() functions in your
|
||||
* board-specific logic. These functions will perform cmd/data selection
|
||||
* operations using GPIOs in the way your board is configured.
|
||||
* 4. Add a call to esp_spibus_initialize() in your low level
|
||||
|
|
@ -110,6 +112,15 @@ int esp_spi2_cmddata(struct spi_dev_s *dev,
|
|||
bool cmd);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI3
|
||||
void esp_spi3_select(struct spi_dev_s *dev, uint32_t devid,
|
||||
bool selected);
|
||||
uint8_t esp_spi3_status(struct spi_dev_s *dev, uint32_t devid);
|
||||
int esp_spi3_cmddata(struct spi_dev_s *dev,
|
||||
uint32_t devid,
|
||||
bool cmd);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp_spibus_uninitialize
|
||||
*
|
||||
|
|
|
|||
|
|
@ -73,9 +73,17 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define SPI_SLAVE_BUFSIZE (CONFIG_ESPRESSIF_SPI2_SLAVE_BUFSIZE)
|
||||
#if defined(CONFIG_ESPRESSIF_SPI2_DMA) || defined(CONFIG_ESPRESSIF_SPI3_DMA)
|
||||
# define USE_DMA 1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_SLAVE
|
||||
# define SPI_SLAVE_BUFSIZE CONFIG_ESPRESSIF_SPI2_SLAVE_BUFSIZE
|
||||
#else
|
||||
# define SPI_SLAVE_BUFSIZE CONFIG_ESPRESSIF_SPI3_SLAVE_BUFSIZE
|
||||
#endif
|
||||
|
||||
#ifdef USE_DMA
|
||||
/* SPI DMA RX/TX number of descriptors */
|
||||
|
||||
#if (SPI_SLAVE_BUFSIZE % DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) > 0
|
||||
|
|
@ -84,7 +92,7 @@
|
|||
# define SPI_DMA_DESC_NUM (SPI_SLAVE_BUFSIZE / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED)
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ESPRESSIF_SPI2_DMA */
|
||||
#endif /* USE_DMA */
|
||||
|
||||
/* Verify whether SPI has been assigned IOMUX pins.
|
||||
* Otherwise, SPI signals will be routed via GPIO Matrix.
|
||||
|
|
@ -193,9 +201,11 @@ struct spislave_priv_s
|
|||
int refs; /* Reference count */
|
||||
int cpuint; /* SPI interrupt ID */
|
||||
enum spi_slave_mode_e mode; /* Current SPI Slave hardware mode */
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
gdma_channel_handle_t dma_channel_tx; /* I2S DMA TX channel being used */
|
||||
gdma_channel_handle_t dma_channel_rx; /* I2S DMA RX channel being used */
|
||||
#ifdef USE_DMA
|
||||
gdma_channel_handle_t dma_channel_tx; /* SPI DMA TX channel being used */
|
||||
gdma_channel_handle_t dma_channel_rx; /* SPI DMA RX channel being used */
|
||||
spi_dma_desc_t *dma_rxdesc; /* DMA RX description */
|
||||
spi_dma_desc_t *dma_txdesc; /* DMA TX description */
|
||||
#endif
|
||||
uint8_t nbits; /* Current configured bit width */
|
||||
uint32_t tx_length; /* Location of next TX value */
|
||||
|
|
@ -208,8 +218,9 @@ struct spislave_priv_s
|
|||
/* SPI Slave RX queue buffer */
|
||||
|
||||
uint8_t rx_buffer[SPI_SLAVE_BUFSIZE];
|
||||
uint32_t buf_size; /* SPI DMA Buffer size in bytes */
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
/* SPI Slave DMA RX buffer - separate from user-accessible buffer */
|
||||
|
||||
uint8_t *dma_rx_buffer;
|
||||
|
|
@ -235,14 +246,14 @@ struct spislave_priv_s
|
|||
|
||||
/* SPI Slave controller buffer operations */
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
static uint32_t spi_slave_common_dma_setup(int chan, bool tx,
|
||||
spi_dma_desc_t *dmadesc,
|
||||
uint32_t num, uint8_t *pbuf,
|
||||
uint32_t len);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifndef USE_DMA
|
||||
static inline void spislave_cpu_tx_fifo_reset(spi_dev_t *hw);
|
||||
#else
|
||||
static inline void spislave_dma_tx_fifo_reset(spi_dev_t *hw);
|
||||
|
|
@ -259,7 +270,7 @@ static int spislave_periph_interrupt(int irq, void *context, void *arg);
|
|||
static void spislave_evict_sent_data(struct spislave_priv_s *priv,
|
||||
uint32_t sent_bytes);
|
||||
static inline void spislave_hal_store_result(spi_slave_hal_context_t *hal);
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
static void spislave_setup_rx_dma(struct spislave_priv_s *priv);
|
||||
static void spislave_setup_tx_dma(struct spislave_priv_s *priv);
|
||||
static void spislave_prepare_next_tx(struct spislave_priv_s *priv);
|
||||
|
|
@ -286,6 +297,16 @@ static size_t spislave_qpoll(struct spi_slave_ctrlr_s *ctrlr);
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
|
||||
/* SPI DMA RX/TX description */
|
||||
|
||||
static spi_dma_desc_t dma_rxdesc[SPI_DMA_DESC_NUM];
|
||||
static spi_dma_desc_t dma_txdesc[SPI_DMA_DESC_NUM];
|
||||
|
||||
#endif
|
||||
|
||||
static const struct spislave_config_s esp_spi2slave_config =
|
||||
{
|
||||
.width = SPI_SLAVE_DEFAULT_WIDTH,
|
||||
|
|
@ -326,6 +347,8 @@ static struct spislave_priv_s esp_spi2slave_priv =
|
|||
0
|
||||
},
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
.dma_rxdesc = dma_rxdesc,
|
||||
.dma_txdesc = dma_txdesc,
|
||||
.dma_rx_buffer = NULL,
|
||||
#endif
|
||||
.is_processing = false,
|
||||
|
|
@ -341,15 +364,74 @@ static struct spislave_priv_s esp_spi2slave_priv =
|
|||
};
|
||||
#endif /* CONFIG_ESPRESSIF_SPI2 */
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef CONFIG_ESPRESSIF_SPI3
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI3_DMA
|
||||
|
||||
/* SPI DMA RX/TX description */
|
||||
|
||||
static spi_dma_desc_t dma_rxdesc[SPI_DMA_DESC_NUM];
|
||||
static spi_dma_desc_t dma_txdesc[SPI_DMA_DESC_NUM];
|
||||
static spi_dma_desc_t spi3_dma_rxdesc[SPI_DMA_DESC_NUM];
|
||||
static spi_dma_desc_t spi3_dma_txdesc[SPI_DMA_DESC_NUM];
|
||||
|
||||
#endif
|
||||
|
||||
static const struct spislave_config_s esp_spi3slave_config =
|
||||
{
|
||||
.width = SPI_SLAVE_DEFAULT_WIDTH,
|
||||
.mode = SPI_SLAVE_DEFAULT_MODE,
|
||||
.cs_pin = CONFIG_ESPRESSIF_SPI3_CSPIN,
|
||||
.mosi_pin = CONFIG_ESPRESSIF_SPI3_MOSIPIN,
|
||||
.miso_pin = CONFIG_ESPRESSIF_SPI3_MISOPIN,
|
||||
.clk_pin = CONFIG_ESPRESSIF_SPI3_CLKPIN,
|
||||
};
|
||||
|
||||
static const struct spi_slave_ctrlrops_s esp_spi3slave_ops =
|
||||
{
|
||||
.bind = spislave_bind,
|
||||
.unbind = spislave_unbind,
|
||||
.enqueue = spislave_enqueue,
|
||||
.qfull = spislave_qfull,
|
||||
.qflush = spislave_qflush,
|
||||
.qpoll = spislave_qpoll
|
||||
};
|
||||
|
||||
static struct spislave_priv_s esp_spi3slave_priv =
|
||||
{
|
||||
.ctrlr =
|
||||
{
|
||||
.ops = &esp_spi3slave_ops
|
||||
},
|
||||
.dev = NULL,
|
||||
.config = &esp_spi3slave_config,
|
||||
.refs = 0,
|
||||
.cpuint = -ENOMEM,
|
||||
.mode = SPISLAVE_MODE0,
|
||||
.nbits = 0,
|
||||
.tx_length = 0,
|
||||
.tx_buffer = NULL,
|
||||
.rx_length = 0,
|
||||
.rx_buffer =
|
||||
{
|
||||
0
|
||||
},
|
||||
#ifdef CONFIG_ESPRESSIF_SPI3_DMA
|
||||
.dma_rxdesc = spi3_dma_rxdesc,
|
||||
.dma_txdesc = spi3_dma_txdesc,
|
||||
.dma_rx_buffer = NULL,
|
||||
#endif
|
||||
.is_processing = false,
|
||||
.is_tx_enabled = false,
|
||||
.ctx =
|
||||
{
|
||||
0
|
||||
},
|
||||
.cfg =
|
||||
{
|
||||
.host_id = SPI3_HOST,
|
||||
}
|
||||
};
|
||||
#endif /* CONFIG_ESPRESSIF_SPI3 */
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -373,7 +455,7 @@ static spi_dma_desc_t dma_txdesc[SPI_DMA_DESC_NUM];
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
static uint32_t spi_slave_common_dma_setup(int chan, bool tx,
|
||||
spi_dma_desc_t *dmadesc,
|
||||
uint32_t num, uint8_t *pbuf,
|
||||
|
|
@ -489,7 +571,7 @@ static inline void spislave_hal_store_result(spi_slave_hal_context_t *hal)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifndef USE_DMA
|
||||
static inline void spislave_cpu_tx_fifo_reset(spi_dev_t *hw)
|
||||
{
|
||||
spi_ll_cpu_tx_fifo_reset(hw);
|
||||
|
|
@ -511,7 +593,7 @@ static inline void spislave_cpu_tx_fifo_reset(spi_dev_t *hw)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
static inline void spislave_dma_tx_fifo_reset(spi_dev_t *hw)
|
||||
{
|
||||
spi_ll_dma_tx_fifo_reset(hw);
|
||||
|
|
@ -533,7 +615,7 @@ static inline void spislave_dma_tx_fifo_reset(spi_dev_t *hw)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
static inline void spislave_dma_rx_fifo_reset(spi_dev_t *hw)
|
||||
{
|
||||
spi_ll_dma_rx_fifo_reset(hw);
|
||||
|
|
@ -622,7 +704,7 @@ static void spislave_evict_sent_data(struct spislave_priv_s *priv,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
static void spislave_setup_rx_dma(struct spislave_priv_s *priv)
|
||||
{
|
||||
uint32_t length = SPI_SLAVE_BUFSIZE;
|
||||
|
|
@ -630,7 +712,7 @@ static void spislave_setup_rx_dma(struct spislave_priv_s *priv)
|
|||
|
||||
gdma_get_group_channel_id(priv->dma_channel_rx, NULL, &rx_dma_channel_id);
|
||||
|
||||
spi_slave_common_dma_setup(rx_dma_channel_id, false, dma_rxdesc,
|
||||
spi_slave_common_dma_setup(rx_dma_channel_id, false, priv->dma_rxdesc,
|
||||
SPI_DMA_DESC_NUM,
|
||||
priv->dma_rx_buffer, length);
|
||||
|
||||
|
|
@ -648,7 +730,7 @@ static void spislave_setup_rx_dma(struct spislave_priv_s *priv)
|
|||
|
||||
spi_ll_dma_rx_enable(priv->ctx.hw, true);
|
||||
|
||||
spi_dma_start(priv->dma_channel_rx, dma_rxdesc);
|
||||
spi_dma_start(priv->dma_channel_rx, priv->dma_rxdesc);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -667,7 +749,7 @@ static void spislave_setup_rx_dma(struct spislave_priv_s *priv)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
static void spislave_setup_tx_dma(struct spislave_priv_s *priv)
|
||||
{
|
||||
int tx_dma_channel_id;
|
||||
|
|
@ -684,7 +766,7 @@ static void spislave_setup_tx_dma(struct spislave_priv_s *priv)
|
|||
gdma_get_group_channel_id(priv->dma_channel_tx, NULL,
|
||||
&tx_dma_channel_id);
|
||||
|
||||
spi_slave_common_dma_setup(tx_dma_channel_id, true, dma_txdesc,
|
||||
spi_slave_common_dma_setup(tx_dma_channel_id, true, priv->dma_txdesc,
|
||||
SPI_DMA_DESC_NUM,
|
||||
priv->tx_buffer, SPI_SLAVE_BUFSIZE);
|
||||
|
||||
|
|
@ -702,7 +784,7 @@ static void spislave_setup_tx_dma(struct spislave_priv_s *priv)
|
|||
|
||||
spi_ll_dma_tx_enable(priv->ctx.hw, true);
|
||||
|
||||
spi_dma_start(priv->dma_channel_tx, dma_txdesc);
|
||||
spi_dma_start(priv->dma_channel_tx, priv->dma_txdesc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -724,7 +806,7 @@ static void spislave_setup_tx_dma(struct spislave_priv_s *priv)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifndef USE_DMA
|
||||
static inline void spi_slave_prepare_data(struct spislave_priv_s *priv,
|
||||
ssize_t nbits_to_send)
|
||||
{
|
||||
|
|
@ -755,7 +837,7 @@ static void spislave_prepare_next_tx(struct spislave_priv_s *priv)
|
|||
|
||||
if (priv->tx_length != 0 && priv->tx_buffer != NULL)
|
||||
{
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
spislave_setup_tx_dma(priv);
|
||||
#else
|
||||
nbits_to_send = priv->nbits * priv->tx_length;
|
||||
|
|
@ -767,7 +849,7 @@ static void spislave_prepare_next_tx(struct spislave_priv_s *priv)
|
|||
{
|
||||
spiwarn("TX buffer empty! Disabling TX for next transaction\n");
|
||||
|
||||
#ifndef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifndef USE_DMA
|
||||
if (priv->tx_buffer != NULL)
|
||||
{
|
||||
memset(priv->tx_buffer, 0, SPI_SLAVE_BUFSIZE);
|
||||
|
|
@ -803,7 +885,7 @@ static int spislave_periph_interrupt(int irq, void *context, void *arg)
|
|||
{
|
||||
struct spislave_priv_s *priv = (struct spislave_priv_s *)arg;
|
||||
esp_err_t ret;
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
uint32_t received_bytes;
|
||||
#endif
|
||||
|
||||
|
|
@ -817,7 +899,7 @@ static int spislave_periph_interrupt(int irq, void *context, void *arg)
|
|||
|
||||
spislave_hal_store_result(&priv->ctx);
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
|
||||
/* Copy received data from DMA buffer to user-accessible buffer */
|
||||
|
||||
|
|
@ -843,7 +925,7 @@ static int spislave_periph_interrupt(int irq, void *context, void *arg)
|
|||
|
||||
SPIS_DEV_NOTIFY(priv->dev, SPISLAVE_RX_COMPLETE);
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
if (priv->rx_length < SPI_SLAVE_BUFSIZE)
|
||||
{
|
||||
spislave_setup_rx_dma(priv);
|
||||
|
|
@ -894,7 +976,7 @@ static int spislave_periph_interrupt(int irq, void *context, void *arg)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
static void spislave_dma_init(struct spislave_priv_s *priv)
|
||||
{
|
||||
/* Initialize GDMA controller */
|
||||
|
|
@ -909,15 +991,31 @@ static void spislave_dma_init(struct spislave_priv_s *priv)
|
|||
0
|
||||
};
|
||||
|
||||
gdma_trigger_t periph_trigger;
|
||||
|
||||
/* Request a GDMA channel for SPI peripheral */
|
||||
|
||||
if (priv->cfg.host_id == SPI2_HOST)
|
||||
{
|
||||
periph_trigger = GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2);
|
||||
}
|
||||
#if defined(SOC_GDMA_TRIG_PERIPH_SPI3)
|
||||
else if (priv->id == SPI3_HOST)
|
||||
{
|
||||
periph_trigger = GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
DEBUGASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
SPI_GDMA_NEW_CHANNEL(&tx_handle, &priv->dma_channel_tx, NULL);
|
||||
gdma_connect(priv->dma_channel_tx,
|
||||
GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2));
|
||||
gdma_connect(priv->dma_channel_tx, periph_trigger);
|
||||
|
||||
SPI_GDMA_NEW_CHANNEL(&rx_handle, NULL, &priv->dma_channel_rx);
|
||||
gdma_connect(priv->dma_channel_rx,
|
||||
GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2));
|
||||
gdma_connect(priv->dma_channel_rx, periph_trigger);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -974,7 +1072,7 @@ static void spislave_initialize(struct spi_slave_ctrlr_s *ctrlr)
|
|||
spi_ll_reset_register(priv->cfg.host_id);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
spislave_dma_init(priv);
|
||||
#endif
|
||||
|
||||
|
|
@ -983,12 +1081,12 @@ static void spislave_initialize(struct spi_slave_ctrlr_s *ctrlr)
|
|||
priv->ctx.rx_lsbfirst = 0;
|
||||
priv->ctx.tx_lsbfirst = 0;
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
priv->ctx.dmadesc_n = SPI_DMA_DESC_NUM;
|
||||
priv->ctx.use_dma = 1;
|
||||
|
||||
priv->ctx.dmadesc_rx = dma_rxdesc;
|
||||
priv->ctx.dmadesc_tx = dma_txdesc;
|
||||
priv->ctx.dmadesc_rx = priv->dma_rxdesc;
|
||||
priv->ctx.dmadesc_tx = priv->dma_txdesc;
|
||||
#else
|
||||
priv->ctx.dmadesc_n = 0;
|
||||
priv->ctx.use_dma = 0;
|
||||
|
|
@ -1039,7 +1137,7 @@ static void spislave_bind(struct spi_slave_ctrlr_s *ctrlr,
|
|||
const void *data = NULL;
|
||||
irqstate_t flags;
|
||||
size_t num_words;
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
size_t alignment;
|
||||
size_t buffer_size;
|
||||
#endif
|
||||
|
|
@ -1069,7 +1167,7 @@ static void spislave_bind(struct spi_slave_ctrlr_s *ctrlr,
|
|||
priv->ctx.mode = mode;
|
||||
priv->ctx.rcv_bitlen = 0;
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
/* Allocate DMA RX buffer with proper alignment */
|
||||
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
|
|
@ -1163,7 +1261,7 @@ static void spislave_unbind(struct spi_slave_ctrlr_s *ctrlr)
|
|||
|
||||
esp_gpioirqdisable(ESP_PIN2IRQ(priv->config->cs_pin));
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_SPI2_DMA
|
||||
#ifdef USE_DMA
|
||||
/* Free DMA RX buffer */
|
||||
|
||||
if (priv->dma_rx_buffer != NULL)
|
||||
|
|
@ -1405,6 +1503,12 @@ struct spi_slave_ctrlr_s *esp_spislave_ctrlr_initialize(int port)
|
|||
priv = &esp_spi2slave_priv;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_ESPRESSIF_SPI3
|
||||
case ESPRESSIF_SPI3:
|
||||
priv = &esp_spi3slave_priv;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -417,6 +417,7 @@ list(
|
|||
${ESP_HAL_3RDPARTY_REPO}/components/spi_flash/spi_flash_os_func_app.c
|
||||
${ESP_HAL_3RDPARTY_REPO}/components/spi_flash/spi_flash_os_func_noos.c
|
||||
${ESP_HAL_3RDPARTY_REPO}/components/ulp/lp_core/lp_core_i2c.c
|
||||
${ESP_HAL_3RDPARTY_REPO}/components/ulp/lp_core/lp_core_spi.c
|
||||
${ESP_HAL_3RDPARTY_REPO}/components/ulp/lp_core/lp_core.c
|
||||
${ESP_HAL_3RDPARTY_REPO}/components/ulp/lp_core/shared/ulp_lp_core_memory_shared.c
|
||||
${ESP_HAL_3RDPARTY_REPO}/components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c
|
||||
|
|
|
|||
|
|
@ -393,6 +393,7 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_
|
|||
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_flash$(DELIM)spi_flash_os_func_app.c
|
||||
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)spi_flash$(DELIM)spi_flash_os_func_noos.c
|
||||
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)ulp$(DELIM)lp_core$(DELIM)lp_core_i2c.c
|
||||
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)ulp$(DELIM)lp_core$(DELIM)lp_core_spi.c
|
||||
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)ulp$(DELIM)lp_core$(DELIM)lp_core.c
|
||||
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)ulp$(DELIM)lp_core$(DELIM)shared$(DELIM)ulp_lp_core_memory_shared.c
|
||||
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)ulp$(DELIM)lp_core$(DELIM)shared$(DELIM)ulp_lp_core_lp_timer_shared.c
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue