spisdcard: revert to 8-bit SPI, optimize spisdcardreceive_block and reduce clk to 12.5MHz for now.

This commit is contained in:
Florent Kermarrec 2020-07-17 11:58:26 +02:00
parent 8143f1a08b
commit 754f140a9d
2 changed files with 27 additions and 19 deletions

View File

@ -1263,7 +1263,7 @@ class LiteXSoC(SoC):
pads = self.platform.request(name) pads = self.platform.request(name)
if hasattr(pads, "rst"): if hasattr(pads, "rst"):
self.comb += pads.rst.eq(0) 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() spisdcard.add_clk_divider()
setattr(self.submodules, name, spisdcard) setattr(self.submodules, name, spisdcard)
self.add_csr(name) self.add_csr(name)

View File

@ -24,20 +24,25 @@
#define SPISDCARD_CLK_FREQ_INIT 400000 #define SPISDCARD_CLK_FREQ_INIT 400000
#endif #endif
#ifndef SPISDCARD_CLK_FREQ #ifndef SPISDCARD_CLK_FREQ
#define SPISDCARD_CLK_FREQ 16000000 #define SPISDCARD_CLK_FREQ 12500000
#endif #endif
/*-----------------------------------------------------------------------*/
/* Helpers */
/*-----------------------------------------------------------------------*/
#define max(x, y) (((x) > (y)) ? (x) : (y))
#define min(x, y) (((x) < (y)) ? (x) : (y))
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SPI Master low-level functions */ /* SPI Master low-level functions */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static void spi_set_clk_freq(uint32_t clk_freq) { static void spi_set_clk_freq(uint32_t clk_freq) {
uint32_t divider; uint32_t divider;
divider = CONFIG_CLOCK_FREQUENCY/clk_freq + 1; divider = CONFIG_CLOCK_FREQUENCY/clk_freq;
if (divider >= 65535) /* 16-bit hardware divider */ divider = max(divider, 2);
divider = 65535; divider = min(divider, 256);
if (divider <= 2) /* At least half CPU speed */
divider = 2;
#ifdef SPISDCARD_DEBUG #ifdef SPISDCARD_DEBUG
printf("Setting SDCard clk freq to "); printf("Setting SDCard clk freq to ");
if (clk_freq > 1000000) if (clk_freq > 1000000)
@ -125,7 +130,8 @@ static void busy_wait_us(unsigned int us)
} }
static uint8_t spisdcardreceive_block(uint8_t *buf) { static uint8_t spisdcardreceive_block(uint8_t *buf) {
uint8_t i; uint16_t i;
uint8_t done;
uint32_t timeout; uint32_t timeout;
/* Wait 100ms for a start of block */ /* Wait 100ms for a start of block */
@ -140,17 +146,19 @@ static uint8_t spisdcardreceive_block(uint8_t *buf) {
return 0; return 0;
/* Receive block */ /* Receive block */
spisdcard_mosi_write(0xffffffff); spisdcard_mosi_write(0xff);
for (i=0; i<128; i++) { i = 0;
uint32_t word; for (;;) {
spisdcard_control_write(32*SPI_LENGTH | SPI_START); done = spisdcard_status_read() & SPI_DONE;
while(spisdcard_status_read() != SPI_DONE); if (done) {
word = spisdcard_miso_read(); spisdcard_control_write(8*SPI_LENGTH | SPI_START);
buf[0] = (word >> 24) & 0xff; *buf = spisdcard_miso_read();
buf[1] = (word >> 16) & 0xff; if (i == 512)
buf[2] = (word >> 8) & 0xff; break;
buf[3] = (word >> 0) & 0xff; if (i != 0)
buf += 4; buf++;
i++;
}
} }
/* Discard CRC */ /* Discard CRC */