This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 6b5ca79509 esp32s3/spi-dma: Fix spi dma transfer.
6b5ca79509 is described below
commit 6b5ca795091a84f7535c21606c3c0a9732dcb047
Author: w2016561536 <[email protected]>
AuthorDate: Tue Jan 23 02:13:58 2024 +0800
esp32s3/spi-dma: Fix spi dma transfer.
Fix esp32s3 spi dma transfer only transmit first byte and receive empty
problem.
---
arch/xtensa/include/esp32s3/irq.h | 4 ++-
arch/xtensa/src/esp32s3/esp32s3_dma.h | 2 +-
arch/xtensa/src/esp32s3/esp32s3_spi.c | 52 +++++++++++++++++++++++++++++------
3 files changed, 47 insertions(+), 11 deletions(-)
diff --git a/arch/xtensa/include/esp32s3/irq.h
b/arch/xtensa/include/esp32s3/irq.h
index 25a248f422..82acc3e12a 100644
--- a/arch/xtensa/include/esp32s3/irq.h
+++ b/arch/xtensa/include/esp32s3/irq.h
@@ -137,17 +137,19 @@
#define ESP32S3_PERIPH_DCACHE_SYNC 63
#define ESP32S3_PERIPH_ICACHE_SYNC 64
#define ESP32S3_PERIPH_APB_ADC 65
+
#define ESP32S3_PERIPH_DMA_IN_CH0 66
#define ESP32S3_PERIPH_DMA_IN_CH1 67
#define ESP32S3_PERIPH_DMA_IN_CH2 68
#define ESP32S3_PERIPH_DMA_IN_CH3 69
-
#define ESP32S3_PERIPH_DMA_IN_CH4 70
+
#define ESP32S3_PERIPH_DMA_OUT_CH0 71
#define ESP32S3_PERIPH_DMA_OUT_CH1 72
#define ESP32S3_PERIPH_DMA_OUT_CH2 73
#define ESP32S3_PERIPH_DMA_OUT_CH3 74
#define ESP32S3_PERIPH_DMA_OUT_CH4 75
+
#define ESP32S3_PERIPH_RSA 76
#define ESP32S3_PERIPH_AES 77
#define ESP32S3_PERIPH_SHA 78
diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.h
b/arch/xtensa/src/esp32s3/esp32s3_dma.h
index db2c91899d..a7b5a2984a 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.h
@@ -64,7 +64,7 @@ extern "C"
/* DMA channel number */
-#define ESP32S3_DMA_CHAN_MAX (3)
+#define ESP32S3_DMA_CHAN_MAX (5)
/* DMA RX MAX priority */
diff --git a/arch/xtensa/src/esp32s3/esp32s3_spi.c
b/arch/xtensa/src/esp32s3/esp32s3_spi.c
index 847602e0eb..2c0d2a6c46 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_spi.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_spi.c
@@ -50,6 +50,7 @@
#ifdef CONFIG_ESP32S3_SPI_DMA
#include "esp32s3_dma.h"
+#include "hardware/esp32s3_dma.h"
#endif
#include "xtensa.h"
@@ -204,12 +205,11 @@ static void esp32s3_spi_dma_exchange(struct
esp32s3_spi_priv_s *priv,
const void *txbuffer,
void *rxbuffer,
uint32_t nwords);
-#else
+#endif
static void esp32s3_spi_poll_exchange(struct esp32s3_spi_priv_s *priv,
const void *txbuffer,
void *rxbuffer,
size_t nwords);
-#endif
#ifndef CONFIG_SPI_EXCHANGE
static void esp32s3_spi_sndblock(struct spi_dev_s *dev,
const void *txbuffer,
@@ -894,10 +894,11 @@ static void esp32s3_spi_dma_exchange(struct
esp32s3_spi_priv_s *priv,
{
/* Reset SPI DMA TX FIFO */
- esp32s3_spi_set_regbits(SPI_DMA_CONF_REG(priv->config->id),
- SPI_DMA_RESET_MASK);
- esp32s3_spi_clr_regbits(SPI_DMA_CONF_REG(priv->config->id),
- SPI_DMA_RESET_MASK);
+ SET_GDMA_CH_BITS(DMA_OUT_CONF0_CH0_REG, priv->dma_channel,
+ DMA_OUT_RST_CH0);
+
+ CLR_GDMA_CH_BITS(DMA_OUT_CONF0_CH0_REG, priv->dma_channel,
+ DMA_OUT_RST_CH0);
/* Enable SPI DMA TX */
@@ -917,6 +918,14 @@ static void esp32s3_spi_dma_exchange(struct
esp32s3_spi_priv_s *priv,
if (rp != NULL)
{
+ /* Reset SPI DMA RX FIFO */
+
+ SET_GDMA_CH_BITS(DMA_IN_CONF0_CH0_REG, priv->dma_channel,
+ DMA_IN_RST_CH0);
+
+ CLR_GDMA_CH_BITS(DMA_IN_CONF0_CH0_REG, priv->dma_channel,
+ DMA_IN_RST_CH0);
+
/* Enable SPI DMA RX */
esp32s3_spi_set_regbits(SPI_DMA_CONF_REG(priv->config->id),
@@ -979,6 +988,14 @@ static void esp32s3_spi_dma_exchange(struct
esp32s3_spi_priv_s *priv,
static uint32_t esp32s3_spi_poll_send(struct esp32s3_spi_priv_s *priv,
uint32_t wd)
{
+#ifdef CONFIG_ESP32S3_SPI_DMA
+ esp32s3_spi_clr_regbits(SPI_DMA_CONF_REG(priv->config->id),
+ SPI_DMA_TX_ENA_M);
+
+ esp32s3_spi_clr_regbits(SPI_DMA_CONF_REG(priv->config->id),
+ SPI_DMA_RX_ENA_M);
+#endif
+
uint32_t val;
putreg32((priv->nbits - 1), SPI_MS_DLEN_REG(priv->config->id));
@@ -1059,6 +1076,14 @@ static void esp32s3_spi_poll_exchange(struct
esp32s3_spi_priv_s *priv,
void *rxbuffer,
size_t nwords)
{
+#ifdef CONFIG_ESP32S3_SPI_DMA
+ esp32s3_spi_clr_regbits(SPI_DMA_CONF_REG(priv->config->id),
+ SPI_DMA_TX_ENA_M);
+
+ esp32s3_spi_clr_regbits(SPI_DMA_CONF_REG(priv->config->id),
+ SPI_DMA_RX_ENA_M);
+#endif
+
const uint32_t total_bytes = nwords * (priv->nbits / 8);
uintptr_t bytes_remaining = total_bytes;
const uint8_t *tp = (const uint8_t *)txbuffer;
@@ -1198,7 +1223,7 @@ static void esp32s3_spi_exchange(struct spi_dev_s *dev,
#ifdef CONFIG_ESP32S3_SPI_DMA
size_t thld = CONFIG_ESP32S3_SPI_DMATHRESHOLD;
- if (nwords > thld)
+ if ((nwords * priv->nbits) / 8 > thld)
{
esp32s3_spi_dma_exchange(priv, txbuffer, rxbuffer, nwords);
}
@@ -1326,8 +1351,17 @@ void esp32s3_spi_dma_init(struct spi_dev_s *dev)
/* Request a GDMA channel for SPI peripheral */
- priv->dma_channel = esp32s3_dma_request(ESP32S3_DMA_PERIPH_SPI2, 1, 1,
- true);
+ if (priv->config->id == 2)
+ {
+ priv->dma_channel = esp32s3_dma_request(ESP32S3_DMA_PERIPH_SPI2, 1, 1,
+ true);
+ }
+ else if (priv->config->id == 3)
+ {
+ priv->dma_channel = esp32s3_dma_request(ESP32S3_DMA_PERIPH_SPI3, 1, 1,
+ true);
+ }
+
if (priv->dma_channel < 0)
{
spierr("Failed to allocate GDMA channel\n");