updated chan_fatfs
Fork of chan_fatfs by
Embed:
(wiki syntax)
Show/hide line numbers
diskio.cpp
00001 /*-----------------------------------------------------------------------*/ 00002 /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */ 00003 /*-----------------------------------------------------------------------*/ 00004 /* This is a stub disk I/O module that acts as front end of the existing */ 00005 /* disk I/O modules and attach it to FatFs module with common interface. */ 00006 /*-----------------------------------------------------------------------*/ 00007 00008 #include "diskio.h" 00009 #include "mbed.h" 00010 #include "mbed_debug.h" 00011 00012 00013 //****************************************************************************************************************** 00014 // MBED SPI/CS Select functions.... Modify for your layout. 00015 //************************************************************************************** 00016 00017 SPI _spi(p5, p6, p7); // mosi, miso, sclk 00018 DigitalOut _cs(p8); 00019 00020 //****************************************************************************************************************** 00021 // Low Level Sector Access Function Prototypes('C' Castrated versions of Simon Ford's C++ MBED SDFileSystem class 00022 //****************************************************************************************************************** 00023 int _cmd(int cmd, int arg); 00024 int _read(BYTE *buffer, int length); 00025 int _write(BYTE *buffer, int length); 00026 uint32_t ext_bits(BYTE *data, int msb, int lsb); 00027 int _sd_sectors(); 00028 int _sectors; 00029 int _cmd(int cmd, int arg); 00030 int _cmdx(int cmd, int arg); 00031 int _cmd8(); 00032 int _cmd58(); 00033 int cdv; 00034 00035 #define SD_COMMAND_TIMEOUT 5000 00036 00037 #define R1_IDLE_STATE (1 << 0) 00038 #define R1_ERASE_RESET (1 << 1) 00039 #define R1_ILLEGAL_COMMAND (1 << 2) 00040 #define R1_COM_CRC_ERROR (1 << 3) 00041 #define R1_ERASE_SEQUENCE_ERROR (1 << 4) 00042 #define R1_ADDRESS_ERROR (1 << 5) 00043 #define R1_PARAMETER_ERROR (1 << 6) 00044 00045 00046 //****************************************************************************************************************** 00047 // Sector Access functions for CHAN FatFs 00048 //****************************************************************************************************************** 00049 00050 DRESULT disk_ioctl ( 00051 BYTE drv, /* Physical drive nmuber (0..) */ 00052 BYTE ctrl, /* Control code */ 00053 void *buff /* Buffer to send/receive control data */ 00054 ) 00055 { 00056 DRESULT res; 00057 00058 switch(ctrl) { 00059 case CTRL_SYNC: 00060 res = RES_OK; 00061 break; 00062 00063 case GET_SECTOR_SIZE: 00064 res = RES_OK; 00065 *(WORD *)buff = 512; 00066 break; 00067 00068 case GET_SECTOR_COUNT: 00069 res = RES_OK; 00070 *(DWORD *)buff = (WORD)_sd_sectors(); 00071 break; 00072 00073 case GET_BLOCK_SIZE: 00074 res = RES_OK; 00075 *(DWORD *)buff = 1; 00076 break; 00077 00078 default: 00079 res = RES_OK; 00080 break; 00081 } 00082 return res; 00083 } 00084 00085 DSTATUS card_initialize(BYTE Drive) 00086 { 00087 // Set to 100kHz for initialisation, and clock card with cs = 1 00088 _spi.frequency(100000); 00089 _cs = 1; 00090 for (int i = 0; i < 16; i++) { 00091 _spi.write(0xFF); 00092 } 00093 00094 // send CMD0, should return with all zeros except IDLE STATE set (bit 0) 00095 if (_cmd(0, 0) != R1_IDLE_STATE) { 00096 debug("No disk, or could not put SD card in to SPI idle state\n"); 00097 return STA_NOINIT; 00098 } 00099 00100 // send CMD8 to determine whther it is ver 2.x 00101 int r = _cmd8(); 00102 if (r == R1_IDLE_STATE) { 00103 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { 00104 wait_ms(50); 00105 _cmd58(); 00106 _cmd(55, 0); 00107 if (_cmd(41, 0x40000000) == 0) { 00108 _cmd58(); 00109 //debug_if(SD_DBG, "\n\rInit: SDCARD_V2\n\r"); 00110 cdv = 1; 00111 return 0; 00112 } 00113 } 00114 debug("Timeout waiting for v2.x card\n"); 00115 return STA_NOINIT; 00116 00117 } else if (r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { 00118 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { 00119 _cmd(55, 0); 00120 if (_cmd(41, 0) == 0) { 00121 cdv = 512; 00122 //debug_if(SD_DBG, "\n\rInit: SEDCARD_V1\n\r"); 00123 return 0; 00124 } 00125 } 00126 debug("Timeout waiting for v1.x card\n"); 00127 return STA_NOINIT; 00128 00129 } else { 00130 debug("Not in idle state after sending CMD8 (not an SD card?)\n"); 00131 return STA_NOINIT; 00132 } 00133 } 00134 00135 DSTATUS disk_initialize(BYTE Drive) 00136 { 00137 DSTATUS ret = card_initialize(Drive); 00138 00139 _sectors = _sd_sectors(); 00140 00141 // Set block length to 512 (CMD16) 00142 if (_cmd(16, 512) != 0) { 00143 debug("Set 512-byte block timed out\n"); 00144 return STA_NOINIT; 00145 } 00146 00147 _spi.frequency(10000000); // Set to 10MHz for data transfer 00148 return ret; 00149 } 00150 00151 DRESULT disk_write(BYTE Drive,const BYTE * Buffer, DWORD SectorNumber, BYTE SectorCount) 00152 { 00153 BYTE i; 00154 00155 BYTE * MyBufOut = (BYTE *)Buffer; 00156 00157 for(i=0; i<SectorCount; i++) { 00158 // set write address for single block (CMD24) 00159 if(_cmd(24, (SectorNumber + i) * 512 ) != 0) { 00160 return RES_ERROR; 00161 } 00162 00163 // send the data block 00164 _write(MyBufOut, 512); 00165 00166 MyBufOut+=512; 00167 } 00168 return RES_OK; 00169 } 00170 00171 DRESULT disk_read(BYTE Drive, BYTE * Buffer,DWORD SectorNumber, BYTE SectorCount) 00172 { 00173 BYTE i; 00174 for(i=0; i<SectorCount; i++) { 00175 // set read address for single block (CMD17) 00176 if(_cmd(17, (SectorNumber+i) * 512) != 0) { 00177 return RES_ERROR; 00178 } 00179 // receive the data 00180 _read(Buffer, 512); 00181 00182 Buffer+=512; 00183 } 00184 return RES_OK; 00185 } 00186 00187 00188 DWORD get_fattime(void) 00189 { 00190 time_t CurrentTimeStamp; 00191 tm *CurrentLocalTime; 00192 DWORD FATFSTimeCode; 00193 00194 CurrentTimeStamp = time(NULL); 00195 CurrentLocalTime = localtime(&CurrentTimeStamp); 00196 00197 //Map the tm struct time into the FatFs time code 00198 FATFSTimeCode = ((CurrentLocalTime->tm_year-80)<<25) | 00199 ((CurrentLocalTime->tm_mon+1)<<21) | 00200 ((CurrentLocalTime->tm_mday)<<16) | 00201 ((CurrentLocalTime->tm_hour)<<11) | 00202 ((CurrentLocalTime->tm_min)<<5) | 00203 ((CurrentLocalTime->tm_sec)); 00204 00205 return FATFSTimeCode; 00206 } 00207 00208 DSTATUS disk_status(BYTE Drive) 00209 { 00210 return 0; 00211 } 00212 00213 //************************************************************************************** 00214 // Low Level Sector Access Functions (Castrated versions of Simon Fords C++ MBED class 00215 //************************************************************************************** 00216 00217 int _cmd(int cmd, int arg) 00218 { 00219 _cs = 0; 00220 00221 // send a command 00222 _spi.write(0x40 | cmd); 00223 _spi.write(arg >> 24); 00224 _spi.write(arg >> 16); 00225 _spi.write(arg >> 8); 00226 _spi.write(arg >> 0); 00227 _spi.write(0x95); 00228 00229 // wait for the repsonse (response[7] == 0) 00230 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { 00231 int response = _spi.write(0xFF); 00232 if (!(response & 0x80)) { 00233 _cs = 1; 00234 _spi.write(0xFF); 00235 return response; 00236 } 00237 } 00238 _cs = 1; 00239 _spi.write(0xFF); 00240 return -1; // timeout 00241 } 00242 int _cmdx(int cmd, int arg) 00243 { 00244 _cs = 0; 00245 00246 // send a command 00247 _spi.write(0x40 | cmd); 00248 _spi.write(arg >> 24); 00249 _spi.write(arg >> 16); 00250 _spi.write(arg >> 8); 00251 _spi.write(arg >> 0); 00252 _spi.write(0x95); 00253 00254 // wait for the repsonse (response[7] == 0) 00255 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { 00256 int response = _spi.write(0xFF); 00257 if (!(response & 0x80)) { 00258 return response; 00259 } 00260 } 00261 _cs = 1; 00262 _spi.write(0xFF); 00263 return -1; // timeout 00264 } 00265 00266 00267 int _cmd58() 00268 { 00269 _cs = 0; 00270 int arg = 0; 00271 00272 // send a command 00273 _spi.write(0x40 | 58); 00274 _spi.write(arg >> 24); 00275 _spi.write(arg >> 16); 00276 _spi.write(arg >> 8); 00277 _spi.write(arg >> 0); 00278 _spi.write(0x95); 00279 00280 // wait for the repsonse (response[7] == 0) 00281 for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { 00282 int response = _spi.write(0xFF); 00283 if (!(response & 0x80)) { 00284 int ocr = _spi.write(0xFF) << 24; 00285 ocr |= _spi.write(0xFF) << 16; 00286 ocr |= _spi.write(0xFF) << 8; 00287 ocr |= _spi.write(0xFF) << 0; 00288 _cs = 1; 00289 _spi.write(0xFF); 00290 return response; 00291 } 00292 } 00293 _cs = 1; 00294 _spi.write(0xFF); 00295 return -1; // timeout 00296 } 00297 00298 int _cmd8() 00299 { 00300 _cs = 0; 00301 00302 // send a command 00303 _spi.write(0x40 | 8); // CMD8 00304 _spi.write(0x00); // reserved 00305 _spi.write(0x00); // reserved 00306 _spi.write(0x01); // 3.3v 00307 _spi.write(0xAA); // check pattern 00308 _spi.write(0x87); // crc 00309 00310 // wait for the repsonse (response[7] == 0) 00311 for (int i = 0; i < SD_COMMAND_TIMEOUT * 1000; i++) { 00312 char response[5]; 00313 response[0] = _spi.write(0xFF); 00314 if (!(response[0] & 0x80)) { 00315 for (int j = 1; j < 5; j++) { 00316 response[i] = _spi.write(0xFF); 00317 } 00318 _cs = 1; 00319 _spi.write(0xFF); 00320 return response[0]; 00321 } 00322 } 00323 _cs = 1; 00324 _spi.write(0xFF); 00325 return -1; // timeout 00326 } 00327 int _read(BYTE *buffer, int length) 00328 { 00329 _cs = 0; 00330 00331 // read until start byte (0xFF) 00332 while (_spi.write(0xFF) != 0xFE); 00333 00334 // read data 00335 for (int i = 0; i < length; i++) { 00336 buffer[i] = _spi.write(0xFF); 00337 } 00338 _spi.write(0xFF); // checksum 00339 _spi.write(0xFF); 00340 00341 _cs = 1; 00342 _spi.write(0xFF); 00343 return 0; 00344 } 00345 00346 00347 int _write(BYTE *buffer, int length) 00348 { 00349 _cs = 0; 00350 00351 // indicate start of block 00352 _spi.write(0xFE); 00353 00354 // write the data 00355 for (int i = 0; i < length; i++) { 00356 _spi.write(buffer[i]); 00357 } 00358 00359 // write the checksum 00360 _spi.write(0xFF); 00361 _spi.write(0xFF); 00362 00363 // check the response token 00364 if ((_spi.write(0xFF) & 0x1F) != 0x05) { 00365 _cs = 1; 00366 _spi.write(0xFF); 00367 return 1; 00368 } 00369 00370 // wait for write to finish 00371 while (_spi.write(0xFF) == 0); 00372 00373 _cs = 1; 00374 _spi.write(0xFF); 00375 return 0; 00376 } 00377 00378 static uint32_t ext_bits(unsigned char *data, int msb, int lsb) 00379 { 00380 uint32_t bits = 0; 00381 uint32_t size = 1 + msb - lsb; 00382 for (int i = 0; i < size; i++) { 00383 uint32_t position = lsb + i; 00384 uint32_t byte = 15 - (position >> 3); 00385 uint32_t bit = position & 0x7; 00386 uint32_t value = (data[byte] >> bit) & 1; 00387 bits |= value << i; 00388 } 00389 return bits; 00390 } 00391 00392 int _sd_sectors() 00393 { 00394 uint32_t c_size, c_size_mult, read_bl_len; 00395 uint32_t block_len, mult, blocknr, capacity; 00396 uint32_t hc_c_size; 00397 uint64_t blocks; 00398 00399 // CMD9, Response R2 (R1 byte + 16-byte block read) 00400 if (_cmdx(9, 0) != 0) { 00401 debug("Didn't get a response from the disk\n"); 00402 return 0; 00403 } 00404 00405 uint8_t csd[16]; 00406 if (_read(csd, 16) != 0) { 00407 debug("Couldn't read csd response from disk\n"); 00408 return 0; 00409 } 00410 00411 // csd_structure : csd[127:126] 00412 // c_size : csd[73:62] 00413 // c_size_mult : csd[49:47] 00414 // read_bl_len : csd[83:80] - the *maximum* read block length 00415 00416 int csd_structure = ext_bits(csd, 127, 126); 00417 00418 switch (csd_structure) { 00419 case 0: 00420 cdv = 512; 00421 c_size = ext_bits(csd, 73, 62); 00422 c_size_mult = ext_bits(csd, 49, 47); 00423 read_bl_len = ext_bits(csd, 83, 80); 00424 00425 block_len = 1 << read_bl_len; 00426 mult = 1 << (c_size_mult + 2); 00427 blocknr = (c_size + 1) * mult; 00428 capacity = blocknr * block_len; 00429 blocks = capacity / 512; 00430 //debug_if(SD_DBG, "\n\rSDCard\n\rc_size: %d \n\rcapacity: %ld \n\rsectors: %lld\n\r", c_size, capacity, blocks); 00431 break; 00432 00433 case 1: 00434 cdv = 1; 00435 hc_c_size = ext_bits(csd, 63, 48); 00436 blocks = (hc_c_size+1)*1024; 00437 //debug_if(SD_DBG, "\n\rSDHC Card \n\rhc_c_size: %d\n\rcapacity: %lld \n\rsectors: %lld\n\r", hc_c_size, blocks*512, blocks); 00438 break; 00439 00440 default: 00441 debug("CSD struct unsupported\r\n"); 00442 return 0; 00443 }; 00444 return blocks; 00445 }
Generated on Fri Jul 15 2022 14:19:29 by 1.7.2