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 51daf8e474669fc54f409747dab62b9b1192cac5
Author: Jorge Guzman <[email protected]>
AuthorDate: Sun Oct 25 00:57:09 2026 -0300

    arch/arm/gd32w51x: do not end an SPI DMA on a DMA exception
    
    The single data mode and FIFO exceptions of the DMA have no effect on
    the transfer (user manual 12.5.2).  A receive request that waits for
    the bus raises the single data mode exception, and the SPI driver
    enabled its interrupt: the callback then woke the waiter before the
    end of the transfer.
    
    - spi: enable only the full transfer finish and access error
      interrupts.
    - dma: clear the exception flags but call back only along with another
      event.
    
    Tested on the GD-xD-W515-EVAL: the ST7735S LCD frame buffer (SPI0 with
    DMA) shows the whole image.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Jorge Guzman <[email protected]>
---
 arch/arm/src/gd32w51x/gd32w51x_dma.c |  8 ++++++--
 arch/arm/src/gd32w51x/gd32w51x_spi.c | 11 ++++++-----
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/arch/arm/src/gd32w51x/gd32w51x_dma.c 
b/arch/arm/src/gd32w51x/gd32w51x_dma.c
index 3fd4299d8f7..e9e6c55275a 100644
--- a/arch/arm/src/gd32w51x/gd32w51x_dma.c
+++ b/arch/arm/src/gd32w51x/gd32w51x_dma.c
@@ -480,9 +480,13 @@ static int gd32_dma_interrupt(int irq, void *context, void 
*arg)
     {
       gd32_dma_interrupt_flag_clear(dmachan->chan_num, status);
 
-      /* Invoke the DMA callback */
+      /* Invoke the DMA callback.  The single data mode and FIFO exceptions
+       * have no effect on the transfer (user manual 12.5.2): they are only
+       * reported along with another event.
+       */
 
-      if (dmachan->callback != NULL)
+      if (dmachan->callback != NULL &&
+          (status & ~(DMA_INTF_SDEIF | DMA_INTF_FEEIF)) != 0)
         {
           dmachan->callback(dmachan, status, dmachan->arg);
         }
diff --git a/arch/arm/src/gd32w51x/gd32w51x_spi.c 
b/arch/arm/src/gd32w51x/gd32w51x_spi.c
index 39fa942748a..0cfca316f39 100644
--- a/arch/arm/src/gd32w51x/gd32w51x_spi.c
+++ b/arch/arm/src/gd32w51x/gd32w51x_spi.c
@@ -99,13 +99,14 @@
 #ifdef CONFIG_GD32W51X_SPI_DMA
 
 /* The DMA interrupts that are enabled while an SPI DMA is in progress:
- * the end of the transfer and the errors.  The half transfer interrupt
- * must stay off: the callback wakes the waiter on any interrupt, which
- * would end the exchange while the second half is still on the wire.
+ * the end of the transfer and the access error.  The callback wakes the
+ * waiter on any interrupt, so the half transfer interrupt must stay off,
+ * or the exchange would end while the second half is still on the wire,
+ * and so must the single data mode exception, which a receive request
+ * raises when it waits for the bus and which does not stop the transfer.
  */
 
-#  define SPI_DMA_INTEN         (DMA_CHXCTL_FTFIE | DMA_CHXCTL_TAEIE | \
-                                 DMA_CHXCTL_SDEIE)
+#  define SPI_DMA_INTEN         (DMA_CHXCTL_FTFIE | DMA_CHXCTL_TAEIE)
 
 /* SPI DMA priority */
 

Reply via email to