00001
00039 #include "sd.h"
00040 #include "hw/hw_sd.h"
00041 #include <kern/kfile.h>
00042 #include <drv/timer.h>
00043
00044 #include <fs/fat.h>
00045
00046 #include <cfg/log.h>
00047 #include <cpu/power.h>
00048
00049 #include <string.h>
00050
00055 typedef struct CardCSD
00056 {
00057 uint16_t block_len;
00058 uint32_t block_num;
00059 uint16_t capacity;
00060 } CardCSD;
00061
00062 #define SD_IN_IDLE 0x01
00063 #define SD_STARTTOKEN 0xFE
00064
00065 #define TIMEOUT_NAC 256
00066
00067 #define SD_DEFAULT_BLOCKLEN 512
00068
00072 static KFile *fd;
00073
00077 static bool sd_status;
00078
00079 #define SD_BUSY_TIMEOUT ms_to_ticks(200)
00080
00081 static bool sd_select(bool state)
00082 {
00083 if (state)
00084 {
00085 ticks_t start = timer_clock();
00086 do
00087 {
00088 SD_CS_ON();
00089 if (kfile_getc(fd) == 0xff)
00090 return true;
00091 SD_CS_OFF();
00092 kfile_putc(0xff, fd);
00093 kfile_flush(fd);
00094 cpu_relax();
00095 }
00096 while (timer_clock() - start < SD_BUSY_TIMEOUT);
00097
00098 LOG_ERR("sd_select timeout\n");
00099 return false;
00100 }
00101 else
00102 {
00103 kfile_putc(0xff, fd);
00104 kfile_flush(fd);
00105 SD_CS_OFF();
00106 return true;
00107 }
00108 }
00109
00110 static int16_t sd_waitR1(void)
00111 {
00112 uint8_t datain;
00113
00114 for (int i = 0; i < TIMEOUT_NAC; i++)
00115 {
00116 datain = kfile_getc(fd);
00117 if (datain != 0xff)
00118 return (int16_t)datain;
00119 }
00120 LOG_ERR("Timeout waiting R1\n");
00121 return EOF;
00122 }
00123
00124 static int16_t sd_sendCommand(uint8_t cmd, uint32_t param, uint8_t crc)
00125 {
00126
00127 kfile_putc(cmd | 0x40, fd);
00128
00129
00130 kfile_putc((param >> 24) & 0xFF, fd);
00131 kfile_putc((param >> 16) & 0xFF, fd);
00132 kfile_putc((param >> 8) & 0xFF, fd);
00133 kfile_putc((param) & 0xFF, fd);
00134
00135 kfile_putc(crc, fd);
00136
00137 return sd_waitR1();
00138 }
00139
00140
00141 static bool sd_getBlock(void *buf, size_t len)
00142 {
00143 uint8_t token;
00144 uint16_t crc;
00145
00146 for (int i = 0; i < TIMEOUT_NAC; i++)
00147 {
00148 token = kfile_getc(fd);
00149 if (token != 0xff)
00150 {
00151 if (token == SD_STARTTOKEN)
00152 {
00153 if (kfile_read(fd, buf, len) == len)
00154 {
00155 if (kfile_read(fd, &crc, sizeof(crc)) == sizeof(crc))
00156
00157 return true;
00158 else
00159 LOG_ERR("get_block error getting crc\n");
00160 }
00161 else
00162 LOG_ERR("get_block len error: %d\n", (int)len);
00163 }
00164 else
00165 LOG_ERR("get_block token error: %02X\n", token);
00166
00167 return false;
00168 }
00169 }
00170
00171 LOG_ERR("get_block timeout waiting token\n");
00172 return false;
00173 }
00174
00175 #define SD_SELECT() \
00176 do \
00177 { \
00178 if (!sd_select(true)) \
00179 { \
00180 LOG_ERR("%s failed, card busy\n", __func__); \
00181 return EOF; \
00182 } \
00183 } \
00184 while (0)
00185
00186 #define SD_SETBLOCKLEN 0x50
00187
00188 static int16_t sd_setBlockLen(uint32_t newlen)
00189 {
00190 SD_SELECT();
00191
00192 int16_t r1 = sd_sendCommand(SD_SETBLOCKLEN, newlen, 0);
00193
00194 sd_select(false);
00195 return r1;
00196 }
00197
00198 #define SD_SEND_CSD 0x49
00199
00200 static int16_t sd_getCSD(CardCSD *csd)
00201 {
00202 SD_SELECT();
00203
00204 int16_t r1 = sd_sendCommand(SD_SEND_CSD, 0, 0);
00205
00206 if (r1)
00207 {
00208 LOG_ERR("send_csd failed: %04X\n", r1);
00209 sd_select(false);
00210 return r1;
00211 }
00212
00213 uint8_t buf[16];
00214 bool res = sd_getBlock(buf, sizeof(buf));
00215 sd_select(false);
00216
00217 if (res)
00218 {
00219 uint16_t mult = (1L << ((((buf[9] & 0x03) << 1) | ((buf[10] & 0x80) >> 7)) + 2));
00220 uint16_t c_size = (((uint16_t)(buf[6] & 0x03)) << 10) | (((uint16_t)buf[7]) << 2) |
00221 (((uint16_t)(buf[8] & 0xC0)) >> 6);
00222
00223 csd->block_len = (1L << (buf[5] & 0x0F));
00224 csd->block_num = (c_size + 1) * mult;
00225 csd->capacity = (csd->block_len * csd->block_num) >> 20;
00226
00227 LOG_INFO("block_len %d bytes, block_num %ld, total capacity %dMB\n", csd->block_len, csd->block_num, csd->capacity);
00228 return 0;
00229 }
00230 else
00231 return EOF;
00232 }
00233
00234
00235 #define SD_READ_SINGLEBLOCK 0x51
00236
00237 static int16_t sd_readBlock(void *buf, uint32_t addr)
00238 {
00239 SD_SELECT();
00240
00241 int16_t r1 = sd_sendCommand(SD_READ_SINGLEBLOCK, addr, 0);
00242
00243 if (r1)
00244 {
00245 LOG_ERR("read single block failed: %04X\n", r1);
00246 sd_select(false);
00247 return r1;
00248 }
00249
00250 bool res = sd_getBlock(buf, SD_DEFAULT_BLOCKLEN);
00251 sd_select(false);
00252 if (!res)
00253 {
00254 LOG_ERR("read single block failed reading data\n");
00255 return EOF;
00256 }
00257 else
00258 return 0;
00259 }
00260
00261 #define SD_WRITE_SINGLEBLOCK 0x58
00262 #define SD_DATA_ACCEPTED 0x05
00263
00264 static int16_t sd_writeBlock(const void *buf, uint32_t addr)
00265 {
00266 SD_SELECT();
00267
00268 int16_t r1 = sd_sendCommand(SD_WRITE_SINGLEBLOCK, addr, 0);
00269
00270 if (r1)
00271 {
00272 LOG_ERR("write single block failed: %04X\n", r1);
00273 sd_select(false);
00274 return r1;
00275 }
00276
00277 kfile_putc(SD_STARTTOKEN, fd);
00278 kfile_write(fd, buf, SD_DEFAULT_BLOCKLEN);
00279
00280 kfile_putc(0, fd);
00281 kfile_putc(0, fd);
00282 uint8_t dataresp = (kfile_getc(fd) & 0x1F);
00283 sd_select(false);
00284
00285
00286 if (dataresp != SD_DATA_ACCEPTED)
00287 {
00288 LOG_ERR("write single block failed: %02X\n", dataresp);
00289 return EOF;
00290 }
00291 else
00292 return 0;
00293 }
00294
00295
00296 bool sd_test(void)
00297 {
00298 CardCSD csd;
00299 sd_getCSD(&csd);
00300
00301 uint8_t buf[SD_DEFAULT_BLOCKLEN];
00302
00303 if (sd_readBlock(buf, 0) != 0)
00304 return false;
00305
00306 kputchar('\n');
00307 for (int i = 0; i < SD_DEFAULT_BLOCKLEN; i++)
00308 {
00309 kprintf("%02X ", buf[i]);
00310 buf[i] = i;
00311 if (!((i+1) % 16))
00312 kputchar('\n');
00313 }
00314
00315 if (sd_writeBlock(buf, 0) != 0)
00316 return false;
00317
00318 memset(buf, 0, sizeof(buf));
00319 if (sd_readBlock(buf, 0) != 0)
00320 return false;
00321
00322 kputchar('\n');
00323 for (int i = 0; i < SD_DEFAULT_BLOCKLEN; i++)
00324 {
00325 kprintf("%02X ", buf[i]);
00326 buf[i] = i;
00327 if (!((i+1) % 16))
00328 kputchar('\n');
00329 }
00330
00331 return true;
00332 }
00333
00334 #define SD_GO_IDLE_STATE 0x40
00335 #define SD_GO_IDLE_STATE_CRC 0x95
00336 #define SD_SEND_OP_COND 0x41
00337 #define SD_SEND_OP_COND_CRC 0xF9
00338
00339 #define SD_START_DELAY ms_to_ticks(10)
00340 #define SD_INIT_TIMEOUT ms_to_ticks(1000)
00341 #define SD_IDLE_RETRIES 4
00342
00343 bool sd_init(KFile *_fd)
00344 {
00345 uint16_t r1;
00346
00347 ASSERT(_fd);
00348 fd = _fd;
00349
00350 SD_CS_INIT();
00351 SD_CS_OFF();
00352
00353
00354 timer_delay(SD_START_DELAY);
00355
00356
00357 for (int i = 0; i < 10; i++)
00358 kfile_putc(0xff, fd);
00359 kfile_flush(fd);
00360
00361 for (int i = 0; i < SD_IDLE_RETRIES; i++)
00362 {
00363 SD_SELECT();
00364 r1 = sd_sendCommand(SD_GO_IDLE_STATE, 0, SD_GO_IDLE_STATE_CRC);
00365 sd_select(false);
00366
00367 if (r1 == SD_IN_IDLE)
00368 break;
00369 }
00370
00371 if (r1 != SD_IN_IDLE)
00372 {
00373 LOG_ERR("go_idle_state failed: %04X\n", r1);
00374 return false;
00375 }
00376
00377 ticks_t start = timer_clock();
00378
00379
00380 do
00381 {
00382 SD_SELECT();
00383 r1 = sd_sendCommand(SD_SEND_OP_COND, 0, SD_SEND_OP_COND_CRC);
00384 sd_select(false);
00385 cpu_relax();
00386 }
00387 while (r1 != 0 && timer_clock() - start < SD_INIT_TIMEOUT);
00388
00389 if (r1)
00390 {
00391 LOG_ERR("send_op_cond failed: %04X\n", r1);
00392 return false;
00393 }
00394
00395 r1 = sd_setBlockLen(SD_DEFAULT_BLOCKLEN);
00396
00397 if (r1)
00398 {
00399 LOG_ERR("setBlockLen failed: %04X\n", r1);
00400 return false;
00401 }
00402
00403 sd_status = !r1;
00404 return sd_status;
00405 }
00406
00407 DSTATUS sd_disk_initialize(BYTE drv)
00408 {
00409 return sd_disk_status(drv);
00410 }
00411
00412 DSTATUS sd_disk_status(BYTE drv)
00413 {
00414 ASSERT(!drv);
00415
00416 if (sd_status)
00417 return RES_OK;
00418 else
00419 return STA_NOINIT;
00420 }
00421
00422 DRESULT sd_disk_read(BYTE drv, BYTE* buf, DWORD sector, BYTE count)
00423 {
00424 ASSERT(!drv);
00425
00426 if (!sd_status)
00427 return RES_NOTRDY;
00428
00429 while (count--)
00430 {
00431 if (sd_readBlock(buf, sector * SD_DEFAULT_BLOCKLEN))
00432 return RES_ERROR;
00433 buf += SD_DEFAULT_BLOCKLEN;
00434 sector++;
00435 }
00436 return RES_OK;
00437 }
00438
00439 DRESULT sd_disk_write(BYTE drv, const BYTE* buf, DWORD sector, BYTE count)
00440 {
00441 ASSERT(!drv);
00442
00443 if (!sd_status)
00444 return RES_NOTRDY;
00445
00446 while (count--)
00447 {
00448 if (sd_writeBlock(buf, sector * SD_DEFAULT_BLOCKLEN))
00449 return RES_ERROR;
00450 buf += SD_DEFAULT_BLOCKLEN;
00451 sector++;
00452 }
00453 return RES_OK;
00454 }
00455
00456 DRESULT sd_disk_ioctl(BYTE drv, BYTE cmd, void* buf)
00457 {
00458 ASSERT(!drv);
00459
00460 if (!sd_status)
00461 return RES_NOTRDY;
00462
00463 switch (cmd)
00464 {
00465 case CTRL_SYNC:
00466 return RES_OK;
00467
00468 case GET_SECTOR_SIZE:
00469 *(WORD *)buf = SD_DEFAULT_BLOCKLEN;
00470 return RES_OK;
00471
00472 case GET_SECTOR_COUNT:
00473 {
00474 CardCSD csd;
00475 if (sd_getCSD(&csd))
00476 return RES_ERROR;
00477 else
00478 {
00479 *(DWORD *)buf = csd.block_num;
00480 return RES_OK;
00481 }
00482
00483 }
00484
00485 case GET_BLOCK_SIZE:
00486 *(DWORD *)buf = 1;
00487 return RES_OK;
00488
00489 default:
00490 LOG_ERR("unknown command: [%d]\n", cmd);
00491 return RES_PARERR;
00492 }
00493 }
00494
00495 DWORD get_fattime(void)
00496 {
00497 return 0;
00498 }