Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 49 additions & 51 deletions ui/lib/sdmmc/sdmmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
#define SD_SPI_SCK 18
#define SD_SPI_MOSI 19

#define SD_SPI_BAUDRATE_INIT (300 * 1000)
#define SD_SPI_BAUDRATE_INIT (400 * 1000)
#define SD_SPI_BAUDRATE (20 * 1000 * 1000)

#define CS_H() gpio_put(SD_SPI_CS, 1) /* Set MMC CS "high" */
Expand Down Expand Up @@ -127,11 +127,11 @@ static int wait_ready(void) /* 1:OK, 0:Timeout */
uint8_t d;
unsigned int tmr;

for (tmr = 5000; tmr; tmr--)
for (tmr = 50000; tmr; tmr--)
{ /* Wait for ready in timeout of 500ms */
rcvr_mmc(&d, 1);
if (d == 0xFF) break;
sleep_us(100);
sleep_us(10);
}

return tmr ? 1 : 0;
Expand Down Expand Up @@ -176,11 +176,11 @@ static int rcvr_datablock( /* 1:OK, 0:Failed */
{
uint8_t d[2];

for (int tmr = 1000; tmr; tmr--)
for (int tmr = 10000; tmr; tmr--)
{ /* Wait for data packet in timeout of 100ms */
rcvr_mmc(d, 1);
if (d[0] != 0xFF) break;
sleep_us(100);
sleep_us(10);
}
if (d[0] != 0xFE) return 0; /* If not valid data token, return with error */

Expand All @@ -194,29 +194,39 @@ static int rcvr_datablock( /* 1:OK, 0:Failed */
/* Send a data packet to the card */
/*-----------------------------------------------------------------------*/

static int xmit_datablock( /* 1:OK, 0:Failed */
const uint8_t *buff, /* 512 byte data block to be transmitted */
uint8_t token /* Data/Stop token */
static int _xmit_datablock( /* 1:OK, 0:Failed */
const uint8_t *buff, /* data block to be transmitted */
uint8_t token, /* Data/Stop token */
unsigned int len, /* length of the data block */
bool wait /* Skip waitingg*/
)
{
uint8_t d[2];
uint8_t d[3];

if (!wait_ready()) return 0;
if (wait)
if(!wait_ready()) return 0;

d[0] = token;
xmit_mmc(d, 1); /* Xmit a token */
if (token != 0xFD)
{ /* Is it data token? */
xmit_mmc(buff, 512); /* Xmit the 512 byte data block to MMC */
rcvr_mmc(d, 2); /* Xmit dummy CRC (0xFF,0xFF) */
rcvr_mmc(d, 1); /* Receive data response */
if ((d[0] & 0x1F) != 0x05) /* If not accepted, return with error */
xmit_mmc(buff, len); /* Xmit the 512 byte data block to MMC */
rcvr_mmc(d, 3); /* Xmit dummy CRC (0xFF,0xFF); Receive data response */
if ((d[2] & 0x1F) != 0x05) /* If not accepted, return with error */
return 0;
}

return 1;
}

static int xmit_datablock( /* Wrapper function */
const uint8_t *buff,
uint8_t token
)
{
return _xmit_datablock(buff, token, 512, true);
}

/*-----------------------------------------------------------------------*/
/* Send a command packet to the card */
/*-----------------------------------------------------------------------*/
Expand Down Expand Up @@ -286,7 +296,7 @@ bool MMC_disk_initialize(void)

sleep_us(10000); /* 10ms */

// Enable SPI at 300khz and connect to GPIOs
// Enable SPI at 400khz and connect to GPIOs
spi_init(SD_SPICH, SD_SPI_BAUDRATE_INIT);
gpio_set_function(SD_SPI_MISO, GPIO_FUNC_SPI);
gpio_set_function(SD_SPI_MOSI, GPIO_FUNC_SPI);
Expand All @@ -296,8 +306,8 @@ bool MMC_disk_initialize(void)
CS_H();
gpio_set_dir(SD_SPI_CS, GPIO_OUT);

for (n = 10; n; n--)
rcvr_mmc(buf, 1); /* Apply 80 dummy clocks and the card gets ready to receive command */
for (n = 20; n; n--)
rcvr_mmc(buf, 4); /* Apply 80 dummy clocks and the card gets ready to receive command */

ty = 0;
if (send_cmd(CMD0, 0) == 1)
Expand All @@ -307,10 +317,10 @@ bool MMC_disk_initialize(void)
rcvr_mmc(buf, 4); /* Get trailing return value of R7 resp */
if (buf[2] == 0x01 && buf[3] == 0xAA)
{ /* The card can work at vdd range of 2.7-3.6V */
for (tmr = 1000; tmr; tmr--)
for (tmr = 10000; tmr; tmr--)
{ /* Wait for leaving idle state (ACMD41 with HCS bit) */
if (send_cmd(ACMD41, 1UL << 30) == 0) break;
sleep_us(1000);
sleep_us(10);
}
if (tmr && send_cmd(CMD58, 0) == 0)
{ /* Check CCS bit in the OCR */
Expand All @@ -331,10 +341,10 @@ bool MMC_disk_initialize(void)
ty = CT_MMC3;
cmd = CMD1; /* MMCv3 */
}
for (tmr = 1000; tmr; tmr--)
for (tmr = 10000; tmr; tmr--)
{ /* Wait for leaving idle state */
if (send_cmd(cmd, 0) == 0) break;
sleep_us(1000);
sleep_us(10);
}
if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */
ty = 0;
Expand Down Expand Up @@ -370,16 +380,21 @@ bool MMC_disk_read(uint8_t *buff, /* Pointer to the data buffer to store rea

if (!(CardType & CT_BLOCK)) sect *= 512; /* Convert LBA to byte address if needed */

cmd = count > 1 ? CMD18 : CMD17; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */
if (send_cmd(cmd, sect) == 0)
if (count > 1)
{
cmd = CMD18;
send_cmd(CMD23, count);
}
else
{
do
{
if (!rcvr_datablock(buff, 512)) break;
buff += 512;
} while (--count);
if (cmd == CMD18) send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
cmd = CMD17;
}

if (send_cmd(cmd, sect) == 0) {
rcvr_datablock(buff, count * 512);
count = 0;
}

deselect();

return (count == 0);
Expand Down Expand Up @@ -409,15 +424,13 @@ bool MMC_disk_write(const uint8_t *buff, /* Pointer to the data to be written */
else
{ /* Multiple block write */
if (CardType & CT_SDC) send_cmd(ACMD23, count);
send_cmd(CMD23, count);
if (send_cmd(CMD25, sect) == 0)
{ /* WRITE_MULTIPLE_BLOCK */
do
{
if (!xmit_datablock(buff, 0xFC)) break;
buff += 512;
} while (--count);
if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
count = 1;
_xmit_datablock(buff, 0xFC, count * 512, false);
count = 0;
// if (!_xmit_datablock(0, 0xFD, 512, false)) /* STOP_TRAN token */
// count = 1;
}
}
deselect();
Expand All @@ -429,21 +442,6 @@ bool MMC_disk_write(const uint8_t *buff, /* Pointer to the data to be written */
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/

bool MMC_sync(void)
{
bool res;

if (!MMC_disk_ready()) return false;

res = select();

deselect();

return res;
}

uint32_t MMC_get_block_size(void) { return 128; }

int32_t MMC_get_sector_count(void)
{
uint8_t n, csd[16];
Expand Down