Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
SDFileSystem.cpp
00001 /* mbed Microcontroller Library - SDFileSystem 00002 * Copyright (c) 2008-2009, sford 00003 * 00004 * Introduction 00005 * ------------ 00006 * SD and MMC cards support a number of interfaces, but common to them all 00007 * is one based on SPI. This is the one I'm implmenting because it means 00008 * it is much more portable even though not so performant, and we already 00009 * have the mbed SPI Interface! 00010 * 00011 * The main reference I'm using is Chapter 7, "SPI Mode" of: 00012 * http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf 00013 * 00014 * SPI Startup 00015 * ----------- 00016 * The SD card powers up in SD mode. The SPI interface mode is selected by 00017 * asserting CS low and sending the reset command (CMD0). The card will 00018 * respond with a (R1) response. 00019 * 00020 * CMD8 is optionally sent to determine the voltage range supported, and 00021 * indirectly determine whether it is a version 1.x SD/non-SD card or 00022 * version 2.x. I'll just ignore this for now. 00023 * 00024 * ACMD41 is repeatedly issued to initialise the card, until "in idle" 00025 * (bit 0) of the R1 response goes to '0', indicating it is initialised. 00026 * 00027 * You should also indicate whether the host supports High Capicity cards, 00028 * and check whether the card is high capacity - i'll also ignore this 00029 * 00030 * SPI Protocol 00031 * ------------ 00032 * The SD SPI protocol is based on transactions made up of 8-bit words, with 00033 * the host starting every bus transaction by asserting the CS signal low. The 00034 * card always responds to commands, data blocks and errors. 00035 * 00036 * The protocol supports a CRC, but by default it is off (except for the 00037 * first reset CMD0, where the CRC can just be pre-calculated, and CMD8) 00038 * I'll leave the CRC off I think! 00039 * 00040 * Standard capacity cards have variable data block sizes, whereas High 00041 * Capacity cards fix the size of data block to 512 bytes. I'll therefore 00042 * just always use the Standard Capacity cards with a block size of 512 bytes. 00043 * This is set with CMD16. 00044 * 00045 * You can read and write single blocks (CMD17, CMD25) or multiple blocks 00046 * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When 00047 * the card gets a read command, it responds with a response token, and then 00048 * a data token or an error. 00049 * 00050 * SPI Command Format 00051 * ------------------ 00052 * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC. 00053 * 00054 * +---------------+------------+------------+-----------+----------+--------------+ 00055 * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 | 00056 * +---------------+------------+------------+-----------+----------+--------------+ 00057 * 00058 * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95) 00059 * 00060 * All Application Specific commands shall be preceded with APP_CMD (CMD55). 00061 * 00062 * SPI Response Format 00063 * ------------------- 00064 * The main response format (R1) is a status byte (normally zero). Key flags: 00065 * idle - 1 if the card is in an idle state/initialising 00066 * cmd - 1 if an illegal command code was detected 00067 * 00068 * +-------------------------------------------------+ 00069 * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle | 00070 * +-------------------------------------------------+ 00071 * 00072 * R1b is the same, except it is followed by a busy signal (zeros) until 00073 * the first non-zero byte when it is ready again. 00074 * 00075 * Data Response Token 00076 * ------------------- 00077 * Every data block written to the card is acknowledged by a byte 00078 * response token 00079 * 00080 * +----------------------+ 00081 * | xxx | 0 | status | 1 | 00082 * +----------------------+ 00083 * 010 - OK! 00084 * 101 - CRC Error 00085 * 110 - Write Error 00086 * 00087 * Single Block Read and Write 00088 * --------------------------- 00089 * 00090 * Block transfers have a byte header, followed by the data, followed 00091 * by a 16-bit CRC. In our case, the data will always be 512 bytes. 00092 * 00093 * +------+---------+---------+- - - -+---------+-----------+----------+ 00094 * | 0xFE | data[0] | data[1] | | data[n] | crc[15:8] | crc[7:0] | 00095 * +------+---------+---------+- - - -+---------+-----------+----------+ 00096 */ 00097 00098 #include "SDFileSystem.h" 00099 00100 #define SD_COMMAND_TIMEOUT 5000 00101 00102 //#define CR "\n" 00103 #define CR "\r\n" 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 int SDFileSystem::disk_initialize() { 00119 00120 _spi.frequency(100000); // Set to 100kHz for initialisation 00121 00122 // Initialise the card by clocking it a bit (cs = 1) 00123 _cs = 1; 00124 for(int i=0; i<16; i++) { 00125 _spi.write(0xFF); 00126 } 00127 00128 // send CMD0, should return with all zeros except IDLE STATE set (bit 0) 00129 if(_cmd(0, 0) != R1_IDLE_STATE) { 00130 fprintf(stderr, "No disk, or could not put SD card into SPI idle state" CR); 00131 return 1; 00132 } 00133 00134 int r = _cmd8(); 00135 if(r == R1_IDLE_STATE) { 00136 printf("SD version 2.x" CR); 00137 } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { 00138 printf("SD version 1.x" CR); 00139 } else { 00140 error("Unknown SD version" CR); 00141 } 00142 00143 // ACMD41 to give host capacity support (repeat until not busy) 00144 // ACMD41 is application specific command, so we send APP_CMD (CMD55) beforehand 00145 for(int i=0;; i++) { 00146 _cmd(55, 0); 00147 int response = _cmd(41, 0); 00148 if(response == 0) { 00149 break; 00150 } else if(i > SD_COMMAND_TIMEOUT) { 00151 fprintf(stderr, "Timeout waiting for card" CR); 00152 return 1; 00153 } 00154 } 00155 00156 // printf("OK" CR); 00157 00158 _sectors = _sd_sectors(); 00159 00160 // Set block length to 512 (CMD16) 00161 if(_cmd(16, 512) != 0) { 00162 fprintf(stderr, "Set block timeout" CR); 00163 return 1; 00164 } 00165 00166 _spi.frequency(1000000); // Set to 1MHz for data transfer 00167 return 0; 00168 } 00169 00170 int SDFileSystem::disk_write(const char *buffer, int block_number) { 00171 // set write address for single block (CMD24) 00172 if(_cmd(24, block_number * 512) != 0) { 00173 return 1; 00174 } 00175 00176 // send the data block 00177 _write(buffer, 512); 00178 return 0; 00179 } 00180 00181 int SDFileSystem::disk_read(char *buffer, int block_number) { 00182 // set read address for single block (CMD17) 00183 if(_cmd(17, block_number * 512) != 0) { 00184 return 1; 00185 } 00186 00187 // receive the data 00188 _read(buffer, 512); 00189 return 0; 00190 } 00191 00192 int SDFileSystem::disk_status() { return 0; } 00193 int SDFileSystem::disk_sync() { return 0; } 00194 int SDFileSystem::disk_sectors() { return _sectors; } 00195 00196 // PRIVATE FUNCTIONS 00197 00198 int SDFileSystem::_cmd(int cmd, int arg) { 00199 _cs = 0; 00200 00201 // send a command 00202 _spi.write(0x40 | cmd); 00203 _spi.write(arg >> 24); 00204 _spi.write(arg >> 16); 00205 _spi.write(arg >> 8); 00206 _spi.write(arg >> 0); 00207 _spi.write(0x95); 00208 00209 // wait for the repsonse (response[7] == 0) 00210 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00211 int response = _spi.write(0xFF); 00212 if(!(response & 0x80)) { 00213 _cs = 1; 00214 _spi.write(0xFF); 00215 return response; 00216 } 00217 } 00218 _cs = 1; 00219 _spi.write(0xFF); 00220 return -1; // timeout 00221 } 00222 00223 int SDFileSystem::_cmd8() { 00224 _cs = 0; 00225 00226 // send a command 00227 _spi.write(0x40 | 8); // CMD8 00228 _spi.write(0x00); // reserved 00229 _spi.write(0x00); // reserved 00230 _spi.write(0x01); // 3.3v 00231 _spi.write(0xAA); // check pattern 00232 _spi.write(0x87); // crc 00233 00234 // wait for the repsonse (response[7] == 0) 00235 for(int i=0; i<SD_COMMAND_TIMEOUT * 1000; i++) { 00236 char response[5]; 00237 response[0] = _spi.write(0xFF); 00238 if(!(response[0] & 0x80)) { 00239 for(int j=1; j<5; j++) { 00240 response[i] = _spi.write(0xFF); 00241 } 00242 _cs = 1; 00243 _spi.write(0xFF); 00244 return response[0]; 00245 } 00246 } 00247 _cs = 1; 00248 _spi.write(0xFF); 00249 return -1; // timeout 00250 } 00251 00252 int SDFileSystem::_read(char *buffer, int length) { 00253 _cs = 0; 00254 00255 // read until start byte (0xFF) 00256 while(_spi.write(0xFF) != 0xFE); 00257 00258 // read data 00259 for(int i=0; i<length; i++) { 00260 buffer[i] = _spi.write(0xFF); 00261 } 00262 _spi.write(0xFF); // checksum 00263 _spi.write(0xFF); 00264 00265 _cs = 1; 00266 _spi.write(0xFF); 00267 return 0; 00268 } 00269 00270 int SDFileSystem::_write(const char *buffer, int length) { 00271 _cs = 0; 00272 00273 // indicate start of block 00274 _spi.write(0xFE); 00275 00276 // write the data 00277 for(int i=0; i<length; i++) { 00278 _spi.write(buffer[i]); 00279 } 00280 00281 // write the checksum 00282 _spi.write(0xFF); 00283 _spi.write(0xFF); 00284 00285 // check the repsonse token 00286 if((_spi.write(0xFF) & 0x1F) != 0x05) { 00287 _cs = 1; 00288 _spi.write(0xFF); 00289 return 1; 00290 } 00291 00292 // wait for write to finish 00293 while(_spi.write(0xFF) == 0); 00294 00295 _cs = 1; 00296 _spi.write(0xFF); 00297 return 0; 00298 } 00299 00300 static int ext_bits(char *data, int msb, int lsb) { 00301 int bits = 0; 00302 int size = 1 + msb - lsb; 00303 for(int i=0; i<size; i++) { 00304 int position = lsb + i; 00305 int byte = 15 - (position >> 3); 00306 int bit = position & 0x7; 00307 int value = (data[byte] >> bit) & 1; 00308 bits |= value << i; 00309 } 00310 return bits; 00311 } 00312 00313 int SDFileSystem::_sd_sectors() { 00314 00315 // CMD9, Response R2 (R1 byte + 16-byte block read) 00316 if(_cmd(9, 0) != 0) { 00317 fprintf(stderr, "Didn't get a response from the disk" CR); 00318 return 0; 00319 } 00320 00321 char csd[16]; 00322 if(_read(csd, 16) != 0) { 00323 fprintf(stderr, "Couldn't read csd response from disk" CR); 00324 return 0; 00325 } 00326 00327 // csd_structure : csd[127:126] 00328 // c_size : csd[73:62] 00329 // c_size_mult : csd[49:47] 00330 // read_bl_len : csd[83:80] 00331 00332 int csd_structure = ext_bits(csd, 127, 126); 00333 int c_size = ext_bits(csd, 73, 62); 00334 int c_size_mult = ext_bits(csd, 49, 47); 00335 int read_bl_len = ext_bits(csd, 83, 80); 00336 00337 if(csd_structure != 0) { 00338 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures" CR); 00339 // Non-zero is SDHC. 00340 return 0; 00341 } 00342 00343 int blocks = (c_size + 1) * (1 << (c_size_mult + 2)); 00344 int block_size = 1 << read_bl_len; 00345 00346 if (block_size != 512 && block_size != 1024) { 00347 fprintf(stderr, "This disk tastes funny! %d byte block. I only like 512 or 1024 -byte blocks" CR, block_size); 00348 return 0; 00349 } 00350 00351 return blocks; 00352 }
Generated on Wed Jul 13 2022 07:13:43 by
 1.7.2
 1.7.2