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 */