Hello all,

This patch add latency of a re-try in BUSY being waiting
for after writing.
The timeout uses CSD register setting, and really calculated.

And "devs_disk_mmc.cdl" Just fixed a missed "}".

I tested it in TOSHIBA SD-M02G and Panasonic SDH512.
High capacity SD has the situation when BUSY is slow.

Thanks
Hajime Ishitani


Index: ecos/packages/devs/disk/generic/mmc/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/disk/generic/mmc/current/ChangeLog,v
retrieving revision 1.4
diff -u -r1.4 ChangeLog
--- ecos/packages/devs/disk/generic/mmc/current/ChangeLog       31 May 2007 
15:56:39 -0000      1.4
+++ ecos/packages/devs/disk/generic/mmc/current/ChangeLog       15 Jun 2007 
12:36:17 -0000
@@ -1,3 +1,9 @@
+2007-06-15  Hajime Ishitani <[EMAIL PROTECTED]>
+
+       * src/mmc_spi.c: Added latency of a re-try in BUSY being waiting
+       for after writing.
+       * cdl/devs_disk_mmc.cdl: Just fixed a missed "}". and kept paragraph.
+
 2007-05-30  Hajime Ishitani <[EMAIL PROTECTED]>
 
        * src/mmc_spi.c: Revise debug information with addition.
Index: ecos/packages/devs/disk/generic/mmc/current/cdl/devs_disk_mmc.cdl
===================================================================
RCS file: 
/cvs/ecos/ecos/packages/devs/disk/generic/mmc/current/cdl/devs_disk_mmc.cdl,v
retrieving revision 1.3
diff -u -r1.3 devs_disk_mmc.cdl
--- ecos/packages/devs/disk/generic/mmc/current/cdl/devs_disk_mmc.cdl   31 May 
2007 15:56:54 -0000      1.3
+++ ecos/packages/devs/disk/generic/mmc/current/cdl/devs_disk_mmc.cdl   15 Jun 
2007 12:36:17 -0000
@@ -65,48 +65,50 @@
        description "
             This option enables support for accessing an MMC card via an
             SPI bus."
-       
-       define_proc {
-           puts $::cdl_system_header "/***** MMC/SPI disk driver output start 
*****/"
+
+        define_proc {
+            puts $::cdl_system_header "/***** MMC/SPI disk driver output start 
*****/"
             puts $::cdl_system_header "#ifndef CYGDAT_DEVS_DISK_CFG"
-           puts $::cdl_system_header "#define CYGDAT_DEVS_DISK_CFG 
<pkgconf/devs_disk_mmc.h>"
+            puts $::cdl_system_header "#define CYGDAT_DEVS_DISK_CFG 
<pkgconf/devs_disk_mmc.h>"
             puts $::cdl_system_header "#endif"
-           puts $::cdl_system_header "/***** MMC/SPI disk driver output end 
*****/"
-       }
+            puts $::cdl_system_header "/***** MMC/SPI disk driver output end 
*****/"
+        }
+
+        cdl_option CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME {
+            display        "Device name for the MMC/SPI disk 0 device"
+            flavor        data
+            default_value    { "\"/dev/hd0/\"" }
+            description "
+                    This is the device name used to access the raw disk device
+                    in eCos, for example for mount operations. Note that the
+                    trailing slash must be present."
+
+            # Testing support. For now just hard-code some values for 
partition 0
+            # on the card.
+            define_proc {
+            puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_DEVICE 
CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME \"1\""
+            puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_MOUNTPOINT 
\"/dosfs\""
+            puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_DIRECTORY  
\"/test\""
+            }
+        }
+
+        cdl_option CYGIMP_DEVS_DISK_MMC_SPI_POLLED {
+            display        "Run the driver in polled mode rather than 
interrupt-driven"
+            default_value    !CYGPKG_KERNEL
+            description "
+                    By default the MMC disk driver will operate in 
interrupt-driven
+                    mode if the kernel is present, i.e. if the application is 
likely
+                    to be multi-threaded. Otherwise it will operate in polled 
mode."
+        }
 
-       cdl_option CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME {
-           display             "Device name for the MMC/SPI disk 0 device"
-           flavor              data
-           default_value       { "\"/dev/hd0/\"" }
-           description "
-                This is the device name used to access the raw disk device
-                in eCos, for example for mount operations. Note that the
-                trailing slash must be present."
-
-           # Testing support. For now just hard-code some values for partition 0
-           # on the card.
-           define_proc {
-               puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_DEVICE 
CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME \"1\""
-               puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_MOUNTPOINT 
\"/dosfs\""
-               puts $::cdl_header "#define CYGDAT_DEVS_DISK_TEST_DIRECTORY  
\"/test\""
-           }
-       }
-       
-       cdl_option CYGIMP_DEVS_DISK_MMC_SPI_POLLED {
-           display             "Run the driver in polled mode rather than 
interrupt-driven"
-           default_value       !CYGPKG_KERNEL
-           description "
-                By default the MMC disk driver will operate in interrupt-driven
-                mode if the kernel is present, i.e. if the application is 
likely
-                to be multi-threaded. Otherwise it will operate in polled 
mode."
-       }
-    cdl_option CYGPKG_DEVS_DISK_MMC_SPI_IDLE_RETRIES_WAIT {
-        display          "Idle to operational retry wait"
-        flavor           booldata
-        default_value    10000
-        description      "
-            This option sets how long to wait between retries of attempts to 
change the
-            card state from idle to operational. It is measured in 
microseconds."
+        cdl_option CYGPKG_DEVS_DISK_MMC_SPI_IDLE_RETRIES_WAIT {
+            display          "Idle to operational retry wait"
+            flavor           booldata
+            default_value    10000
+            description      "
+                This option sets how long to wait between retries of attempts 
to change the
+                card state from idle to operational. It is measured in 
microseconds."
+        }
     }
 }
 
Index: ecos/packages/devs/disk/generic/mmc/current/src/mmc_spi.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/disk/generic/mmc/current/src/mmc_spi.c,v
retrieving revision 1.3
diff -u -r1.3 mmc_spi.c
--- ecos/packages/devs/disk/generic/mmc/current/src/mmc_spi.c   31 May 2007 
15:56:39 -0000      1.3
+++ ecos/packages/devs/disk/generic/mmc/current/src/mmc_spi.c   15 Jun 2007 
12:36:27 -0000
@@ -176,6 +176,7 @@
     cyg_uint32          mmc_sectors_per_head;
     cyg_uint32          mmc_read_block_length;
     cyg_uint32          mmc_write_block_length;
+    cyg_uint32          mmc_write_busy_delay;
     mmc_cid_register    mmc_id;
 } cyg_mmc_spi_disk_info_t;
 
@@ -506,6 +507,7 @@
     for (i = 0; (i < MMC_SPI_WRITE_BUSY_RETRIES) && (0x00 == extra[0]); i++) {
         cyg_spi_transaction_transfer(dev, cyg_mmc_spi_polled, 1, 
mmc_spi_ff_data, extra, 0);
         DEBUG2("mmc_spi_write_disk_block(), polling for ! busy, got response 
%02x\n", extra[0]);
+        CYGACC_CALL_IF_DELAY_US( disk->mmc_write_busy_delay );
     }
 #endif
     
@@ -542,6 +544,7 @@
     cyg_uint32          reply;
     Cyg_ErrNo           code;
     mmc_csd_register    csd;
+    cyg_uint32          taac_speed;
 
 #ifdef MMC_SPI_BACKGROUND_WRITES    
     // If we have unmounted a disk and are remounting it, assume that
@@ -649,7 +652,21 @@
            csd.csd_data[ 4], csd.csd_data[ 5], csd.csd_data[ 6], 
csd.csd_data[7],                           \
            csd.csd_data[ 8], csd.csd_data[ 9], csd.csd_data[10], 
csd.csd_data[11],                          \
            csd.csd_data[12], csd.csd_data[13], csd.csd_data[14], 
csd.csd_data[15]);
-    
+    {
+        static cyg_uint32 taac_mantissa_speeds_x10[16]   = { 0, 10, 12, 13, 
15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
+        static cyg_uint32 taac_exponent_speeds_div10[8]  = { 10, 100, 1000, 
10000, 100000, 1000000, 10000000, 100000000 };
+        static cyg_uint32 r2w_factor_val[8]  = { 1, 2, 4, 8, 16, 32, 0, 0 };
+        cyg_uint32 nsac_time, retry_delay;
+
+        taac_speed = 
taac_mantissa_speeds_x10[MMC_CSD_REGISTER_TAAC_MANTISSA(&csd)] *
+                     
taac_exponent_speeds_div10[MMC_CSD_REGISTER_TAAC_EXPONENT(&csd)];
+        taac_speed /= 100;
+
+        nsac_time = MMC_CSD_REGISTER_NSAC(&csd) != 0 ? 10000000 / 
MMC_CSD_REGISTER_NSAC(&csd): 0;
+        retry_delay  = ( taac_speed + nsac_time ) * 
r2w_factor_val[MMC_CSD_REGISTER_R2W_FACTOR(&csd)];
+        disk->mmc_write_busy_delay = retry_delay / 1000000;
+    }
+
     // Optionally dump the whole CSD register. This takes a lot of
     // code but gives a lot of info about the card. If the info looks
     // correct then we really are interacting properly with an MMC card.
@@ -690,18 +707,15 @@
     }
     DEBUG1("        : WR_BL_LEN block length 2^%d (%d)\n", \
            MMC_CSD_REGISTER_WRITE_BL_LEN(&csd), 0x01 << 
MMC_CSD_REGISTER_WRITE_BL_LEN(&csd));
-    {
-        static cyg_uint32 taac_mantissa_speeds_x10[16]   = { 0, 10, 12, 13, 
15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
-        static cyg_uint32 taac_exponent_speeds_div10[8]  = { 10, 100, 1000, 
10000, 100000, 1000000, 10000000, 100000000 };
-        cyg_uint32 taac_speed = 
taac_mantissa_speeds_x10[MMC_CSD_REGISTER_TAAC_MANTISSA(&csd)] *
-            taac_exponent_speeds_div10[MMC_CSD_REGISTER_TAAC_EXPONENT(&csd)];
-        taac_speed /= 100;
-        DEBUG1("        : asynchronous read access time TAAC %d %d -> %d 
ns\n", \
-               MMC_CSD_REGISTER_TAAC_MANTISSA(&csd), 
MMC_CSD_REGISTER_TAAC_EXPONENT(&csd), taac_speed);
-    }
+    DEBUG1("        : asynchronous read access time TAAC %d %d -> %d ns\n", \
+           MMC_CSD_REGISTER_TAAC_MANTISSA(&csd), 
MMC_CSD_REGISTER_TAAC_EXPONENT(&csd), taac_speed);
     DEBUG1("        : synchronous read access time NSAC %d * 100 cycles\n", \
            MMC_CSD_REGISTER_NSAC(&csd));
-    DEBUG1("        : typical write program time %d * read time\n", 
MMC_CSD_REGISTER_R2W_FACTOR(&csd));
+    {
+        static char *r2w_factor_tbl[8]  = { "1", "2", "4", "8", "16", "32", 
"unknown(reserved)", "unknown(reserved)" };
+        DEBUG1("        : typical write program time %d -> %s * read time\n", \
+           MMC_CSD_REGISTER_R2W_FACTOR(&csd), 
r2w_factor_tbl[MMC_CSD_REGISTER_R2W_FACTOR(&csd)]);
+    }
     DEBUG1("        : CCC command classes 0x%04x\n", 
MMC_CSD_REGISTER_CCC(&csd));
     DEBUG1("        : READ_BL_PARTIAL %d, WRITE_BLK_MISALIGN %d, 
READ_BLK_MISALIGN %d, DSR_IMP %d\n",   \
            MMC_CSD_REGISTER_READ_BL_PARTIAL(&csd), 
MMC_CSD_REGISTER_WRITE_BLK_MISALIGN(&csd),           \
@@ -728,6 +742,8 @@
     DEBUG1("        : crc 0x%08x\n", MMC_CSD_REGISTER_CRC(&csd));
 #endif                
 
+    DEBUG1("Write retry delay time %dus\n", disk->mmc_write_busy_delay );
+
     // There is information available about the file format, e.g.
     // partitioned vs. simple FAT. With the current version of the
     // generic disk code this needs to be known statically, via

Reply via email to