diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-11-02 08:27:13 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-11-02 08:27:13 -0600 |
commit | b3053774d6c60a998a0e582adcb11384fcbd686e (patch) | |
tree | 800c9af499cab85de497bdf166a4c63d85f2dd13 /nuttx | |
parent | f367b9d3f3fb0f4159828b17bfafd15c0917a098 (diff) | |
download | px4-nuttx-b3053774d6c60a998a0e582adcb11384fcbd686e.tar.gz px4-nuttx-b3053774d6c60a998a0e582adcb11384fcbd686e.tar.bz2 px4-nuttx-b3053774d6c60a998a0e582adcb11384fcbd686e.zip |
Fix to SST25 driver to permit faster write modes. From David Sidrane
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/ChangeLog | 10 | ||||
-rw-r--r-- | nuttx/configs/spark/composite/defconfig | 2 | ||||
-rw-r--r-- | nuttx/configs/spark/nsh/defconfig | 2 | ||||
-rw-r--r-- | nuttx/configs/spark/usbmsc/defconfig | 2 | ||||
-rw-r--r-- | nuttx/drivers/mtd/Kconfig | 8 | ||||
-rw-r--r-- | nuttx/drivers/mtd/sst25.c | 85 |
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 */ |