diff options
Diffstat (limited to 'nuttx')
-rwxr-xr-x | nuttx/arch/arm/src/lm3s/lm3s_ssi.c | 15 | ||||
-rw-r--r-- | nuttx/configs/eagle100/README.txt | 2 | ||||
-rw-r--r-- | nuttx/configs/eagle100/httpd/defconfig | 2 | ||||
-rw-r--r-- | nuttx/configs/eagle100/nettest/defconfig | 2 | ||||
-rw-r--r-- | nuttx/configs/eagle100/nsh/defconfig | 2 | ||||
-rw-r--r-- | nuttx/configs/eagle100/ostest/defconfig | 2 | ||||
-rw-r--r-- | nuttx/drivers/mmcsd/mmcsd_spi.c | 139 | ||||
-rw-r--r-- | nuttx/drivers/mmcsd/mmcsd_spi.h | 3 |
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 */ |