summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/ChangeLog19
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_otgfsdev.c7
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_spi.c23
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_spi.c80
-rw-r--r--nuttx/drivers/usbdev/usbmsc_scsi.c18
5 files changed, 99 insertions, 48 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index dea9e937b..db909eab2 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -4205,12 +4205,23 @@
* configs/ekk-lm3s9b96/ostest and nsh: All EKK-LM3S9B96 configurations
converted to use the mconf configuration tool.
* configs/zkit-arm-1769: Add support for Zilogic System's ARM development
- Kit, ZKIT-ARM-1769.
+ Kit, ZKIT-ARM-1769. From Rashid.
* configs/zkit-arm-1769/hello: Add a "Hello, World!" configuration for
- the KBIT-ARM-1769 board.
+ the KBIT-ARM-1769 board. From Rashid.
* configs/zkit-arm-1769/thttpd: Add a THTTPD configuration for the
- KBIT-ARM-1769 board.
+ KBIT-ARM-1769 board. From Rashid.
* 2013-02-27: All configurations for the Cortex-M0 NuTINY-SDK-NUC120
appear to be functional and stable.
* configs/zkit-arm-1769/nsh: Add an NSH configuration for the
- KBIT-ARM-1769 board.
+ KBIT-ARM-1769 board. From Rashid.
+ * arch/arm/src/stm32/stm32_otgfsdev.c: Fixes from Petterri Aimonen
+ related to corner cases that can cause infinite interrupts.
+ * drivers/usbdev/usbmsc_scsi.c: Change to allow the full name in the
+ USB descriptor but a truncated, 8-byte name in the SCSI field.
+ From Petteri Aimonen.
+ * arch/arm/src/stm32/stm32_spi.c: Need to clear error flags to prevent
+ corruption of subsequent transfers. Also, bit count should not be
+ changed while the SPI peripheral is enabled. From Petteri Aimonen.
+ * drivers/mmcsd/mmcsd_spi.c: When bus is shared, the speed has to be
+ set every time. Also SD cards require a few dummy clocks to react
+ into CS release. From Petteri Aimonen.
diff --git a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
index 1aab2ebc9..ece965b01 100644
--- a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
+++ b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
@@ -4050,7 +4050,7 @@ static void stm32_epout_disable(FAR struct stm32_ep_s *privep)
up_mdelay(50);
#endif
- /* Clear the EPDISD interrupt */
+ /* Clear the EPDISD interrupt indication */
stm32_putreg(OTGFS_DOEPINT_EPDISD, STM32_OTGFS_DOEPINT(privep->epphy));
@@ -4124,6 +4124,9 @@ static void stm32_epin_disable(FAR struct stm32_ep_s *privep)
regaddr = STM32_OTGFS_DIEPINT(privep->epphy);
while ((stm32_getreg(regaddr) & OTGFS_DIEPINT_INEPNE) == 0);
+
+ /* Clear the INEPNE interrupt indication */
+
stm32_putreg(OTGFS_DIEPINT_INEPNE, regaddr);
#endif
@@ -4146,7 +4149,7 @@ static void stm32_epin_disable(FAR struct stm32_ep_s *privep)
regaddr = STM32_OTGFS_DIEPINT(privep->epphy);
while ((stm32_getreg(regaddr) & OTGFS_DIEPINT_EPDISD) == 0);
- /* Clear the EPDISD interrupt */
+ /* Clear the EPDISD interrupt indication */
stm32_putreg(OTGFS_DIEPINT_EPDISD, stm32_getreg(regaddr));
diff --git a/nuttx/arch/arm/src/stm32/stm32_spi.c b/nuttx/arch/arm/src/stm32/stm32_spi.c
index 09c4c72aa..c8714e7df 100644
--- a/nuttx/arch/arm/src/stm32/stm32_spi.c
+++ b/nuttx/arch/arm/src/stm32/stm32_spi.c
@@ -777,7 +777,7 @@ static void spi_modifycr1(FAR struct stm32_spidev_s *priv, uint16_t setbits, uin
spi_putreg(priv, STM32_SPI_CR1_OFFSET, cr1);
}
-/****************************************************************************
+/************************************************************************************
* Name: spi_lock
*
* Description:
@@ -796,7 +796,7 @@ static void spi_modifycr1(FAR struct stm32_spidev_s *priv, uint16_t setbits, uin
* Returned Value:
* None
*
- ****************************************************************************/
+ ************************************************************************************/
#ifndef CONFIG_SPI_OWNBUS
static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
@@ -1049,12 +1049,14 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
return;
}
- spi_modifycr1(priv, setbits, clrbits);
-
- /* Save the selection so the subsequence re-configurations will be faster */
+ spi_modifycr1(priv, 0, SPI_CR1_SPE);
+ spi_modifycr1(priv, setbits, clrbits);
+ spi_modifycr1(priv, SPI_CR1_SPE, 0);
+
+ /* Save the selection so the subsequence re-configurations will be faster */
#ifndef CONFIG_SPI_OWNBUS
- priv->nbits = nbits;
+ priv->nbits = nbits;
}
#endif
}
@@ -1078,6 +1080,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
{
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
+ uint32_t regval;
uint16_t ret;
DEBUGASSERT(priv && priv->spibase);
@@ -1085,11 +1088,15 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
spi_writeword(priv, wd);
ret = spi_readword(priv);
- spivdbg("Sent: %04x Return: %04x\n", wd, ret);
+ /* Check and clear any error flags (Reading from the SR clears the error flags) */
+
+ regval = spi_getreg(priv, STM32_SPI_SR_OFFSET);
+ spivdbg("Sent: %04x Return: %04x Status: %02x\n", wd, ret, regval);
+
return ret;
}
-/*************************************************************************
+/************************************************************************************
* Name: spi_exchange (no DMA)
*
* Description:
diff --git a/nuttx/drivers/mmcsd/mmcsd_spi.c b/nuttx/drivers/mmcsd/mmcsd_spi.c
index 9939fa9de..8c4eb4429 100644
--- a/nuttx/drivers/mmcsd/mmcsd_spi.c
+++ b/nuttx/drivers/mmcsd/mmcsd_spi.c
@@ -154,6 +154,7 @@ struct mmcsd_slot_s
uint32_t twrite; /* Card write time */
uint32_t ocr; /* Last 4 bytes of OCR (R3) */
uint32_t r7; /* Last 4 bytes of R7 */
+ uint32_t spispeed; /* Speed to use for SPI in data mode */
};
struct mmcsd_cmdinfo_s
@@ -169,8 +170,8 @@ struct mmcsd_cmdinfo_s
/* Misc *********************************************************************/
-static void mmcsd_semtake(sem_t *sem, FAR struct spi_dev_s *spi);
-static void mmcsd_semgive(sem_t *sem, FAR struct spi_dev_s *spi);
+static void mmcsd_semtake(FAR struct mmcsd_slot_s *slot);
+static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot);
/* Card SPI interface *******************************************************/
@@ -340,19 +341,23 @@ static const struct mmcsd_cmdinfo_s g_acmd41 = {ACMD41, MMCSD_CMDRESP_R1, 0xff};
* Name: mmcsd_semtake
****************************************************************************/
-static void mmcsd_semtake(sem_t *sem, FAR struct spi_dev_s *spi)
+static void mmcsd_semtake(FAR struct mmcsd_slot_s *slot)
{
/* Get exclusive access to the SPI bus (if necessary) */
#ifndef CONFIG_SPI_OWNBUS
- (void)SPI_LOCK(spi, true);
+ (void)SPI_LOCK(slot->spi, true);
+
+ /* Set the frequency, as some other driver could have changed it. */
+
+ SPI_SETFREQUENCY(slot->spi, slot->spispeed);
#endif
/* Get exclusive access to the MMC/SD device (prossibly un-necessary if
* SPI_LOCK is also implemented as a semaphore.
*/
-
- while (sem_wait(sem) != 0)
+
+ while (sem_wait(&slot->sem) != 0)
{
/* The only case that an error should occur here is if the wait was
* awakened by a signal.
@@ -362,19 +367,27 @@ static void mmcsd_semtake(sem_t *sem, FAR struct spi_dev_s *spi)
}
}
-static void mmcsd_semgive(sem_t *sem, FAR struct spi_dev_s *spi)
+static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot)
{
/* Relinquish the lock on the MMC/SD device */
- sem_post(sem);
+ sem_post(&slot->sem);
/* Relinquish the lock on the SPI bus */
-
+
#ifndef CONFIG_SPI_OWNBUS
- (void)SPI_LOCK(spi, false);
+ /* The card may need up to 8 SCLK cycles to sample the CS status
+ * and release the MISO line.
+ */
+
+ (void)SPI_SEND(slot->spi, 0xff);
+
+ /* Relinquish exclusive access to the SPI bus */
+
+ (void)SPI_LOCK(slot->spi, false);
#endif
}
-
+
/****************************************************************************
* Name: mmcsd_waitready
*
@@ -680,6 +693,10 @@ static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, uint8_t *csd)
frequency = CONFIG_MMCSD_SPICLOCK;
}
+ /* Store the value for future use */
+
+ slot->spispeed = frequency;
+
/* Set the actual SPI frequency as close as possible to that value */
frequency = SPI_SETFREQUENCY(spi, frequency);
@@ -1027,7 +1044,7 @@ static int mmcsd_open(FAR struct inode *inode)
/* Verify that an MMC/SD card has been inserted */
ret = -ENODEV;
- mmcsd_semtake(&slot->sem, spi);
+ mmcsd_semtake(slot);
if ((SPI_STATUS(spi, SPIDEV_MMCSD) & SPI_STATUS_PRESENT) != 0)
{
/* Yes.. a card is present. Has it been initialized? */
@@ -1052,7 +1069,7 @@ static int mmcsd_open(FAR struct inode *inode)
}
errout_with_sem:
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
return ret;
}
@@ -1146,7 +1163,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
/* Select the slave */
- mmcsd_semtake(&slot->sem, spi);
+ mmcsd_semtake(slot);
SPI_SELECT(spi, SPIDEV_MMCSD, true);
/* Single or multiple block read? */
@@ -1207,7 +1224,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
SPI_SELECT(spi, SPIDEV_MMCSD, false);
SPI_SEND(spi, 0xff);
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
fvdbg("Read %d bytes:\n", nbytes);
mmcsd_dumpbuffer("Read buffer", buffer, nbytes);
@@ -1215,7 +1232,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
errout_with_eio:
SPI_SELECT(spi, SPIDEV_MMCSD, false);
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
return -EIO;
}
@@ -1309,7 +1326,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
/* Select the slave */
- mmcsd_semtake(&slot->sem, spi);
+ mmcsd_semtake(slot);
SPI_SELECT(spi, SPIDEV_MMCSD, true);
/* Single or multiple block transfer? */
@@ -1380,7 +1397,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
ret = mmcsd_waitready(slot);
SPI_SELECT(spi, SPIDEV_MMCSD, false);
SPI_SEND(spi, 0xff);
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
/* The success return value is the number of sectors written */
@@ -1388,7 +1405,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
errout_with_sem:
SPI_SELECT(spi, SPIDEV_MMCSD, false);
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
return -EIO;
}
#endif
@@ -1437,14 +1454,14 @@ static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
/* Re-sample the CSD */
- mmcsd_semtake(&slot->sem, spi);
+ mmcsd_semtake(slot);
SPI_SELECT(spi, SPIDEV_MMCSD, true);
ret = mmcsd_getcsd(slot, csd);
SPI_SELECT(spi, SPIDEV_MMCSD, false);
if (ret < 0)
{
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
fdbg("mmcsd_getcsd returned %d\n", ret);
return ret;
}
@@ -1473,7 +1490,7 @@ static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
*/
slot->state &= ~MMCSD_SLOTSTATUS_MEDIACHGD;
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
fvdbg("geo_available: %d\n", geometry->geo_available);
fvdbg("geo_mediachanged: %d\n", geometry->geo_mediachanged);
@@ -1578,7 +1595,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
{
fdbg("Send CMD0 failed: R1=%02x\n", result);
SPI_SELECT(spi, SPIDEV_MMCSD, false);
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
return -EIO;
}
@@ -1703,7 +1720,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
{
fdbg("Failed to exit IDLE state\n");
SPI_SELECT(spi, SPIDEV_MMCSD, false);
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
return -EIO;
}
}
@@ -1712,7 +1729,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
{
fdbg("Failed to identify card\n");
SPI_SELECT(spi, SPIDEV_MMCSD, false);
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
return -EIO;
}
@@ -1724,7 +1741,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
{
fdbg("mmcsd_getcsd(CMD9) failed: %d\n", result);
SPI_SELECT(spi, SPIDEV_MMCSD, false);
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
return -EIO;
}
@@ -1797,7 +1814,7 @@ static void mmcsd_mediachanged(void *arg)
/* Save the current slot state and reassess the new state */
- mmcsd_semtake(&slot->sem, spi);
+ mmcsd_semtake(slot);
oldstate = slot->state;
/* Check if media was removed or inserted */
@@ -1833,8 +1850,8 @@ static void mmcsd_mediachanged(void *arg)
slot->state |= MMCSD_SLOTSTATUS_MEDIACHGD;
}
}
-
- mmcsd_semgive(&slot->sem, spi);
+
+ mmcsd_semgive(slot);
}
/****************************************************************************
@@ -1889,12 +1906,13 @@ int mmcsd_spislotinitialize(int minor, int slotno, FAR struct spi_dev_s *spi)
/* Bind the SPI port to the slot */
slot->spi = spi;
+ slot->spispeed = MMCSD_IDMODE_CLOCK;
/* Ininitialize for the media in the slot (if any) */
- mmcsd_semtake(&slot->sem, spi);
+ mmcsd_semtake(slot);
ret = mmcsd_mediainitialize(slot);
- mmcsd_semgive(&slot->sem, spi);
+ mmcsd_semgive(slot);
if (ret == 0)
{
fvdbg("mmcsd_mediainitialize returned OK\n");
diff --git a/nuttx/drivers/usbdev/usbmsc_scsi.c b/nuttx/drivers/usbdev/usbmsc_scsi.c
index ccc967618..ff551871c 100644
--- a/nuttx/drivers/usbdev/usbmsc_scsi.c
+++ b/nuttx/drivers/usbdev/usbmsc_scsi.c
@@ -607,15 +607,27 @@ static inline int usbmsc_cmdinquiry(FAR struct usbmsc_dev_s *priv,
memset(response->vendorid, ' ', 8+16+4);
len = strlen(g_mscvendorstr);
- DEBUGASSERT(len <= 8);
+ if (len > 8)
+ {
+ len = 8;
+ }
+
memcpy(response->vendorid, g_mscvendorstr, len);
len = strlen(g_mscproductstr);
- DEBUGASSERT(len <= 16);
+ if (len > 16)
+ {
+ len = 16;
+ }
+
memcpy(response->productid, g_mscproductstr, len);
len = strlen(g_mscserialstr);
- DEBUGASSERT(len <= 4);
+ if (len > 4)
+ {
+ len = 4;
+ }
+
memcpy(response->revision, g_mscserialstr, len);
}
}