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");

Reply via email to