mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +08:00
Final integration of microSD
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1830 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -122,6 +122,20 @@
|
|||||||
|
|
||||||
#define LM3S_TXFIFO_WORDS 8
|
#define LM3S_TXFIFO_WORDS 8
|
||||||
|
|
||||||
|
/* Configuration settings */
|
||||||
|
|
||||||
|
#ifndef CONFIG_SSI_TXLIMIT
|
||||||
|
# define CONFIG_SSI_TXLIMIT (LM3S_TXFIFO_WORDS/2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_SSI_TXLIMIT < 1 || CONFIG_SSI_TXLIMIT > LM3S_TXFIFO_WORDS
|
||||||
|
# error "Invalid range for CONFIG_SSI_TXLIMIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_SSI_TXLIMIT && CONFIG_SSI_TXLIMIT < (LM3S_TXFIFO_WORDS/2)
|
||||||
|
# error "CONFIG_SSI_TXLIMIT must be at least half the TX FIFO size"
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Type Definitions
|
* Private Type Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -196,7 +210,11 @@ static void ssi_rxuint16(struct lm32_ssidev_s *priv);
|
|||||||
static void ssi_rxubyte(struct lm32_ssidev_s *priv);
|
static void ssi_rxubyte(struct lm32_ssidev_s *priv);
|
||||||
static inline boolean ssi_txfifofull(struct lm32_ssidev_s *priv);
|
static inline boolean ssi_txfifofull(struct lm32_ssidev_s *priv);
|
||||||
static inline boolean ssi_rxfifoempty(struct lm32_ssidev_s *priv);
|
static inline boolean ssi_rxfifoempty(struct lm32_ssidev_s *priv);
|
||||||
|
#if CONFIG_SSI_TXLIMIT == 1 && defined(CONFIG_SSI_POLLWAIT)
|
||||||
|
static inline int ssi_performtx(struct lm32_ssidev_s *priv);
|
||||||
|
#else
|
||||||
static int ssi_performtx(struct lm32_ssidev_s *priv);
|
static int ssi_performtx(struct lm32_ssidev_s *priv);
|
||||||
|
#endif
|
||||||
static inline void ssi_performrx(struct lm32_ssidev_s *priv);
|
static inline void ssi_performrx(struct lm32_ssidev_s *priv);
|
||||||
static int ssi_transfer(struct lm32_ssidev_s *priv, const void *txbuffer,
|
static int ssi_transfer(struct lm32_ssidev_s *priv, const void *txbuffer,
|
||||||
void *rxbuffer, unsigned int nwords);
|
void *rxbuffer, unsigned int nwords);
|
||||||
@@ -543,6 +561,24 @@ static inline boolean ssi_rxfifoempty(struct lm32_ssidev_s *priv)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if CONFIG_SSI_TXLIMIT == 1 && defined(CONFIG_SSI_POLLWAIT)
|
||||||
|
static inline int ssi_performtx(struct lm32_ssidev_s *priv)
|
||||||
|
{
|
||||||
|
/* Check if the Tx FIFO is full and more data to transfer */
|
||||||
|
|
||||||
|
if (!ssi_txfifofull(priv) && priv->ntxwords > 0)
|
||||||
|
{
|
||||||
|
/* Transfer one word to the Tx FIFO */
|
||||||
|
|
||||||
|
priv->txword(priv);
|
||||||
|
priv->ntxwords--;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* CONFIG_SSI_TXLIMIT == 1 CONFIG_SSI_POLLWAIT */
|
||||||
|
|
||||||
static int ssi_performtx(struct lm32_ssidev_s *priv)
|
static int ssi_performtx(struct lm32_ssidev_s *priv)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_SSI_POLLWAIT
|
#ifndef CONFIG_SSI_POLLWAIT
|
||||||
@@ -561,12 +597,12 @@ static int ssi_performtx(struct lm32_ssidev_s *priv)
|
|||||||
/* No.. Transfer more words until either the Tx FIFO is full or
|
/* No.. Transfer more words until either the Tx FIFO is full or
|
||||||
* until all of the user provided data has been sent.
|
* until all of the user provided data has been sent.
|
||||||
*/
|
*/
|
||||||
#if 1
|
#ifdef CONFIG_SSI_TXLIMIT
|
||||||
/* Further limit the number of words that we put into the Tx
|
/* Further limit the number of words that we put into the Tx
|
||||||
* FIFO to half the half the FIFO depth. Otherwise, we could
|
* FIFO to CONFIG_SSI_TXLIMIT. Otherwise, we could
|
||||||
* overrun the Rx FIFO on a very fast SSI bus.
|
* overrun the Rx FIFO on a very fast SSI bus.
|
||||||
*/
|
*/
|
||||||
for (; ntxd < priv->ntxwords && ntxd < LM3S_TXFIFO_WORDS/2 && !ssi_txfifofull(priv); ntxd++)
|
for (; ntxd < priv->ntxwords && ntxd < CONFIG_SSI_TXLIMIT && !ssi_txfifofull(priv); ntxd++)
|
||||||
#else
|
#else
|
||||||
for (; ntxd < priv->ntxwords && !ssi_txfifofull(priv); ntxd++)
|
for (; ntxd < priv->ntxwords && !ssi_txfifofull(priv); ntxd++)
|
||||||
#endif
|
#endif
|
||||||
@@ -609,6 +645,8 @@ static int ssi_performtx(struct lm32_ssidev_s *priv)
|
|||||||
return ntxd;
|
return ntxd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_SSI_TXLIMIT == 1 CONFIG_SSI_POLLWAIT */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ssi_performrx
|
* Name: ssi_performrx
|
||||||
*
|
*
|
||||||
@@ -751,6 +789,7 @@ static int ssi_transfer(struct lm32_ssidev_s *priv, const void *txbuffer,
|
|||||||
ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x\n",
|
ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x\n",
|
||||||
priv->ntxwords, priv->nrxwords, priv->nwords,
|
priv->ntxwords, priv->nrxwords, priv->nwords,
|
||||||
ssi_getreg(priv, LM3S_SSI_SR_OFFSET));
|
ssi_getreg(priv, LM3S_SSI_SR_OFFSET));
|
||||||
|
|
||||||
ntxd = ssi_performtx(priv);
|
ntxd = ssi_performtx(priv);
|
||||||
|
|
||||||
/* For the case where nwords < Tx FIFO size, ssi_performrx will
|
/* For the case where nwords < Tx FIFO size, ssi_performrx will
|
||||||
@@ -759,6 +798,7 @@ static int ssi_transfer(struct lm32_ssidev_s *priv, const void *txbuffer,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ssi_performrx(priv);
|
ssi_performrx(priv);
|
||||||
|
|
||||||
ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x IM: %08x\n",
|
ssivdbg("ntxwords: %d nrxwords: %d nwords: %d SR: %08x IM: %08x\n",
|
||||||
priv->ntxwords, priv->nrxwords, priv->nwords,
|
priv->ntxwords, priv->nrxwords, priv->nwords,
|
||||||
ssi_getreg(priv, LM3S_SSI_SR_OFFSET),
|
ssi_getreg(priv, LM3S_SSI_SR_OFFSET),
|
||||||
|
|||||||
@@ -139,7 +139,6 @@ defconfig -- This is a configuration file similar to the Linux
|
|||||||
CONFIG_DRAM_START - The start address of DRAM (physical)
|
CONFIG_DRAM_START - The start address of DRAM (physical)
|
||||||
CONFIG_DRAM_VSTART - The start address of DRAM (virtual)
|
CONFIG_DRAM_VSTART - The start address of DRAM (virtual)
|
||||||
|
|
||||||
|
|
||||||
General build options
|
General build options
|
||||||
|
|
||||||
CONFIG_RRLOAD_BINARY - make the rrload binary format used with
|
CONFIG_RRLOAD_BINARY - make the rrload binary format used with
|
||||||
|
|||||||
@@ -205,6 +205,10 @@ Eagle100-specific Configuration Options
|
|||||||
CONFIG_SSI_POLLWAIT - Select to disable interrupt driven SSI support.
|
CONFIG_SSI_POLLWAIT - Select to disable interrupt driven SSI support.
|
||||||
Poll-waiting is recommended if the interrupt rate would be to
|
Poll-waiting is recommended if the interrupt rate would be to
|
||||||
high in the interrupt driven case.
|
high in the interrupt driven case.
|
||||||
|
CONFIG_SSI_TXLIMIT - Write this many words to the Tx FIFO before
|
||||||
|
emptying the Rx FIFO. If the SPI frequency is high and this
|
||||||
|
value is large, then larger values of this setting may cause
|
||||||
|
Rx FIFO overrun errors. Default: half of the Tx FIFO size (4).
|
||||||
|
|
||||||
CONFIG_LM3S_ETHERNET - This must be set (along with CONFIG_NET)
|
CONFIG_LM3S_ETHERNET - This must be set (along with CONFIG_NET)
|
||||||
to build the LM3S Ethernet driver
|
to build the LM3S Ethernet driver
|
||||||
|
|||||||
@@ -126,10 +126,17 @@ CONFIG_UART1_2STOP=0
|
|||||||
# CONFIG_SSIn_DISABLE - select to disable all support for
|
# CONFIG_SSIn_DISABLE - select to disable all support for
|
||||||
# the SSI
|
# the SSI
|
||||||
# CONFIG_SSI_POLLWAIT - Select to disable interrupt driven SSI support
|
# CONFIG_SSI_POLLWAIT - Select to disable interrupt driven SSI support
|
||||||
|
# Poll-waiting is recommended if the interrupt rate would be to
|
||||||
|
# high in the interrupt driven case.
|
||||||
|
# CONFIG_SSI_TXLIMIT - Write this many words to the Tx FIFO before
|
||||||
|
# emptying the Rx FIFO. If the SPI frequency is high and this
|
||||||
|
# value is large, then larger values of this setting may cause
|
||||||
|
# Rx FIFO overrun errors. Default: half of the Tx FIFO size (4).
|
||||||
#
|
#
|
||||||
CONFIG_SSI0_DISABLE=n
|
CONFIG_SSI0_DISABLE=n
|
||||||
CONFIG_SSI1_DISABLE=y
|
CONFIG_SSI1_DISABLE=y
|
||||||
CONFIG_SSI_POLLWAIT=y
|
CONFIG_SSI_POLLWAIT=y
|
||||||
|
#CONFIG_SSI_TXLIMIT=4
|
||||||
|
|
||||||
#
|
#
|
||||||
# LM3S6918 specific serial device driver settings
|
# LM3S6918 specific serial device driver settings
|
||||||
|
|||||||
@@ -126,10 +126,17 @@ CONFIG_UART1_2STOP=0
|
|||||||
# CONFIG_SSIn_DISABLE - select to disable all support for
|
# CONFIG_SSIn_DISABLE - select to disable all support for
|
||||||
# the SSI
|
# the SSI
|
||||||
# CONFIG_SSI_POLLWAIT - Select to disable interrupt driven SSI support
|
# CONFIG_SSI_POLLWAIT - Select to disable interrupt driven SSI support
|
||||||
|
# Poll-waiting is recommended if the interrupt rate would be to
|
||||||
|
# high in the interrupt driven case.
|
||||||
|
# CONFIG_SSI_TXLIMIT - Write this many words to the Tx FIFO before
|
||||||
|
# emptying the Rx FIFO. If the SPI frequency is high and this
|
||||||
|
# value is large, then larger values of this setting may cause
|
||||||
|
# Rx FIFO overrun errors. Default: half of the Tx FIFO size (4).
|
||||||
#
|
#
|
||||||
CONFIG_SSI0_DISABLE=n
|
CONFIG_SSI0_DISABLE=n
|
||||||
CONFIG_SSI1_DISABLE=y
|
CONFIG_SSI1_DISABLE=y
|
||||||
CONFIG_SSI_POLLWAIT=y
|
CONFIG_SSI_POLLWAIT=y
|
||||||
|
#CONFIG_SSI_TXLIMIT=4
|
||||||
|
|
||||||
#
|
#
|
||||||
# LM3S6918 specific serial device driver settings
|
# LM3S6918 specific serial device driver settings
|
||||||
|
|||||||
@@ -126,10 +126,17 @@ CONFIG_UART1_2STOP=0
|
|||||||
# CONFIG_SSIn_DISABLE - select to disable all support for
|
# CONFIG_SSIn_DISABLE - select to disable all support for
|
||||||
# the SSI
|
# the SSI
|
||||||
# CONFIG_SSI_POLLWAIT - Select to disable interrupt driven SSI support
|
# CONFIG_SSI_POLLWAIT - Select to disable interrupt driven SSI support
|
||||||
|
# Poll-waiting is recommended if the interrupt rate would be to
|
||||||
|
# high in the interrupt driven case.
|
||||||
|
# CONFIG_SSI_TXLIMIT - Write this many words to the Tx FIFO before
|
||||||
|
# emptying the Rx FIFO. If the SPI frequency is high and this
|
||||||
|
# value is large, then larger values of this setting may cause
|
||||||
|
# Rx FIFO overrun errors. Default: half of the Tx FIFO size (4).
|
||||||
#
|
#
|
||||||
CONFIG_SSI0_DISABLE=n
|
CONFIG_SSI0_DISABLE=n
|
||||||
CONFIG_SSI1_DISABLE=y
|
CONFIG_SSI1_DISABLE=y
|
||||||
CONFIG_SSI_POLLWAIT=y
|
CONFIG_SSI_POLLWAIT=y
|
||||||
|
#CONFIG_SSI_TXLIMIT=4
|
||||||
|
|
||||||
#
|
#
|
||||||
# LM3S6918 specific serial device driver settings
|
# LM3S6918 specific serial device driver settings
|
||||||
|
|||||||
@@ -126,10 +126,17 @@ CONFIG_UART1_2STOP=0
|
|||||||
# CONFIG_SSIn_DISABLE - select to disable all support for
|
# CONFIG_SSIn_DISABLE - select to disable all support for
|
||||||
# the SSI
|
# the SSI
|
||||||
# CONFIG_SSI_POLLWAIT - Select to disable interrupt driven SSI support
|
# CONFIG_SSI_POLLWAIT - Select to disable interrupt driven SSI support
|
||||||
|
# Poll-waiting is recommended if the interrupt rate would be to
|
||||||
|
# high in the interrupt driven case.
|
||||||
|
# CONFIG_SSI_TXLIMIT - Write this many words to the Tx FIFO before
|
||||||
|
# emptying the Rx FIFO. If the SPI frequency is high and this
|
||||||
|
# value is large, then larger values of this setting may cause
|
||||||
|
# Rx FIFO overrun errors. Default: half of the Tx FIFO size (4).
|
||||||
#
|
#
|
||||||
CONFIG_SSI0_DISABLE=n
|
CONFIG_SSI0_DISABLE=n
|
||||||
CONFIG_SSI1_DISABLE=y
|
CONFIG_SSI1_DISABLE=y
|
||||||
CONFIG_SSI_POLLWAIT=y
|
CONFIG_SSI_POLLWAIT=y
|
||||||
|
#CONFIG_SSI_TXLIMIT=4
|
||||||
|
|
||||||
#
|
#
|
||||||
# LM3S6918 specific serial device driver settings
|
# LM3S6918 specific serial device driver settings
|
||||||
|
|||||||
+69
-17
@@ -81,6 +81,10 @@
|
|||||||
# define CONFIG_MMCSD_SPICLOCK 20000000
|
# define CONFIG_MMCSD_SPICLOCK 20000000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_MMCSD_SECTOR512
|
||||||
|
# define CONFIG_MMCSD_SECTOR512 /* Force 512 byte sectors on all cards */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Slot struct info *********************************************************/
|
/* Slot struct info *********************************************************/
|
||||||
/* Slot status definitions */
|
/* Slot status definitions */
|
||||||
|
|
||||||
@@ -98,6 +102,12 @@
|
|||||||
#define MMCSD_CMDRESP_R3 3
|
#define MMCSD_CMDRESP_R3 3
|
||||||
#define MMCSD_CMDRESP_R7 4
|
#define MMCSD_CMDRESP_R7 4
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMCSD_SECTOR512
|
||||||
|
# define SECTORSIZE(s) (512)
|
||||||
|
#else
|
||||||
|
# define SECTORSIZE(s) ((s)->sectorsize)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Time delays in units of the system clock. CLK_TCK is the number of clock
|
/* Time delays in units of the system clock. CLK_TCK is the number of clock
|
||||||
* ticks per second.
|
* ticks per second.
|
||||||
*/
|
*/
|
||||||
@@ -131,7 +141,9 @@ struct mmcsd_slot_s
|
|||||||
ubyte state; /* State of the slot (see MMCSD_SLOTSTATUS_* definitions) */
|
ubyte state; /* State of the slot (see MMCSD_SLOTSTATUS_* definitions) */
|
||||||
ubyte type; /* Disk type */
|
ubyte type; /* Disk type */
|
||||||
ubyte csd[16]; /* Copy of card CSD */
|
ubyte csd[16]; /* Copy of card CSD */
|
||||||
|
#ifndef CONFIG_MMCSD_SECTOR512
|
||||||
uint16 sectorsize; /* Media block size (in bytes) */
|
uint16 sectorsize; /* Media block size (in bytes) */
|
||||||
|
#endif
|
||||||
uint32 nsectors; /* Number of blocks on the media */
|
uint32 nsectors; /* Number of blocks on the media */
|
||||||
uint32 taccess; /* Card access time */
|
uint32 taccess; /* Card access time */
|
||||||
uint32 twrite; /* Card write time */
|
uint32 twrite; /* Card write time */
|
||||||
@@ -707,21 +719,37 @@ static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, ubyte *csd)
|
|||||||
csize = MMCSD_CSD_CSIZE(csd) + 1;
|
csize = MMCSD_CSD_CSIZE(csd) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SDHC cards have fixed sector size of 512 bytes */
|
/* SDHC ver2.x cards have fixed block transfer size of 512 bytes. SDC
|
||||||
|
* ver1.x cards with capacity less than 1Gb, will have sector size
|
||||||
|
* 512 byes. SDC ver1.x cards with capacity of 2Gb will report readbllen
|
||||||
|
* of 1024 but should use 512 bytes for block transfers. SDC ver1.x 4Gb
|
||||||
|
* cards will report readbllen of 2048 bytes -- are they also 512 bytes?
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMCSD_SECTOR512
|
||||||
|
if (readbllen > 9)
|
||||||
|
{
|
||||||
|
csizemult += (readbllen - 9);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUGASSERT(readbllen == 9);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (IS_SDV2(slot->type))
|
if (IS_SDV2(slot->type))
|
||||||
{
|
{
|
||||||
if (readbllen > 9)
|
if (readbllen > 9)
|
||||||
{
|
{
|
||||||
fdbg("Forcing 512 byte sector size\n");
|
fdbg("Forcing 512 byte sector size\n");
|
||||||
csizemult += (readbllen - 9);
|
csizemult += (readbllen - 9);
|
||||||
readbllen = 9;
|
readbllen = 9;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
slot->sectorsize = 1 << readbllen;
|
slot->sectorsize = 1 << readbllen;
|
||||||
|
#endif
|
||||||
slot->nsectors = csize << csizemult;
|
slot->nsectors = csize << csizemult;
|
||||||
fvdbg("Sector size: %d\n", slot->sectorsize);
|
fvdbg("Sector size: %d\n", SECTORSIZE(slot));
|
||||||
fvdbg("Number of sectors: %d\n", slot->nsectors);
|
fvdbg("Number of sectors: %d\n", slot->nsectors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1037,7 +1065,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
|
|||||||
|
|
||||||
/* Convert sector and nsectors to nbytes and byte offset */
|
/* Convert sector and nsectors to nbytes and byte offset */
|
||||||
|
|
||||||
nbytes = nsectors * slot->sectorsize;
|
nbytes = nsectors * SECTORSIZE(slot);
|
||||||
if (IS_BLOCK(slot->type))
|
if (IS_BLOCK(slot->type))
|
||||||
{
|
{
|
||||||
offset = start_sector;
|
offset = start_sector;
|
||||||
@@ -1045,7 +1073,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset = start_sector * slot->sectorsize;
|
offset = start_sector * SECTORSIZE(slot);
|
||||||
fvdbg("nbytes=%d byte offset=%d\n", nbytes, offset);
|
fvdbg("nbytes=%d byte offset=%d\n", nbytes, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1072,7 +1100,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
|
|||||||
|
|
||||||
/* Receive the block */
|
/* Receive the block */
|
||||||
|
|
||||||
if (mmcsd_recvblock(slot, buffer, slot->sectorsize) != 0)
|
if (mmcsd_recvblock(slot, buffer, SECTORSIZE(slot)) != 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed: to receive the block\n");
|
fdbg("Failed: to receive the block\n");
|
||||||
goto errout_with_eio;
|
goto errout_with_eio;
|
||||||
@@ -1095,12 +1123,12 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
|
|||||||
|
|
||||||
for (i = 0; i < nsectors; i++)
|
for (i = 0; i < nsectors; i++)
|
||||||
{
|
{
|
||||||
if (mmcsd_recvblock(slot, buffer, slot->sectorsize) != 0)
|
if (mmcsd_recvblock(slot, buffer, SECTORSIZE(slot)) != 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed: to receive the block\n");
|
fdbg("Failed: to receive the block\n");
|
||||||
goto errout_with_eio;
|
goto errout_with_eio;
|
||||||
}
|
}
|
||||||
buffer += slot->sectorsize;
|
buffer += SECTORSIZE(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send CMD12: Stops transmission */
|
/* Send CMD12: Stops transmission */
|
||||||
@@ -1198,7 +1226,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
|
|||||||
|
|
||||||
/* Convert sector and nsectors to nbytes and byte offset */
|
/* Convert sector and nsectors to nbytes and byte offset */
|
||||||
|
|
||||||
nbytes = nsectors * slot->sectorsize;
|
nbytes = nsectors * SECTORSIZE(slot);
|
||||||
if (IS_BLOCK(slot->type))
|
if (IS_BLOCK(slot->type))
|
||||||
{
|
{
|
||||||
offset = start_sector;
|
offset = start_sector;
|
||||||
@@ -1206,7 +1234,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset = start_sector * slot->sectorsize;
|
offset = start_sector * SECTORSIZE(slot);
|
||||||
fvdbg("nbytes=%d byte offset=%d\n", nbytes, offset);
|
fvdbg("nbytes=%d byte offset=%d\n", nbytes, offset);
|
||||||
}
|
}
|
||||||
mmcsd_dumpbuffer(buffer, nbytes);
|
mmcsd_dumpbuffer(buffer, nbytes);
|
||||||
@@ -1232,7 +1260,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
|
|||||||
|
|
||||||
/* Then transfer the sector */
|
/* Then transfer the sector */
|
||||||
|
|
||||||
if (mmcsd_xmitblock(slot, buffer, slot->sectorsize, 0xfe) != 0)
|
if (mmcsd_xmitblock(slot, buffer, SECTORSIZE(slot), 0xfe) != 0)
|
||||||
{
|
{
|
||||||
fdbg("Block transfer failed\n");
|
fdbg("Block transfer failed\n");
|
||||||
goto errout_with_sem;
|
goto errout_with_sem;
|
||||||
@@ -1267,12 +1295,12 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
|
|||||||
|
|
||||||
for (i = 0; i < nsectors; i++)
|
for (i = 0; i < nsectors; i++)
|
||||||
{
|
{
|
||||||
if (mmcsd_xmitblock(slot, buffer, slot->sectorsize, 0xfc) != 0)
|
if (mmcsd_xmitblock(slot, buffer, SECTORSIZE(slot), 0xfc) != 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed: to receive the block\n");
|
fdbg("Failed: to receive the block\n");
|
||||||
goto errout_with_sem;
|
goto errout_with_sem;
|
||||||
}
|
}
|
||||||
buffer += slot->sectorsize;
|
buffer += SECTORSIZE(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the stop transmission token */
|
/* Send the stop transmission token */
|
||||||
@@ -1371,7 +1399,7 @@ static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
|
|||||||
geometry->geo_writeenabled = FALSE;
|
geometry->geo_writeenabled = FALSE;
|
||||||
#endif
|
#endif
|
||||||
geometry->geo_nsectors = slot->nsectors;
|
geometry->geo_nsectors = slot->nsectors;
|
||||||
geometry->geo_sectorsize = slot->sectorsize;
|
geometry->geo_sectorsize = SECTORSIZE(slot);
|
||||||
|
|
||||||
/* After reporting mediachanged, clear the indication so that it is not
|
/* After reporting mediachanged, clear the indication so that it is not
|
||||||
* reported again.
|
* reported again.
|
||||||
@@ -1629,12 +1657,36 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
|
|||||||
mmcsd_decodecsd(slot, csd);
|
mmcsd_decodecsd(slot, csd);
|
||||||
mmcsd_checkwrprotect(slot, csd);
|
mmcsd_checkwrprotect(slot, csd);
|
||||||
|
|
||||||
/* SD Version 2.xx block length is always 512 */
|
/* SDHC ver2.x cards have fixed block transfer size of 512 bytes. SDC
|
||||||
|
* ver1.x cards with capacity less than 1Gb, will have sector size
|
||||||
|
* 512 byes. SDC ver1.x cards with capacity of 2Gb will report readbllen
|
||||||
|
* of 1024 but should use 512 bytes for block transfers. SDC ver1.x 4Gb
|
||||||
|
* cards will report readbllen of 2048 bytes -- are they also 512 bytes?
|
||||||
|
* I think that none of these high capacity cards support setting the
|
||||||
|
* block length??
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMCSD_SECTOR512
|
||||||
|
/* Using 512 byte sectors, the maximum ver1.x capacity is 4096 x 512 blocks.
|
||||||
|
* The saved slot->nsectors is converted to 512 byte blocks, so if slot->nsectors
|
||||||
|
* exceeds 4096 x 512, then we must be dealing with a card with read_bl_len
|
||||||
|
* of 1024 or 2048.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!IS_SDV2(slot->type) && slot->nsectors <= 4096*12)
|
||||||
|
{
|
||||||
|
/* Don't set the block len on high capacity cards (ver1.x or ver2.x) */
|
||||||
|
|
||||||
|
mmcsd_setblklen(slot, SECTORSIZE(slot));
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (!IS_SDV2(slot->type))
|
if (!IS_SDV2(slot->type))
|
||||||
{
|
{
|
||||||
mmcsd_setblklen(slot, slot->sectorsize);
|
/* Don't set the block len on ver2.x cards */
|
||||||
|
|
||||||
|
mmcsd_setblklen(slot, SECTORSIZE(slot));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
slot->state &= ~MMCSD_SLOTSTATUS_NOTREADY;
|
slot->state &= ~MMCSD_SLOTSTATUS_NOTREADY;
|
||||||
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
|
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
|
||||||
|
|||||||
Reference in New Issue
Block a user