test
Embed:
(wiki syntax)
Show/hide line numbers
diskio.c
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 00011 00012 //****************************************************************************************************************** 00013 // MBED SPI/CS Select functions.... Modify for your layout. 00014 //************************************************************************************** 00015 00016 SPI _spi(p5, p6, p7); // mosi, miso, sclk 00017 DigitalOut _cs(p8); 00018 00019 //****************************************************************************************************************** 00020 // Low Level Sector Access Function Prototypes('C' Castrated versions of Simon Ford's C++ MBED SDFileSystem class 00021 //****************************************************************************************************************** 00022 int _cmd(int cmd, int arg); 00023 int _read(BYTE *buffer, int length); 00024 int _write(BYTE *buffer, int length); 00025 int ext_bits(BYTE *data, int msb, int lsb); 00026 int _sd_sectors(); 00027 int _sectors; 00028 00029 #define SD_COMMAND_TIMEOUT 5000 00030 00031 00032 //****************************************************************************************************************** 00033 // Sector Access functions for CHAN FatFs 00034 //****************************************************************************************************************** 00035 00036 DRESULT disk_ioctl ( 00037 BYTE drv, /* Physical drive nmuber (0..) */ 00038 BYTE ctrl, /* Control code */ 00039 void *buff /* Buffer to send/receive control data */ 00040 ) 00041 { 00042 DRESULT res; 00043 00044 switch(ctrl) 00045 { 00046 case CTRL_SYNC: 00047 res = RES_OK; 00048 break; 00049 00050 case GET_SECTOR_SIZE: 00051 res = RES_OK; 00052 *(WORD *)buff = 512; 00053 break; 00054 00055 case GET_SECTOR_COUNT: 00056 res = RES_OK; 00057 *(DWORD *)buff = (WORD)_sd_sectors(); 00058 break; 00059 00060 case GET_BLOCK_SIZE: 00061 res = RES_OK; 00062 *(DWORD *)buff = 1; 00063 break; 00064 00065 default: 00066 res = RES_OK; 00067 break; 00068 } 00069 return res; 00070 } 00071 00072 DSTATUS disk_initialize(BYTE Drive) { 00073 00074 _spi.frequency(100000); // Set to 100kHz for initialisation 00075 00076 // Initialise the card by clocking it a bit (cs = 1) 00077 for(int i=0; i<16; i++) { 00078 _spi.write(0xFF); 00079 } 00080 00081 // send CMD0, should return with all zeros except IDLE STATE set (bit 0) 00082 if(_cmd(0, 0) != 0x01) { 00083 fprintf(stderr, "Not in idle state\n"); 00084 return STA_NOINIT; 00085 } 00086 00087 // ACMD41 to give host capacity support (repeat until not busy) 00088 // ACMD41 is application specific command, so we send APP_CMD (CMD55) beforehand 00089 for(int i=0;; i++) { 00090 _cmd(55, 0); 00091 int response = _cmd(41, 0); 00092 if(response == 0) { 00093 break; 00094 } else if(i > SD_COMMAND_TIMEOUT) { 00095 fprintf(stderr, "Timeout waiting for card\n"); 00096 return STA_NOINIT; 00097 } 00098 } 00099 00100 _sectors = _sd_sectors(); 00101 00102 // Set block length to 512 (CMD16) 00103 if(_cmd(16, 512) != 0) { 00104 fprintf(stderr, "Set block timeout\n"); 00105 return STA_NOINIT; 00106 } 00107 00108 _spi.frequency(10000000); // Set to 10MHz for data transfer 00109 return 0; 00110 } 00111 00112 DRESULT disk_write(BYTE Drive,const BYTE * Buffer, DWORD SectorNumber, BYTE SectorCount) 00113 { 00114 BYTE i; 00115 00116 BYTE * MyBufOut = (BYTE *)Buffer; 00117 00118 for(i=0;i<SectorCount;i++) 00119 { 00120 // set write address for single block (CMD24) 00121 if(_cmd(24, (SectorNumber + i) * 512 ) != 0) { 00122 return RES_ERROR; 00123 } 00124 00125 // send the data block 00126 _write(MyBufOut, 512); 00127 00128 MyBufOut+=512; 00129 } 00130 return RES_OK; 00131 } 00132 00133 DRESULT disk_read(BYTE Drive, BYTE * Buffer,DWORD SectorNumber, BYTE SectorCount) 00134 { 00135 BYTE i; 00136 for(i=0;i<SectorCount;i++) 00137 { 00138 // set read address for single block (CMD17) 00139 if(_cmd(17, (SectorNumber+i) * 512) != 0) 00140 { 00141 return RES_ERROR; 00142 } 00143 // receive the data 00144 _read(Buffer, 512); 00145 00146 Buffer+=512; 00147 } 00148 return RES_OK; 00149 } 00150 00151 00152 DWORD get_fattime(void) 00153 { 00154 time_t CurrentTimeStamp; 00155 tm *CurrentLocalTime; 00156 DWORD FATFSTimeCode; 00157 00158 CurrentTimeStamp = time(NULL); 00159 CurrentLocalTime = localtime(&CurrentTimeStamp); 00160 00161 //Map the tm struct time into the FatFs time code 00162 FATFSTimeCode = ((CurrentLocalTime->tm_year-80)<<25) | 00163 ((CurrentLocalTime->tm_mon+1)<<21) | 00164 ((CurrentLocalTime->tm_mday)<<16) | 00165 ((CurrentLocalTime->tm_hour)<<11) | 00166 ((CurrentLocalTime->tm_min)<<5) | 00167 ((CurrentLocalTime->tm_sec)); 00168 00169 return FATFSTimeCode; 00170 } 00171 00172 DSTATUS disk_status(BYTE Drive) 00173 { 00174 return 0; 00175 } 00176 00177 //************************************************************************************** 00178 // Low Level Sector Access Functions (Castrated versions of Simon Fords C++ MBED class 00179 //************************************************************************************** 00180 00181 int _cmd(int cmd, int arg) { 00182 _cs = 0; 00183 00184 // send a command 00185 _spi.write(0x40 | cmd); 00186 _spi.write(arg >> 24); 00187 _spi.write(arg >> 16); 00188 _spi.write(arg >> 8); 00189 _spi.write(arg >> 0); 00190 _spi.write(0x95); 00191 00192 // wait for the repsonse (response[7] == 0) 00193 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00194 int response = _spi.write(0xFF); 00195 if(!(response & 0x80)) { 00196 _cs = 1; 00197 return response; 00198 } 00199 } 00200 _cs = 1; 00201 return -1; // timeout 00202 } 00203 00204 int _read(BYTE *buffer, int length) { 00205 _cs = 0; 00206 00207 // read until start byte (0xFF) 00208 while(_spi.write(0xFF) != 0xFE); 00209 00210 // read data 00211 for(int i=0; i<length; i++) { 00212 buffer[i] = _spi.write(0xFF); 00213 } 00214 _spi.write(0xFF); // checksum 00215 _spi.write(0xFF); 00216 00217 _cs = 1; 00218 return 0; 00219 } 00220 00221 int _write(BYTE *buffer, int length) { 00222 _cs = 0; 00223 00224 // indicate start of block 00225 _spi.write(0xFE); 00226 00227 // write the data 00228 for(int i=0; i<length; i++) { 00229 _spi.write(buffer[i]); 00230 } 00231 00232 // write the checksum 00233 _spi.write(0xFF); 00234 _spi.write(0xFF); 00235 00236 // check the repsonse token 00237 if((_spi.write(0xFF) & 0x1F) != 0x05) { 00238 _cs = 1; 00239 return 1; 00240 } 00241 00242 // wait for write to finish 00243 while(_spi.write(0xFF) == 0); 00244 00245 _cs = 1; 00246 return 0; 00247 } 00248 00249 int ext_bits(BYTE *data, int msb, int lsb) { 00250 int bits = 0; 00251 int size = 1 + msb - lsb; 00252 for(int i=0; i<size; i++) { 00253 int position = lsb + i; 00254 int byte = 15 - (position >> 3); 00255 int bit = position & 0x7; 00256 int value = (data[byte] >> bit) & 1; 00257 bits |= value << i; 00258 } 00259 return bits; 00260 } 00261 00262 int _sd_sectors() { 00263 00264 // CMD9, Response R2 (R1 byte + 16-byte block read) 00265 if(_cmd(9, 0) != 0) { 00266 fprintf(stderr, "Didn't get a response from the disk\n"); 00267 return 0; 00268 } 00269 00270 BYTE csd[16]; 00271 if(_read(csd, 16) != 0) { 00272 fprintf(stderr, "Couldn't read csd response from disk\n"); 00273 return 0; 00274 } 00275 00276 // csd_structure : csd[127:126] 00277 // c_size : csd[73:62] 00278 // c_size_mult : csd[49:47] 00279 // read_bl_len : csd[83:80] 00280 00281 int csd_structure = ext_bits(csd, 127, 126); 00282 int c_size = ext_bits(csd, 73, 62); 00283 int c_size_mult = ext_bits(csd, 49, 47); 00284 int read_bl_len = ext_bits(csd, 83, 80); 00285 00286 if(csd_structure != 0) { 00287 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures"); 00288 return 0; 00289 } 00290 00291 int blocks = (c_size + 1) * (1 << (c_size_mult + 2)); 00292 int block_size = 1 << read_bl_len; 00293 00294 if(block_size != 512) { 00295 fprintf(stderr, "This disk tastes funny! I only like 512 byte blocks (%d)\r\n",block_size); 00296 return 0; 00297 } 00298 00299 return blocks; 00300 }
Generated on Thu Jul 21 2022 12:09:04 by 1.7.2