software/liblitesdcard: add retries when setting card to Idle.

This commit is contained in:
Florent Kermarrec 2020-06-09 19:59:38 +02:00
parent 04d0ba6187
commit 32ebbc7761
1 changed files with 23 additions and 17 deletions

View File

@ -18,13 +18,13 @@
#ifdef CSR_SPISDCARD_BASE #ifdef CSR_SPISDCARD_BASE
#define SPISDCARD_DEBUG //#define SPISDCARD_DEBUG
#ifndef SPISDCARD_CLK_FREQ_INIT #ifndef SPISDCARD_CLK_FREQ_INIT
#define SPISDCARD_CLK_FREQ_INIT 400000 #define SPISDCARD_CLK_FREQ_INIT 200000
#endif #endif
#ifndef SPISDCARD_CLK_FREQ #ifndef SPISDCARD_CLK_FREQ
#define SPISDCARD_CLK_FREQ 10000000 #define SPISDCARD_CLK_FREQ 25000000
#endif #endif
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -63,14 +63,14 @@ static uint8_t spi_xfer(uint8_t byte) {
/* SDCard Select/Deselect functions */ /* SDCard Select/Deselect functions */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static void spisdcarddeselect(void) { static void spisdcard_deselect(void) {
/* Set SPI CS High */ /* Set SPI CS High */
spisdcard_cs_write(SPI_CS_HIGH); spisdcard_cs_write(SPI_CS_HIGH);
/* Generate 8 dummy clocks */ /* Generate 8 dummy clocks */
spi_xfer(0xff); spi_xfer(0xff);
} }
static int spisdcardselect(void) { static int spisdcard_select(void) {
uint16_t timeout; uint16_t timeout;
/* Set SPI CS Low */ /* Set SPI CS Low */
@ -89,7 +89,7 @@ static int spisdcardselect(void) {
} }
/* Deselect card on error */ /* Deselect card on error */
spisdcarddeselect(); spisdcard_deselect();
return 0; return 0;
} }
@ -158,8 +158,8 @@ static uint8_t spisdcardsend_cmd(uint8_t cmd, uint32_t arg)
/* Select the card and wait for it, except for CMD12: STOP_TRANSMISSION */ /* Select the card and wait for it, except for CMD12: STOP_TRANSMISSION */
if (cmd != CMD12) { if (cmd != CMD12) {
spisdcarddeselect(); spisdcard_deselect();
if (spisdcardselect() == 0) if (spisdcard_select() == 0)
return 0xff; return 0xff;
} }
@ -203,15 +203,21 @@ uint8_t spisdcard_init(void) {
/* Set SPI clk freq to initialization frequency */ /* Set SPI clk freq to initialization frequency */
spi_set_clk_freq(SPISDCARD_CLK_FREQ_INIT); spi_set_clk_freq(SPISDCARD_CLK_FREQ_INIT);
/* Wait 10ms */ timeout = 1000;
busy_wait(10); while (timeout) {
/* Set SDCard in SPI Mode (generate 80 dummy clocks) */ /* Set SDCard in SPI Mode (generate 80 dummy clocks) */
spisdcard_cs_write(SPI_CS_HIGH);
for (i=0; i<10; i++) for (i=0; i<10; i++)
spi_xfer(0xff); spi_xfer(0xff);
spisdcard_cs_write(SPI_CS_LOW);
/* Set SDCard in Idle state */ /* Set SDCard in Idle state */
if (spisdcardsend_cmd(CMD0, 0) != 0x1) if (spisdcardsend_cmd(CMD0, 0) == 0x1)
break;
timeout--;
}
if (timeout == 0)
return 0; return 0;
/* Set SDCard voltages, only supported by ver2.00+ SDCards */ /* Set SDCard voltages, only supported by ver2.00+ SDCards */
@ -253,7 +259,7 @@ DSTATUS disk_initialize(uint8_t drv) {
if (drv) return RES_NOTRDY; if (drv) return RES_NOTRDY;
r = spisdcard_init(); r = spisdcard_init();
spisdcarddeselect(); spisdcard_deselect();
spisdcardstatus = r ? 0 : STA_NOINIT; spisdcardstatus = r ? 0 : STA_NOINIT;
return spisdcardstatus; return spisdcardstatus;
@ -275,7 +281,7 @@ DRESULT disk_read(uint8_t drv, uint8_t *buf, uint32_t sector, uint32_t count) {
if (cmd == CMD18) if (cmd == CMD18)
spisdcardsend_cmd(CMD12, 0); /* STOP_TRANSMISSION */ spisdcardsend_cmd(CMD12, 0); /* STOP_TRANSMISSION */
} }
spisdcarddeselect(); spisdcard_deselect();
if (count) if (count)
return RES_ERROR; return RES_ERROR;