Simon Ford
/
SDCardTest
Revision 3:68ef62208d4d, committed 2009-12-31
- Comitter:
- simon
- Date:
- Thu Dec 31 15:11:08 2009 +0000
- Parent:
- 2:849162a1207f
- Commit message:
Changed in this revision
diff -r 849162a1207f -r 68ef62208d4d SDFileSystem.cpp --- a/SDFileSystem.cpp Mon Dec 14 22:32:28 2009 +0000 +++ b/SDFileSystem.cpp Thu Dec 31 15:11:08 2009 +0000 @@ -1,7 +1,10 @@ /* mbed Microcontroller Library - SDFileSystem * Copyright (c) 2008-2009, sford - * - * Introduction + */ + +// VERY DRAFT CODE! Needs serious rework/refactoring + +/* Introduction * ------------ * SD and MMC cards support a number of interfaces, but common to them all * is one based on SPI. This is the one I'm implmenting because it means @@ -112,11 +115,20 @@ #define R1_ADDRESS_ERROR (1 << 5) #define R1_PARAMETER_ERROR (1 << 6) -int SDFileSystem::disk_initialize() { +// Types +// - v1.x Standard Capacity +// - v2.x Standard Capacity +// - v2.x High Capacity +// - Not recognised as an SD Card - _spi.frequency(100000); // Set to 100kHz for initialisation - - // Initialise the card by clocking it with cs = 1 +#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); _cs = 1; for(int i=0; i<16; i++) { _spi.write(0xFF); @@ -125,38 +137,58 @@ // send CMD0, should return with all zeros except IDLE STATE set (bit 0) if(_cmd(0, 0) != R1_IDLE_STATE) { fprintf(stderr, "No disk, or could not put SD card in to SPI idle state\n"); - return 1; + return SDCARD_FAIL; } + // send CMD8 to determine whther it is ver 2.x int r = _cmd8(); if(r == R1_IDLE_STATE) { - printf("SD version 2.x\n"); + return initialise_card_v2(); } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { - printf("SD version 1.x\n"); + return initialise_card_v1(); } else { - error("Unknown SD version\n"); + fprintf(stderr, "Not in idle state after sending CMD8 (not an SD card?)\n"); + return SDCARD_FAIL; } - - // ACMD41 to give host capacity support (repeat until not busy) - // ACMD41 is application specific command, so we send APP_CMD (CMD55) beforehand - for(int i=0;; i++) { +} + +int SDFileSystem::initialise_card_v1() { + for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { _cmd(55, 0); - int response = _cmd(41, 0); - if(response == 0) { - break; - } else if(i > SD_COMMAND_TIMEOUT) { - fprintf(stderr, "Timeout waiting for card\n"); - return 1; - } + if(_cmd(41, 0) == 0) { + return SDCARD_V1; + } } - printf("OK\n"); + fprintf(stderr, "Timeout waiting for v1.x card\n"); + return SDCARD_FAIL; +} + +int SDFileSystem::initialise_card_v2() { + + for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { + _cmd(55, 0); + if(_cmd(41, 0) == 0) { + _cmd58(); + return SDCARD_V2; + } + } + + fprintf(stderr, "Timeout waiting for v2.x card\n"); + return SDCARD_FAIL; +} + +int SDFileSystem::disk_initialize() { + + int i = initialise_card(); +// printf("init card = %d\n", i); +// printf("OK\n"); _sectors = _sd_sectors(); // Set block length to 512 (CMD16) if(_cmd(16, 512) != 0) { - fprintf(stderr, "Set block timeout\n"); + fprintf(stderr, "Set 512-byte block timed out\n"); return 1; } @@ -216,6 +248,60 @@ _spi.write(0xFF); return -1; // timeout } +int SDFileSystem::_cmdx(int cmd, int arg) { + _cs = 0; + + // send a command + _spi.write(0x40 | cmd); + _spi.write(arg >> 24); + _spi.write(arg >> 16); + _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); + if(!(response & 0x80)) { + return response; + } + } + _cs = 1; + _spi.write(0xFF); + return -1; // timeout +} + + +int SDFileSystem::_cmd58() { + _cs = 0; + int arg = 0; + + // send a command + _spi.write(0x40 | 58); + _spi.write(arg >> 24); + _spi.write(arg >> 16); + _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); + if(!(response & 0x80)) { + int ocr = _spi.write(0xFF) << 24; + ocr |= _spi.write(0xFF) << 16; + ocr |= _spi.write(0xFF) << 8; + ocr |= _spi.write(0xFF) << 0; +// printf("OCR = 0x%08X\n", ocr); + _cs = 1; + _spi.write(0xFF); + return response; + } + } + _cs = 1; + _spi.write(0xFF); + return -1; // timeout +} int SDFileSystem::_cmd8() { _cs = 0; @@ -310,7 +396,7 @@ int SDFileSystem::_sd_sectors() { // CMD9, Response R2 (R1 byte + 16-byte block read) - if(_cmd(9, 0) != 0) { + if(_cmdx(9, 0) != 0) { fprintf(stderr, "Didn't get a response from the disk\n"); return 0; } @@ -324,25 +410,32 @@ // csd_structure : csd[127:126] // c_size : csd[73:62] // c_size_mult : csd[49:47] - // read_bl_len : csd[83:80] + // read_bl_len : csd[83:80] - the *maximum* read block length int csd_structure = ext_bits(csd, 127, 126); int c_size = ext_bits(csd, 73, 62); int c_size_mult = ext_bits(csd, 49, 47); int read_bl_len = ext_bits(csd, 83, 80); + +// printf("CSD_STRUCT = %d\n", csd_structure); if(csd_structure != 0) { - fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures"); + fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures\n"); return 0; } + + // memory capacity = BLOCKNR * BLOCK_LEN + // where + // BLOCKNR = (C_SIZE+1) * MULT + // MULT = 2^(C_SIZE_MULT+2) (C_SIZE_MULT < 8) + // BLOCK_LEN = 2^READ_BL_LEN, (READ_BL_LEN < 12) - int blocks = (c_size + 1) * (1 << (c_size_mult + 2)); - int block_size = 1 << read_bl_len; - - if(block_size != 512) { - fprintf(stderr, "This disk tastes funny! I only like 512-byte blocks"); - return 0; - } - + int block_len = 1 << read_bl_len; + int mult = 1 << (c_size_mult + 2); + int blocknr = (c_size + 1) * mult; + int capacity = blocknr * block_len; + + int blocks = capacity / 512; + return blocks; }
diff -r 849162a1207f -r 68ef62208d4d SDFileSystem.h --- a/SDFileSystem.h Mon Dec 14 22:32:28 2009 +0000 +++ b/SDFileSystem.h Thu Dec 31 15:11:08 2009 +0000 @@ -1,6 +1,8 @@ /* mbed Microcontroller Library - SDFileSystem * Copyright (c) 2008-2009, sford */ + +// VERY DRAFT CODE!!! #ifndef SDFILESYSTEM_H #define SDFILESYSTEM_H @@ -44,7 +46,13 @@ protected: int _cmd(int cmd, int arg); + int _cmdx(int cmd, int arg); int _cmd8(); + int _cmd58(); + int initialise_card(); + int initialise_card_v1(); + int initialise_card_v2(); + int _read(char *buffer, int length); int _write(const char *buffer, int length);
diff -r 849162a1207f -r 68ef62208d4d main.cpp --- a/main.cpp Mon Dec 14 22:32:28 2009 +0000 +++ b/main.cpp Thu Dec 31 15:11:08 2009 +0000 @@ -10,7 +10,7 @@ if(fp == NULL) { error("Could not open file for write\n"); } - fprintf(fp, "Hello SD Card World!"); + fprintf(fp, "Hello fun SD Card World!"); fclose(fp); printf("Goodbye World!\n");