summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2010-06-22 11:36:14 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2010-06-22 11:36:14 +0000
commit0596902ec8701ecfeec90828ba4f23dca48d3454 (patch)
tree3277f70177b2983d7646d34ae510f93e6f28401e /c
parent2010-06-22 Arnout Vandecappelle <arnout@mind.be> (diff)
downloadrtems-0596902ec8701ecfeec90828ba4f23dca48d3454.tar.bz2
2010-06-22 Arnout Vandecappelle <arnout@mind.be>
PR 1580/misc * libchip/i2c/spi-sd-card.c: Use bigger chunks and yield processor while waiting for read data.
Diffstat (limited to 'c')
-rw-r--r--c/src/ChangeLog6
-rw-r--r--c/src/libchip/i2c/spi-sd-card.c56
2 files changed, 38 insertions, 24 deletions
diff --git a/c/src/ChangeLog b/c/src/ChangeLog
index 61f5669538..2de3e8fe4d 100644
--- a/c/src/ChangeLog
+++ b/c/src/ChangeLog
@@ -1,5 +1,11 @@
2010-06-22 Arnout Vandecappelle <arnout@mind.be>
+ PR 1580/misc
+ * libchip/i2c/spi-sd-card.c: Use bigger chunks and yield processor
+ while waiting for read data.
+
+2010-06-22 Arnout Vandecappelle <arnout@mind.be>
+
PR 1579/misc
* libchip/i2c/spi-sd-card.c: Gradually increasing sleep times when
waiting for write to finish.
diff --git a/c/src/libchip/i2c/spi-sd-card.c b/c/src/libchip/i2c/spi-sd-card.c
index 3370fa3dd7..6f88b585d1 100644
--- a/c/src/libchip/i2c/spi-sd-card.c
+++ b/c/src/libchip/i2c/spi-sd-card.c
@@ -374,7 +374,7 @@ static int sd_card_wait( sd_card_driver_entry *e)
FIXME should actually look at R2W_FACTOR for non-HC cards. */
int retries = e->n_ac_max * 25 / 10;
/* n_ac_max/100 is supposed to be the average waiting time. To
- approximate this, we start with waiting n_ac_max/250 and
+ approximate this, we start with waiting n_ac_max/150 and
gradually increase the waiting time. */
int wait_time_bytes = (retries + 149) / 150;
while (e->busy) {
@@ -530,57 +530,65 @@ static int sd_card_read( sd_card_driver_entry *e, uint8_t start_token, uint8_t *
{
int rv = 0;
- /* Access time idle tokens */
- uint32_t n_ac = 1;
-
/* Discard command response */
int r = e->response_index + 1;
- /* Minimum token number before data start */
- int next_response_size = 2;
-
/* Standard response size */
int response_size = SD_CARD_COMMAND_SIZE;
+ /* Where the response is stored */
+ uint8_t *response = e->response;
+
/* Data input index */
int i = 0;
/* CRC check of data */
uint16_t crc16;
+ /* Maximum number of tokens to read. */
+ int retries = e->n_ac_max;
+
SD_CARD_INVALIDATE_RESPONSE_INDEX( e);
while (true) {
RTEMS_DEBUG_PRINT( "Search from %u to %u\n", r, response_size - 1);
/* Search the data start token in in current response buffer */
+ retries -= (response_size - r);
while (r < response_size) {
- RTEMS_DEBUG_PRINT( "Token [%02u]: 0x%02x\n", r, e->response [r]);
- if (n_ac > e->n_ac_max) {
- RTEMS_SYSLOG_ERROR( "Timeout\n");
- return -RTEMS_IO_ERROR;
- } else if (e->response [r] == start_token) {
+ RTEMS_DEBUG_PRINT( "Token [%02u]: 0x%02x\n", r, response [r]);
+ if (response [r] == start_token) {
/* Discard data start token */
++r;
goto sd_card_read_start;
- } else if (SD_CARD_IS_DATA_ERROR( e->response [r])) {
- RTEMS_SYSLOG_ERROR( "Data error token [%02i]: 0x%02" PRIx8 "\n", r, e->response [r]);
+ } else if (SD_CARD_IS_DATA_ERROR( response [r])) {
+ RTEMS_SYSLOG_ERROR( "Data error token [%02i]: 0x%02" PRIx8 "\n", r, response [r]);
return -RTEMS_IO_ERROR;
- } else if (e->response [r] != SD_CARD_IDLE_TOKEN) {
- RTEMS_SYSLOG_ERROR( "Unexpected token [%02i]: 0x%02" PRIx8 "\n", r, e->response [r]);
+ } else if (response [r] != SD_CARD_IDLE_TOKEN) {
+ RTEMS_SYSLOG_ERROR( "Unexpected token [%02i]: 0x%02" PRIx8 "\n", r, response [r]);
return -RTEMS_IO_ERROR;
}
- ++n_ac;
++r;
}
- /* Query more */
- rv = sd_card_query( e, e->response, next_response_size);
- RTEMS_CHECK_RV( rv, "Query data start token");
+ if (retries <= 0) {
+ RTEMS_SYSLOG_ERROR( "Timeout\n");
+ return -RTEMS_IO_ERROR;
+ }
- /* Set standard query size */
- response_size = next_response_size;
- next_response_size = SD_CARD_COMMAND_SIZE;
+ if (e->schedule_if_busy)
+ rtems_task_wake_after( RTEMS_YIELD_PROCESSOR);
+
+ /* Query more. We typically have to wait between 10 and 100
+ bytes. To reduce overhead, read the response in chunks of
+ 50 bytes - this doesn't introduce too much copy overhead
+ but does allow SPI DMA transfers to work efficiently. */
+ response = in;
+ response_size = 50;
+ if (response_size > n)
+ response_size = n;
+ rv = sd_card_query( e, response, response_size);
+ RTEMS_CHECK_RV( rv, "Query data start token");
/* Reset start position */
r = 0;
@@ -590,7 +598,7 @@ sd_card_read_start:
/* Read data */
while (r < response_size && i < n) {
- in [i++] = e->response [r++];
+ in [i++] = response [r++];
}
/* Read more data? */