diff --git a/features/filesystem/sd/SDBlockDevice.cpp b/features/filesystem/sd/SDBlockDevice.cpp index 911f80f908..127695df5d 100644 --- a/features/filesystem/sd/SDBlockDevice.cpp +++ b/features/filesystem/sd/SDBlockDevice.cpp @@ -148,9 +148,7 @@ #include "mbed_debug.h" #define SD_COMMAND_TIMEOUT 5000 /*!< Number of times to query card for correct result */ -#define SD_CMD0_GO_IDLE_STATE_RETRIES 3 /*!< Number of retries for sending CMDO*/ -#define SD_CMD0_GO_IDLE_STATE 0x00 /*!< CMD0 code value */ -#define SD_CMD0_INVALID_RESPONSE_TIMEOUT -1 /*!< CMD0 received invalid responses and timed out */ +#define SD_CMD0_GO_IDLE_STATE_RETRIES 5 /*!< Number of retries for sending CMDO */ #define SD_DBG 1 #define SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */ @@ -251,9 +249,12 @@ SDBlockDevice::~SDBlockDevice() int SDBlockDevice::_initialise_card() { _dbg = SD_DBG; + + // Initialize the SPI interface: Card by default is in SD mode _spi_init(); - /* Transition from SD Card mode to SPI mode by sending CMD0 GO_IDLE_STATE command */ + // The card is transitioned from SDCard mode to SPI mode by sending the + // CMD0 (GO_IDLE_STATE) command with CS asserted if (_go_idle_state() != R1_IDLE_STATE) { debug_if(_dbg, "No disk, or could not put SD card in to SPI idle state\n"); return SD_BLOCK_DEVICE_ERROR_NO_DEVICE; @@ -572,40 +573,21 @@ int SDBlockDevice::_cmd8() { _deselect(); return -1; // timeout } +uint32_t SDBlockDevice::_go_idle_state() { + uint32_t response; -int SDBlockDevice::_go_idle_state() { - int cmd_arg = 0; /* CMD0 argument is just "stuff bits" */ - int ret = SD_CMD0_INVALID_RESPONSE_TIMEOUT; - - _select(); /* Reseting the MCU SPI master may not reset the on-board SDCard, in which * case when MCU power-on occurs the SDCard will resume operations as * though there was no reset. In this scenario the first CMD0 will * not be interpreted as a command and get lost. For some cards retrying * the command overcomes this situation. */ - for (int num_retries = 0; ret != R1_IDLE_STATE && (num_retries < SD_CMD0_GO_IDLE_STATE_RETRIES); num_retries++) { - /* send a CMD0 */ - _spi.write(0x40 | SD_CMD0_GO_IDLE_STATE); - _spi.write(cmd_arg >> 24); - _spi.write(cmd_arg >> 16); - _spi.write(cmd_arg >> 8); - _spi.write(cmd_arg >> 0); - _spi.write(0x95); - - /* wait for the R1_IDLE_STATE response */ - for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { - int response = _spi.write(0xFF); - /* Explicitly check for the R1_IDLE_STATE response rather that most significant bit - * being 0 because invalid data can be returned. */ - if ((response == R1_IDLE_STATE)) { - ret = response; - break; - } - wait_ms(1); - } + for (int i = 0; i < SD_CMD0_GO_IDLE_STATE_RETRIES; i++) { + _cmd(CMD0_GO_IDLE_STATE, 0, &response); + if (R1_IDLE_STATE == response) + break; + wait_ms(1); } - _deselect(); - return ret; + return response; } int SDBlockDevice::_read(uint8_t *buffer, uint32_t length) { @@ -733,7 +715,6 @@ void SDBlockDevice::_spi_init() { _spi.unlock(); } - void SDBlockDevice::_select() { _spi.lock(); _cs = 0; diff --git a/features/filesystem/sd/SDBlockDevice.h b/features/filesystem/sd/SDBlockDevice.h index f36360737a..8272368dd5 100644 --- a/features/filesystem/sd/SDBlockDevice.h +++ b/features/filesystem/sd/SDBlockDevice.h @@ -179,11 +179,10 @@ private: * "SPI Startup" section of the comments at the head of the * implementation file for further details and specification references. * - * @return -1 if an error occurred e.g. a valid response was not - * received. Otherwise R1_IDLE_STATE (0x1), the successful - * response from CMD0. + * @return Response form the card. R1_IDLE_STATE (0x1), the successful + * response from CMD0. R1_XXX_XXX for more response */ - int _go_idle_state(); + uint32_t _go_idle_state(); int _initialise_card(); int _initialise_card_v1(); int _initialise_card_v2();