mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-13 11:25:24 +08:00
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.
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
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>
|
2010-06-22 Arnout Vandecappelle <arnout@mind.be>
|
||||||
|
|
||||||
PR 1579/misc
|
PR 1579/misc
|
||||||
|
|||||||
@@ -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. */
|
FIXME should actually look at R2W_FACTOR for non-HC cards. */
|
||||||
int retries = e->n_ac_max * 25 / 10;
|
int retries = e->n_ac_max * 25 / 10;
|
||||||
/* n_ac_max/100 is supposed to be the average waiting time. To
|
/* 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. */
|
gradually increase the waiting time. */
|
||||||
int wait_time_bytes = (retries + 149) / 150;
|
int wait_time_bytes = (retries + 149) / 150;
|
||||||
while (e->busy) {
|
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;
|
int rv = 0;
|
||||||
|
|
||||||
/* Access time idle tokens */
|
|
||||||
uint32_t n_ac = 1;
|
|
||||||
|
|
||||||
/* Discard command response */
|
/* Discard command response */
|
||||||
int r = e->response_index + 1;
|
int r = e->response_index + 1;
|
||||||
|
|
||||||
/* Minimum token number before data start */
|
|
||||||
int next_response_size = 2;
|
|
||||||
|
|
||||||
/* Standard response size */
|
/* Standard response size */
|
||||||
int response_size = SD_CARD_COMMAND_SIZE;
|
int response_size = SD_CARD_COMMAND_SIZE;
|
||||||
|
|
||||||
|
/* Where the response is stored */
|
||||||
|
uint8_t *response = e->response;
|
||||||
|
|
||||||
/* Data input index */
|
/* Data input index */
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
/* CRC check of data */
|
/* CRC check of data */
|
||||||
uint16_t crc16;
|
uint16_t crc16;
|
||||||
|
|
||||||
|
/* Maximum number of tokens to read. */
|
||||||
|
int retries = e->n_ac_max;
|
||||||
|
|
||||||
SD_CARD_INVALIDATE_RESPONSE_INDEX( e);
|
SD_CARD_INVALIDATE_RESPONSE_INDEX( e);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
RTEMS_DEBUG_PRINT( "Search from %u to %u\n", r, response_size - 1);
|
RTEMS_DEBUG_PRINT( "Search from %u to %u\n", r, response_size - 1);
|
||||||
|
|
||||||
/* Search the data start token in in current response buffer */
|
/* Search the data start token in in current response buffer */
|
||||||
|
retries -= (response_size - r);
|
||||||
while (r < response_size) {
|
while (r < response_size) {
|
||||||
RTEMS_DEBUG_PRINT( "Token [%02u]: 0x%02x\n", r, e->response [r]);
|
RTEMS_DEBUG_PRINT( "Token [%02u]: 0x%02x\n", r, response [r]);
|
||||||
if (n_ac > e->n_ac_max) {
|
if (response [r] == start_token) {
|
||||||
RTEMS_SYSLOG_ERROR( "Timeout\n");
|
|
||||||
return -RTEMS_IO_ERROR;
|
|
||||||
} else if (e->response [r] == start_token) {
|
|
||||||
/* Discard data start token */
|
/* Discard data start token */
|
||||||
++r;
|
++r;
|
||||||
goto sd_card_read_start;
|
goto sd_card_read_start;
|
||||||
} else if (SD_CARD_IS_DATA_ERROR( e->response [r])) {
|
} else if (SD_CARD_IS_DATA_ERROR( response [r])) {
|
||||||
RTEMS_SYSLOG_ERROR( "Data error token [%02i]: 0x%02" PRIx8 "\n", r, e->response [r]);
|
RTEMS_SYSLOG_ERROR( "Data error token [%02i]: 0x%02" PRIx8 "\n", r, response [r]);
|
||||||
return -RTEMS_IO_ERROR;
|
return -RTEMS_IO_ERROR;
|
||||||
} else if (e->response [r] != SD_CARD_IDLE_TOKEN) {
|
} else if (response [r] != SD_CARD_IDLE_TOKEN) {
|
||||||
RTEMS_SYSLOG_ERROR( "Unexpected token [%02i]: 0x%02" PRIx8 "\n", r, e->response [r]);
|
RTEMS_SYSLOG_ERROR( "Unexpected token [%02i]: 0x%02" PRIx8 "\n", r, response [r]);
|
||||||
return -RTEMS_IO_ERROR;
|
return -RTEMS_IO_ERROR;
|
||||||
}
|
}
|
||||||
++n_ac;
|
|
||||||
++r;
|
++r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Query more */
|
if (retries <= 0) {
|
||||||
rv = sd_card_query( e, e->response, next_response_size);
|
RTEMS_SYSLOG_ERROR( "Timeout\n");
|
||||||
RTEMS_CHECK_RV( rv, "Query data start token");
|
return -RTEMS_IO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set standard query size */
|
if (e->schedule_if_busy)
|
||||||
response_size = next_response_size;
|
rtems_task_wake_after( RTEMS_YIELD_PROCESSOR);
|
||||||
next_response_size = SD_CARD_COMMAND_SIZE;
|
|
||||||
|
/* 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 */
|
/* Reset start position */
|
||||||
r = 0;
|
r = 0;
|
||||||
@@ -590,7 +598,7 @@ sd_card_read_start:
|
|||||||
|
|
||||||
/* Read data */
|
/* Read data */
|
||||||
while (r < response_size && i < n) {
|
while (r < response_size && i < n) {
|
||||||
in [i++] = e->response [r++];
|
in [i++] = response [r++];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read more data? */
|
/* Read more data? */
|
||||||
|
|||||||
Reference in New Issue
Block a user