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