sd_sam3.c
Go to the documentation of this file.
00001
00038 #include "hw/hw_sd.h"
00039 #include "cfg/cfg_sd.h"
00040
00041 #include <drv/sd.h>
00042 #include <drv/timer.h>
00043 #include <drv/hsmci_sam3.h>
00044
00045 #include <io/kfile.h>
00046 #include <io/kblock.h>
00047
00048 #include <fs/fat.h>
00049
00050 #define LOG_LEVEL  SD_LOG_LEVEL
00051 #define LOG_FORMAT SD_LOG_FORMAT
00052 #include <cfg/log.h>
00053 #include <cpu/power.h>
00054
00055 #include <string.h> /* memset */
00056
00057
00058 #define SD_SEND_ALL_CID        BV(0)
00059 #define SD_STATUS_APP_CMD      BV(5)
00060 #define SD_STATUS_READY        BV(8)
00061 #define SD_CARD_IS_LOCKED      BV(25)
00062 
00063 #define SD_OCR_CCS              BV(30)     
00064 #define SD_OCR_BUSY             BV(31)     
00066 #define SD_OCR_VDD_27_28        BV(15)
00067 #define SD_OCR_VDD_28_29        BV(16)
00068 #define SD_OCR_VDD_29_30        BV(17)
00069 #define SD_OCR_VDD_30_31        BV(18)
00070 #define SD_OCR_VDD_31_32        BV(19)
00071 #define SD_OCR_VDD_32_33        BV(20)
00072 
00073
00074 #define SD_HOST_VOLTAGE_RANGE     (SD_OCR_VDD_27_28 | \
00075                                    SD_OCR_VDD_28_29 | \
00076                                    SD_OCR_VDD_29_30 | \
00077                                    SD_OCR_VDD_30_31 | \
00078                                    SD_OCR_VDD_31_32 | \
00079                                    SD_OCR_VDD_32_33)
00080 
00081
00082 #define CMD8_V_RANGE_CHECK_PAT    0xAA
00083 #define CMD8_V_RANGE_27V_36V      (0x100 | CMD8_V_RANGE_CHECK_PAT)
00084 #define CMD8_V_RANGE_LOW          (0x1000 | CMD8_V_RANGE_CHECK_PAT)
00085 #define CMD8_V_ECHO_REPLY         0xFF
00086 #define CMD8_SUPP_V_RANGE_REPLY   0xFF00
00087 
00088 #define SD_STATUS_ERROR          BV(19)
00089 
00090 #define SD_GET_ERRORS(status)   ((status) & 0xFFF80000)
00091 #define SD_ADDR_TO_RCA(addr)    (uint32_t)(((addr) << 16) & 0xFFFF0000)
00092 #define SD_GET_STATE(status)    (uint8_t)(((status) & 0x1E00) >> 9)
00093 
00094 static const uint32_t tran_exp[] =
00095 {
00096     10000,      100000,     1000000,    10000000,
00097     0,      0,      0,      0
00098 };
00099
00100 static const uint8_t tran_mant[] =
00101 {
00102     0,  10, 12, 13, 15, 20, 25, 30,
00103     35, 40, 45, 50, 55, 60, 70, 80,
00104 };
00105
00106
00107 void sd_dumpCsd(SdCSD *csd);
00108 void sd_dumpCid(SdCID *cid);
00109 void sd_dumpSsr(SdSSR *ssr);
00110
00111 void sd_sendInit(void);
00112 void sd_goIdle(void);
00113 int sd_sendIfCond(Sd *sd);
00114 int sd_sendAppOpCond(Sd *sd);
00115
00116 int sd_getCid(Sd *sd, SdCID *cid, uint32_t addr, uint8_t flag);
00117 int sd_getCsd(Sd *sd, SdCSD *csd);
00118 int sd_getSrc(Sd *sd);
00119
00120 int sd_appStatus(Sd *sd);
00121 int sd_getRelativeAddr(Sd *sd);
00122 int sd_getStatus(Sd *sd, SdSSR *ssr, uint32_t *buf, size_t words);
00123
00124 int sd_selectCard(Sd *sd);
00125 int sd_deSelectCard(Sd *sd);
00126 int sd_setBusWidth(Sd *sd, size_t len);
00127 int sd_set_BlockLen(Sd *sd, size_t len);
00128 void sd_setHightSpeed(Sd *sd);
00129
00130
00131 INLINE int sd_setBus4bit(Sd *sd)
00132 {
00133     return sd_setBusWidth(sd, 4);
00134 }
00135
00136 INLINE int sd_setBus1bit(Sd *sd)
00137 {
00138     return sd_setBusWidth(sd, 1);
00139 }
00140
00141
00142 LOG_INFOB(
00143 static void dump(const char *label, uint32_t *r, size_t len)
00144 {
00145     ASSERT(r);
00146     size_t i;
00147     int j = 0;
00148     kprintf("\n%s [\n", label);
00149     for (i = 0; i < len; i++)
00150     {
00151         if (j == 5)
00152         {
00153             kputs("\n");
00154             j = 0;
00155         }
00156         kprintf("%08lx ", r[i]);
00157         j++;
00158     }
00159     kprintf("\n] len=%d\n\n", i);
00160 }
00161 )
00162
00163 void sd_dumpCsd(SdCSD *csd)
00164 {
00165     ASSERT(csd);
00166
00167     LOG_INFO("VERSION: %d.0\n", csd->structure ? 2 : 1);
00168     LOG_INFO("CARD COMMAND CLASS: %d\n", csd->ccc);
00169     LOG_INFO("MAX DATA RATE: %ld\n", csd->max_data_rate);
00170     LOG_INFO("WRITE BLK LEN BITS: %ld\n", csd->write_blk_bits);
00171     LOG_INFO("READ BLK LEN BITS: %ld\n", csd->read_blk_bits);
00172     LOG_INFO("ERASE SIZE: %ld\n", csd->erase_size);
00173     LOG_INFO("BLK NUM: %ld\n", csd->block_num);
00174     LOG_INFO("BLK LEN: %ld\n", csd->block_len);
00175     LOG_INFO("CAPACITY %ld\n", csd->capacity);
00176     LOG_INFO("FLAG Write: WP %d, W MISALIGN %d\n", csd->write_partial, csd->write_misalign);
00177     LOG_INFO("FLAG Read: RP %d, R MISALIGN %d\n", csd->read_partial, csd->read_misalign);
00178
00179 }
00180
00181 void sd_dumpCid(SdCID *cid)
00182 {
00183     ASSERT(cid);
00184
00185     LOG_INFO("MANFID: %d\n", cid->manfid);
00186     LOG_INFO("OEMID: %d\n", cid->oemid);
00187     LOG_INFO("SERIAL: %ld\n", cid->serial);
00188     LOG_INFO("PROD_NAME: %s\n", cid->prod_name);
00189     LOG_INFO("REV: %d.%d\n", cid->m_rev, cid->l_rev);
00190     LOG_INFO("OFF,Y,M: %lx, %ld %ld\n", cid->year_off, (BCD_TO_INT_32BIT(cid->year_off) / 12) + 2000,
00191                                                 (BCD_TO_INT_32BIT(cid->year_off) % 12));
00192 }
00193
00194 void sd_dumpSsr(SdSSR *ssr)
00195 {
00196     ASSERT(ssr);
00197
00198     LOG_INFO("BUS_WIDTH: %d\n", ssr->bus_width);
00199     LOG_INFO("TYPE: %d\n", ssr->card_type);
00200     LOG_INFO("AU_TYPE: %d\n", ssr->au_size);
00201     LOG_INFO("ERASE_SIZE: %d\n", ssr->erase_size);
00202     LOG_INFO("SPEED_CLASS: %d\n", ssr->speed_class);
00203 }
00204
00205
00206 static int sd_decodeCsd(SdCSD *csd, uint32_t *resp, size_t len)
00207 {
00208     ASSERT(csd);
00209     ASSERT(resp);
00210     ASSERT(len >= 4);
00211
00212     csd->structure = UNSTUFF_BITS(resp, 126, 2);
00213     csd->ccc = UNSTUFF_BITS(resp, 84, 12);
00214
00215     csd->max_data_rate  = tran_exp[UNSTUFF_BITS(resp, 96, 3)] * tran_mant[UNSTUFF_BITS(resp, 99, 4)];
00216
00217     /*
00218      * CSD structure:
00219      * - 0:
00220      *      - Version 1.01-1.10
00221      *      - Version 2.00/Standard Capacity
00222      * - 1:
00223      *      - Version 2.00/High Capacity
00224      * - >1: not defined.
00225      */
00226
00227     if (csd->structure == 0)
00228     {
00229         // (C_size + 1) x 2^(C_SIZE_MUL+2)
00230         csd->block_num = (1 + UNSTUFF_BITS(resp, 62, 12)) << (UNSTUFF_BITS(resp, 47, 3) + 2);
00231
00232         csd->read_blk_bits = UNSTUFF_BITS(resp, 80, 4);
00233         csd->write_blk_bits = UNSTUFF_BITS(resp, 22, 4);
00234
00235         csd->block_len = 1 << csd->read_blk_bits;
00236         csd->capacity  = csd->block_num * csd->block_len;
00237
00238         csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
00239         csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
00240
00241         csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
00242         csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
00243
00244         if (UNSTUFF_BITS(resp, 46, 1))
00245         {
00246             csd->erase_size = 1;
00247         }
00248         else if(csd->write_blk_bits >= 9)
00249         {
00250             csd->erase_size = UNSTUFF_BITS(resp, 39, 7) + 1;
00251             csd->erase_size <<= csd->write_blk_bits - 9;
00252         }
00253
00254         return 0;
00255     }
00256     else if (csd->structure == 1)
00257     {
00258         kprintf("csize %ld\n", UNSTUFF_BITS(resp, 48, 22));
00259         csd->capacity  = (1 + UNSTUFF_BITS(resp, 48, 22)) << 10;
00260
00261         csd->write_blk_bits = 9;
00262         csd->write_partial = 0;
00263         csd->write_misalign = 0;
00264
00265         csd->read_blk_bits = 9;
00266         csd->read_partial = 0;
00267         csd->read_misalign = 0;
00268
00269         csd->erase_size = 1;
00270         // the block size if fixed to 512kb
00271         csd->block_len = (1 << csd->write_blk_bits) << 10;
00272
00273         return 0;
00274     }
00275     else
00276     {
00277         kprintf("Unrecognised CSD structure version %d\n", csd->structure);
00278         return -1;
00279     }
00280
00281     return 0;
00282 }
00283
00284 void sd_sendInit(void)
00285 {
00286     hsmci_init(NULL); //TODO: REMOVE IT!
00287
00288     if (hsmci_sendCmd(0, 0, HSMCI_CMDR_SPCMD_INIT | HSMCI_CMDR_RSPTYP_NORESP))
00289         LOG_ERR("INIT: %lx\n", HSMCI_SR);
00290 }
00291
00292
00293 void sd_goIdle(void)
00294 {
00295     hsmci_setSpeed(HSMCI_INIT_SPEED, false);
00296     if (hsmci_sendCmd(0, 0, HSMCI_CMDR_RSPTYP_NORESP))
00297         LOG_ERR("GO_IDLE: %lx\n", HSMCI_SR);
00298 }
00299
00300 int sd_sendIfCond(Sd *sd)
00301 {
00302     if (hsmci_sendCmd(8, CMD8_V_RANGE_27V_36V, HSMCI_CMDR_RSPTYP_48_BIT))
00303     {
00304         LOG_ERR("IF_COND %lx\n", HSMCI_SR);
00305         return -1;
00306     }
00307     hsmci_readResp(&(sd->status), 1);
00308     if (((sd->status) & 0xFFF) == CMD8_V_RANGE_27V_36V)
00309     {
00310         LOG_INFO("IF_COND: %lx\n", (sd->status));
00311         return 0;
00312     }
00313     LOG_ERR("IF_COND: %lx\n", (sd->status));
00314     return -1;
00315 }
00316
00317 int sd_sendAppOpCond(Sd *sd)
00318 {
00319     if (hsmci_sendCmd(55, 0, HSMCI_CMDR_RSPTYP_48_BIT))
00320     {
00321         LOG_ERR("APP_CMD %lx\n", HSMCI_SR);
00322         return -1;
00323     }
00324
00325     hsmci_readResp(&(sd->status), 1);
00326     if ((sd->status) & (SD_STATUS_APP_CMD | SD_STATUS_READY))
00327     {
00328         if (hsmci_sendCmd(41, SD_HOST_VOLTAGE_RANGE | SD_OCR_CCS, HSMCI_CMDR_RSPTYP_48_BIT))// se cmd 8 va ok.
00329         {
00330             LOG_ERR("APP_OP_COND %lx\n", HSMCI_SR);
00331             return -1;
00332         }
00333         else
00334         {
00335             hsmci_readResp(&(sd->status), 1);
00336             if ((sd->status) & SD_OCR_BUSY)
00337             {
00338                 LOG_INFO("SD power up! Hight Capability [%d]\n", (bool)((sd->status) & SD_OCR_CCS));
00339                 return 0;
00340             }
00341         }
00342     }
00343
00344     return -1;
00345 }
00346
00347
00348 int sd_getCid(Sd *sd, SdCID *cid, uint32_t addr, uint8_t flag)
00349 {
00350     ASSERT(sd);
00351     ASSERT(cid);
00352     memset(cid, 0, sizeof(SdCID));
00353
00354     uint8_t idx = 9; // CMD9 get cid from gived sd address (RCA)
00355     if (flag & SD_SEND_ALL_CID)
00356         idx = 2;
00357
00358
00359     if (hsmci_sendCmd(idx, SD_ADDR_TO_RCA(addr), HSMCI_CMDR_RSPTYP_136_BIT))
00360     {
00361         LOG_ERR("GET_CID %lx\n", HSMCI_SR);
00362         return -1;
00363     }
00364     else
00365     {
00366         uint32_t resp[4];
00367         hsmci_readResp(resp, 4);
00368         LOG_INFOB(dump("CID", resp, 4););
00369
00370         cid->manfid        = UNSTUFF_BITS(resp, 120, 8);
00371         cid->oemid         = UNSTUFF_BITS(resp, 104, 16);
00372         cid->prod_name[0]      = UNSTUFF_BITS(resp, 96, 8);
00373         cid->prod_name[1]      = UNSTUFF_BITS(resp, 88, 8);
00374         cid->prod_name[2]      = UNSTUFF_BITS(resp, 80, 8);
00375         cid->prod_name[3]      = UNSTUFF_BITS(resp, 72, 8);
00376         cid->prod_name[4]      = UNSTUFF_BITS(resp, 64, 8);
00377         cid->m_rev         = UNSTUFF_BITS(resp, 60, 4);
00378         cid->l_rev         = UNSTUFF_BITS(resp, 56, 4);
00379         cid->serial        = (uint32_t)UNSTUFF_BITS(resp, 24, 32);
00380         cid->year_off      = UNSTUFF_BITS(resp, 8, 12);
00381     }
00382
00383     return 0;
00384 }
00385
00386 int sd_getCsd(Sd *sd, SdCSD *csd)
00387 {
00388     ASSERT(sd);
00389     ASSERT(csd);
00390     memset(csd, 0, sizeof(SdCSD));
00391
00392     LOG_INFO("Send to RCA: %lx\n", SD_ADDR_TO_RCA(sd->addr));
00393     if (hsmci_sendCmd(9, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_136_BIT))
00394     {
00395         LOG_ERR("GET_CSD %lx\n", HSMCI_SR);
00396         return -1;
00397     }
00398     else
00399     {
00400         uint32_t resp[4];
00401         hsmci_readResp(resp, 4);
00402         LOG_INFOB(dump("CSD", resp, 4););
00403         sd_decodeCsd(csd, resp, 4);
00404     }
00405
00406     return 0;
00407 }
00408
00409 int sd_getRelativeAddr(Sd *sd)
00410 {
00411     ASSERT(sd);
00412     if (hsmci_sendCmd(3, 0, HSMCI_CMDR_RSPTYP_48_BIT))
00413     {
00414         LOG_ERR("RCA: %lx\n", HSMCI_SR);
00415         return -1;
00416     }
00417
00418     hsmci_readResp(&sd->addr, 1);
00419     sd->addr = sd->addr >> 16;
00420
00421     LOG_INFOB(dump("RCA", &sd->addr, 1););
00422
00423     return 0;
00424 }
00425
00426 int sd_appStatus(Sd *sd)
00427 {
00428     ASSERT(sd);
00429     LOG_INFO("Send to RCA: %lx\n", SD_ADDR_TO_RCA(sd->addr));
00430     if (hsmci_sendCmd(13, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
00431     {
00432         LOG_ERR("STATUS: %lx\n", HSMCI_SR);
00433         sd->status |= SD_STATUS_ERROR;
00434         return -1;
00435     }
00436
00437     hsmci_readResp(&(sd->status), 1);
00438     LOG_INFOB(dump("STATUS", &(sd->status), 1););
00439
00440     LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
00441
00442     if (sd->status & SD_STATUS_READY)
00443         return 0;
00444
00445     return -1;
00446 }
00447
00448
00449 INLINE int sd_cardSelection(Sd *sd, uint32_t rca)
00450 {
00451     ASSERT(sd);
00452     LOG_INFO("Select RCA: %lx\n", rca);
00453     if (hsmci_sendCmd(7, rca, HSMCI_CMDR_RSPTYP_R1B))
00454     {
00455         LOG_ERR("SELECT_SD: %lx\n", HSMCI_SR);
00456         sd->status |= SD_STATUS_ERROR;
00457         return -1;
00458     }
00459
00460     HSMCI_CHECK_BUSY();
00461     hsmci_readResp(&(sd->status), 1);
00462     LOG_INFOB(dump("SELECT_SD", &(sd->status), 1););
00463
00464     LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
00465
00466     if (sd->status & SD_STATUS_READY)
00467         return 0;
00468
00469     return -1;
00470 }
00471
00472 int sd_selectCard(Sd *sd)
00473 {
00474     ASSERT(sd);
00475     uint32_t rca = SD_ADDR_TO_RCA(sd->addr);
00476     LOG_INFO("Select RCA: %lx\n", rca);
00477     if (hsmci_sendCmd(7, rca, HSMCI_CMDR_RSPTYP_R1B))
00478     {
00479         LOG_ERR("SELECT_SD: %lx\n", HSMCI_SR);
00480         return -1;
00481     }
00482
00483     HSMCI_CHECK_BUSY();
00484     hsmci_readResp(&(sd->status), 1);
00485
00486     LOG_INFOB(dump("SELECT_SD", &(sd->status), 1););
00487     LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
00488
00489     if (sd->status & SD_STATUS_READY)
00490         return 0;
00491
00492     return -1;
00493 }
00494
00495 int sd_deSelectCard(Sd *sd)
00496 {
00497     ASSERT(sd);
00498
00499     uint32_t rca = 0;
00500     if (!sd->addr)
00501         rca = SD_ADDR_TO_RCA(sd->addr + 1);
00502
00503     LOG_INFO("Select RCA: %lx\n", rca);
00504
00505     if (hsmci_sendCmd(7, rca, HSMCI_CMDR_RSPTYP_NORESP))
00506     {
00507         LOG_ERR("DESELECT_SD: %lx\n", HSMCI_SR);
00508         return -1;
00509     }
00510
00511     return 0;
00512 }
00513
00514 int sd_setBusWidth(Sd *sd, size_t len)
00515 {
00516     ASSERT(sd);
00517
00518     if (hsmci_sendCmd(55, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
00519     {
00520         LOG_ERR("APP_CMD %lx\n", HSMCI_SR);
00521         return -1;
00522     }
00523
00524     hsmci_readResp(&(sd->status), 1);
00525     if ((sd->status) & (SD_STATUS_APP_CMD | SD_STATUS_READY))
00526     {
00527
00528         uint8_t arg = 0;
00529         if (len == 4)
00530             arg = 2;
00531
00532         if (hsmci_sendCmd(6, arg, HSMCI_CMDR_RSPTYP_48_BIT))
00533         {
00534             LOG_ERR("SET_BUS_WIDTH CMD: %lx\n", HSMCI_SR);
00535             return -1;
00536         }
00537
00538         hsmci_readResp(&(sd->status), 1);
00539
00540         LOG_INFOB(dump("SET_BUS_WIDTH", &(sd->status), 1););
00541         LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
00542
00543         if (sd->status & SD_STATUS_READY)
00544         {
00545             hsmci_setBusWidth(len);
00546             return 0;
00547         }
00548     }
00549
00550     LOG_ERR("SET_BUS_WIDTH REP %lx\n", (sd->status));
00551     return -1;
00552 }
00553
00554
00555 int sd_set_BlockLen(Sd *sd, size_t len)
00556 {
00557     ASSERT(sd);
00558
00559     if (hsmci_sendCmd(16, len, HSMCI_CMDR_RSPTYP_48_BIT))
00560     {
00561         LOG_ERR("SET_BLK_LEN: %lx\n", HSMCI_SR);
00562         return -1;
00563     }
00564
00565     hsmci_readResp(&(sd->status), 1);
00566
00567     LOG_INFOB(dump("SET_BLK_LEN", &(sd->status), 1););
00568     LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
00569
00570     sd->b.blk_size = len;
00571
00572     if (sd->status & SD_STATUS_READY)
00573         return 0;
00574
00575     return -1;
00576 }
00577
00578 int sd_getStatus(Sd *sd, SdSSR *ssr, uint32_t *buf, size_t words)
00579 {
00580     ASSERT(sd);
00581     ASSERT(ssr);
00582
00583     // Status reply with 512bit data, so the block size in byte is 64
00584     hsmci_read(buf, words, 64);
00585
00586     if (hsmci_sendCmd(55, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
00587     {
00588         LOG_ERR("APP_CMD %lx\n", HSMCI_SR);
00589         return -1;
00590     }
00591
00592     hsmci_readResp(&(sd->status), 1);
00593     if (sd->status & (SD_STATUS_APP_CMD | SD_STATUS_READY))
00594     {
00595         if (hsmci_sendCmd(13, 0, HSMCI_CMDR_RSPTYP_48_BIT |
00596                 BV(HSMCI_CMDR_TRDIR) | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_SINGLE))
00597         {
00598             LOG_ERR("STATUS CMD: %lx\n", HSMCI_SR);
00599             return -1;
00600         }
00601
00602         hsmci_readResp(&(sd->status), 1);
00603         LOG_INFOB(dump("STATUS", &(sd->status), 1););
00604         LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
00605
00606         if (sd->status & SD_STATUS_READY)
00607         {
00608             hsmci_waitTransfer();
00609
00610             LOG_INFOB(dump("STATUS", buf, words););
00611             memset(ssr, 0, sizeof(SdSSR));
00612             ssr->bus_width  = UNSTUFF_BITS(buf, 510, 2);
00613             ssr->card_type  = UNSTUFF_BITS(buf, 480, 16);
00614             ssr->au_size  = UNSTUFF_BITS(buf, 432, 8);
00615             ssr->speed_class  = UNSTUFF_BITS(buf, 440, 8);
00616             ssr->erase_size = UNSTUFF_BITS(buf, 408, 24);
00617
00618             return 0;
00619         }
00620     }
00621
00622     return -1;
00623 }
00624
00625
00626 void sd_setHightSpeed(Sd *sd)
00627 {
00628     (void)sd;
00629     hsmci_setSpeed(HSMCI_HIGH_SPEED, HSMCI_HS_MODE);
00630 }
00631
00632
00633 static size_t sd_SdReadDirect(struct KBlock *b, block_idx_t idx, void *buf, size_t offset, size_t size)
00634 {
00635     ASSERT(buf);
00636     ASSERT(!((uint32_t)buf & 0x3));
00637
00638     Sd *sd = SD_CAST(b);
00639     LOG_INFO("reading from block %ld, offset %d, size %d\n", idx, offset, size);
00640
00641     hsmci_waitTransfer();
00642     hsmci_read(buf, size / 4, sd->b.blk_size);
00643
00644     if (hsmci_sendCmd(17, idx * sd->b.blk_size + offset, HSMCI_CMDR_RSPTYP_48_BIT |
00645             BV(HSMCI_CMDR_TRDIR) | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_SINGLE))
00646     {
00647         LOG_ERR("SIGLE_BLK_READ: %lx\n", HSMCI_SR);
00648         return -1;
00649     }
00650
00651     hsmci_readResp(&(sd->status), 1);
00652
00653     LOG_INFOB(dump("SIGLE_BLK_READ", &(sd->status), 1););
00654     LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
00655
00656     if (sd->status & SD_STATUS_READY)
00657     {
00658         hsmci_waitTransfer();
00659         return size;
00660     }
00661     return -1;
00662 }
00663
00664 static size_t sd_SdWriteDirect(KBlock *b, block_idx_t idx, const void *buf, size_t offset, size_t size)
00665 {
00666     ASSERT(buf);
00667     ASSERT(!((uint32_t)buf & 0x3));
00668
00669     Sd *sd = SD_CAST(b);
00670     const uint32_t *_buf = (const uint32_t *)buf;
00671     LOG_INFO("writing block %ld, offset %d, size %d\n", idx, offset, size);
00672
00673     hsmci_waitTransfer();
00674     hsmci_write(_buf, size / 4, sd->b.blk_size);
00675
00676     if (hsmci_sendCmd(24, idx * sd->b.blk_size + offset, HSMCI_CMDR_RSPTYP_48_BIT |
00677                         HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_SINGLE))
00678     {
00679         LOG_ERR("SIGLE_BLK_WRITE: %lx\n", HSMCI_SR);
00680         return -1;
00681     }
00682
00683     hsmci_readResp(&(sd->status), 1);
00684
00685     LOG_INFOB(dump("SIGLE_BLK_WR", &(sd->status), 1););
00686     LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
00687
00688     if (sd->status & SD_STATUS_READY)
00689     {
00690         return size;
00691     }
00692
00693     return -1;
00694 }
00695
00696
00697 static int sd_SdError(KBlock *b)
00698 {
00699     Sd *sd = SD_CAST(b);
00700     return SD_GET_ERRORS(sd->status);
00701 }
00702
00703 static void sd_SdClearerr(KBlock *b)
00704 {
00705     Sd *sd = SD_CAST(b);
00706     sd->status = 0;
00707 }
00708
00709 static bool sd_blockInit(Sd *sd, KFile *ch)
00710 {
00711     (void)ch;
00712     ASSERT(sd);
00713     memset(sd, 0, sizeof(*sd));
00714     DB(sd->b.priv.type = KBT_SD);
00715
00716     /* Wait a few moments for supply voltage to stabilize */
00717     timer_delay(SD_START_DELAY);
00718
00719     sd_sendInit();
00720     sd_goIdle();
00721
00722     sd_sendIfCond(sd);
00723
00724     ticks_t start = timer_clock();
00725     bool sd_power_on = false;
00726     do
00727     {
00728         if (!sd_sendAppOpCond(sd))
00729         {
00730             sd_power_on = true;
00731             break;
00732         }
00733         cpu_relax();
00734     }
00735     while (timer_clock() - start < SD_INIT_TIMEOUT);
00736
00737
00738     if (sd_power_on)
00739     {
00740         SdCID cid;
00741         if(sd_getCid(sd, &cid, 0, SD_SEND_ALL_CID) < 0)
00742             return false;
00743         else
00744         {
00745             sd_dumpCid(&cid);
00746         }
00747
00748         if (sd_getRelativeAddr(sd) < 0)
00749             return false;
00750         else
00751         {
00752             LOG_INFO("RCA: %0lx\n", sd->addr);
00753         }
00754
00755         SdCSD csd;
00756         if (sd_getCsd(sd, &csd) < 0)
00757             return false;
00758         else
00759         {
00760             sd->b.blk_cnt = csd.block_num * (csd.block_len / SD_DEFAULT_BLOCKLEN);
00761             LOG_INFO("blk_size %d, blk_cnt %ld\n", sd->b.blk_size, sd->b.blk_cnt);
00762             sd_dumpCsd(&csd);
00763         }
00764
00765         if (sd_appStatus(sd) < 0)
00766         {
00767             LOG_INFO("STATUS: %ld\n", sd->status);
00768             return false;
00769         }
00770
00771         if (sd->status & SD_CARD_IS_LOCKED)
00772         {
00773             LOG_INFO("SD is locked!\n");
00774             return false;
00775         }
00776
00777         if (sd->status & SD_STATUS_READY)
00778         {
00779             sd_selectCard(sd);
00780             sd_set_BlockLen(sd, SD_DEFAULT_BLOCKLEN);
00781             sd_setBus4bit(sd);
00782             sd_setHightSpeed(sd);
00783
00784             #if CONFIG_SD_AUTOASSIGN_FAT
00785                 disk_assignDrive(&sd->b, 0);
00786             #endif
00787 
00788             return true;
00789         }
00790     }
00791     LOG_ERR("SD not ready.\n");
00792     return false;
00793 }
00794
00795 static const KBlockVTable sd_unbuffered_vt =
00796 {
00797     .readDirect = sd_SdReadDirect,
00798     .writeDirect = sd_SdWriteDirect,
00799
00800     .error = sd_SdError,
00801     .clearerr = sd_SdClearerr,
00802 };
00803
00804 static const KBlockVTable sd_buffered_vt =
00805 {
00806     .readDirect = sd_SdReadDirect,
00807     .writeDirect = sd_SdWriteDirect,
00808
00809     .readBuf = kblock_swReadBuf,
00810     .writeBuf = kblock_swWriteBuf,
00811     .load = kblock_swLoad,
00812     .store = kblock_swStore,
00813
00814     .error = sd_SdError,
00815     .clearerr = sd_SdClearerr,
00816 };
00817
00818 bool sd_hw_initUnbuf(Sd *sd, KFile *ch)
00819 {
00820     if (sd_blockInit(sd, ch))
00821     {
00822         sd->b.priv.vt = &sd_unbuffered_vt;
00823         return true;
00824     }
00825     else
00826         return false;
00827 }
00828
00829 static uint8_t sd_buf[SD_DEFAULT_BLOCKLEN];
00830
00831 bool sd_hw_initBuf(Sd *sd, KFile *ch)
00832 {
00833     if (sd_blockInit(sd, ch))
00834     {
00835         sd->b.priv.buf = sd_buf;
00836         sd->b.priv.flags |= KB_BUFFERED | KB_PARTIAL_WRITE;
00837         sd->b.priv.vt = &sd_buffered_vt;
00838         sd->b.priv.vt->load(&sd->b, 0);
00839         return true;
00840     }
00841     else
00842         return false;
00843 }
00844
00845
00846