reinit spi sd when sd status is wrong.
Signed-off-by: licheng <chengli@bestechnic.com>
This commit is contained in:
parent
ff05cc593f
commit
6a01099c59
6
drivers/mmcsd/Kconfig
Normal file → Executable file
6
drivers/mmcsd/Kconfig
Normal file → Executable 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
36
drivers/mmcsd/mmcsd_spi.c
Normal file → Executable 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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user