This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit e47b8a7298ffa1017e8b80c1866fdd498c5811a2
Author: Liam Howatt <[email protected]>
AuthorDate: Wed Aug 19 16:22:57 2026 -0400

    arch/arm/stm32h5: Port DMA support to SPI driver.
    
    The stm32h5 SPI driver is based on stm32h7's.
    It does not build when DMA is enabled. Port
    stm32h5 DMA to the stm32h5 SPI driver using the
    H5-specific DMA API. Use equivalents.
    
    Use correct cache line definition.
    
    Signed-off-by: Liam Howatt <[email protected]>
---
 arch/arm/src/stm32h5/stm32_spi.c | 137 +++++++++++++++++++++------------------
 1 file changed, 73 insertions(+), 64 deletions(-)

diff --git a/arch/arm/src/stm32h5/stm32_spi.c b/arch/arm/src/stm32h5/stm32_spi.c
index 55c70df9f92..6e2f0cadcaa 100644
--- a/arch/arm/src/stm32h5/stm32_spi.c
+++ b/arch/arm/src/stm32h5/stm32_spi.c
@@ -109,34 +109,39 @@
 
 #  if defined(CONFIG_SPI_DMAPRIO)
 #    define SPI_DMA_PRIO  CONFIG_SPI_DMAPRIO
-#  elif defined(DMA_SCR_PRIMED)
-#    define SPI_DMA_PRIO  DMA_SCR_PRILO
+#  elif defined(GPDMACFG_PRIO_LM)
+#    define SPI_DMA_PRIO  GPDMACFG_PRIO_LL
 #  else
 #    error "Unknown STM32 DMA"
 #  endif
 
-#  if (SPI_DMA_PRIO & ~DMA_SCR_PL_MASK) != 0
+#  if SPI_DMA_PRIO != GPDMACFG_PRIO_LL && SPI_DMA_PRIO != GPDMACFG_PRIO_LM \
+      && SPI_DMA_PRIO != GPMDACFG_PRIO_LH && SPI_DMA_PRIO != GPDMACFG_PRIO_H
 #    error "Illegal value for CONFIG_SPI_DMAPRIO"
 #  endif
 
-/* DMA channel configuration */
-#  define SPI_RXDMA16_CONFIG        
(SPI_DMA_PRIO|DMA_SCR_MSIZE_16BITS|DMA_SCR_PSIZE_16BITS|DMA_SCR_MINC|DMA_SCR_DIR_P2M)
-#  define SPI_RXDMA8_CONFIG         (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS 
|DMA_SCR_PSIZE_8BITS |DMA_SCR_MINC|DMA_SCR_DIR_P2M)
-#  define SPI_RXDMA16NULL_CONFIG    (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS 
|DMA_SCR_PSIZE_16BITS             |DMA_SCR_DIR_P2M)
-#  define SPI_RXDMA8NULL_CONFIG     (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS 
|DMA_SCR_PSIZE_8BITS              |DMA_SCR_DIR_P2M)
-#  define SPI_TXDMA16_CONFIG        
(SPI_DMA_PRIO|DMA_SCR_MSIZE_16BITS|DMA_SCR_PSIZE_16BITS|DMA_SCR_MINC|DMA_SCR_DIR_M2P)
-#  define SPI_TXDMA8_CONFIG         (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS 
|DMA_SCR_PSIZE_8BITS |DMA_SCR_MINC|DMA_SCR_DIR_M2P)
-#  define SPI_TXDMA16NULL_CONFIG    (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS 
|DMA_SCR_PSIZE_16BITS             |DMA_SCR_DIR_M2P)
-#  define SPI_TXDMA8NULL_CONFIG     (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS 
|DMA_SCR_PSIZE_8BITS              |DMA_SCR_DIR_M2P)
-
-/* If built with CONFIG_ARMV7M_DCACHE Buffers need to be aligned and
- * multiples of ARMV7M_DCACHE_LINESIZE
+/* DMA channel configuration.
+ * For RX, memory is the destination (DDW)
+ * and peripheral is the source (SDW).
+ * For TX, it's the opposite.
+ */
+#  define SPI_RXDMA16_CONFIG        (GPDMA_CXTR1_DDW_LOG2_HW  
|GPDMA_CXTR1_SDW_LOG2_HW  |GPDMA_CXTR1_DINC)
+#  define SPI_RXDMA8_CONFIG         
(GPDMA_CXTR1_DDW_LOG2_BYTE|GPDMA_CXTR1_SDW_LOG2_BYTE|GPDMA_CXTR1_DINC)
+#  define SPI_RXDMA16NULL_CONFIG    
(GPDMA_CXTR1_DDW_LOG2_BYTE|GPDMA_CXTR1_SDW_LOG2_HW                   )
+#  define SPI_RXDMA8NULL_CONFIG     
(GPDMA_CXTR1_DDW_LOG2_BYTE|GPDMA_CXTR1_SDW_LOG2_BYTE                 )
+#  define SPI_TXDMA16_CONFIG        (GPDMA_CXTR1_DDW_LOG2_HW  
|GPDMA_CXTR1_SDW_LOG2_HW  |GPDMA_CXTR1_SINC)
+#  define SPI_TXDMA8_CONFIG         
(GPDMA_CXTR1_DDW_LOG2_BYTE|GPDMA_CXTR1_SDW_LOG2_BYTE|GPDMA_CXTR1_SINC)
+#  define SPI_TXDMA16NULL_CONFIG    (GPDMA_CXTR1_DDW_LOG2_HW  
|GPDMA_CXTR1_SDW_LOG2_BYTE                 )
+#  define SPI_TXDMA8NULL_CONFIG     
(GPDMA_CXTR1_DDW_LOG2_BYTE|GPDMA_CXTR1_SDW_LOG2_BYTE                 )
+
+/* If built with CONFIG_ARMV8M_DCACHE Buffers need to be aligned and
+ * multiples of ARMV8M_DCACHE_LINESIZE
  */
 
-#  if defined(CONFIG_ARMV7M_DCACHE)
-#    define SPIDMA_BUFFER_MASK   (ARMV7M_DCACHE_LINESIZE - 1)
+#  if defined(CONFIG_ARMV8M_DCACHE)
+#    define SPIDMA_BUFFER_MASK   (ARMV8M_DCACHE_LINESIZE - 1)
 #    define SPIDMA_SIZE(b) (((b) + SPIDMA_BUFFER_MASK) & ~SPIDMA_BUFFER_MASK)
-#    define SPIDMA_BUF_ALIGN   aligned_data(ARMV7M_DCACHE_LINESIZE)
+#    define SPIDMA_BUF_ALIGN   aligned_data(ARMV8M_DCACHE_LINESIZE)
 #  else
 #    define SPIDMA_SIZE(b)  (b)
 #    define SPIDMA_BUF_ALIGN
@@ -285,8 +290,8 @@ struct stm32_spidev_s
   bool             defertrig;    /* Flag indicating that trigger should be 
deferred */
   bool             trigarmed;    /* Flag indicating that the trigger is armed 
*/
 #endif
-  uint32_t         rxch;         /* The RX DMA channel number */
-  uint32_t         txch;         /* The TX DMA channel number */
+  uint16_t         rxreq;        /* The RX GPDMA request number */
+  uint16_t         txreq;        /* The TX GPDMA request number */
   uint8_t          *rxbuf;       /* The RX DMA buffer */
   uint8_t          *txbuf;       /* The TX DMA buffer */
   size_t           buflen;       /* The DMA buffer length */
@@ -294,8 +299,8 @@ struct stm32_spidev_s
   DMA_HANDLE       txdma;        /* DMA channel handle for TX transfers */
   sem_t            rxsem;        /* Wait for RX DMA to complete */
   sem_t            txsem;        /* Wait for TX DMA to complete */
-  uint32_t         txccr;        /* DMA control register for TX transfers */
-  uint32_t         rxccr;        /* DMA control register for RX transfers */
+  uint32_t         txtr1;        /* DMA channel transfer register for TX 
transfers */
+  uint32_t         rxtr1;        /* DMA channel transfer register for RX 
transfers */
 #endif
   bool             initialized;  /* Has SPI interface been initialized */
   mutex_t          lock;         /* Held while chip is selected for mutual 
exclusion */
@@ -339,12 +344,12 @@ static void        spi_dmarxsetup(struct stm32_spidev_s 
*priv,
                                   void *rxbuffer,
                                   void *rxdummy,
                                   size_t nwords,
-                                  stm32_dmacfg_t *dmacfg);
+                                  struct stm32_gpdma_cfg_s *dmacfg);
 static void        spi_dmatxsetup(struct stm32_spidev_s *priv,
                                   const void *txbuffer,
                                   const void *txdummy,
                                   size_t nwords,
-                                  stm32_dmacfg_t *dmacfg);
+                                  struct stm32_gpdma_cfg_s *dmacfg);
 static inline void spi_dmarxstart(struct stm32_spidev_s *priv);
 static inline void spi_dmatxstart(struct stm32_spidev_s *priv);
 #endif
@@ -445,8 +450,8 @@ static struct stm32_spidev_s g_spi1dev =
   .spiclock = STM32_SPI1_FREQUENCY,
   .spiirq   = STM32_IRQ_SPI1,
 #ifdef CONFIG_STM32_SPI1_DMA
-  .rxch     = DMAMAP_SPI1_RX,
-  .txch     = DMAMAP_SPI1_TX,
+  .rxreq    = GPDMA_REQ_SPI1_RX,
+  .txreq    = GPDMA_REQ_SPI1_TX,
 #  if defined(SPI1_DMABUFSIZE_ADJUSTED)
   .rxbuf    = g_spi1_rxbuf,
   .txbuf    = g_spi1_txbuf,
@@ -518,8 +523,8 @@ static struct stm32_spidev_s g_spi2dev =
   .spiclock = STM32_SPI2_FREQUENCY,
   .spiirq   = STM32_IRQ_SPI2,
 #ifdef CONFIG_STM32_SPI2_DMA
-  .rxch     = DMAMAP_SPI2_RX,
-  .txch     = DMAMAP_SPI2_TX,
+  .rxreq    = GPDMA_REQ_SPI2_RX,
+  .txreq    = GPDMA_REQ_SPI2_TX,
 #  if defined(SPI2_DMABUFSIZE_ADJUSTED)
   .rxbuf    = g_spi2_rxbuf,
   .txbuf    = g_spi2_txbuf,
@@ -591,8 +596,8 @@ static struct stm32_spidev_s g_spi3dev =
   .spiclock = STM32_SPI3_FREQUENCY,
   .spiirq   = STM32_IRQ_SPI3,
 #ifdef CONFIG_STM32_SPI3_DMA
-  .rxch     = DMAMAP_SPI3_RX,
-  .txch     = DMAMAP_SPI3_TX,
+  .rxreq    = GPDMA_REQ_SPI3_RX,
+  .txreq    = GPDMA_REQ_SPI3_TX,
 #  if defined(SPI3_DMABUFSIZE_ADJUSTED)
   .rxbuf    = g_spi3_rxbuf,
   .txbuf    = g_spi3_txbuf,
@@ -664,8 +669,8 @@ static struct stm32_spidev_s g_spi4dev =
   .spiclock = STM32_SPI4_FREQUENCY,
   .spiirq   = STM32_IRQ_SPI4,
 #ifdef CONFIG_STM32_SPI4_DMA
-  .rxch     = DMAMAP_SPI4_RX,
-  .txch     = DMAMAP_SPI4_TX,
+  .rxreq    = GPDMA_REQ_SPI4_RX,
+  .txreq    = GPDMA_REQ_SPI4_TX,
 #  if defined(SPI4_DMABUFSIZE_ADJUSTED)
   .rxbuf    = g_spi4_rxbuf,
   .txbuf    = g_spi4_txbuf,
@@ -737,8 +742,8 @@ static struct stm32_spidev_s g_spi5dev =
   .spiclock = STM32_SPI5_FREQUENCY,
   .spiirq   = STM32_IRQ_SPI5,
 #ifdef CONFIG_STM32_SPI5_DMA
-  .rxch     = DMAMAP_SPI5_RX,
-  .txch     = DMAMAP_SPI5_TX,
+  .rxreq    = GPDMA_REQ_SPI5_RX,
+  .txreq    = GPDMA_REQ_SPI5_TX,
 #  if defined(SPI5_DMABUFSIZE_ADJUSTED)
   .rxbuf    = g_spi5_rxbuf,
   .txbuf    = g_spi5_txbuf,
@@ -811,8 +816,8 @@ static struct stm32_spidev_s g_spi6dev =
   .spiclock = STM32_SPI6_FREQUENCY,
   .spiirq   = STM32_IRQ_SPI6,
 #ifdef CONFIG_STM32_SPI6_DMA
-  .rxch     = DMAMAP_SPI6_RX,
-  .txch     = DMAMAP_SPI6_TX,
+  .rxreq    = GPDMA_REQ_SPI6_RX,
+  .txreq    = GPDMA_REQ_SPI6_TX,
 #  if defined(SPI6_DMABUFSIZE_ADJUSTED)
   .rxbuf    = g_spi6_rxbuf,
   .txbuf    = g_spi6_txbuf,
@@ -1298,13 +1303,13 @@ static void spi_dmarxcallback(DMA_HANDLE handle, 
uint8_t isr, void *arg)
 #ifdef CONFIG_STM32_SPI_DMA
 static void spi_dmarxsetup(struct stm32_spidev_s *priv,
                            void *rxbuffer, void *rxdummy,
-                           size_t nwords, stm32_dmacfg_t *dmacfg)
+                           size_t nwords, struct stm32_gpdma_cfg_s *dmacfg)
 {
   /* Can't receive in tx only mode */
 
   if (priv->config == SIMPLEX_TX)
     {
-      priv->rxccr = 0;
+      priv->rxtr1 = 0;
       return;
     }
 
@@ -1316,12 +1321,12 @@ static void spi_dmarxsetup(struct stm32_spidev_s *priv,
 
       if (rxbuffer)
         {
-          priv->rxccr = SPI_RXDMA16_CONFIG;
+          priv->rxtr1 = SPI_RXDMA16_CONFIG;
         }
       else
         {
           rxbuffer    = rxdummy;
-          priv->rxccr = SPI_RXDMA16NULL_CONFIG;
+          priv->rxtr1 = SPI_RXDMA16NULL_CONFIG;
         }
     }
   else
@@ -1330,22 +1335,24 @@ static void spi_dmarxsetup(struct stm32_spidev_s *priv,
 
       if (rxbuffer)
         {
-          priv->rxccr = SPI_RXDMA8_CONFIG;
+          priv->rxtr1 = SPI_RXDMA8_CONFIG;
         }
       else
         {
           rxbuffer    = rxdummy;
-          priv->rxccr = SPI_RXDMA8NULL_CONFIG;
+          priv->rxtr1 = SPI_RXDMA8NULL_CONFIG;
         }
     }
 
   /* Configure the RX DMA */
 
-  dmacfg->paddr = priv->spibase + STM32_SPI_RXDR_OFFSET;
-  dmacfg->maddr = (uint32_t)rxbuffer;
-  dmacfg->ndata = nwords;
-  dmacfg->cfg1  = priv->rxccr;
-  dmacfg->cfg2  = 0;
+  dmacfg->src_addr   = priv->spibase + STM32_SPI_RXDR_OFFSET;
+  dmacfg->dest_addr  = (uint32_t)rxbuffer;
+  dmacfg->ntransfers = nwords;
+  dmacfg->tr1        = priv->rxtr1;
+  dmacfg->request    = priv->rxreq;
+  dmacfg->priority   = SPI_DMA_PRIO;
+  dmacfg->mode       = 0;
 }
 #endif
 
@@ -1360,13 +1367,13 @@ static void spi_dmarxsetup(struct stm32_spidev_s *priv,
 #ifdef CONFIG_STM32_SPI_DMA
 static void spi_dmatxsetup(struct stm32_spidev_s *priv,
                            const void *txbuffer, const void *txdummy,
-                           size_t nwords, stm32_dmacfg_t *dmacfg)
+                           size_t nwords, struct stm32_gpdma_cfg_s *dmacfg)
 {
   /* Can't transmit in rx only mode */
 
   if (priv->config == SIMPLEX_RX)
     {
-      priv->txccr = 0;
+      priv->txtr1 = 0;
       return;
     }
 
@@ -1378,12 +1385,12 @@ static void spi_dmatxsetup(struct stm32_spidev_s *priv,
 
       if (txbuffer)
         {
-          priv->txccr = SPI_TXDMA16_CONFIG;
+          priv->txtr1 = SPI_TXDMA16_CONFIG;
         }
       else
         {
           txbuffer    = txdummy;
-          priv->txccr = SPI_TXDMA16NULL_CONFIG;
+          priv->txtr1 = SPI_TXDMA16NULL_CONFIG;
         }
     }
   else
@@ -1392,20 +1399,22 @@ static void spi_dmatxsetup(struct stm32_spidev_s *priv,
 
       if (txbuffer)
         {
-          priv->txccr = SPI_TXDMA8_CONFIG;
+          priv->txtr1 = SPI_TXDMA8_CONFIG;
         }
       else
         {
           txbuffer    = txdummy;
-          priv->txccr = SPI_TXDMA8NULL_CONFIG;
+          priv->txtr1 = SPI_TXDMA8NULL_CONFIG;
         }
     }
 
-  dmacfg->paddr = priv->spibase + STM32_SPI_TXDR_OFFSET;
-  dmacfg->maddr = (uint32_t)txbuffer;
-  dmacfg->ndata = nwords;
-  dmacfg->cfg1  = priv->txccr;
-  dmacfg->cfg2  = 0;
+  dmacfg->src_addr   = (uint32_t)txbuffer;
+  dmacfg->dest_addr  = priv->spibase + STM32_SPI_TXDR_OFFSET;
+  dmacfg->ntransfers = nwords;
+  dmacfg->tr1        = priv->txtr1;
+  dmacfg->request    = priv->txreq;
+  dmacfg->priority   = SPI_DMA_PRIO;
+  dmacfg->mode       = 0;
 }
 #endif
 
@@ -2188,10 +2197,10 @@ static void spi_exchange(struct spi_dev_s *dev, const 
void *txbuffer,
                          void *rxbuffer, size_t nwords)
 {
   struct stm32_spidev_s *priv = (struct stm32_spidev_s *)dev;
-  stm32_dmacfg_t rxdmacfg;
-  stm32_dmacfg_t txdmacfg;
-  static uint8_t rxdummy[ARMV7M_DCACHE_LINESIZE]
-    aligned_data(ARMV7M_DCACHE_LINESIZE);
+  struct stm32_gpdma_cfg_s rxdmacfg;
+  struct stm32_gpdma_cfg_s txdmacfg;
+  static uint8_t rxdummy[ARMV8M_DCACHE_LINESIZE]
+    aligned_data(ARMV8M_DCACHE_LINESIZE);
   static const uint16_t txdummy = 0xffff;
   void *orig_rxbuffer = rxbuffer;
 
@@ -2668,14 +2677,14 @@ static void spi_bus_initialize(struct stm32_spidev_s 
*priv)
   priv->txdma = NULL;
   if (priv->config != SIMPLEX_TX)
     {
-      priv->rxdma = stm32_dmachannel(priv->rxch);
+      priv->rxdma = stm32_dmachannel(GPDMA_TTYPE_P2M);
       DEBUGASSERT(priv->rxdma);
       spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0, SPI_CFG1_RXDMAEN);
     }
 
   if (priv->config != SIMPLEX_RX)
     {
-      priv->txdma = stm32_dmachannel(priv->txch);
+      priv->txdma = stm32_dmachannel(GPDMA_TTYPE_M2P);
       DEBUGASSERT(priv->txdma);
       spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0, SPI_CFG1_TXDMAEN);
     }

Reply via email to