diff options
author | Jack Halpin <jack.halpin@gmail.com> | 2010-02-25 06:46:16 +0000 |
---|---|---|
committer | Jack Halpin <jack.halpin@gmail.com> | 2010-02-25 06:46:16 +0000 |
commit | d95211a23d974d175a8609fa3efc7ca43d403993 (patch) | |
tree | 6079a077f5617943b458860bebf07ce83881a70f /firmware/target/arm | |
parent | 62e6a2f9d8f11a4b46c0aa37679c77ff0849dec2 (diff) | |
download | rockbox-d95211a23d974d175a8609fa3efc7ca43d403993.tar.gz rockbox-d95211a23d974d175a8609fa3efc7ca43d403993.zip |
sd-as3525v2: Controller and card init much more reliably now.
Remove MCI_HCON read from init_controller() as it now appears unneccesary.
Make sd-init_card() use similar init sequence to the one in sd-as3525.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24903 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525v2.c | 84 |
1 files changed, 31 insertions, 53 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c index 52db0c0420..0b2699e505 100644 --- a/firmware/target/arm/as3525/sd-as3525v2.c +++ b/firmware/target/arm/as3525/sd-as3525v2.c | |||
@@ -395,88 +395,73 @@ static int sd_init_card(void) | |||
395 | { | 395 | { |
396 | unsigned long response; | 396 | unsigned long response; |
397 | unsigned long temp_reg[4]; | 397 | unsigned long temp_reg[4]; |
398 | int max_tries = 100; /* max acmd41 attemps */ | 398 | long init_timeout; |
399 | bool sd_v2; | 399 | bool sd_v2 = false; |
400 | int i; | 400 | int i; |
401 | 401 | ||
402 | /* assume 24 MHz clock / 60 = 400 kHz */ | 402 | /* assume 24 MHz clock / 60 = 400 kHz */ |
403 | MCI_CLKDIV = (MCI_CLKDIV & ~(0xFF)) | 0x3C; /* CLK_DIV_0 : bits 7:0 */ | 403 | MCI_CLKDIV = (MCI_CLKDIV & ~(0xFF)) | 0x3C; /* CLK_DIV_0 : bits 7:0 */ |
404 | 404 | ||
405 | /* 100 - 400kHz clock required for Identification Mode */ | ||
406 | /* Start of Card Identification Mode ************************************/ | ||
407 | |||
408 | /* CMD0 Go Idle */ | ||
405 | if(!send_cmd(SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL)) | 409 | if(!send_cmd(SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL)) |
406 | return -1; | 410 | return -1; |
407 | |||
408 | mci_delay(); | 411 | mci_delay(); |
409 | 412 | ||
410 | sd_v2 = false; | 413 | /* CMD8 Check for v2 sd card. Must be sent before using ACMD41 |
414 | Non v2 cards will not respond to this command*/ | ||
411 | if(send_cmd(SD_SEND_IF_COND, 0x1AA, MCI_RESP, &response)) | 415 | if(send_cmd(SD_SEND_IF_COND, 0x1AA, MCI_RESP, &response)) |
412 | if((response & 0xFFF) == 0x1AA) | 416 | if((response & 0xFFF) == 0x1AA) |
413 | sd_v2 = true; | 417 | sd_v2 = true; |
414 | 418 | ||
419 | /* timeout for initialization is 1sec, from SD Specification 2.00 */ | ||
420 | init_timeout = current_tick + HZ; | ||
421 | |||
415 | do { | 422 | do { |
416 | /* some MicroSD cards seems to need more delays, so play safe */ | 423 | /* this timeout is the only valid error for this loop*/ |
417 | mci_delay(); | 424 | if(TIME_AFTER(current_tick, init_timeout)) |
418 | mci_delay(); | 425 | return -2; |
419 | mci_delay(); | ||
420 | 426 | ||
421 | /* app_cmd */ | 427 | /* app_cmd */ |
422 | if( !send_cmd(SD_APP_CMD, 0, MCI_RESP, &response) || | 428 | send_cmd(SD_APP_CMD, 0, MCI_RESP, &response); |
423 | !(response & (1<<5))) | ||
424 | { | ||
425 | return -2; | ||
426 | } | ||
427 | 429 | ||
428 | /* acmd41 */ | 430 | /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */ |
429 | if(!send_cmd(SD_APP_OP_COND, (sd_v2 ? 0x40FF8000 : (1<<23)), | 431 | if(!send_cmd(SD_APP_OP_COND, (sd_v2 ? 0x40FF8000 : (1<<23)), |
430 | MCI_RESP, &card_info.ocr)) | 432 | MCI_RESP, &card_info.ocr)) |
431 | return -3; | 433 | return -3; |
432 | } while(!(card_info.ocr & (1<<31)) && max_tries--); | 434 | } while(!(card_info.ocr & (1<<31)) ); |
433 | 435 | ||
434 | if(max_tries < 0) | 436 | /* CMD2 send CID */ |
435 | return -4; | ||
436 | |||
437 | mci_delay(); | ||
438 | mci_delay(); | ||
439 | mci_delay(); | ||
440 | |||
441 | /* send CID */ | ||
442 | if(!send_cmd(SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP, card_info.cid)) | 437 | if(!send_cmd(SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP, card_info.cid)) |
443 | return -5; | 438 | return -5; |
444 | 439 | ||
445 | /* send RCA */ | 440 | for(i=0; i<4; i++) |
441 | card_info.cid[3-i] = temp_reg[i]; | ||
442 | |||
443 | /* CMD3 send RCA */ | ||
446 | if(!send_cmd(SD_SEND_RELATIVE_ADDR, 0, MCI_RESP, &card_info.rca)) | 444 | if(!send_cmd(SD_SEND_RELATIVE_ADDR, 0, MCI_RESP, &card_info.rca)) |
447 | return -6; | 445 | return -4; |
446 | |||
447 | /* End of Card Identification Mode ************************************/ | ||
448 | 448 | ||
449 | /* send CSD */ | 449 | /* CMD9 send CSD */ |
450 | if(!send_cmd(SD_SEND_CSD, card_info.rca, | 450 | if(!send_cmd(SD_SEND_CSD, card_info.rca, |
451 | MCI_RESP|MCI_LONG_RESP, temp_reg)) | 451 | MCI_RESP|MCI_LONG_RESP, temp_reg)) |
452 | return -7; | 452 | return -5; |
453 | 453 | ||
454 | for(i=0; i<4; i++) | 454 | for(i=0; i<4; i++) |
455 | card_info.csd[3-i] = temp_reg[i]; | 455 | card_info.csd[3-i] = temp_reg[i]; |
456 | 456 | ||
457 | sd_parse_csd(&card_info); | 457 | sd_parse_csd(&card_info); |
458 | 458 | ||
459 | if(!send_cmd(SD_APP_CMD, 0, MCI_RESP, &response) || | 459 | /* Card back to full speed */ |
460 | !send_cmd(42, 0, MCI_NO_RESP, NULL)) /* disconnect the 50 KOhm pull-up | 460 | MCI_CLKDIV &= ~(0xFF); /* CLK_DIV_0 : bits 7:0 = 0x00 */ |
461 | resistor on CD/DAT3 */ | ||
462 | return -13; | ||
463 | |||
464 | if(!send_cmd(SD_APP_CMD, card_info.rca, MCI_NO_RESP, NULL)) | ||
465 | return -10; | ||
466 | |||
467 | if(!send_cmd(SD_SET_BUS_WIDTH, card_info.rca | 2, MCI_NO_RESP, NULL)) | ||
468 | return -11; | ||
469 | 461 | ||
462 | /* CMD7 w/rca: Select card to put it in TRAN state */ | ||
470 | if(!send_cmd(SD_SELECT_CARD, card_info.rca, MCI_NO_RESP, NULL)) | 463 | if(!send_cmd(SD_SELECT_CARD, card_info.rca, MCI_NO_RESP, NULL)) |
471 | return -9; | 464 | return -6; |
472 | |||
473 | /* not sent in init_card() by OF */ | ||
474 | if(!send_cmd(SD_SET_BLOCKLEN, card_info.blocksize, MCI_NO_RESP, | ||
475 | NULL)) | ||
476 | return -12; | ||
477 | |||
478 | /* Card back to full speed */ | ||
479 | MCI_CLKDIV &= ~(0xFF); /* CLK_DIV_0 : bits 7:0 */ | ||
480 | 465 | ||
481 | card_info.initialized = 1; | 466 | card_info.initialized = 1; |
482 | 467 | ||
@@ -529,13 +514,6 @@ static void sd_thread(void) | |||
529 | 514 | ||
530 | static void init_controller(void) | 515 | static void init_controller(void) |
531 | { | 516 | { |
532 | |||
533 | int temp = MCI_HCON; /* we just need to read HCON */ | ||
534 | (void)temp; | ||
535 | // panicf("HCON: %8x",temp); | ||
536 | // int idx = (MCI_HCON >> 1) & 31; /* Maximum card Index */ | ||
537 | // int idx_bits = (1 << idx) -1; | ||
538 | |||
539 | MCI_PWREN = 0x0; /* power off all cards */ | 517 | MCI_PWREN = 0x0; /* power off all cards */ |
540 | 518 | ||
541 | MCI_CLKSRC = 0x00; /* All CLK_SRC_CRD set to 0*/ | 519 | MCI_CLKSRC = 0x00; /* All CLK_SRC_CRD set to 0*/ |