test

Committer:
emh203
Date:
Sun Feb 21 02:45:09 2010 +0000
Revision:
0:c1253c12d4bc

        

Who changed what in which revision?

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