reinit spi sd when sd status is wrong.

Signed-off-by: licheng <chengli@bestechnic.com>
This commit is contained in:
licheng 2022-09-06 18:58:00 +08:00 committed by Alan Carvalho de Assis
parent ff05cc593f
commit 6a01099c59
2 changed files with 42 additions and 0 deletions

6
drivers/mmcsd/Kconfig Normal file → Executable file
View File

@ -98,6 +98,12 @@ config MMCSD_IDMODE_CLOCK
SPI clock identify MMC/SD card. SPI clock identify MMC/SD card.
Should be 400KHz or less. Should be 400KHz or less.
config MMCSD_SPIRETRY_COUNT
int "MMC/SD read/write fail retry max count"
default 0
---help---
Try to recovery MMCSD read/write fail.
endif endif
config SDIO_DMA config SDIO_DMA

36
drivers/mmcsd/mmcsd_spi.c Normal file → Executable file
View File

@ -1161,6 +1161,8 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
{ {
FAR struct mmcsd_slot_s *slot; FAR struct mmcsd_slot_s *slot;
FAR struct spi_dev_s *spi; FAR struct spi_dev_s *spi;
FAR unsigned char *restore = buffer;
int retry_count = 0;
size_t nbytes; size_t nbytes;
off_t offset; off_t offset;
uint8_t response; uint8_t response;
@ -1235,6 +1237,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
return (ssize_t)ret; return (ssize_t)ret;
} }
retry:
SPI_SELECT(spi, SPIDEV_MMCSD(0), true); SPI_SELECT(spi, SPIDEV_MMCSD(0), true);
/* Single or multiple block read? */ /* Single or multiple block read? */
@ -1307,6 +1310,21 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
errout_with_eio: errout_with_eio:
SPI_SELECT(spi, SPIDEV_MMCSD(0), false); SPI_SELECT(spi, SPIDEV_MMCSD(0), false);
if (retry_count++ < CONFIG_MMCSD_SPIRETRY_COUNT)
{
buffer = restore;
ret = mmcsd_mediainitialize(slot);
if (ret < 0)
{
ferr("ERROR: Failed to reinitialize card\n");
}
else
{
fwarn("ERROR: retry %d\n", retry_count);
goto retry;
}
}
mmcsd_semgive(slot); mmcsd_semgive(slot);
return -EIO; return -EIO;
} }
@ -1326,6 +1344,8 @@ static ssize_t mmcsd_write(FAR struct inode *inode,
{ {
FAR struct mmcsd_slot_s *slot; FAR struct mmcsd_slot_s *slot;
FAR struct spi_dev_s *spi; FAR struct spi_dev_s *spi;
FAR const unsigned char *restore = buffer;
int retry_count = 0;
size_t nbytes; size_t nbytes;
off_t offset; off_t offset;
uint8_t response; uint8_t response;
@ -1410,6 +1430,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode,
return (ssize_t)ret; return (ssize_t)ret;
} }
retry:
SPI_SELECT(spi, SPIDEV_MMCSD(0), true); SPI_SELECT(spi, SPIDEV_MMCSD(0), true);
/* Single or multiple block transfer? */ /* Single or multiple block transfer? */
@ -1502,6 +1523,21 @@ static ssize_t mmcsd_write(FAR struct inode *inode,
errout_with_sem: errout_with_sem:
SPI_SELECT(spi, SPIDEV_MMCSD(0), false); SPI_SELECT(spi, SPIDEV_MMCSD(0), false);
if (retry_count++ < CONFIG_MMCSD_SPIRETRY_COUNT)
{
buffer = restore;
ret = mmcsd_mediainitialize(slot);
if (ret < 0)
{
ferr("ERROR: Failed to reinitialize card\n");
}
else
{
fwarn("ERROR: retry %d\n", retry_count);
goto retry;
}
}
mmcsd_semgive(slot); mmcsd_semgive(slot);
return -EIO; return -EIO;
} }