prueba sd card

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
fabeltranm
Date:
Tue Apr 17 23:34:09 2018 +0000
Commit message:
sdcard

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 9b6d6fa5c401 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Apr 17 23:34:09 2018 +0000
@@ -0,0 +1,232 @@
+#include "mbed.h"
+ /* SPI Command Format
+ * ------------------
+ * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC.
+ *
+ * +---------------+------------+------------+-----------+----------+--------------+
+ * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 |
+ * +---------------+------------+------------+-----------+----------+--------------+
+ *
+ * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95)
+ *
+ * All Application Specific commands shall be preceded with APP_CMD (CMD55).
+ *
+ * SPI Response Format
+ * -------------------
+ * The main response format (R1) is a status byte (normally zero). Key flags:
+ *  idle - 1 if the card is in an idle state/initialising
+ *  cmd  - 1 if an illegal command code was detected
+ *
+ *    +-------------------------------------------------+
+ * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle |
+ *    +-------------------------------------------------+
+ *
+ * R1b is the same, except it is followed by a busy signal (zeros) until
+ * the first non-zero byte when it is ready again.
+ *
+ * Data Response Token
+ * -------------------
+ * Every data block written to the card is acknowledged by a byte
+ * response token
+ *
+ * +----------------------+
+ * | xxx | 0 | status | 1 |
+ * +----------------------+
+ *              010 - OK!
+ *              101 - CRC Error
+ *              110 - Write Error
+ *
+ * Single Block Read and Write
+ * ---------------------------
+ *
+ * Block transfers have a byte header, followed by the data, followed
+ * by a 16-bit CRC. In our case, the data will always be 512 bytes.
+ *
+ * +------+---------+---------+- -  - -+---------+-----------+----------+
+ * | 0xFE | data[0] | data[1] |        | data[n] | crc[15:8] | crc[7:0] |
+ * +------+---------+---------+- -  - -+---------+-----------+----------+
+ */
+
+
+#define SD_COMMAND_TIMEOUT 5000
+
+#define R1_IDLE_STATE           (1 << 0)
+#define R1_ERASE_RESET          (1 << 1)
+#define R1_ILLEGAL_COMMAND      (1 << 2)
+#define R1_COM_CRC_ERROR        (1 << 3)
+#define R1_ERASE_SEQUENCE_ERROR (1 << 4)
+#define R1_ADDRESS_ERROR        (1 << 5)
+#define R1_PARAMETER_ERROR      (1 << 6)
+
+#define SDCARD_FAIL 0
+#define SDCARD_V1   1
+#define SDCARD_V2   2
+#define SDCARD_V2HC 3
+#define SD_DBG             0
+
+SPI sd(PB_15, PB_14, PB_13); //miso,mosi, sclk
+DigitalOut ssel (PB_12);
+
+int cmd(int cmd, int arg);
+int cmd8();
+int cmd58();
+int initialise_card();
+int cdv;   
+  
+
+void main ()
+{
+    spi.format(16, 0);
+    sd.frequency(2);
+    while(1)
+     sd.write(0xAA);
+     
+    initialise_card();
+    
+}
+
+
+int cmd(int cmd, int arg) {
+    ssel = 0;
+
+    // send a command
+    sd.write(0x40 | cmd);
+    sd.write(arg >> 24);
+    sd.write(arg >> 16);
+    sd.write(arg >> 8);
+    sd.write(arg >> 0);
+    sd.write(0x95);
+
+    // wait for the repsonse (response[7] == 0)
+    for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
+        int response = sd.write(0xFF);
+        if (!(response & 0x80)) {
+            ssel= 1;
+            sd.write(0xFF);
+            return response;
+        }
+    }
+    ssel = 1;
+    sd.write(0xFF);
+    return -1; // timeout
+}
+
+
+int initialise_card_v1() {
+    for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
+        cmd(55, 0);
+        if (cmd(41, 0) == 0) {
+            cdv = 512;
+            debug_if(SD_DBG, "\n\rInit: SEDCARD_V1\n\r");
+            return SDCARD_V1;
+        }
+    }
+
+    debug("Timeout waiting for v1.x card\n");
+    return SDCARD_FAIL;
+}
+
+int initialise_card_v2() {
+    for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
+        wait_ms(50);
+        cmd58();
+        cmd(55, 0);
+        if (cmd(41, 0x40000000) == 0) {
+            cmd58();
+            debug_if(SD_DBG, "\n\rInit: SDCARD_V2\n\r");
+            cdv = 1;
+            return SDCARD_V2;
+        }
+    }
+
+    debug("Timeout waiting for v2.x card\n");
+    return SDCARD_FAIL;
+}
+
+
+int initialise_card() {
+    // Set to SCK for initialisation, and clock card with cs = 1
+    sd.frequency(100000);
+    ssel = 1;
+    for (int i = 0; i < 16; i++) {
+        sd.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) {
+        return initialise_card_v2();
+    } else if (r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) {
+        return initialise_card_v1();
+    } else {
+        debug("Not in idle state after sending CMD8 (not an SD card?)\n");
+        return SDCARD_FAIL;
+    }
+}
+
+
+int cmd8() {
+    ssel = 0;
+
+    // send a command
+    sd.write(0x40 | 8); // CMD8
+    sd.write(0x00);     // reserved
+    sd.write(0x00);     // reserved
+    sd.write(0x01);     // 3.3v
+    sd.write(0xAA);     // check pattern
+    sd.write(0x87);     // crc
+
+    // wait for the repsonse (response[7] == 0)
+    for (int i = 0; i < SD_COMMAND_TIMEOUT * 1000; i++) {
+        char response[5];
+        response[0] = sd.write(0xFF);
+        if (!(response[0] & 0x80)) {
+            for (int j = 1; j < 5; j++) {
+                response[i] = sd.write(0xFF);
+            }
+            ssel = 1;
+            sd.write(0xFF);
+            return response[0];
+        }
+    }
+    ssel = 1;
+    sd.write(0xFF);
+    return -1; // timeout
+}
+
+
+int cmd58() {
+    ssel = 0;
+    int arg = 0;
+
+    // send a command
+    sd.write(0x40 | 58);
+    sd.write(arg >> 24);
+    sd.write(arg >> 16);
+    sd.write(arg >> 8);
+    sd.write(arg >> 0);
+    sd.write(0x95);
+
+    // wait for the repsonse (response[7] == 0)
+    for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
+        int response = sd.write(0xFF);
+        if (!(response & 0x80)) {
+            int ocr = sd.write(0xFF) << 24;
+            ocr |= sd.write(0xFF) << 16;
+            ocr |= sd.write(0xFF) << 8;
+            ocr |= sd.write(0xFF) << 0;
+            ssel = 1;
+            sd.write(0xFF);
+            return response;
+        }
+    }
+    ssel = 1;
+    sd.write(0xFF);
+    return -1; // timeout
+}
\ No newline at end of file
diff -r 000000000000 -r 9b6d6fa5c401 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Apr 17 23:34:09 2018 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/994bdf8177cb
\ No newline at end of file