You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by an...@apache.org on 2021/05/07 21:39:24 UTC

[incubator-nuttx] 03/03: stm32:SDIO:Use 250 Ms Data path timeout, regardless of Card Clock frequency

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

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

commit 17b786399cc271af02c837a0b69ffe3c17509b11
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Thu May 6 09:24:31 2021 -0700

    stm32:SDIO:Use 250 Ms Data path timeout, regardless of Card Clock frequency
---
 arch/arm/src/stm32/stm32_sdio.c | 47 ++++++++++++++++++++++++++++++-----------
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/arch/arm/src/stm32/stm32_sdio.c b/arch/arm/src/stm32/stm32_sdio.c
index 898e32b..5c78d79 100644
--- a/arch/arm/src/stm32/stm32_sdio.c
+++ b/arch/arm/src/stm32/stm32_sdio.c
@@ -153,7 +153,7 @@
 #  define SDIO_CLKCR_EDGE SDIO_CLKCR_RISINGEDGE
 #endif
 
-/* Mode dependent settings.  These depend on clock devisor settings that must
+/* Mode dependent settings.  These depend on clock divisor settings that must
  * be defined in the board-specific board.h header file: SDIO_INIT_CLKDIV,
  * SDIO_MMCXFR_CLKDIV, and SDIO_SDXFR_CLKDIV.
  */
@@ -172,9 +172,12 @@
 #define SDIO_CMDTIMEOUT          (100000)
 #define SDIO_LONGTIMEOUT         (0x7fffffff)
 
-/* Big DTIMER setting */
+/* DTIMER setting */
 
-#define SDIO_DTIMER_DATATIMEOUT  (0x000fffff)
+/* Assuming Max timeout in bypass 48 Mhz */
+
+#define IP_CLCK_FREQ               UINT32_C(48000000)
+#define SDIO_DTIMER_DATATIMEOUT_MS 250
 
 /* DMA channel/stream configuration register settings.  The following
  * must be selected.  The DMA driver will select the remaining fields.
@@ -1016,9 +1019,24 @@ static uint8_t stm32_log2(uint16_t value)
 
 static void stm32_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl)
 {
-  uint32_t regval = 0;
+  uint32_t clkdiv;
+  uint32_t regval;
+  uint32_t sdio_clk = IP_CLCK_FREQ;
+
+  /* Enable data path using a timeout scaled to the SD_CLOCK (the card
+   * clock).
+   */
 
-  /* Enable data path */
+  regval = getreg32(STM32_SDIO_CLKCR);
+  clkdiv = (regval & SDIO_CLKCR_CLKDIV_MASK) >> SDIO_CLKCR_CLKDIV_SHIFT;
+  if ((regval & SDIO_CLKCR_BYPASS) == 0)
+    {
+      sdio_clk = sdio_clk / (2 + clkdiv);
+    }
+
+  /*  Convert Timeout in Ms to SD_CLK counts */
+
+  timeout  = timeout * (sdio_clk / 1000);
 
   putreg32(timeout, STM32_SDIO_DTIMER); /* Set DTIMER */
   putreg32(dlen,    STM32_SDIO_DLEN);   /* Set DLEN */
@@ -1049,10 +1067,15 @@ static void stm32_datadisable(void)
 {
   uint32_t regval;
 
-  /* Disable the data path */
+  /* Disable the data path  */
+
+  /* Reset DTIMER */
+
+  putreg32(UINT32_MAX, STM32_SDIO_DTIMER);
+
+  /* Reset DLEN */
 
-  putreg32(SDIO_DTIMER_DATATIMEOUT, STM32_SDIO_DTIMER); /* Reset DTIMER */
-  putreg32(0,                       STM32_SDIO_DLEN);   /* Reset DLEN */
+  putreg32(0, STM32_SDIO_DLEN);
 
   /* Reset DCTRL DTEN, DTDIR, DTMODE, DMAEN, and DBLOCKSIZE fields */
 
@@ -1992,7 +2015,7 @@ static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
       dblocksize = stm32_log2(nbytes) << SDIO_DCTRL_DBLOCKSIZE_SHIFT;
     }
 
-  stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, nbytes,
+  stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT_MS, nbytes,
                    dblocksize | SDIO_DCTRL_DTDIR);
 
   /* And enable interrupts */
@@ -2057,7 +2080,7 @@ static int stm32_sendsetup(FAR struct sdio_dev_s *dev,
       dblocksize = stm32_log2(nbytes) << SDIO_DCTRL_DBLOCKSIZE_SHIFT;
     }
 
-  stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, nbytes, dblocksize);
+  stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT_MS, nbytes, dblocksize);
 
   /* Enable TX interrupts */
 
@@ -2800,7 +2823,7 @@ static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev,
       dblocksize = stm32_log2(buflen) << SDIO_DCTRL_DBLOCKSIZE_SHIFT;
     }
 
-  stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, buflen,
+  stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT_MS, buflen,
                    dblocksize | SDIO_DCTRL_DTDIR);
 
   /* Configure the RX DMA */
@@ -2880,7 +2903,7 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev,
       dblocksize = stm32_log2(buflen) << SDIO_DCTRL_DBLOCKSIZE_SHIFT;
     }
 
-  stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, buflen, dblocksize);
+  stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT_MS, buflen, dblocksize);
 
   /* Configure the TX DMA */