sd.c

Go to the documentation of this file.
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> /* memset */
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     /* The 7th bit of command must be a 1 */
00127     kfile_putc(cmd | 0x40, fd);
00128 
00129     /* send parameter */
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                         /* check CRC here if needed */
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; // in MB
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     /* send fake crc */
00280     kfile_putc(0, fd);
00281     kfile_putc(0, fd);
00282     uint8_t dataresp = (kfile_getc(fd) & 0x1F);
00283     sd_select(false);
00284 
00285     // FIXME: sometimes dataresp is 0, find out why.
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     /* Wait a few moments for supply voltage to stabilize */
00354     timer_delay(SD_START_DELAY);
00355 
00356     /* Give 80 clk pulses to wake up the card */
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     /* Wait for card to start */
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 }