diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index aee695c10..6e64e8493 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -1263,7 +1263,7 @@ class LiteXSoC(SoC): pads = self.platform.request(name) if hasattr(pads, "rst"): self.comb += pads.rst.eq(0) - spisdcard = SPIMaster(pads, 32, self.sys_clk_freq, spi_clk_freq, mode="aligned") + spisdcard = SPIMaster(pads, 8, self.sys_clk_freq, spi_clk_freq) spisdcard.add_clk_divider() setattr(self.submodules, name, spisdcard) self.add_csr(name) diff --git a/litex/soc/software/liblitesdcard/spisdcard.c b/litex/soc/software/liblitesdcard/spisdcard.c index 7131d0830..55854b76a 100644 --- a/litex/soc/software/liblitesdcard/spisdcard.c +++ b/litex/soc/software/liblitesdcard/spisdcard.c @@ -24,20 +24,25 @@ #define SPISDCARD_CLK_FREQ_INIT 400000 #endif #ifndef SPISDCARD_CLK_FREQ -#define SPISDCARD_CLK_FREQ 16000000 +#define SPISDCARD_CLK_FREQ 12500000 #endif +/*-----------------------------------------------------------------------*/ +/* Helpers */ +/*-----------------------------------------------------------------------*/ + +#define max(x, y) (((x) > (y)) ? (x) : (y)) +#define min(x, y) (((x) < (y)) ? (x) : (y)) + /*-----------------------------------------------------------------------*/ /* SPI Master low-level functions */ /*-----------------------------------------------------------------------*/ static void spi_set_clk_freq(uint32_t clk_freq) { uint32_t divider; - divider = CONFIG_CLOCK_FREQUENCY/clk_freq + 1; - if (divider >= 65535) /* 16-bit hardware divider */ - divider = 65535; - if (divider <= 2) /* At least half CPU speed */ - divider = 2; + divider = CONFIG_CLOCK_FREQUENCY/clk_freq; + divider = max(divider, 2); + divider = min(divider, 256); #ifdef SPISDCARD_DEBUG printf("Setting SDCard clk freq to "); if (clk_freq > 1000000) @@ -125,7 +130,8 @@ static void busy_wait_us(unsigned int us) } static uint8_t spisdcardreceive_block(uint8_t *buf) { - uint8_t i; + uint16_t i; + uint8_t done; uint32_t timeout; /* Wait 100ms for a start of block */ @@ -140,17 +146,19 @@ static uint8_t spisdcardreceive_block(uint8_t *buf) { return 0; /* Receive block */ - spisdcard_mosi_write(0xffffffff); - for (i=0; i<128; i++) { - uint32_t word; - spisdcard_control_write(32*SPI_LENGTH | SPI_START); - while(spisdcard_status_read() != SPI_DONE); - word = spisdcard_miso_read(); - buf[0] = (word >> 24) & 0xff; - buf[1] = (word >> 16) & 0xff; - buf[2] = (word >> 8) & 0xff; - buf[3] = (word >> 0) & 0xff; - buf += 4; + spisdcard_mosi_write(0xff); + i = 0; + for (;;) { + done = spisdcard_status_read() & SPI_DONE; + if (done) { + spisdcard_control_write(8*SPI_LENGTH | SPI_START); + *buf = spisdcard_miso_read(); + if (i == 512) + break; + if (i != 0) + buf++; + i++; + } } /* Discard CRC */