SDCardTest
Published 31 Dec 2009, by
Simon Ford

No tags
« Back to documentation index
Show/hide line numbers
SDFileSystem.cpp Source File
SDFileSystem.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 #include "SDFileSystem.h"
00102
00103 #define SD_COMMAND_TIMEOUT 5000
00104
00105 SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) :
00106 FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs) {
00107 _cs = 1;
00108 }
00109
00110 #define R1_IDLE_STATE (1 << 0)
00111 #define R1_ERASE_RESET (1 << 1)
00112 #define R1_ILLEGAL_COMMAND (1 << 2)
00113 #define R1_COM_CRC_ERROR (1 << 3)
00114 #define R1_ERASE_SEQUENCE_ERROR (1 << 4)
00115 #define R1_ADDRESS_ERROR (1 << 5)
00116 #define R1_PARAMETER_ERROR (1 << 6)
00117
00118
00119
00120
00121
00122
00123
00124 #define SDCARD_FAIL 0
00125 #define SDCARD_V1 1
00126 #define SDCARD_V2 2
00127 #define SDCARD_V2HC 3
00128
00129 int SDFileSystem::initialise_card() {
00130
00131 _spi.frequency(100000);
00132 _cs = 1;
00133 for(int i=0; i<16; i++) {
00134 _spi.write(0xFF);
00135 }
00136
00137
00138 if(_cmd(0, 0) != R1_IDLE_STATE) {
00139 fprintf(stderr, "No disk, or could not put SD card in to SPI idle state\n");
00140 return SDCARD_FAIL;
00141 }
00142
00143
00144 int r = _cmd8();
00145 if(r == R1_IDLE_STATE) {
00146 return initialise_card_v2();
00147 } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) {
00148 return initialise_card_v1();
00149 } else {
00150 fprintf(stderr, "Not in idle state after sending CMD8 (not an SD card?)\n");
00151 return SDCARD_FAIL;
00152 }
00153 }
00154
00155 int SDFileSystem::initialise_card_v1() {
00156 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
00157 _cmd(55, 0);
00158 if(_cmd(41, 0) == 0) {
00159 return SDCARD_V1;
00160 }
00161 }
00162
00163 fprintf(stderr, "Timeout waiting for v1.x card\n");
00164 return SDCARD_FAIL;
00165 }
00166
00167 int SDFileSystem::initialise_card_v2() {
00168
00169 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
00170 _cmd(55, 0);
00171 if(_cmd(41, 0) == 0) {
00172 _cmd58();
00173 return SDCARD_V2;
00174 }
00175 }
00176
00177 fprintf(stderr, "Timeout waiting for v2.x card\n");
00178 return SDCARD_FAIL;
00179 }
00180
00181 int SDFileSystem::disk_initialize() {
00182
00183 int i = initialise_card();
00184
00185
00186
00187 _sectors = _sd_sectors();
00188
00189
00190 if(_cmd(16, 512) != 0) {
00191 fprintf(stderr, "Set 512-byte block timed out\n");
00192 return 1;
00193 }
00194
00195 _spi.frequency(1000000);
00196 return 0;
00197 }
00198
00199 int SDFileSystem::disk_write(const char *buffer, int block_number) {
00200
00201 if(_cmd(24, block_number * 512) != 0) {
00202 return 1;
00203 }
00204
00205
00206 _write(buffer, 512);
00207 return 0;
00208 }
00209
00210 int SDFileSystem::disk_read(char *buffer, int block_number) {
00211
00212 if(_cmd(17, block_number * 512) != 0) {
00213 return 1;
00214 }
00215
00216
00217 _read(buffer, 512);
00218 return 0;
00219 }
00220
00221 int SDFileSystem::disk_status() { return 0; }
00222 int SDFileSystem::disk_sync() { return 0; }
00223 int SDFileSystem::disk_sectors() { return _sectors; }
00224
00225
00226
00227 int SDFileSystem::_cmd(int cmd, int arg) {
00228 _cs = 0;
00229
00230
00231 _spi.write(0x40 | cmd);
00232 _spi.write(arg >> 24);
00233 _spi.write(arg >> 16);
00234 _spi.write(arg >> 8);
00235 _spi.write(arg >> 0);
00236 _spi.write(0x95);
00237
00238
00239 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
00240 int response = _spi.write(0xFF);
00241 if(!(response & 0x80)) {
00242 _cs = 1;
00243 _spi.write(0xFF);
00244 return response;
00245 }
00246 }
00247 _cs = 1;
00248 _spi.write(0xFF);
00249 return -1;
00250 }
00251 int SDFileSystem::_cmdx(int cmd, int arg) {
00252 _cs = 0;
00253
00254
00255 _spi.write(0x40 | cmd);
00256 _spi.write(arg >> 24);
00257 _spi.write(arg >> 16);
00258 _spi.write(arg >> 8);
00259 _spi.write(arg >> 0);
00260 _spi.write(0x95);
00261
00262
00263 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
00264 int response = _spi.write(0xFF);
00265 if(!(response & 0x80)) {
00266 return response;
00267 }
00268 }
00269 _cs = 1;
00270 _spi.write(0xFF);
00271 return -1;
00272 }
00273
00274
00275 int SDFileSystem::_cmd58() {
00276 _cs = 0;
00277 int arg = 0;
00278
00279
00280 _spi.write(0x40 | 58);
00281 _spi.write(arg >> 24);
00282 _spi.write(arg >> 16);
00283 _spi.write(arg >> 8);
00284 _spi.write(arg >> 0);
00285 _spi.write(0x95);
00286
00287
00288 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
00289 int response = _spi.write(0xFF);
00290 if(!(response & 0x80)) {
00291 int ocr = _spi.write(0xFF) << 24;
00292 ocr |= _spi.write(0xFF) << 16;
00293 ocr |= _spi.write(0xFF) << 8;
00294 ocr |= _spi.write(0xFF) << 0;
00295
00296 _cs = 1;
00297 _spi.write(0xFF);
00298 return response;
00299 }
00300 }
00301 _cs = 1;
00302 _spi.write(0xFF);
00303 return -1;
00304 }
00305
00306 int SDFileSystem::_cmd8() {
00307 _cs = 0;
00308
00309
00310 _spi.write(0x40 | 8);
00311 _spi.write(0x00);
00312 _spi.write(0x00);
00313 _spi.write(0x01);
00314 _spi.write(0xAA);
00315 _spi.write(0x87);
00316
00317
00318 for(int i=0; i<SD_COMMAND_TIMEOUT * 1000; i++) {
00319 char response[5];
00320 response[0] = _spi.write(0xFF);
00321 if(!(response[0] & 0x80)) {
00322 for(int j=1; j<5; j++) {
00323 response[i] = _spi.write(0xFF);
00324 }
00325 _cs = 1;
00326 _spi.write(0xFF);
00327 return response[0];
00328 }
00329 }
00330 _cs = 1;
00331 _spi.write(0xFF);
00332 return -1;
00333 }
00334
00335 int SDFileSystem::_read(char *buffer, int length) {
00336 _cs = 0;
00337
00338
00339 while(_spi.write(0xFF) != 0xFE);
00340
00341
00342 for(int i=0; i<length; i++) {
00343 buffer[i] = _spi.write(0xFF);
00344 }
00345 _spi.write(0xFF);
00346 _spi.write(0xFF);
00347
00348 _cs = 1;
00349 _spi.write(0xFF);
00350 return 0;
00351 }
00352
00353 int SDFileSystem::_write(const char *buffer, int length) {
00354 _cs = 0;
00355
00356
00357 _spi.write(0xFE);
00358
00359
00360 for(int i=0; i<length; i++) {
00361 _spi.write(buffer[i]);
00362 }
00363
00364
00365 _spi.write(0xFF);
00366 _spi.write(0xFF);
00367
00368
00369 if((_spi.write(0xFF) & 0x1F) != 0x05) {
00370 _cs = 1;
00371 _spi.write(0xFF);
00372 return 1;
00373 }
00374
00375
00376 while(_spi.write(0xFF) == 0);
00377
00378 _cs = 1;
00379 _spi.write(0xFF);
00380 return 0;
00381 }
00382
00383 static int ext_bits(char *data, int msb, int lsb) {
00384 int bits = 0;
00385 int size = 1 + msb - lsb;
00386 for(int i=0; i<size; i++) {
00387 int position = lsb + i;
00388 int byte = 15 - (position >> 3);
00389 int bit = position & 0x7;
00390 int value = (data[byte] >> bit) & 1;
00391 bits |= value << i;
00392 }
00393 return bits;
00394 }
00395
00396 int SDFileSystem::_sd_sectors() {
00397
00398
00399 if(_cmdx(9, 0) != 0) {
00400 fprintf(stderr, "Didn't get a response from the disk\n");
00401 return 0;
00402 }
00403
00404 char csd[16];
00405 if(_read(csd, 16) != 0) {
00406 fprintf(stderr, "Couldn't read csd response from disk\n");
00407 return 0;
00408 }
00409
00410
00411
00412
00413
00414
00415 int csd_structure = ext_bits(csd, 127, 126);
00416 int c_size = ext_bits(csd, 73, 62);
00417 int c_size_mult = ext_bits(csd, 49, 47);
00418 int read_bl_len = ext_bits(csd, 83, 80);
00419
00420
00421
00422 if(csd_structure != 0) {
00423 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures\n");
00424 return 0;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433 int block_len = 1 << read_bl_len;
00434 int mult = 1 << (c_size_mult + 2);
00435 int blocknr = (c_size + 1) * mult;
00436 int capacity = blocknr * block_len;
00437
00438 int blocks = capacity / 512;
00439
00440 return blocks;
00441 }