summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-05-27 20:45:39 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-05-27 20:45:39 +0000
commit541f8a338b93b1d1cc58573765de286cf441ee6f (patch)
tree4f8b1b153ee4ef51692d8e9899284abcebdd0e41
parent45736d3dd038edade97535c9bbedfae4553c05e7 (diff)
downloadnuttx-541f8a338b93b1d1cc58573765de286cf441ee6f.tar.gz
nuttx-541f8a338b93b1d1cc58573765de286cf441ee6f.tar.bz2
nuttx-541f8a338b93b1d1cc58573765de286cf441ee6f.zip
Integrating SHDC
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1828 42af7a65-404d-4744-a932-0658087f49c3
-rwxr-xr-xnuttx/arch/arm/src/lm3s/lm3s_ssi.c15
-rw-r--r--nuttx/configs/eagle100/README.txt2
-rw-r--r--nuttx/configs/eagle100/httpd/defconfig2
-rw-r--r--nuttx/configs/eagle100/nettest/defconfig2
-rw-r--r--nuttx/configs/eagle100/nsh/defconfig2
-rw-r--r--nuttx/configs/eagle100/ostest/defconfig2
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_spi.c139
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_spi.h3
8 files changed, 85 insertions, 82 deletions
diff --git a/nuttx/arch/arm/src/lm3s/lm3s_ssi.c b/nuttx/arch/arm/src/lm3s/lm3s_ssi.c
index 4b9386c8a..ae45dbf97 100755
--- a/nuttx/arch/arm/src/lm3s/lm3s_ssi.c
+++ b/nuttx/arch/arm/src/lm3s/lm3s_ssi.c
@@ -426,7 +426,7 @@ static void ssi_semtake(sem_t *sem)
static void ssi_txnull(struct lm32_ssidev_s *priv)
{
- ssivdbg("TX: ones\n");
+ ssivdbg("TX: ->0xffff\n");
ssi_putreg(priv, LM3S_SSI_DR_OFFSET, 0xffff);
}
@@ -545,7 +545,9 @@ static inline boolean ssi_rxfifoempty(struct lm32_ssidev_s *priv)
static int ssi_performtx(struct lm32_ssidev_s *priv)
{
+#ifndef CONFIG_SSI_POLLWAIT
uint32 regval;
+#endif
int ntxd = 0; /* Number of words written to Tx FIFO */
/* Check if the Tx FIFO is full */
@@ -559,8 +561,15 @@ static int ssi_performtx(struct lm32_ssidev_s *priv)
/* No.. Transfer more words until either the Tx FIFO is full or
* until all of the user provided data has been sent.
*/
-
+#if 1
+ /* Further limit the number of words that we put into the Tx
+ * FIFO to half the half the FIFO depth. Otherwise, we could
+ * overrun the Rx FIFO on a very fast SSI bus.
+ */
+ for (; ntxd < priv->ntxwords && ntxd < LM3S_TXFIFO_WORDS/2 && !ssi_txfifofull(priv); ntxd++)
+#else
for (; ntxd < priv->ntxwords && !ssi_txfifofull(priv); ntxd++)
+#endif
{
priv->txword(priv);
}
@@ -809,7 +818,7 @@ static int ssi_transfer(struct lm32_ssidev_s *priv, const void *txbuffer,
*
* Returned Value:
* On success, a reference to the private data structgure for this IRQ.
- * NULL on failrue.
+ * NULL on failure.
*
****************************************************************************/
diff --git a/nuttx/configs/eagle100/README.txt b/nuttx/configs/eagle100/README.txt
index 29c5323bb..cc6cf3944 100644
--- a/nuttx/configs/eagle100/README.txt
+++ b/nuttx/configs/eagle100/README.txt
@@ -203,6 +203,8 @@ Eagle100-specific Configuration Options
CONFIG_SSI0_DISABLE - Select to disable support for SSI0
CONFIG_SSI1_DISABLE - Select to disable support for SSI1
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_LM3S_ETHERNET - This must be set (along with CONFIG_NET)
to build the LM3S Ethernet driver
diff --git a/nuttx/configs/eagle100/httpd/defconfig b/nuttx/configs/eagle100/httpd/defconfig
index e6b40982d..d6aa384a5 100644
--- a/nuttx/configs/eagle100/httpd/defconfig
+++ b/nuttx/configs/eagle100/httpd/defconfig
@@ -129,7 +129,7 @@ CONFIG_UART1_2STOP=0
#
CONFIG_SSI0_DISABLE=n
CONFIG_SSI1_DISABLE=y
-CONFIG_SSI_POLLWAIT=n
+CONFIG_SSI_POLLWAIT=y
#
# LM3S6918 specific serial device driver settings
diff --git a/nuttx/configs/eagle100/nettest/defconfig b/nuttx/configs/eagle100/nettest/defconfig
index fd74f7bed..1bd4c2320 100644
--- a/nuttx/configs/eagle100/nettest/defconfig
+++ b/nuttx/configs/eagle100/nettest/defconfig
@@ -129,7 +129,7 @@ CONFIG_UART1_2STOP=0
#
CONFIG_SSI0_DISABLE=n
CONFIG_SSI1_DISABLE=y
-CONFIG_SSI_POLLWAIT=n
+CONFIG_SSI_POLLWAIT=y
#
# LM3S6918 specific serial device driver settings
diff --git a/nuttx/configs/eagle100/nsh/defconfig b/nuttx/configs/eagle100/nsh/defconfig
index 4bcb2decf..1fab6e4a2 100644
--- a/nuttx/configs/eagle100/nsh/defconfig
+++ b/nuttx/configs/eagle100/nsh/defconfig
@@ -129,7 +129,7 @@ CONFIG_UART1_2STOP=0
#
CONFIG_SSI0_DISABLE=n
CONFIG_SSI1_DISABLE=y
-CONFIG_SSI_POLLWAIT=n
+CONFIG_SSI_POLLWAIT=y
#
# LM3S6918 specific serial device driver settings
diff --git a/nuttx/configs/eagle100/ostest/defconfig b/nuttx/configs/eagle100/ostest/defconfig
index cd430ca08..c8f5ef36a 100644
--- a/nuttx/configs/eagle100/ostest/defconfig
+++ b/nuttx/configs/eagle100/ostest/defconfig
@@ -129,7 +129,7 @@ CONFIG_UART1_2STOP=0
#
CONFIG_SSI0_DISABLE=n
CONFIG_SSI1_DISABLE=y
-CONFIG_SSI_POLLWAIT=n
+CONFIG_SSI_POLLWAIT=y
#
# LM3S6918 specific serial device driver settings
diff --git a/nuttx/drivers/mmcsd/mmcsd_spi.c b/nuttx/drivers/mmcsd/mmcsd_spi.c
index b3a19affe..da18cca80 100644
--- a/nuttx/drivers/mmcsd/mmcsd_spi.c
+++ b/nuttx/drivers/mmcsd/mmcsd_spi.c
@@ -90,15 +90,6 @@
#define MMCSD_SLOTSTATUS_MEDIACHGD 0x08 /* Media changed in slot */
/* Values in the MMC/SD command table ***************************************/
-/* These define the expected arguments of the MMC/SD command */
-
-#define MMCSD_CMDARG_NONE 0
-#define MMCSD_CMDARG_BLKLEN 1
-#define MMCSD_CMDARG_ADDRESS 2
-#define MMCSD_CMDARG_NSECT 3
-#define MMCSD_CMDARG_1AA 4
-#define MMCSD_CMDARG_DUMMY 5
-
/* These define the value returned by the MMC/SD command */
#define MMCSD_CMDRESP_R1 0
@@ -117,6 +108,7 @@
#define MMCSD_DELAY_250MS (CLK_TCK/4 + 1)
#define MMCSD_DELAY_500MS (CLK_TCK/2 + 1)
#define MMCSD_DELAY_1SEC (CLK_TCK + 1)
+#define MMCSD_DELAY_10SEC (10 * CLK_TCK + 1)
#define ELAPSED_TIME(t) (g_system_timer-(t))
#define START_TIME (g_system_timer)
@@ -150,7 +142,6 @@ struct mmcsd_slot_s
struct mmcsd_cmdinfo_s
{
ubyte cmd;
- ubyte arg;
ubyte resp;
ubyte chksum;
};
@@ -219,10 +210,10 @@ static const struct block_operations g_bops =
#if defined(CONFIG_FS_WRITABLE) && !defined(CONFIG_MMCSD_READONLY)
mmcsd_write, /* write */
#else
- NULL, /* write */
+ NULL, /* write */
#endif
mmcsd_geometry, /* geometry */
- NULL /* ioctl */
+ NULL /* ioctl */
};
/* A slot structure allocated for each configured slot */
@@ -277,13 +268,13 @@ static const uint32 g_transpeedtu[16] =
#define MAX_USTUNDX 2
static const uint16 g_taactu[8] =
{
-/* Units of nanoseconds */
+ /* Units of nanoseconds */
1, /* 0: 1 ns */
10, /* 1: 10 ns */
100, /* 2: 100 ns */
-/* Units of microseconds */
+ /* Units of microseconds */
1, /* 3: 1 us 1,000 ns */
10, /* 4: 10 us 10,000 ns */
@@ -302,21 +293,21 @@ static const uint16 g_taactv[] =
/* Commands *****************************************************************/
-static const struct mmcsd_cmdinfo_s g_cmd0 = {CMD0, MMCSD_CMDARG_NONE, MMCSD_CMDRESP_R1, 0x95};
-static const struct mmcsd_cmdinfo_s g_cmd1 = {CMD1, MMCSD_CMDARG_NONE, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd8 = {CMD8, MMCSD_CMDARG_1AA, MMCSD_CMDRESP_R7, 0x87};
-static const struct mmcsd_cmdinfo_s g_cmd9 = {CMD9, MMCSD_CMDARG_NONE, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd10 = {CMD10, MMCSD_CMDARG_NONE, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd12 = {CMD12, MMCSD_CMDARG_NONE, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd16 = {CMD16, MMCSD_CMDARG_BLKLEN, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd17 = {CMD17, MMCSD_CMDARG_ADDRESS, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd18 = {CMD18, MMCSD_CMDARG_ADDRESS, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd24 = {CMD24, MMCSD_CMDARG_ADDRESS, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd25 = {CMD25, MMCSD_CMDARG_ADDRESS, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd55 = {CMD55, MMCSD_CMDARG_NONE, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd58 = {CMD58, MMCSD_CMDARG_NONE, MMCSD_CMDRESP_R3, 0xff};
-static const struct mmcsd_cmdinfo_s g_acmd23 = {ACMD23, MMCSD_CMDARG_NSECT, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_acmd41 = {ACMD41, MMCSD_CMDARG_NONE, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd0 = {CMD0, MMCSD_CMDRESP_R1, 0x95};
+static const struct mmcsd_cmdinfo_s g_cmd1 = {CMD1, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd8 = {CMD8, MMCSD_CMDRESP_R7, 0x87};
+static const struct mmcsd_cmdinfo_s g_cmd9 = {CMD9, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd10 = {CMD10, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd12 = {CMD12, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd16 = {CMD16, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd17 = {CMD17, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd18 = {CMD18, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd24 = {CMD24, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd25 = {CMD25, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd55 = {CMD55, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_cmd58 = {CMD58, MMCSD_CMDRESP_R3, 0xff};
+static const struct mmcsd_cmdinfo_s g_acmd23 = {ACMD23, MMCSD_CMDRESP_R1, 0xff};
+static const struct mmcsd_cmdinfo_s g_acmd41 = {ACMD41, MMCSD_CMDRESP_R1, 0xff};
/****************************************************************************
* Private Functions
@@ -399,22 +390,12 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
SPI_SEND(spi, cmd->cmd);
- /* Send command's arguments */
+ /* Send command's arguments (should be zero if there are no arguements) */
- if (cmd->arg == MMCSD_CMDARG_NONE)
- {
- SPI_SEND(spi, 0x00);
- SPI_SEND(spi, 0x00);
- SPI_SEND(spi, 0x00);
- SPI_SEND(spi, 0x00);
- }
- else
- {
- SPI_SEND(spi, arg >> 24);
- SPI_SEND(spi, arg >> 16);
- SPI_SEND(spi, arg >> 8);
- SPI_SEND(spi, arg);
- }
+ SPI_SEND(spi, (arg >> 24) & 0xff);
+ SPI_SEND(spi, (arg >> 16) & 0xff);
+ SPI_SEND(spi, (arg >> 8) & 0xff);
+ SPI_SEND(spi, arg & 0xff);
/* Send CRC if needed. The SPI interface is initialized in non-protected
* mode. However, the reset command (CMD0) and CMD8 are received by the
@@ -473,7 +454,8 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
return (uint32)-1;
}
- fvdbg("Return R1B=%04x\n", response);
+ fvdbg("CMD%d[%08x] R1B=%02x\n",
+ cmd->cmd & 0x3f, arg, response);
}
break;
@@ -481,7 +463,8 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
case MMCSD_CMDRESP_R1:
{
- fvdbg("Return R1=%02x\n", response);
+ fvdbg("CMD%d[%08x] R1=%02x\n",
+ cmd->cmd & 0x3f, arg, response);
}
break;
@@ -491,7 +474,9 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
{
result = ((uint32)(response & 0xff) << 8);
result |= SPI_SEND(spi, 0xff) & 0xff;
- fvdbg("Return R2=%04x\n", result);
+
+ fvdbg("CMD%d[%08x] R2=%04x\n",
+ cmd->cmd & 0x3f, arg, result);
}
break;
@@ -499,22 +484,26 @@ static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
case MMCSD_CMDRESP_R3:
{
- slot->ocr = ((uint32)(response & 0xff) << 24);
+ slot->ocr = ((uint32)(SPI_SEND(spi, 0xff) & 0xff) << 24);
slot->ocr |= ((uint32)(SPI_SEND(spi, 0xff) & 0xff) << 16);
slot->ocr |= ((uint32)(SPI_SEND(spi, 0xff) & 0xff) << 8);
slot->ocr |= SPI_SEND(spi, 0xff) & 0xff;
- fvdbg("R1=%02x OCR=%08x\n", response, slot->ocr);
+
+ fvdbg("CMD%d[%08x] R1=%02x OCR=%08x\n",
+ cmd->cmd & 0x3f, arg, response, slot->ocr);
}
/* The R7 response is 5 bytes long */
case MMCSD_CMDRESP_R7:
default:
{
- slot->r7 = ((uint32)(response & 0xff) << 24);
+ slot->r7 = ((uint32)(SPI_SEND(spi, 0xff) & 0xff) << 24);
slot->r7 |= ((uint32)(SPI_SEND(spi, 0xff) & 0xff) << 16);
slot->r7 |= ((uint32)(SPI_SEND(spi, 0xff) & 0xff) << 8);
slot->r7 |= SPI_SEND(spi, 0xff) & 0xff;
- fvdbg("R1=%02x R7=%08x\n", response, slot->r7);
+
+ fvdbg("CMD%d[%08x] R1=%02x R7=%08x\n",
+ cmd->cmd & 0x3f, arg, response, slot->r7);
}
break;
}
@@ -869,7 +858,7 @@ static int mmcsd_recvblock(FAR struct mmcsd_slot_s *slot, ubyte *buffer, int nby
return OK;
}
- fdbg("Did not received data token (%02x)\n", token);
+ fdbg("Did not receive data token (%02x)\n", token);
return ERROR;
}
@@ -1453,29 +1442,36 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
* IDLE state.
*/
- /* After power up at least 74 clock cycles are required prior to starting bus communication */
-
- fvdbg("Send CMD0\n");
for (i = 0; i < 2; i++)
{
- SPI_SELECT(spi, SPIDEV_MMCSD, TRUE);
- SPI_SEND(spi, 0xff);
+ /* After power up at least 74 clock cycles are required prior to
+ * starting bus communication
+ */
for (j = 10; j; j--)
{
SPI_SEND(spi, 0xff);
}
- /* Send CMD0 (GO_TO_IDLE) to put MMC/SD in IDLE/SPI mode.
- * Return from CMD0 is R1 which should now show IDLE STATE
+ /* Send CMD0 (GO_TO_IDLE) with CS asserted to put MMC/SD in
+ * IDLE/SPI mode. Return from CMD0 is R1 which should now
+ * show IDLE STATE
*/
+ fvdbg("Send CMD0\n");
+ SPI_SELECT(spi, SPIDEV_MMCSD, TRUE);
result = mmcsd_sendcmd(slot, &g_cmd0, 0);
if (result == MMCSD_SPIR1_IDLESTATE)
{
+ /* Break out of the loop with card selected */
+
fvdbg("Card is in IDLE state\n");
break;
}
+
+ /* De-select card and try again */
+
+ SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
}
/* Verify that we exit the above loop with the card reporting IDLE state */
@@ -1493,26 +1489,25 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
fvdbg("Send CMD8\n");
result = mmcsd_sendcmd(slot, &g_cmd8, 0x1aa);
-
if (result == MMCSD_SPIR1_IDLESTATE)
{
- /* Should also check the operating voltage here */
+ /* Verify the operating voltage and that the 0xaa was correctly echoed */
- if ((slot->r7 & MMCSD_SPIR7_ECHO_MASK) == 0xaa)
+ if (((slot->r7 & MMCSD_SPIR7_VOLTAGE_MASK) == MMCSD_SPIR7_VOLTAGE_27) &&
+ ((slot->r7 & MMCSD_SPIR7_ECHO_MASK) == 0xaa))
{
- /* Try CMD55/ACMD41 up to 100 times */
+ /* Try CMD55/ACMD41 for up to 1 second or until the card exits
+ * the IDLE state
+ */
start = START_TIME;
elapsed = 0;
do
{
- fvdbg("%d. Send CMD55\n", i);
- SPI_SEND(spi, 0xff);
+ fvdbg("%d. Send CMD55/ACMD41\n", elapsed);
result = mmcsd_sendcmd(slot, &g_cmd55, 0);
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
{
- fvdbg("%d. Send ACMD41\n", i);
- SPI_SEND(spi, 0xff);
result = mmcsd_sendcmd(slot, &g_acmd41, 1 << 30);
if (result == MMCSD_SPIR1_OK)
{
@@ -1554,15 +1549,12 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
{
/* Both the MMC card and the SD card support CMD55 */
- fvdbg("Send CMD55\n");
- SPI_SEND(spi, 0xff);
+ fvdbg("Send CMD55/ACMD41\n");
result = mmcsd_sendcmd(slot, &g_cmd55, 0);
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
{
/* But ACMD41 is supported only on SD */
- fvdbg("Send ACMD41\n");
- SPI_SEND(spi, 0xff);
result = mmcsd_sendcmd(slot, &g_acmd41, 0);
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
{
@@ -1579,11 +1571,10 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
{
if (IS_SD(slot->type))
{
- fvdbg("%d. Send CMD55\n", i);
+ fvdbg("%d. Send CMD55/ACMD41\n", elapsed);
result = mmcsd_sendcmd(slot, &g_cmd55, 0);
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
{
- fvdbg("%d. Send ACMD41\n", i);
SPI_SEND(spi, 0xff);
result = mmcsd_sendcmd(slot, &g_acmd41, 0);
if (result == MMCSD_SPIR1_OK)
@@ -1623,7 +1614,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
return -EIO;
}
- /* Read CSD. CSD must always be valid */
+ /* Read CSD. CSD must always be valid */
fvdbg("Get CSD\n");
result = mmcsd_getcsd(slot, csd);
diff --git a/nuttx/drivers/mmcsd/mmcsd_spi.h b/nuttx/drivers/mmcsd/mmcsd_spi.h
index d32ce65a9..b7be2182d 100644
--- a/nuttx/drivers/mmcsd/mmcsd_spi.h
+++ b/nuttx/drivers/mmcsd/mmcsd_spi.h
@@ -126,8 +126,9 @@
#define MMCSD_SPIR7_VERSION_MASK (0x0f << MMCSD_SPIR7_VERSION_SHIFT)
#define MMCSD_SPIR7_VOLTAGE_SHIFT 8 /* Bits 8-11: Voltage accepted */
#define MMCSD_SPIR7_VOLTAGE_MASK (0x0f << MMCSD_SPIR7_VOLTAGE_SHIFT)
+#define MMCSD_SPIR7_VOLTAGE_27 (0x01 << MMCSD_SPIR7_VOLTAGE_SHIFT) /* 2.7-3.6V */
#define MMCSD_SPIR7_ECHO_SHIFT 0 /* Bits 0-7: Echoed check pattern */
-#define MMCSD_SPIR7_ECHO_MASK (0x0f << MMCSD_SPIR7_ECHO_SHIFT)
+#define MMCSD_SPIR7_ECHO_MASK (0xff << MMCSD_SPIR7_ECHO_SHIFT)
/* Data Response */