This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

mmc_spi patch


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 <pigmon@mail.snd.co.jp>
+
+	* 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 <pigmon@mail.snd.co.jp>
 
 	* 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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]