summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/ChangeLog10
-rw-r--r--nuttx/configs/spark/composite/defconfig2
-rw-r--r--nuttx/configs/spark/nsh/defconfig2
-rw-r--r--nuttx/configs/spark/usbmsc/defconfig2
-rw-r--r--nuttx/drivers/mtd/Kconfig8
-rw-r--r--nuttx/drivers/mtd/sst25.c85
6 files changed, 58 insertions, 51 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 21ce7cd88..1cbbd8a9d 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -5945,4 +5945,12 @@
from David Sidrane plugs the hole for now (2013-11-1).
* drivers/mtd/mtd_config.c: Reduce configuration header size. From
Ken Pettit (2013-11-1).
-
+ * drivers/mtd/sst25.c: Improved write performance by fixing a bug
+ that prevented operation in the faster write mode. The code did
+ not wait on the last write complete before issuing the WRDI The
+ loop in general failed to wait on the fist 2 bytes after the
+ SST25_AAI if the next 2 were FF FF, then it would reissue the
+ address but not cancel the write. Reorganized to always wait for
+ completion after and address with data write and on any data
+ write so that the device is complete before WRDI is sent. From
+ David Sidrane (2013-11-2).
diff --git a/nuttx/configs/spark/composite/defconfig b/nuttx/configs/spark/composite/defconfig
index cea1150ae..eb87a0efb 100644
--- a/nuttx/configs/spark/composite/defconfig
+++ b/nuttx/configs/spark/composite/defconfig
@@ -465,7 +465,7 @@ CONFIG_SST25_SPIMODE=0
CONFIG_SST25_SPIFREQUENCY=80000000
# CONFIG_SST25_READONLY is not set
CONFIG_SST25_SECTOR512=y
-CONFIG_SST25_SLOWWRITE=y
+# CONFIG_SST25_SLOWWRITE is not set
# CONFIG_SST25_SLOWREAD is not set
# CONFIG_MTD_SST39FV is not set
# CONFIG_MTD_W25 is not set
diff --git a/nuttx/configs/spark/nsh/defconfig b/nuttx/configs/spark/nsh/defconfig
index 17a612408..a520c16da 100644
--- a/nuttx/configs/spark/nsh/defconfig
+++ b/nuttx/configs/spark/nsh/defconfig
@@ -439,7 +439,7 @@ CONFIG_SST25_SPIMODE=0
CONFIG_SST25_SPIFREQUENCY=80000000
# CONFIG_SST25_READONLY is not set
CONFIG_SST25_SECTOR512=y
-CONFIG_SST25_SLOWWRITE=y
+# CONFIG_SST25_SLOWWRITE is not set
# CONFIG_SST25_SLOWREAD is not set
# CONFIG_MTD_SST39FV is not set
# CONFIG_MTD_W25 is not set
diff --git a/nuttx/configs/spark/usbmsc/defconfig b/nuttx/configs/spark/usbmsc/defconfig
index b78e951d3..468ddccb8 100644
--- a/nuttx/configs/spark/usbmsc/defconfig
+++ b/nuttx/configs/spark/usbmsc/defconfig
@@ -439,7 +439,7 @@ CONFIG_SST25_SPIMODE=0
CONFIG_SST25_SPIFREQUENCY=80000000
# CONFIG_SST25_READONLY is not set
CONFIG_SST25_SECTOR512=y
-CONFIG_SST25_SLOWWRITE=y
+# CONFIG_SST25_SLOWWRITE is not set
# CONFIG_SST25_SLOWREAD is not set
# CONFIG_MTD_SST39FV is not set
# CONFIG_MTD_W25 is not set
diff --git a/nuttx/drivers/mtd/Kconfig b/nuttx/drivers/mtd/Kconfig
index d4b334800..0d703ed51 100644
--- a/nuttx/drivers/mtd/Kconfig
+++ b/nuttx/drivers/mtd/Kconfig
@@ -259,7 +259,13 @@ config SST25_SECTOR512
config SST25_SLOWWRITE
bool
- default y
+ default n
+ ---help---
+ There used to be a bug in the current code when using the higher speed AAI
+ write sequence. The nature of the bug is that the WRDI instruction is not
+ working. At the end of the AAI sequence, the status register continues to
+ report that the SST25 is write enabled (WEL bit) and in AAI mode (AAI
+ bit). This has been fixed by David Sidrane!
config SST25_SLOWREAD
bool
diff --git a/nuttx/drivers/mtd/sst25.c b/nuttx/drivers/mtd/sst25.c
index 17c3d6fc7..a77b4e21e 100644
--- a/nuttx/drivers/mtd/sst25.c
+++ b/nuttx/drivers/mtd/sst25.c
@@ -82,17 +82,6 @@
# define CONFIG_SST25_SPIFREQUENCY 20000000
#endif
-/* There is a bug in the current code when using the higher speed AAI write sequence.
- * The nature of the bug is that the WRDI instruction is not working. At the end
- * of the AAI sequence, the status register continues to report that the SST25 is
- * write enabled (WEL bit) and in AAI mode (AAI bit). This *must* be fixed in any
- * production code if you want to have proper write performance.
- */
-
-#warning "REVISIT"
-#undef CONFIG_SST25_SLOWWRITE
-#define CONFIG_SST25_SLOWWRITE 1
-
/* SST25 Instructions ***************************************************************/
/* Command Value Description Addr Data */
/* Dummy */
@@ -225,9 +214,10 @@ static void sst25_lock(FAR struct spi_dev_s *dev);
static inline void sst25_unlock(FAR struct spi_dev_s *dev);
static inline int sst25_readid(FAR struct sst25_dev_s *priv);
#ifndef CONFIG_SST25_READONLY
-static void sst25_unprotect(FAR struct spi_dev_s *dev);
+static void sst25_unprotect(FAR struct sst25_dev_s *priv);
#endif
static uint8_t sst25_waitwritecomplete(FAR struct sst25_dev_s *priv);
+static inline void sst25_cmd(struct sst25_dev_s *priv, uint8_t cmd);
static inline void sst25_wren(FAR struct sst25_dev_s *priv);
#if !defined(CONFIG_SST25_SLOWWRITE) && !defined(CONFIG_SST25_READONLY)
static inline void sst25_wrdi(FAR struct sst25_dev_s *priv);
@@ -377,30 +367,23 @@ static inline int sst25_readid(struct sst25_dev_s *priv)
************************************************************************************/
#ifndef CONFIG_SST25_READONLY
-static void sst25_unprotect(FAR struct spi_dev_s *dev)
+static void sst25_unprotect(struct sst25_dev_s *priv)
{
- /* Select this FLASH part */
-
- SPI_SELECT(dev, SPIDEV_FLASH, true);
-
/* Send "Write enable status (EWSR)" */
- SPI_SEND(dev, SST25_EWSR);
+ sst25_cmd(priv, SST25_EWSR);
- /* Re-select this FLASH part (This might not be necessary... but is it shown in
- * the timing diagrams)
- */
+ /* Send "Write enable status (WRSR)" */
- SPI_SELECT(dev, SPIDEV_FLASH, false);
- SPI_SELECT(dev, SPIDEV_FLASH, true);
+ SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
- /* Send "Write enable status (EWSR)" */
+ SPI_SEND(priv->dev, SST25_WRSR);
- SPI_SEND(dev, SST25_WRSR);
+ /* Followed by the new status value */
- /* Following by the new status value */
+ SPI_SEND(priv->dev, 0);
- SPI_SEND(dev, 0);
+ SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
}
#endif
@@ -481,41 +464,45 @@ static uint8_t sst25_waitwritecomplete(struct sst25_dev_s *priv)
}
/************************************************************************************
- * Name: sst25_wren
+ * Name: sst25_cmd
************************************************************************************/
-static inline void sst25_wren(struct sst25_dev_s *priv)
+static inline void sst25_cmd(struct sst25_dev_s *priv, uint8_t cmd)
{
/* Select this FLASH part */
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
- /* Send "Write Enable (WREN)" command */
+ /* Send command */
+
+ (void)SPI_SEND(priv->dev, cmd);
- (void)SPI_SEND(priv->dev, SST25_WREN);
-
/* Deselect the FLASH */
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
}
/************************************************************************************
+ * Name: sst25_wren
+ ************************************************************************************/
+
+static inline void sst25_wren(struct sst25_dev_s *priv)
+{
+ /* Send "Write Enable (WREN)" command */
+
+ sst25_cmd(priv, SST25_WREN);
+}
+
+/************************************************************************************
* Name: sst25_wrdi
************************************************************************************/
+
#if !defined(CONFIG_SST25_SLOWWRITE) && !defined(CONFIG_SST25_READONLY)
static inline void sst25_wrdi(struct sst25_dev_s *priv)
{
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
/* Send "Write Disable (WRDI)" command */
- (void)SPI_SEND(priv->dev, SST25_WRDI);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
+ sst25_cmd(priv, SST25_WRDI);
}
#endif
@@ -770,6 +757,11 @@ static void sst25_wordwrite(struct sst25_dev_s *priv, FAR const uint8_t *buffer,
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
+ /* Wait for the preceding write to complete. */
+
+ status = sst25_waitwritecomplete(priv);
+ DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == (SST25_SR_WEL|SST25_SR_AAI));
+
/* Decrement the word count and advance the write position */
nwords--;
@@ -785,10 +777,6 @@ static void sst25_wordwrite(struct sst25_dev_s *priv, FAR const uint8_t *buffer,
(buffer[0] != SST25_ERASED_STATE ||
buffer[1] != SST25_ERASED_STATE))
{
- /* Wait for the preceding write to complete. */
-
- status = sst25_waitwritecomplete(priv);
- DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == (SST25_SR_WEL|SST25_SR_AAI));
/* Select this FLASH part */
@@ -806,6 +794,11 @@ static void sst25_wordwrite(struct sst25_dev_s *priv, FAR const uint8_t *buffer,
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
+ /* Wait for the preceding write to complete. */
+
+ status = sst25_waitwritecomplete(priv);
+ DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == (SST25_SR_WEL|SST25_SR_AAI));
+
/* Decrement the word count and advance the write position */
nwords--;
@@ -1251,7 +1244,7 @@ FAR struct mtd_dev_s *sst25_initialize(FAR struct spi_dev_s *dev)
/* Make sure that the FLASH is unprotected so that we can write into it */
#ifndef CONFIG_SST25_READONLY
- sst25_unprotect(priv->dev);
+ sst25_unprotect(priv);
#endif
#ifdef CONFIG_SST25_SECTOR512 /* Simulate a 512 byte sector */