summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c73
1 files changed, 39 insertions, 34 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index 919cd50e9d..d7989db073 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -571,50 +571,55 @@ static int sd_select_bank(signed char bank)
571 unsigned char card_data[512]; 571 unsigned char card_data[512];
572 int ret; 572 int ret;
573 573
574 ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN); 574 do {
575 if (ret < 0) 575 /* The ISR will set this to true if an error occurred */
576 return ret - 2; 576 retry = false;
577 577
578 if(!send_cmd(INTERNAL_AS3525, SD_SWITCH_FUNC, 0x80ffffef, MCI_ARG, NULL)) 578 ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN);
579 return -1; 579 if (ret < 0)
580 return ret - 2;
580 581
581 mci_delay(); 582 if(!send_cmd(INTERNAL_AS3525, SD_SWITCH_FUNC, 0x80ffffef, MCI_ARG, NULL))
583 return -1;
582 584
583 if(!send_cmd(INTERNAL_AS3525, 35, 0, MCI_NO_FLAGS, NULL)) 585 mci_delay();
584 return -2;
585 586
586 mci_delay(); 587 if(!send_cmd(INTERNAL_AS3525, 35, 0, MCI_NO_FLAGS, NULL))
588 return -2;
587 589
588 memset(card_data, 0, 512); 590 mci_delay();
589 if(bank == -1)
590 { /* enable bank switching */
591 card_data[0] = 16;
592 card_data[1] = 1;
593 card_data[2] = 10;
594 }
595 else
596 card_data[0] = bank;
597 591
598 dma_retain(); 592 memset(card_data, 0, 512);
599 dma_enable_channel(0, card_data, MCI_FIFO(INTERNAL_AS3525), DMA_PERI_SD, 593 if(bank == -1)
600 DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL); 594 { /* enable bank switching */
595 card_data[0] = 16;
596 card_data[1] = 1;
597 card_data[2] = 10;
598 }
599 else
600 card_data[0] = bank;
601 601
602 MCI_DATA_TIMER(INTERNAL_AS3525) = SD_MAX_WRITE_TIMEOUT; 602 dma_retain();
603 MCI_DATA_LENGTH(INTERNAL_AS3525) = 512; 603 dma_enable_channel(0, card_data, MCI_FIFO(INTERNAL_AS3525), DMA_PERI_SD,
604 MCI_DATA_CTRL(INTERNAL_AS3525) = (1<<0) /* enable */ | 604 DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL);
605 (0<<1) /* transfer direction */ |
606 (1<<3) /* DMA */ |
607 (9<<4) /* 2^9 = 512 */ ;
608 605
609 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 606 MCI_DATA_TIMER(INTERNAL_AS3525) = SD_MAX_WRITE_TIMEOUT;
607 MCI_DATA_LENGTH(INTERNAL_AS3525) = 512;
608 MCI_DATA_CTRL(INTERNAL_AS3525) = (1<<0) /* enable */ |
609 (0<<1) /* transfer direction */ |
610 (1<<3) /* DMA */ |
611 (9<<4) /* 2^9 = 512 */ ;
610 612
611 dma_release(); 613 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
612 614
613 mci_delay(); 615 dma_release();
614 616
615 ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN); 617 mci_delay();
616 if (ret < 0) 618
617 return ret - 4; 619 ret = sd_wait_for_state(INTERNAL_AS3525, SD_TRAN);
620 if (ret < 0)
621 return ret - 4;
622 } while(retry);
618 623
619 card_info[INTERNAL_AS3525].current_bank = (bank == -1) ? 0 : bank; 624 card_info[INTERNAL_AS3525].current_bank = (bank == -1) ? 0 : bank;
620 625
@@ -670,7 +675,7 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start,
670 write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; 675 write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
671 unsigned long bank_start = start; 676 unsigned long bank_start = start;
672 677
673 /* Interrupt handler might set this to true during transfer */ 678 /* The ISR will set this to true if an error occurred */
674 retry = false; 679 retry = false;
675 680
676 /* Only switch banks for internal storage */ 681 /* Only switch banks for internal storage */