SDFileSystem

Dependencies:   FATFileSystem

Dependents:   WavePlayer_HelloWorld CAN_LOG_SD SDCard GPSLogger ... more

mbed 2 and mbed OS 5

This is an mbed 2 library. For mbed-os files system functionality, please see the File System documentation.

Files at this revision

API Documentation at this revision

Comitter:
maclobdell
Date:
Wed Aug 24 02:51:06 2016 +0000
Parent:
3:7b35d1709458
Child:
5:8a6740f6c555
Commit message:
Pull in updates for 'FATFileSystem -Fixed API integer widths'. Synchronizes with https://github.com/ARMmbed/mbed-os/commit/bee1c953f03a0e4f6a4c397e97409076516614a4#diff-79708982e17fde53fd51da54fda17b32

Changed in this revision

FATFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.cpp Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.h Show annotated file Show diff for this revision Revisions of this file
--- a/FATFileSystem.lib	Mon Mar 17 14:34:01 2014 +0000
+++ b/FATFileSystem.lib	Wed Aug 24 02:51:06 2016 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/FATFileSystem/#e960e2b81a3c
+https://developer.mbed.org/teams/mbed-official/code/FATFileSystem/#073c375847a5
--- 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
--- a/SDFileSystem.h	Mon Mar 17 14:34:01 2014 +0000
+++ b/SDFileSystem.h	Wed Aug 24 02:51:06 2016 +0000
@@ -32,14 +32,13 @@
  * #include "mbed.h"
  * #include "SDFileSystem.h"
  *
- * SDFileSystem sd(p5, p6, p7, p12, "sd"); // MOSI, MISO, SCLK, SSEL
- *  
+ * SDFileSystem sd(p5, p6, p7, p12, "sd"); // mosi, miso, sclk, cs
+ *
  * int main() {
- *     FILE *fp = fopen("/sd/mbed.txt", "w");
+ *     FILE *fp = fopen("/sd/myfile.txt", "w");
  *     fprintf(fp, "Hello World!\n");
  *     fclose(fp);
  * }
- * @endcode
  */
 class SDFileSystem : public FATFileSystem {
 public:
@@ -53,13 +52,12 @@
      * @param name The name used to access the virtual filesystem
      */
     SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name);
-    
     virtual int disk_initialize();
     virtual int disk_status();
-    virtual int disk_read(uint8_t * buffer, uint64_t block_number);
-    virtual int disk_write(const uint8_t * buffer, uint64_t block_number);
+    virtual int disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count);
+    virtual int disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count);
     virtual int disk_sync();
-    virtual uint64_t disk_sectors();
+    virtual uint32_t disk_sectors();
 
 protected:
 
@@ -70,15 +68,22 @@
     int initialise_card();
     int initialise_card_v1();
     int initialise_card_v2();
-    
+
     int _read(uint8_t * buffer, uint32_t length);
     int _write(const uint8_t *buffer, uint32_t length);
-    uint64_t _sd_sectors();
-    uint64_t _sectors;
-    
+    uint32_t _sd_sectors();
+    uint32_t _sectors;
+
+    void set_init_sck(uint32_t sck) { _init_sck = sck; }
+    // Note: The highest SPI clock rate is 20 MHz for MMC and 25 MHz for SD
+    void set_transfer_sck(uint32_t sck) { _transfer_sck = sck; }
+    uint32_t _init_sck;
+    uint32_t _transfer_sck;
+
     SPI _spi;
     DigitalOut _cs;
     int cdv;
+    int _is_initialized;
 };
 
-#endif
+#endif
\ No newline at end of file