From c21462e52fa2e271ebbfc9d3d3bca65198052959 Mon Sep 17 00:00:00 2001 From: Daniele Verducci su MatissePenguin Date: Sat, 26 Dec 2020 20:59:24 +0100 Subject: [PATCH] Testing sdcard initialization with Arduino --- arduino/sdcard-test/sdcard-test.ino | 113 ++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 arduino/sdcard-test/sdcard-test.ino diff --git a/arduino/sdcard-test/sdcard-test.ino b/arduino/sdcard-test/sdcard-test.ino new file mode 100644 index 0000000..382fc17 --- /dev/null +++ b/arduino/sdcard-test/sdcard-test.ino @@ -0,0 +1,113 @@ +/** + * SPI SD-Card test sketch + * Reads the first 128 bytes from cf and prints it out as ascii characters in serial monitor at 9200 baud + * + * Implementation of the specification at http://elm-chan.org/docs/mmc/mmc_e.html + */ + +#define CS 5 // aka CAT3 +#define MOSI 4 // aka DI or CMD +#define SCK 3 // aka CAT3 +#define MISO 2 // aka DAT0 + +void setup() { + pinMode(CS, OUTPUT); + pinMode(MOSI, OUTPUT); + pinMode(SCK, OUTPUT); + pinMode(MISO, INPUT); + + Serial.begin(9600); + + /***** Init sequence *******/ + + // Wait 1ms + delay(1); + + Serial.println("Init card..."); + + + // >= 75 clocks with CS and DI high + digitalWrite(CS, HIGH); + digitalWrite(MOSI, HIGH); + for (byte i=0; i<80; i++) { + clk(); + } + + // CMD0 with CS low (Software reset). Means "Leave native mode and enter SPI mode" + digitalWrite(CS, LOW); + sendCommand(B01000000); // First two bits are always 01. Command is 0 (000000). + byte resp = receiveResponse(); + Serial.println("Card response:"); + Serial.println(resp, HEX); + digitalWrite(CS, HIGH); + +} + +void loop() {} + +/** + * Sends a clock cycle + */ +void clk() { + digitalWrite(SCK, HIGH); + //delayMicroseconds(1); + digitalWrite(SCK, LOW); + //delayMicroseconds(1); +} + +/** + * Sends a command to card. + * The sent CRC field is valid for the CMD0 message. + * This is ok, since the CRC field will not be checked in SPI mode. + * @param index: the command index byte. First two bytes are the sync bytes "01". + */ +void sendCommand(byte index) { + // Send command index (2+6=8 bits) + sendByte(index); + // Send argument (32 bit) + for(byte i=0; i<4; i++) { + sendByte(0); + } + // Send CRC with final stop bit (7+1=8 bits) + sendByte(B10010101); // We send always the CMD0 CRC, because is not checked in SPI mode +} + +/** + * Sends a byte to the card. The two MSB must be 01 as per specification. + * Byte is sent MSB first. + */ +void sendByte(byte b) { + for (byte i=0; i<8; i++) { + // If last bit is 1 set MOSI HIGH, else LOW + digitalWrite(MOSI, (b & B10000000) == B10000000 ? HIGH : LOW); + clk(); + // Shift byte to have, in the next cycle, the next bit in last position + b = b << 1; + } +} + +/** + * Receives the response from card + * MSB first. + */ +byte receiveResponse() { + digitalWrite(CS, LOW); + digitalWrite(MOSI, HIGH); + + // continuously toggle the SD CLK signal and observe the MISO line for data: + // message response starts with 0 + while (digitalRead(MISO)) { + clk(); + } // Wait for first 0 + + byte resp = 0; + // Read 8 bits + for (byte i=0; i<8; i++) { + if (digitalRead(MISO)) { + resp = resp | B00000001; + } + resp = resp << 1; + clk(); + } + +}