This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
mmc_spi patch
- From: Hajime Ishitani <pigmon at snd dot co dot jp>
- To: ecos-patches at sources dot redhat dot com
- Date: Fri, 15 Jun 2007 22:24:45 +0900
- Subject: 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