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
![(please configure the [header_logo] section in trac.ini)](/chrome/site/bertos_logo.png)