Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SDFileSystem by
Diff: SDFileSystem.cpp
- Revision:
- 4:3f40cbfe801c
- Parent:
- 3:7b35d1709458
diff -r 7b35d1709458 -r 3f40cbfe801c SDFileSystem.cpp --- a/SDFileSystem.cpp Mon Mar 17 14:34:01 2014 +0000 +++ b/SDFileSystem.cpp Wed Aug 24 02:51:06 2016 +0000 @@ -19,7 +19,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - /* Introduction * ------------ * SD and MMC cards support a number of interfaces, but common to them all @@ -121,8 +120,12 @@ #define SD_DBG 0 SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) : - FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs) { + FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0) { _cs = 1; + + // Set default to 100kHz for initialisation and 1MHz for data transfer + _init_sck = 100000; + _transfer_sck = 1000000; } #define R1_IDLE_STATE (1 << 0) @@ -134,25 +137,29 @@ #define R1_PARAMETER_ERROR (1 << 6) // Types -#define SDCARD_FAIL 0 //!< v1.x Standard Capacity -#define SDCARD_V1 1 //!< v2.x Standard Capacity -#define SDCARD_V2 2 //!< v2.x High Capacity -#define SDCARD_V2HC 3 //!< Not recognised as an SD Card +// - v1.x Standard Capacity +// - v2.x Standard Capacity +// - v2.x High Capacity +// - Not recognised as an SD Card +#define SDCARD_FAIL 0 +#define SDCARD_V1 1 +#define SDCARD_V2 2 +#define SDCARD_V2HC 3 int SDFileSystem::initialise_card() { - // Set to 100kHz for initialisation, and clock card with cs = 1 - _spi.frequency(100000); + // Set to SCK for initialisation, and clock card with cs = 1 + _spi.frequency(_init_sck); _cs = 1; for (int i = 0; i < 16; i++) { _spi.write(0xFF); } - + // send CMD0, should return with all zeros except IDLE STATE set (bit 0) if (_cmd(0, 0) != R1_IDLE_STATE) { debug("No disk, or could not put SD card in to SPI idle state\n"); return SDCARD_FAIL; } - + // send CMD8 to determine whther it is ver 2.x int r = _cmd8(); if (r == R1_IDLE_STATE) { @@ -174,7 +181,7 @@ return SDCARD_V1; } } - + debug("Timeout waiting for v1.x card\n"); return SDCARD_FAIL; } @@ -191,57 +198,86 @@ return SDCARD_V2; } } - + debug("Timeout waiting for v2.x card\n"); return SDCARD_FAIL; } int SDFileSystem::disk_initialize() { - int i = initialise_card(); - debug_if(SD_DBG, "init card = %d\n", i); + _is_initialized = initialise_card(); + if (_is_initialized == 0) { + debug("Fail to initialize card\n"); + return 1; + } + debug_if(SD_DBG, "init card = %d\n", _is_initialized); _sectors = _sd_sectors(); - + // Set block length to 512 (CMD16) if (_cmd(16, 512) != 0) { debug("Set 512-byte block timed out\n"); return 1; } + + // Set SCK for data transfer + _spi.frequency(_transfer_sck); + return 0; +} + +int SDFileSystem::disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count) { + if (!_is_initialized) { + return -1; + } - _spi.frequency(1000000); // Set to 1MHz for data transfer + for (uint32_t b = block_number; b < block_number + count; b++) { + // set write address for single block (CMD24) + if (_cmd(24, b * cdv) != 0) { + return 1; + } + + // send the data block + _write(buffer, 512); + buffer += 512; + } + return 0; } -int SDFileSystem::disk_write(const uint8_t *buffer, uint64_t block_number) { - // set write address for single block (CMD24) - if (_cmd(24, block_number * cdv) != 0) { - return 1; +int SDFileSystem::disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count) { + if (!_is_initialized) { + return -1; } - // send the data block - _write(buffer, 512); + for (uint32_t b = block_number; b < block_number + count; b++) { + // set read address for single block (CMD17) + if (_cmd(17, b * cdv) != 0) { + return 1; + } + + // receive the data + _read(buffer, 512); + buffer += 512; + } + return 0; } -int SDFileSystem::disk_read(uint8_t *buffer, uint64_t block_number) { - // set read address for single block (CMD17) - if (_cmd(17, block_number * cdv) != 0) { +int SDFileSystem::disk_status() { + // FATFileSystem::disk_status() returns 0 when initialized + if (_is_initialized) { + return 0; + } else { return 1; } - - // receive the data - _read(buffer, 512); - return 0; } -int SDFileSystem::disk_status() { return 0; } int SDFileSystem::disk_sync() { return 0; } -uint64_t SDFileSystem::disk_sectors() { return _sectors; } +uint32_t SDFileSystem::disk_sectors() { return _sectors; } // PRIVATE FUNCTIONS int SDFileSystem::_cmd(int cmd, int arg) { _cs = 0; - + // send a command _spi.write(0x40 | cmd); _spi.write(arg >> 24); @@ -249,7 +285,7 @@ _spi.write(arg >> 8); _spi.write(arg >> 0); _spi.write(0x95); - + // wait for the repsonse (response[7] == 0) for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { int response = _spi.write(0xFF); @@ -265,7 +301,7 @@ } int SDFileSystem::_cmdx(int cmd, int arg) { _cs = 0; - + // send a command _spi.write(0x40 | cmd); _spi.write(arg >> 24); @@ -273,7 +309,7 @@ _spi.write(arg >> 8); _spi.write(arg >> 0); _spi.write(0x95); - + // wait for the repsonse (response[7] == 0) for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { int response = _spi.write(0xFF); @@ -290,7 +326,7 @@ int SDFileSystem::_cmd58() { _cs = 0; int arg = 0; - + // send a command _spi.write(0x40 | 58); _spi.write(arg >> 24); @@ -298,7 +334,7 @@ _spi.write(arg >> 8); _spi.write(arg >> 0); _spi.write(0x95); - + // wait for the repsonse (response[7] == 0) for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { int response = _spi.write(0xFF); @@ -319,7 +355,7 @@ int SDFileSystem::_cmd8() { _cs = 0; - + // send a command _spi.write(0x40 | 8); // CMD8 _spi.write(0x00); // reserved @@ -327,7 +363,7 @@ _spi.write(0x01); // 3.3v _spi.write(0xAA); // check pattern _spi.write(0x87); // crc - + // wait for the repsonse (response[7] == 0) for (int i = 0; i < SD_COMMAND_TIMEOUT * 1000; i++) { char response[5]; @@ -348,17 +384,17 @@ int SDFileSystem::_read(uint8_t *buffer, uint32_t length) { _cs = 0; - + // read until start byte (0xFF) while (_spi.write(0xFF) != 0xFE); - + // read data - for (int i = 0; i < length; i++) { + for (uint32_t i = 0; i < length; i++) { buffer[i] = _spi.write(0xFF); } _spi.write(0xFF); // checksum _spi.write(0xFF); - + _cs = 1; _spi.write(0xFF); return 0; @@ -366,29 +402,29 @@ int SDFileSystem::_write(const uint8_t*buffer, uint32_t length) { _cs = 0; - + // indicate start of block _spi.write(0xFE); - + // write the data - for (int i = 0; i < length; i++) { + for (uint32_t i = 0; i < length; i++) { _spi.write(buffer[i]); } - + // write the checksum _spi.write(0xFF); _spi.write(0xFF); - + // check the response token if ((_spi.write(0xFF) & 0x1F) != 0x05) { _cs = 1; _spi.write(0xFF); return 1; } - + // wait for write to finish while (_spi.write(0xFF) == 0); - + _cs = 1; _spi.write(0xFF); return 0; @@ -397,7 +433,7 @@ static uint32_t ext_bits(unsigned char *data, int msb, int lsb) { uint32_t bits = 0; uint32_t size = 1 + msb - lsb; - for (int i = 0; i < size; i++) { + for (uint32_t i = 0; i < size; i++) { uint32_t position = lsb + i; uint32_t byte = 15 - (position >> 3); uint32_t bit = position & 0x7; @@ -407,38 +443,38 @@ return bits; } -uint64_t SDFileSystem::_sd_sectors() { +uint32_t SDFileSystem::_sd_sectors() { uint32_t c_size, c_size_mult, read_bl_len; uint32_t block_len, mult, blocknr, capacity; uint32_t hc_c_size; - uint64_t blocks; - + uint32_t blocks; + // CMD9, Response R2 (R1 byte + 16-byte block read) if (_cmdx(9, 0) != 0) { debug("Didn't get a response from the disk\n"); return 0; } - + uint8_t csd[16]; if (_read(csd, 16) != 0) { debug("Couldn't read csd response from disk\n"); return 0; } - + // csd_structure : csd[127:126] // c_size : csd[73:62] // c_size_mult : csd[49:47] // read_bl_len : csd[83:80] - the *maximum* read block length - + int csd_structure = ext_bits(csd, 127, 126); - + switch (csd_structure) { case 0: cdv = 512; c_size = ext_bits(csd, 73, 62); c_size_mult = ext_bits(csd, 49, 47); read_bl_len = ext_bits(csd, 83, 80); - + block_len = 1 << read_bl_len; mult = 1 << (c_size_mult + 2); blocknr = (c_size + 1) * mult; @@ -446,17 +482,17 @@ blocks = capacity / 512; debug_if(SD_DBG, "\n\rSDCard\n\rc_size: %d \n\rcapacity: %ld \n\rsectors: %lld\n\r", c_size, capacity, blocks); break; - + case 1: cdv = 1; hc_c_size = ext_bits(csd, 63, 48); blocks = (hc_c_size+1)*1024; debug_if(SD_DBG, "\n\rSDHC Card \n\rhc_c_size: %d\n\rcapacity: %lld \n\rsectors: %lld\n\r", hc_c_size, blocks*512, blocks); break; - + default: debug("CSD struct unsupported\r\n"); return 0; }; return blocks; -} +} \ No newline at end of file