updated chan_fatfs

Dependents:   HARP2 HARP3

Fork of chan_fatfs by Eli Hughes

Committer:
emh203
Date:
Mon Jan 10 15:02:22 2011 +0000
Revision:
1:68378811b1e2
test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emh203 1:68378811b1e2 1 /*-----------------------------------------------------------------------*/
emh203 1:68378811b1e2 2 /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
emh203 1:68378811b1e2 3 /*-----------------------------------------------------------------------*/
emh203 1:68378811b1e2 4 /* This is a stub disk I/O module that acts as front end of the existing */
emh203 1:68378811b1e2 5 /* disk I/O modules and attach it to FatFs module with common interface. */
emh203 1:68378811b1e2 6 /*-----------------------------------------------------------------------*/
emh203 1:68378811b1e2 7
emh203 1:68378811b1e2 8 #include "diskio.h"
emh203 1:68378811b1e2 9 #include "mbed.h"
emh203 1:68378811b1e2 10
emh203 1:68378811b1e2 11
emh203 1:68378811b1e2 12 //******************************************************************************************************************
emh203 1:68378811b1e2 13 // MBED SPI/CS Select functions.... Modify for your layout.
emh203 1:68378811b1e2 14 //**************************************************************************************
emh203 1:68378811b1e2 15
emh203 1:68378811b1e2 16 SPI _spi(p5, p6, p7); // mosi, miso, sclk
emh203 1:68378811b1e2 17 DigitalOut _cs(p8);
emh203 1:68378811b1e2 18
emh203 1:68378811b1e2 19 //******************************************************************************************************************
emh203 1:68378811b1e2 20 // Low Level Sector Access Function Prototypes('C' Castrated versions of Simon Ford's C++ MBED SDFileSystem class
emh203 1:68378811b1e2 21 //******************************************************************************************************************
emh203 1:68378811b1e2 22 int _cmd(int cmd, int arg);
emh203 1:68378811b1e2 23 int _read(BYTE *buffer, int length);
emh203 1:68378811b1e2 24 int _write(BYTE *buffer, int length);
emh203 1:68378811b1e2 25 int ext_bits(BYTE *data, int msb, int lsb);
emh203 1:68378811b1e2 26 int _sd_sectors();
emh203 1:68378811b1e2 27 int _sectors;
emh203 1:68378811b1e2 28
emh203 1:68378811b1e2 29 #define SD_COMMAND_TIMEOUT 5000
emh203 1:68378811b1e2 30
emh203 1:68378811b1e2 31
emh203 1:68378811b1e2 32 //******************************************************************************************************************
emh203 1:68378811b1e2 33 // Sector Access functions for CHAN FatFs
emh203 1:68378811b1e2 34 //******************************************************************************************************************
emh203 1:68378811b1e2 35
emh203 1:68378811b1e2 36 DRESULT disk_ioctl (
emh203 1:68378811b1e2 37 BYTE drv, /* Physical drive nmuber (0..) */
emh203 1:68378811b1e2 38 BYTE ctrl, /* Control code */
emh203 1:68378811b1e2 39 void *buff /* Buffer to send/receive control data */
emh203 1:68378811b1e2 40 )
emh203 1:68378811b1e2 41 {
emh203 1:68378811b1e2 42 DRESULT res;
emh203 1:68378811b1e2 43
emh203 1:68378811b1e2 44 switch(ctrl)
emh203 1:68378811b1e2 45 {
emh203 1:68378811b1e2 46 case CTRL_SYNC:
emh203 1:68378811b1e2 47 res = RES_OK;
emh203 1:68378811b1e2 48 break;
emh203 1:68378811b1e2 49
emh203 1:68378811b1e2 50 case GET_SECTOR_SIZE:
emh203 1:68378811b1e2 51 res = RES_OK;
emh203 1:68378811b1e2 52 *(WORD *)buff = 512;
emh203 1:68378811b1e2 53 break;
emh203 1:68378811b1e2 54
emh203 1:68378811b1e2 55 case GET_SECTOR_COUNT:
emh203 1:68378811b1e2 56 res = RES_OK;
emh203 1:68378811b1e2 57 *(DWORD *)buff = (WORD)_sd_sectors();
emh203 1:68378811b1e2 58 break;
emh203 1:68378811b1e2 59
emh203 1:68378811b1e2 60 case GET_BLOCK_SIZE:
emh203 1:68378811b1e2 61 res = RES_OK;
emh203 1:68378811b1e2 62 *(DWORD *)buff = 1;
emh203 1:68378811b1e2 63 break;
emh203 1:68378811b1e2 64
emh203 1:68378811b1e2 65 default:
emh203 1:68378811b1e2 66 res = RES_OK;
emh203 1:68378811b1e2 67 break;
emh203 1:68378811b1e2 68 }
emh203 1:68378811b1e2 69 return res;
emh203 1:68378811b1e2 70 }
emh203 1:68378811b1e2 71
emh203 1:68378811b1e2 72 DSTATUS disk_initialize(BYTE Drive) {
emh203 1:68378811b1e2 73
emh203 1:68378811b1e2 74 _spi.frequency(100000); // Set to 100kHz for initialisation
emh203 1:68378811b1e2 75
emh203 1:68378811b1e2 76 // Initialise the card by clocking it a bit (cs = 1)
emh203 1:68378811b1e2 77 for(int i=0; i<16; i++) {
emh203 1:68378811b1e2 78 _spi.write(0xFF);
emh203 1:68378811b1e2 79 }
emh203 1:68378811b1e2 80
emh203 1:68378811b1e2 81 // send CMD0, should return with all zeros except IDLE STATE set (bit 0)
emh203 1:68378811b1e2 82 if(_cmd(0, 0) != 0x01) {
emh203 1:68378811b1e2 83 fprintf(stderr, "Not in idle state\n");
emh203 1:68378811b1e2 84 return STA_NOINIT;
emh203 1:68378811b1e2 85 }
emh203 1:68378811b1e2 86
emh203 1:68378811b1e2 87 // ACMD41 to give host capacity support (repeat until not busy)
emh203 1:68378811b1e2 88 // ACMD41 is application specific command, so we send APP_CMD (CMD55) beforehand
emh203 1:68378811b1e2 89 for(int i=0;; i++) {
emh203 1:68378811b1e2 90 _cmd(55, 0);
emh203 1:68378811b1e2 91 int response = _cmd(41, 0);
emh203 1:68378811b1e2 92 if(response == 0) {
emh203 1:68378811b1e2 93 break;
emh203 1:68378811b1e2 94 } else if(i > SD_COMMAND_TIMEOUT) {
emh203 1:68378811b1e2 95 fprintf(stderr, "Timeout waiting for card\n");
emh203 1:68378811b1e2 96 return STA_NOINIT;
emh203 1:68378811b1e2 97 }
emh203 1:68378811b1e2 98 }
emh203 1:68378811b1e2 99
emh203 1:68378811b1e2 100 _sectors = _sd_sectors();
emh203 1:68378811b1e2 101
emh203 1:68378811b1e2 102 // Set block length to 512 (CMD16)
emh203 1:68378811b1e2 103 if(_cmd(16, 512) != 0) {
emh203 1:68378811b1e2 104 fprintf(stderr, "Set block timeout\n");
emh203 1:68378811b1e2 105 return STA_NOINIT;
emh203 1:68378811b1e2 106 }
emh203 1:68378811b1e2 107
emh203 1:68378811b1e2 108 _spi.frequency(10000000); // Set to 10MHz for data transfer
emh203 1:68378811b1e2 109 return 0;
emh203 1:68378811b1e2 110 }
emh203 1:68378811b1e2 111
emh203 1:68378811b1e2 112 DRESULT disk_write(BYTE Drive,const BYTE * Buffer, DWORD SectorNumber, BYTE SectorCount)
emh203 1:68378811b1e2 113 {
emh203 1:68378811b1e2 114 BYTE i;
emh203 1:68378811b1e2 115
emh203 1:68378811b1e2 116 BYTE * MyBufOut = (BYTE *)Buffer;
emh203 1:68378811b1e2 117
emh203 1:68378811b1e2 118 for(i=0;i<SectorCount;i++)
emh203 1:68378811b1e2 119 {
emh203 1:68378811b1e2 120 // set write address for single block (CMD24)
emh203 1:68378811b1e2 121 if(_cmd(24, (SectorNumber + i) * 512 ) != 0) {
emh203 1:68378811b1e2 122 return RES_ERROR;
emh203 1:68378811b1e2 123 }
emh203 1:68378811b1e2 124
emh203 1:68378811b1e2 125 // send the data block
emh203 1:68378811b1e2 126 _write(MyBufOut, 512);
emh203 1:68378811b1e2 127
emh203 1:68378811b1e2 128 MyBufOut+=512;
emh203 1:68378811b1e2 129 }
emh203 1:68378811b1e2 130 return RES_OK;
emh203 1:68378811b1e2 131 }
emh203 1:68378811b1e2 132
emh203 1:68378811b1e2 133 DRESULT disk_read(BYTE Drive, BYTE * Buffer,DWORD SectorNumber, BYTE SectorCount)
emh203 1:68378811b1e2 134 {
emh203 1:68378811b1e2 135 BYTE i;
emh203 1:68378811b1e2 136 for(i=0;i<SectorCount;i++)
emh203 1:68378811b1e2 137 {
emh203 1:68378811b1e2 138 // set read address for single block (CMD17)
emh203 1:68378811b1e2 139 if(_cmd(17, (SectorNumber+i) * 512) != 0)
emh203 1:68378811b1e2 140 {
emh203 1:68378811b1e2 141 return RES_ERROR;
emh203 1:68378811b1e2 142 }
emh203 1:68378811b1e2 143 // receive the data
emh203 1:68378811b1e2 144 _read(Buffer, 512);
emh203 1:68378811b1e2 145
emh203 1:68378811b1e2 146 Buffer+=512;
emh203 1:68378811b1e2 147 }
emh203 1:68378811b1e2 148 return RES_OK;
emh203 1:68378811b1e2 149 }
emh203 1:68378811b1e2 150
emh203 1:68378811b1e2 151
emh203 1:68378811b1e2 152 DWORD get_fattime(void)
emh203 1:68378811b1e2 153 {
emh203 1:68378811b1e2 154 time_t CurrentTimeStamp;
emh203 1:68378811b1e2 155 tm *CurrentLocalTime;
emh203 1:68378811b1e2 156 DWORD FATFSTimeCode;
emh203 1:68378811b1e2 157
emh203 1:68378811b1e2 158 CurrentTimeStamp = time(NULL);
emh203 1:68378811b1e2 159 CurrentLocalTime = localtime(&CurrentTimeStamp);
emh203 1:68378811b1e2 160
emh203 1:68378811b1e2 161 //Map the tm struct time into the FatFs time code
emh203 1:68378811b1e2 162 FATFSTimeCode = ((CurrentLocalTime->tm_year-80)<<25) |
emh203 1:68378811b1e2 163 ((CurrentLocalTime->tm_mon+1)<<21) |
emh203 1:68378811b1e2 164 ((CurrentLocalTime->tm_mday)<<16) |
emh203 1:68378811b1e2 165 ((CurrentLocalTime->tm_hour)<<11) |
emh203 1:68378811b1e2 166 ((CurrentLocalTime->tm_min)<<5) |
emh203 1:68378811b1e2 167 ((CurrentLocalTime->tm_sec));
emh203 1:68378811b1e2 168
emh203 1:68378811b1e2 169 return FATFSTimeCode;
emh203 1:68378811b1e2 170 }
emh203 1:68378811b1e2 171
emh203 1:68378811b1e2 172 DSTATUS disk_status(BYTE Drive)
emh203 1:68378811b1e2 173 {
emh203 1:68378811b1e2 174 return 0;
emh203 1:68378811b1e2 175 }
emh203 1:68378811b1e2 176
emh203 1:68378811b1e2 177 //**************************************************************************************
emh203 1:68378811b1e2 178 // Low Level Sector Access Functions (Castrated versions of Simon Fords C++ MBED class
emh203 1:68378811b1e2 179 //**************************************************************************************
emh203 1:68378811b1e2 180
emh203 1:68378811b1e2 181 int _cmd(int cmd, int arg) {
emh203 1:68378811b1e2 182 _cs = 0;
emh203 1:68378811b1e2 183
emh203 1:68378811b1e2 184 // send a command
emh203 1:68378811b1e2 185 _spi.write(0x40 | cmd);
emh203 1:68378811b1e2 186 _spi.write(arg >> 24);
emh203 1:68378811b1e2 187 _spi.write(arg >> 16);
emh203 1:68378811b1e2 188 _spi.write(arg >> 8);
emh203 1:68378811b1e2 189 _spi.write(arg >> 0);
emh203 1:68378811b1e2 190 _spi.write(0x95);
emh203 1:68378811b1e2 191
emh203 1:68378811b1e2 192 // wait for the repsonse (response[7] == 0)
emh203 1:68378811b1e2 193 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
emh203 1:68378811b1e2 194 int response = _spi.write(0xFF);
emh203 1:68378811b1e2 195 if(!(response & 0x80)) {
emh203 1:68378811b1e2 196 _cs = 1;
emh203 1:68378811b1e2 197 return response;
emh203 1:68378811b1e2 198 }
emh203 1:68378811b1e2 199 }
emh203 1:68378811b1e2 200 _cs = 1;
emh203 1:68378811b1e2 201 return -1; // timeout
emh203 1:68378811b1e2 202 }
emh203 1:68378811b1e2 203
emh203 1:68378811b1e2 204 int _read(BYTE *buffer, int length) {
emh203 1:68378811b1e2 205 _cs = 0;
emh203 1:68378811b1e2 206
emh203 1:68378811b1e2 207 // read until start byte (0xFF)
emh203 1:68378811b1e2 208 while(_spi.write(0xFF) != 0xFE);
emh203 1:68378811b1e2 209
emh203 1:68378811b1e2 210 // read data
emh203 1:68378811b1e2 211 for(int i=0; i<length; i++) {
emh203 1:68378811b1e2 212 buffer[i] = _spi.write(0xFF);
emh203 1:68378811b1e2 213 }
emh203 1:68378811b1e2 214 _spi.write(0xFF); // checksum
emh203 1:68378811b1e2 215 _spi.write(0xFF);
emh203 1:68378811b1e2 216
emh203 1:68378811b1e2 217 _cs = 1;
emh203 1:68378811b1e2 218 return 0;
emh203 1:68378811b1e2 219 }
emh203 1:68378811b1e2 220
emh203 1:68378811b1e2 221 int _write(BYTE *buffer, int length) {
emh203 1:68378811b1e2 222 _cs = 0;
emh203 1:68378811b1e2 223
emh203 1:68378811b1e2 224 // indicate start of block
emh203 1:68378811b1e2 225 _spi.write(0xFE);
emh203 1:68378811b1e2 226
emh203 1:68378811b1e2 227 // write the data
emh203 1:68378811b1e2 228 for(int i=0; i<length; i++) {
emh203 1:68378811b1e2 229 _spi.write(buffer[i]);
emh203 1:68378811b1e2 230 }
emh203 1:68378811b1e2 231
emh203 1:68378811b1e2 232 // write the checksum
emh203 1:68378811b1e2 233 _spi.write(0xFF);
emh203 1:68378811b1e2 234 _spi.write(0xFF);
emh203 1:68378811b1e2 235
emh203 1:68378811b1e2 236 // check the repsonse token
emh203 1:68378811b1e2 237 if((_spi.write(0xFF) & 0x1F) != 0x05) {
emh203 1:68378811b1e2 238 _cs = 1;
emh203 1:68378811b1e2 239 return 1;
emh203 1:68378811b1e2 240 }
emh203 1:68378811b1e2 241
emh203 1:68378811b1e2 242 // wait for write to finish
emh203 1:68378811b1e2 243 while(_spi.write(0xFF) == 0);
emh203 1:68378811b1e2 244
emh203 1:68378811b1e2 245 _cs = 1;
emh203 1:68378811b1e2 246 return 0;
emh203 1:68378811b1e2 247 }
emh203 1:68378811b1e2 248
emh203 1:68378811b1e2 249 int ext_bits(BYTE *data, int msb, int lsb) {
emh203 1:68378811b1e2 250 int bits = 0;
emh203 1:68378811b1e2 251 int size = 1 + msb - lsb;
emh203 1:68378811b1e2 252 for(int i=0; i<size; i++) {
emh203 1:68378811b1e2 253 int position = lsb + i;
emh203 1:68378811b1e2 254 int byte = 15 - (position >> 3);
emh203 1:68378811b1e2 255 int bit = position & 0x7;
emh203 1:68378811b1e2 256 int value = (data[byte] >> bit) & 1;
emh203 1:68378811b1e2 257 bits |= value << i;
emh203 1:68378811b1e2 258 }
emh203 1:68378811b1e2 259 return bits;
emh203 1:68378811b1e2 260 }
emh203 1:68378811b1e2 261
emh203 1:68378811b1e2 262 int _sd_sectors() {
emh203 1:68378811b1e2 263
emh203 1:68378811b1e2 264 // CMD9, Response R2 (R1 byte + 16-byte block read)
emh203 1:68378811b1e2 265 if(_cmd(9, 0) != 0) {
emh203 1:68378811b1e2 266 fprintf(stderr, "Didn't get a response from the disk\n");
emh203 1:68378811b1e2 267 return 0;
emh203 1:68378811b1e2 268 }
emh203 1:68378811b1e2 269
emh203 1:68378811b1e2 270 BYTE csd[16];
emh203 1:68378811b1e2 271 if(_read(csd, 16) != 0) {
emh203 1:68378811b1e2 272 fprintf(stderr, "Couldn't read csd response from disk\n");
emh203 1:68378811b1e2 273 return 0;
emh203 1:68378811b1e2 274 }
emh203 1:68378811b1e2 275
emh203 1:68378811b1e2 276 // csd_structure : csd[127:126]
emh203 1:68378811b1e2 277 // c_size : csd[73:62]
emh203 1:68378811b1e2 278 // c_size_mult : csd[49:47]
emh203 1:68378811b1e2 279 // read_bl_len : csd[83:80]
emh203 1:68378811b1e2 280
emh203 1:68378811b1e2 281 int csd_structure = ext_bits(csd, 127, 126);
emh203 1:68378811b1e2 282 int c_size = ext_bits(csd, 73, 62);
emh203 1:68378811b1e2 283 int c_size_mult = ext_bits(csd, 49, 47);
emh203 1:68378811b1e2 284 int read_bl_len = ext_bits(csd, 83, 80);
emh203 1:68378811b1e2 285
emh203 1:68378811b1e2 286 if(csd_structure != 0) {
emh203 1:68378811b1e2 287 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures");
emh203 1:68378811b1e2 288 return 0;
emh203 1:68378811b1e2 289 }
emh203 1:68378811b1e2 290
emh203 1:68378811b1e2 291 int blocks = (c_size + 1) * (1 << (c_size_mult + 2));
emh203 1:68378811b1e2 292 int block_size = 1 << read_bl_len;
emh203 1:68378811b1e2 293
emh203 1:68378811b1e2 294 if(block_size != 512) {
emh203 1:68378811b1e2 295 fprintf(stderr, "This disk tastes funny! I only like 512 byte blocks (%d)\r\n",block_size);
emh203 1:68378811b1e2 296 return 0;
emh203 1:68378811b1e2 297 }
emh203 1:68378811b1e2 298
emh203 1:68378811b1e2 299 return blocks;
emh203 1:68378811b1e2 300 }