From commits-return-6430-archive-asf-public=cust-asf.ponee.io@nuttx.apache.org Fri Apr 3 16:50:37 2020 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id 932AE180660 for ; Fri, 3 Apr 2020 18:50:37 +0200 (CEST) Received: (qmail 42737 invoked by uid 500); 3 Apr 2020 16:50:37 -0000 Mailing-List: contact commits-help@nuttx.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@nuttx.apache.org Delivered-To: mailing list commits@nuttx.apache.org Received: (qmail 42684 invoked by uid 99); 3 Apr 2020 16:50:36 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 03 Apr 2020 16:50:36 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 47BA6819F7; Fri, 3 Apr 2020 16:50:36 +0000 (UTC) Date: Fri, 03 Apr 2020 16:50:37 +0000 To: "commits@nuttx.apache.org" Subject: [incubator-nuttx] 02/02: stm32h7:Fix DMA Overrun error MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit From: gnutt@apache.org In-Reply-To: <158593263595.24967.12297041232522653531@gitbox.apache.org> References: <158593263595.24967.12297041232522653531@gitbox.apache.org> X-Git-Host: gitbox.apache.org X-Git-Repo: incubator-nuttx X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Rev: fc3ab3e085ce5e904d26db674cdee4c8c5cb1068 X-Git-NotificationType: diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated Message-Id: <20200403165036.47BA6819F7@gitbox.apache.org> This is an automated email from the ASF dual-hosted git repository. gnutt pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git commit fc3ab3e085ce5e904d26db674cdee4c8c5cb1068 Author: David Sidrane AuthorDate: Thu Apr 2 12:06:58 2020 -0700 stm32h7:Fix DMA Overrun error --- arch/arm/src/stm32h7/stm32_spi.c | 78 ++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/arch/arm/src/stm32h7/stm32_spi.c b/arch/arm/src/stm32h7/stm32_spi.c index e56bde7..8c304b5 100644 --- a/arch/arm/src/stm32h7/stm32_spi.c +++ b/arch/arm/src/stm32h7/stm32_spi.c @@ -1451,16 +1451,6 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) spi_modifyreg(priv, STM32_SPI_CFG2_OFFSET, clrbits, setbits); -#ifdef CONFIG_STM32H7_SPI_DMA - /* Enabling SPI causes a spurious received character indication - * which confuse the DMA controller so we disable DMA during that - * enabling; and flush the SPI RX FIFO before re-enabling DMA. - */ - - spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, SPI_CFG1_RXDMAEN | - SPI_CFG1_TXDMAEN, 0); -#endif - /* Re-enable SPI */ spi_enable(priv, true); @@ -1469,19 +1459,9 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode) { /* Flush SPI read FIFO */ - spi_getreg(priv, STM32_SPI_TXDR_OFFSET); + spi_getreg(priv, STM32_SPI_RXDR_OFFSET); } -#ifdef CONFIG_STM32H7_SPI_DMA - - /* Re-enable DMA (with SPI disabled) */ - - spi_enable(priv, false); - spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0, SPI_CFG1_RXDMAEN | - SPI_CFG1_TXDMAEN); - spi_enable(priv, true); -#endif - /* Save the mode so that subsequent re-configurations will be faster */ priv->mode = mode; @@ -1913,6 +1893,22 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, static uint8_t rxdummy[4] __attribute__((aligned(4))); static const uint16_t txdummy = 0xffff; + /* When starting communication using DMA, to prevent DMA channel + * management raising error events, these steps must be followed in + * order: + * 1. Enable DMA Rx buffer in the RXDMAEN bit in the SPI_CFG1 register, + * if DMA Rx is used. + * 2. Enable DMA requests for Tx and Rx in DMA registers, if the DMA is + * used. + * 3. Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CFG1 register, + * if DMA Tx is used. + * 4. Enable the SPI by setting the SPE bit. + */ + + spi_enable(priv, false); + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, SPI_CFG1_TXDMAEN, + SPI_CFG1_RXDMAEN); + spiinfo("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords); DEBUGASSERT(priv->spibase != 0); @@ -1920,6 +1916,9 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, spi_dmarxsetup(priv, rxbuffer, (uint16_t *)rxdummy, nbytes); spi_dmatxsetup(priv, txbuffer, &txdummy, nbytes); + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, 0, SPI_CFG1_TXDMAEN | + SPI_CFG1_RXDMAEN); + /* Flush cache to physical memory */ if (txbuffer) @@ -1927,19 +1926,17 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, up_flush_dcache((uintptr_t)txbuffer, (uintptr_t)txbuffer + nbytes); } - /* REVISIT: Master transfer start */ - - spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_CSTART); - #ifdef CONFIG_SPI_TRIGGER /* Is deferred triggering in effect? */ if (!priv->defertrig) { - /* No.. Start the DMAs */ + /* No.. Start the DMAs then the SPI */ spi_dmarxstart(priv); spi_dmatxstart(priv); + spi_enable(priv, true); + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_CSTART); } else { @@ -1948,20 +1945,32 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer, priv->trigarmed = true; } #else - /* Start the DMAs */ + /* Start the DMAs then the SPI */ spi_dmarxstart(priv); spi_dmatxstart(priv); + spi_enable(priv, true); + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_CSTART); #endif /* Then wait for each to complete */ - ret = spi_dmarxwait(priv); - if (ret >= 0) - { - ret = spi_dmatxwait(priv); - UNUSED(ret); - } + spi_dmarxwait(priv); + spi_dmatxwait(priv); + + /* To close communication it is mandatory to follow these steps in + * order: + * 1. Disable DMA request for Tx and Rx in the DMA registers, if the + * DMA issued. + * 2. Disable the SPI by following the SPI disable procedure. + * 3. Disable DMA Tx and Rx buffers by clearing the TXDMAEN and RXDMAEN + * bits in the SPI_CFG1 register, if DMA Tx and/or DMA Rx are used. + */ + + spi_enable(priv, false); + spi_modifyreg(priv, STM32_SPI_CFG1_OFFSET, SPI_CFG1_TXDMAEN | + SPI_CFG1_RXDMAEN, 0); + spi_enable(priv, true); #ifdef CONFIG_SPI_TRIGGER priv->trigarmed = false; @@ -2012,7 +2021,8 @@ static int spi_trigger(FAR struct spi_dev_s *dev) spi_dmarxstart(priv); spi_dmatxstart(priv); - + spi_enable(priv, true); + spi_modifyreg(priv, STM32_SPI_CR1_OFFSET, 0, SPI_CR1_CSTART); return OK; #else return -ENOSYS;