From af1830dc73e603e272685a2090dda09619386697 Mon Sep 17 00:00:00 2001
From: patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>
Date: Sun, 29 Nov 2009 15:46:13 +0000
Subject: [PATCH] SDIO now works

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2287 42af7a65-404d-4744-a932-0658087f49c3
---
 ChangeLog                       |  4 ---
 Documentation/NuttX.html        |  6 +---
 TODO                            | 12 +++++--
 arch/arm/src/stm32/stm32_sdio.c | 60 ++++++++++++++++++++-------------
 4 files changed, 48 insertions(+), 34 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 954c7f5526..7625fcaa2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -960,10 +960,6 @@
 	* drivers/mmcsd/mmcsd_sdio.c -- Provides a an SDIO-based MMC/SD driver.
 	* arch/arm/src/stm32/stm32_sdio.c -- Provides an STM32 implementation of
 	  the SDIO interface defined in include/nuttx/sdio.h.
-
-	  NOTE: On initial check-in, mmcsd_sdio.c and stm32_sdio.c are merely
-	  skeleton frameworks for the driver.
-
 	* fs/fs_mount.c -- Correct error handling logic.  If the bind() method
 	  fails, then a reserved node is left in the tree.  This causes subsequent
 	  attempts to mount at the location to fail (reporting that the node
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index 4066bd9f53..f5776a92bd 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -8,7 +8,7 @@
   <tr align="center" bgcolor="#e4e4e4">
     <td>
       <h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
-      <p>Last Updated: November 25, 2009</p>
+      <p>Last Updated: November 29, 2009</p>
     </td>
   </tr>
 </table>
@@ -1608,10 +1608,6 @@ nuttx-4.14 2009-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
 	* drivers/mmcsd/mmcsd_sdio.c -- Provides a an SDIO-based MMC/SD driver.
 	* arch/arm/src/stm32/stm32_sdio.c -- Provides an STM32 implementation of
 	  the SDIO interface defined in include/nuttx/sdio.h.
-
-	  NOTE: On initial check-in, mmcsd_sdio.c and stm32_sdio.c are merely
-	  skeleton frameworks for the driver.
-
 	* fs/fs_mount.c -- Correct error handling logic.  If the bind() method
 	  fails, then a reserved node is left in the tree.  This causes subsequent
 	  attempts to mount at the location to fail (reporting that the node
diff --git a/TODO b/TODO
index 00d7b1fcda..cf890b0f24 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-NuttX TODO List (Last updated November 25, 2009)
+NuttX TODO List (Last updated November 29, 2009)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
   (5)  Task/Scheduler (sched/)
@@ -26,7 +26,7 @@ NuttX TODO List (Last updated November 25, 2009)
   (8)  ARM/LPC214x (arch/arm/src/lpc214x/)
   (3)  ARM/STR71x (arch/arm/src/str71x/)
   (3)  ARM/LM3S6918 (arch/arm/src/lm3s/)
-  (4)  ARM/STM32 (arch/arm/src/stm32/)
+  (5)  ARM/STM32 (arch/arm/src/stm32/)
   (4)  pjrc-8052 / MCS51 (arch/pjrc-8051/)
   (2)  Hitachi/Renesas SH-1 (arch/sh/src/sh1)
   (4)  Renesas M16C/26 (arch/sh/src/m16c)
@@ -680,6 +680,14 @@ o ARM/STM32 (arch/arm/src/stm32/)
   Priority:    Low until someone needs DMA1, Channel 5 (ADC3, UART4_TX, TIM5_CH1, or
                TIM8_CH2).
 
+  Desription:  I am unable to access a 2Gb SanDisk microSD card (in adaptor) on the
+               the STM3210E-EVAL board.  The card reports that it is a SDV1.x card
+               with a 1Kb block size, but the CMD16 to set the block length to
+               1024 fails.
+  Status:      Open
+  Priority:    Uncertain.  I don't this is a bug, I think I just don't understand
+               how to work with this type of SD card.
+
 o pjrc-8052 / MCS51 (arch/pjrc-8051/)
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/arch/arm/src/stm32/stm32_sdio.c b/arch/arm/src/stm32/stm32_sdio.c
index 3779efaf47..b23da9a05e 100644
--- a/arch/arm/src/stm32/stm32_sdio.c
+++ b/arch/arm/src/stm32/stm32_sdio.c
@@ -89,6 +89,10 @@
 #  define CONFIG_SDIO_DMAPRIO    DMA_CCR_PRIMED
 #endif
 
+#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_VERBOSE)
+#  undef CONFIG_SDIO_XFRDEBUG
+#endif
+
 /* Friendly CLKCR bit re-definitions ****************************************/
 
 #define SDIO_CLKCR_RISINGEDGE    (0)
@@ -147,7 +151,8 @@
 /* Event waiting interrupt mask bits */
 
 #define SDIO_CMDDONE_STA   (SDIO_STA_CMDSENT)
-#define SDIO_RESPDONE_STA  (SDIO_STA_CTIMEOUT|SDIO_STA_CCRCFAIL|SDIO_STA_CMDREND)
+#define SDIO_RESPDONE_STA  (SDIO_STA_CTIMEOUT|SDIO_STA_CCRCFAIL|\
+                            SDIO_STA_CMDREND)
 #define SDIO_XFRDONE_STA   (0)
 
 #define SDIO_CMDDONE_MASK  (SDIO_MASK_CMDSENTIE)
@@ -156,15 +161,18 @@
 #define SDIO_XFRDONE_MASK  (0)
 
 #define SDIO_CMDDONE_ICR   (SDIO_ICR_CMDSENTC)
-#define SDIO_RESPDONE_ICR  (SDIO_ICR_CTIMEOUTC|SDIO_ICR_CCRCFAILC|SDIO_ICR_CMDRENDC)
-#define SDIO_XFRDONE_ICR   (0)
+#define SDIO_RESPDONE_ICR  (SDIO_ICR_CTIMEOUTC|SDIO_ICR_CCRCFAILC|\
+                            SDIO_ICR_CMDRENDC)
+#define SDIO_XFRDONE_ICR   (SDIO_ICR_DATAENDC|SDIO_ICR_DCRCFAILC|\
+                            SDIO_ICR_DTIMEOUTC|SDIO_ICR_RXOVERRC|\
+                            SDIO_ICR_TXUNDERRC|SDIO_ICR_STBITERRC)
 
-#define SDIO_WAITALL_ICR   (SDIO_ICR_CMDSENTC|SDIO_ICR_CTIMEOUTC|\
-                            SDIO_ICR_CCRCFAILC|SDIO_ICR_CMDRENDC)
+#define SDIO_WAITALL_ICR   (SDIO_CMDDONE_ICR|SDIO_RESPDONE_ICR|\
+                            SDIO_XFRDONE_ICR)
 
 /* Register logging support */
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+#ifdef CONFIG_SDIO_XFRDEBUG
 #  if defined(CONFIG_DEBUG_DMA) && defined(CONFIG_SDIO_DMA)
 #    define SAMPLENDX_BEFORE_SETUP  0
 #    define SAMPLENDX_BEFORE_ENABLE 1
@@ -224,7 +232,7 @@ struct stm32_dev_s
 
 /* Register logging support */
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+#ifdef CONFIG_SDIO_XFRDEBUG
 struct stm32_sdioregs_s
 {
   ubyte  power;
@@ -265,7 +273,7 @@ static inline uint32 stm32_getpwrctrl(void);
 /* DMA Helpers **************************************************************/
 
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+#ifdef CONFIG_SDIO_XFRDEBUG
 static void   stm32_sampleinit(void);
 static void   stm32_sdiosample(struct stm32_sdioregs_s *regs);
 static void   stm32_sample(struct stm32_dev_s *priv, int index);
@@ -275,7 +283,7 @@ static void   stm32_dumpsample(struct stm32_dev_s *priv,
 static void   stm32_dumpsamples(struct stm32_dev_s *priv);
 #else
 #  define     stm32_sampleinit()
-#  define     smt32_sample(priv,index)
+#  define     stm32_sample(priv,index)
 #  define     stm32_dumpsamples(priv)
 #endif
 
@@ -394,7 +402,7 @@ struct stm32_dev_s g_sdiodev =
 
 /* Register logging support */
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+#ifdef CONFIG_SDIO_XFRDEBUG
 static struct stm32_sampleregs_s g_sampleregs[DEBUG_NSAMPLES];
 #endif
 
@@ -587,7 +595,7 @@ static inline uint32 stm32_getpwrctrl(void)
  *
  ****************************************************************************/
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+#ifdef CONFIG_SDIO_XFRDEBUG
 static void stm32_sampleinit(void)
 {
   memset(g_sampleregs, 0xff, DEBUG_NSAMPLES * sizeof(struct stm32_sampleregs_s));
@@ -602,7 +610,7 @@ static void stm32_sampleinit(void)
  *
  ****************************************************************************/
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+#ifdef CONFIG_SDIO_XFRDEBUG
 static void stm32_sdiosample(struct stm32_sdioregs_s *regs)
 {
   regs->power   = (ubyte)getreg32(STM32_SDIO_POWER);
@@ -625,7 +633,7 @@ static void stm32_sdiosample(struct stm32_sdioregs_s *regs)
  *
  ****************************************************************************/
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+#ifdef CONFIG_SDIO_XFRDEBUG
 static void stm32_sample(struct stm32_dev_s *priv, int index)
 {
   struct stm32_sampleregs_s *regs = &g_sampleregs[index];
@@ -647,7 +655,7 @@ static void stm32_sample(struct stm32_dev_s *priv, int index)
  *
  ****************************************************************************/
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+#ifdef CONFIG_SDIO_XFRDEBUG
 static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg)
 {
   fdbg("SDIO Registers: %s\n", msg);
@@ -671,7 +679,7 @@ static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg)
  *
  ****************************************************************************/
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+#ifdef CONFIG_SDIO_XFRDEBUG
 static void stm32_dumpsample(struct stm32_dev_s *priv,
                              struct stm32_sampleregs_s *regs, const char *msg)
 {
@@ -693,7 +701,7 @@ static void stm32_dumpsample(struct stm32_dev_s *priv,
  *
  ****************************************************************************/
 
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DEBUG_VERBOSE)
+#ifdef CONFIG_SDIO_XFRDEBUG
 static void  stm32_dumpsamples(struct stm32_dev_s *priv)
 {
   stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_SETUP], "Before setup");
@@ -1022,7 +1030,9 @@ static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent)
  * Name: stm32_endtransfer
  *
  * Description:
- *   Terminate a transfer with the provided status
+ *   Terminate a transfer with the provided status.  This function is called
+ *   only from the SDIO interrupt handler when end-of-transfer conditions
+ *   are detected.
  *
  * Input Parameters:
  *   priv   - An instance of the SDIO device interface
@@ -1042,6 +1052,10 @@ static void stm32_endtransfer(struct stm32_dev_s *priv, sdio_eventset_t wkupeven
 
   stm32_configxfrints(priv, 0);
 
+  /* Clearing pending interrupt status on all transfer related interrupts */
+ 
+  putreg32(SDIO_XFRDONE_ICR, STM32_SDIO_ICR);
+
   /* If this was a DMA transfer, make sure that DMA is stopped */
 
 #ifdef CONFIG_SDIO_DMA
@@ -1160,7 +1174,6 @@ static int stm32_interrupt(int irq, void *context)
 
               /* Then terminate the transfer */
 
-              putreg32(SDIO_ICR_DATAENDC, STM32_SDIO_ICR);
               stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE);
             }
 
@@ -1170,7 +1183,6 @@ static int stm32_interrupt(int irq, void *context)
             {
               /* Terminate the transfer with an error */
 
-              putreg32(SDIO_ICR_DCRCFAILC, STM32_SDIO_ICR);
               flldbg("ERROR: Data block CRC failure, remaining: %d\n", priv->remaining);
               stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_ERROR);
             }
@@ -1181,7 +1193,6 @@ static int stm32_interrupt(int irq, void *context)
             {
               /* Terminate the transfer with an error */
 
-              putreg32(SDIO_ICR_DTIMEOUTC, STM32_SDIO_ICR);
               flldbg("ERROR: Data timeout, remaining: %d\n", priv->remaining);
               stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT);
             }
@@ -1192,7 +1203,6 @@ static int stm32_interrupt(int irq, void *context)
             {
               /* Terminate the transfer with an error */
 
-              putreg32(SDIO_ICR_RXOVERRC, STM32_SDIO_ICR);
               flldbg("ERROR: RX FIFO overrun, remaining: %d\n", priv->remaining);
               stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_ERROR);
             }
@@ -1203,7 +1213,6 @@ static int stm32_interrupt(int irq, void *context)
             {
               /* Terminate the transfer with an error */
 
-              putreg32(SDIO_ICR_TXUNDERRC, STM32_SDIO_ICR);
               flldbg("ERROR: TX FIFO underrun, remaining: %d\n", priv->remaining);
               stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_ERROR);
             }
@@ -1214,7 +1223,6 @@ static int stm32_interrupt(int irq, void *context)
             {
               /* Terminate the transfer with an error */
 
-              putreg32(SDIO_ICR_STBITERRC, STM32_SDIO_ICR);
               flldbg("ERROR: Start bit, remaining: %d\n", priv->remaining);
               stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE|SDIOWAIT_ERROR);
            }
@@ -1668,6 +1676,12 @@ static int stm32_cancel(FAR struct sdio_dev_s *dev)
   stm32_configxfrints(priv, 0);
   stm32_configwaitints(priv, 0, 0, 0);
 
+  /* Clearing pending interrupt status on all transfer- and event- related
+   * interrupts
+   */
+ 
+  putreg32(SDIO_WAITALL_ICR, STM32_SDIO_ICR);
+
   /* Cancel any watchdog timeout */
 
   (void)wd_cancel(priv->waitwdog);
-- 
GitLab