drivers: mtd: fix nxstyle errors

Fix nxstyle errors to pass the CI errors.

Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
This commit is contained in:
Alin Jerpelea
2021-01-27 16:48:40 +01:00
committed by Xiang Xiao
parent 95adb15824
commit 2d8b193df4
24 changed files with 3804 additions and 2972 deletions
+114 -82
View File
@@ -1,6 +1,7 @@
/************************************************************************************ /****************************************************************************
* drivers/mtd/at24xx.c * drivers/mtd/at24xx.c
* Driver for I2C-based at24cxx EEPROM(at24c32,at24c64,at24c128,at24c256,at24c512) * Driver for I2C-based at24cxx EEPROM
* (at24c32,at24c64,at24c128,at24c256,at24c512)
* *
* Copyright (C) 2011 Li Zhuoyi. All rights reserved. * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
* Author: Li Zhuoyi <lzyy.cn@gmail.com> * Author: Li Zhuoyi <lzyy.cn@gmail.com>
@@ -40,11 +41,11 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Included Files * Included Files
************************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
@@ -66,11 +67,13 @@
#ifdef CONFIG_MTD_AT24XX #ifdef CONFIG_MTD_AT24XX
/************************************************************************************ /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ****************************************************************************/
/* As a minimum, the size of the AT24 part and its 7-bit I2C address are required. */ /* As a minimum,
* the size of the AT24 part and its 7-bit I2C address are required.
*/
#ifndef CONFIG_AT24XX_SIZE #ifndef CONFIG_AT24XX_SIZE
# warning "Assuming AT24 size 64" # warning "Assuming AT24 size 64"
@@ -129,11 +132,11 @@
# define AT24XX_ADDRSIZE 2 # define AT24XX_ADDRSIZE 2
#endif #endif
/* For applications where a file system is used on the AT24, the tiny page sizes /* For applications where a file system is used on the AT24, the tiny page
* will result in very inefficient FLASH usage. In such cases, it is better if * sizes will result in very inefficient FLASH usage. In such cases, it is
* blocks are comprised of "clusters" of pages so that the file system block * better if blocks are comprised of "clusters" of pages so that the file
* size is, say, 256 or 512 bytes. In any event, the block size *must* be an * system block size is, say, 256 or 512 bytes.
* even multiple of the pages. * In any event, the block size *must* be an even multiple of the pages.
*/ */
#ifndef CONFIG_AT24XX_MTD_BLOCKSIZE #ifndef CONFIG_AT24XX_MTD_BLOCKSIZE
@@ -145,9 +148,9 @@
# define CONFIG_AT24XX_TIMEOUT_MS 10 # define CONFIG_AT24XX_TIMEOUT_MS 10
#endif #endif
/************************************************************************************ /****************************************************************************
* Private Types * Private Types
************************************************************************************/ ****************************************************************************/
/* This type represents the state of the MTD device. The struct mtd_dev_s /* This type represents the state of the MTD device. The struct mtd_dev_s
* must appear at the beginning of the definition so that you can freely * must appear at the beginning of the definition so that you can freely
@@ -167,24 +170,33 @@ struct at24c_dev_s
uint16_t npages; /* 128, 256, 512, 1024 */ uint16_t npages; /* 128, 256, 512, 1024 */
}; };
/************************************************************************************ /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
************************************************************************************/ ****************************************************************************/
/* MTD driver methods */ /* MTD driver methods */
static int at24c_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks); static int at24c_erase(FAR struct mtd_dev_s *dev,
static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock, off_t startblock,
size_t nblocks);
static ssize_t at24c_bread(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks, FAR uint8_t *buf); size_t nblocks, FAR uint8_t *buf);
static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev,
size_t nblocks, FAR const uint8_t *buf); off_t startblock,
static ssize_t at24c_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, size_t nblocks,
FAR const uint8_t *buf);
static ssize_t at24c_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer); FAR uint8_t *buffer);
static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); static int at24c_ioctl(FAR struct mtd_dev_s *dev,
int cmd,
unsigned long arg);
/************************************************************************************ /****************************************************************************
* Private Data * Private Data
************************************************************************************/ ****************************************************************************/
#ifndef CONFIG_AT24XX_MULTI #ifndef CONFIG_AT24XX_MULTI
/* If only a signal AT24 part is supported then a statically allocated state /* If only a signal AT24 part is supported then a statically allocated state
@@ -194,17 +206,17 @@ static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
static struct at24c_dev_s g_at24c; static struct at24c_dev_s g_at24c;
#endif #endif
/************************************************************************************ /****************************************************************************
* Private Functions * Private Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: at24c_i2c_write * Name: at24c_i2c_write
* *
* Description: * Description:
* Write to the I2C device. * Write to the I2C device.
* *
************************************************************************************/ ****************************************************************************/
static int at24c_i2c_write(FAR struct at24c_dev_s *priv, uint16_t at24addr, static int at24c_i2c_write(FAR struct at24c_dev_s *priv, uint16_t at24addr,
FAR const uint8_t *buffer, int buflen) FAR const uint8_t *buffer, int buflen)
@@ -224,13 +236,13 @@ static int at24c_i2c_write(FAR struct at24c_dev_s *priv, uint16_t at24addr,
return I2C_TRANSFER(priv->dev, &msg, 1); return I2C_TRANSFER(priv->dev, &msg, 1);
} }
/************************************************************************************ /****************************************************************************
* Name: at24c_i2c_read * Name: at24c_i2c_read
* *
* Description: * Description:
* Read from the I2C device. * Read from the I2C device.
* *
************************************************************************************/ ****************************************************************************/
static int at24c_i2c_read(FAR struct at24c_dev_s *priv, uint16_t at24addr, static int at24c_i2c_read(FAR struct at24c_dev_s *priv, uint16_t at24addr,
FAR uint8_t *buffer, int buflen) FAR uint8_t *buffer, int buflen)
@@ -250,9 +262,9 @@ static int at24c_i2c_read(FAR struct at24c_dev_s *priv, uint16_t at24addr,
return I2C_TRANSFER(priv->dev, &msg, 1); return I2C_TRANSFER(priv->dev, &msg, 1);
} }
/************************************************************************************ /****************************************************************************
* Name: at24c_eraseall * Name: at24c_eraseall
************************************************************************************/ ****************************************************************************/
static int at24c_eraseall(FAR struct at24c_dev_s *priv) static int at24c_eraseall(FAR struct at24c_dev_s *priv)
{ {
@@ -277,7 +289,10 @@ static int at24c_eraseall(FAR struct at24c_dev_s *priv)
#endif #endif
wait = CONFIG_AT24XX_TIMEOUT_MS; wait = CONFIG_AT24XX_TIMEOUT_MS;
while (at24c_i2c_write(priv, at24addr, buf, AT24XX_ADDRSIZE) < 0) while (at24c_i2c_write(priv,
at24addr,
buf,
AT24XX_ADDRSIZE) < 0)
{ {
finfo("wait\n"); finfo("wait\n");
if (!wait--) if (!wait--)
@@ -288,29 +303,36 @@ static int at24c_eraseall(FAR struct at24c_dev_s *priv)
nxsig_usleep(1000); nxsig_usleep(1000);
} }
at24c_i2c_write(priv, at24addr, buf, AT24XX_PAGESIZE + AT24XX_ADDRSIZE); at24c_i2c_write(priv,
at24addr,
buf,
AT24XX_PAGESIZE + AT24XX_ADDRSIZE);
} }
return OK; return OK;
} }
/************************************************************************************ /****************************************************************************
* Name: at24c_erase * Name: at24c_erase
************************************************************************************/ ****************************************************************************/
static int at24c_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks) static int at24c_erase(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks)
{ {
/* EEprom need not erase */ /* EEprom need not erase */
return (int)nblocks; return (int)nblocks;
} }
/************************************************************************************ /****************************************************************************
* Name: at24c_read_internal * Name: at24c_read_internal
************************************************************************************/ ****************************************************************************/
static ssize_t at24c_read_internal(FAR struct at24c_dev_s *priv, off_t offset, static ssize_t at24c_read_internal(FAR struct at24c_dev_s *priv,
size_t nbytes, FAR uint8_t *buffer, off_t offset,
size_t nbytes,
FAR uint8_t *buffer,
uint8_t address) uint8_t address)
{ {
uint8_t buf[AT24XX_ADDRSIZE]; uint8_t buf[AT24XX_ADDRSIZE];
@@ -363,9 +385,9 @@ static ssize_t at24c_read_internal(FAR struct at24c_dev_s *priv, off_t offset,
return nbytes; return nbytes;
} }
/************************************************************************************ /****************************************************************************
* Name: at24c_bread * Name: at24c_bread
************************************************************************************/ ****************************************************************************/
static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, FAR uint8_t *buffer) size_t nblocks, FAR uint8_t *buffer)
@@ -421,12 +443,12 @@ static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock,
#endif #endif
} }
/************************************************************************************ /****************************************************************************
* Name: at24c_bwrite * Name: at24c_bwrite
* *
* Operates on MTD block's and translates to FLASH pages * Operates on MTD block's and translates to FLASH pages
* *
************************************************************************************/ ****************************************************************************/
static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, size_t nblocks,
@@ -495,18 +517,22 @@ static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
#endif #endif
} }
/************************************************************************************ /****************************************************************************
* Name: at24c_read * Name: at24c_read
************************************************************************************/ ****************************************************************************/
static ssize_t at24c_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t at24c_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer) FAR uint8_t *buffer)
{ {
FAR struct at24c_dev_s *priv = (FAR struct at24c_dev_s *)dev; FAR struct at24c_dev_s *priv = (FAR struct at24c_dev_s *)dev;
size_t memsize; size_t memsize;
uint8_t addr; uint8_t addr;
finfo("offset: %lu nbytes: %lu\n", (unsigned long)offset, (unsigned long)nbytes); finfo("offset: %lu nbytes: %lu\n",
(unsigned long)offset,
(unsigned long)nbytes);
/* Don't permit reads beyond the end of the memory region */ /* Don't permit reads beyond the end of the memory region */
@@ -543,9 +569,9 @@ static ssize_t at24c_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes
return at24c_read_internal(priv, offset, nbytes, buffer, addr); return at24c_read_internal(priv, offset, nbytes, buffer, addr);
} }
/************************************************************************************ /****************************************************************************
* Name: at24c_ioctl * Name: at24c_ioctl
************************************************************************************/ ****************************************************************************/
static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{ {
@@ -562,25 +588,28 @@ static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
((uintptr_t)arg); ((uintptr_t)arg);
if (geo) if (geo)
{ {
/* Populate the geometry structure with information need to know /* Populate the geometry structure with information need to
* the capacity and how to access the device. * know the capacity and how to access the device.
* *
* NOTE: that the device is treated as though it where just an array * NOTE:
* of fixed size blocks. That is most likely not true, but the client * that the device is treated as though it where just an array
* will expect the device logic to do whatever is necessary to make it * of fixed size blocks.
* appear so. * That is most likely not true, but the client will expect the
* device logic to do whatever is necessary to make it appear
* so.
* *
* blocksize: * blocksize:
* May be user defined. The block size for the at24XX devices may be * May be user defined.
* larger than the page size in order to better support file systems. * The block size for the at24XX devices may be larger than
* The read and write functions translate BLOCKS to pages for the * the page size in order to better support file systems.
* small flash devices * The read and write functions translate BLOCKS to pages
* for the small flash devices
* erasesize: * erasesize:
* It has to be at least as big as the blocksize, bigger serves no * It has to be at least as big as the blocksize, bigger
* purpose. * serves no purpose.
* neraseblocks * neraseblocks
* Note that the device size is in kilobits and must be scaled by * Note that the device size is in kilobits and must be
* 1024 / 8 * scaled by 1024 / 8
*/ */
#if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE #if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE
@@ -622,22 +651,24 @@ static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
return ret; return ret;
} }
/************************************************************************************ /****************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: at24c_initialize * Name: at24c_initialize
* *
* Description: * Description:
* Create an initialized MTD device instance. MTD devices are not registered * Create an initialized MTD device instance.
* in the file system, but are created as instances that can be bound to * MTD devices are not registered in the file system, but are created
* other functions (such as a block or character driver front end). * as instances that can be bound to other functions
* (such as a block or character driver front end).
* *
************************************************************************************/ ****************************************************************************/
#ifdef CONFIG_AT24XX_MULTI #ifdef CONFIG_AT24XX_MULTI
FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev, uint8_t address) FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev,
uint8_t address)
#else #else
FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev) FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev)
#endif #endif
@@ -650,8 +681,8 @@ FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev)
/* Allocate a state structure (we allocate the structure instead of using /* Allocate a state structure (we allocate the structure instead of using
* a fixed, static allocation so that we can handle multiple FLASH devices. * a fixed, static allocation so that we can handle multiple FLASH devices.
* The current implementation would handle only one FLASH part per I2C * The current implementation would handle only one FLASH part per I2C
* device (only because of the SPIDEV_FLASH(0) definition) and so would have * device (only because of the SPIDEV_FLASH(0) definition) and so would
* to be extended to handle multiple FLASH parts on the same I2C bus. * have to be extended to handle multiple FLASH parts on the same I2C bus.
*/ */
priv = (FAR struct at24c_dev_s *)kmm_zalloc(sizeof(struct at24c_dev_s)); priv = (FAR struct at24c_dev_s *)kmm_zalloc(sizeof(struct at24c_dev_s));
@@ -664,8 +695,8 @@ FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev)
#else #else
finfo("dev: %p\n", dev); finfo("dev: %p\n", dev);
/* If only a signal AT24 part is supported then a statically allocated state /* If only a signal AT24 part is supported then a statically allocated
* structure is used. * state structure is used.
*/ */
priv = &g_at24c; priv = &g_at24c;
@@ -703,14 +734,15 @@ FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_master_s *dev)
return (FAR struct mtd_dev_s *)priv; return (FAR struct mtd_dev_s *)priv;
} }
/************************************************************************************ /****************************************************************************
* Name: at24c_uninitialize * Name: at24c_uninitialize
* *
* Description: * Description:
* Release resources held by an allocated MTD device instance. Resources are only * Release resources held by an allocated MTD device instance.
* allocated for the case where multiple AT24xx devices are support. * Resources are only allocated for the case where multiple AT24xx
* devices are support.
* *
************************************************************************************/ ****************************************************************************/
#ifdef CONFIG_AT24XX_MULTI #ifdef CONFIG_AT24XX_MULTI
void at24c_uninitialize(FAR struct mtd_dev_s *mtd) void at24c_uninitialize(FAR struct mtd_dev_s *mtd)
+108 -78
View File
@@ -1,4 +1,4 @@
/************************************************************************************ /****************************************************************************
* drivers/mtd/at25.c * drivers/mtd/at25.c
* Driver for SPI-based AT25DF321 (32Mbit) flash. * Driver for SPI-based AT25DF321 (32Mbit) flash.
* *
@@ -33,11 +33,11 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Included Files * Included Files
************************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
@@ -56,11 +56,11 @@
#include <nuttx/spi/spi.h> #include <nuttx/spi/spi.h>
#include <nuttx/mtd/mtd.h> #include <nuttx/mtd/mtd.h>
/************************************************************************************ /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ****************************************************************************/
/* Configuration ********************************************************************/ /* Configuration ************************************************************/
#ifndef CONFIG_AT25_SPIMODE #ifndef CONFIG_AT25_SPIMODE
# define CONFIG_AT25_SPIMODE SPIDEV_MODE0 # define CONFIG_AT25_SPIMODE SPIDEV_MODE0
@@ -70,7 +70,7 @@
# define CONFIG_AT25_SPIFREQUENCY 20000000 # define CONFIG_AT25_SPIFREQUENCY 20000000
#endif #endif
/* AT25 Registers *******************************************************************/ /* AT25 Registers ***********************************************************/
/* Identification register values */ /* Identification register values */
@@ -129,9 +129,9 @@
#define AT25_DUMMY 0xa5 #define AT25_DUMMY 0xa5
/************************************************************************************ /****************************************************************************
* Private Types * Private Types
************************************************************************************/ ****************************************************************************/
/* This type represents the state of the MTD device. The struct mtd_dev_s /* This type represents the state of the MTD device. The struct mtd_dev_s
* must appear at the beginning of the definition so that you can freely * must appear at the beginning of the definition so that you can freely
@@ -148,9 +148,9 @@ struct at25_dev_s
uint32_t npages; /* 32,768 or 65,536 */ uint32_t npages; /* 32,768 or 65,536 */
}; };
/************************************************************************************ /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
************************************************************************************/ ****************************************************************************/
/* Helpers */ /* Helpers */
@@ -159,29 +159,41 @@ static inline void at25_unlock(FAR struct spi_dev_s *dev);
static inline int at25_readid(struct at25_dev_s *priv); static inline int at25_readid(struct at25_dev_s *priv);
static void at25_waitwritecomplete(struct at25_dev_s *priv); static void at25_waitwritecomplete(struct at25_dev_s *priv);
static void at25_writeenable(struct at25_dev_s *priv); static void at25_writeenable(struct at25_dev_s *priv);
static inline void at25_sectorerase(struct at25_dev_s *priv, off_t offset); static inline void at25_sectorerase(struct at25_dev_s *priv,
off_t offset);
static inline int at25_bulkerase(struct at25_dev_s *priv); static inline int at25_bulkerase(struct at25_dev_s *priv);
static inline void at25_pagewrite(struct at25_dev_s *priv, FAR const uint8_t *buffer, static inline void at25_pagewrite(struct at25_dev_s *priv,
FAR const uint8_t *buffer,
off_t offset); off_t offset);
/* MTD driver methods */ /* MTD driver methods */
static int at25_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks); static int at25_erase(FAR struct mtd_dev_s *dev,
static ssize_t at25_bread(FAR struct mtd_dev_s *dev, off_t startblock, off_t startblock,
size_t nblocks, FAR uint8_t *buf); size_t nblocks);
static ssize_t at25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t at25_bread(FAR struct mtd_dev_s *dev,
size_t nblocks, FAR const uint8_t *buf); off_t startblock,
static ssize_t at25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, size_t nblocks,
FAR uint8_t *buf);
static ssize_t at25_bwrite(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
FAR const uint8_t *buf);
static ssize_t at25_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer); FAR uint8_t *buffer);
static int at25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); static int at25_ioctl(FAR struct mtd_dev_s *dev,
int cmd,
unsigned long arg);
/************************************************************************************ /****************************************************************************
* Private Functions * Private Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: at25_lock * Name: at25_lock
************************************************************************************/ ****************************************************************************/
static void at25_lock(FAR struct spi_dev_s *dev) static void at25_lock(FAR struct spi_dev_s *dev)
{ {
@@ -189,16 +201,18 @@ static void at25_lock(FAR struct spi_dev_s *dev)
* lock SPI to have exclusive access to the buses for a sequence of * lock SPI to have exclusive access to the buses for a sequence of
* transfers. The bus should be locked before the chip is selected. * transfers. The bus should be locked before the chip is selected.
* *
* This is a blocking call and will not return until we have exclusive access to * This is a blocking call and will not return until we have exclusive
* the SPI bus. We will retain that exclusive access until the bus is unlocked. * access to the SPI bus.
* We will retain that exclusive access until the bus is unlocked.
*/ */
SPI_LOCK(dev, true); SPI_LOCK(dev, true);
/* After locking the SPI bus, the we also need call the setfrequency, setbits, and /* After locking the SPI bus, the we also need call the setfrequency,
* setmode methods to make sure that the SPI is properly configured for the device. * setbits, and setmode methods to make sure that the SPI is properly
* If the SPI bus is being shared, then it may have been left in an incompatible * configured for the device.
* state. * If the SPI bus is being shared, then it may have been left in an
* incompatible state.
*/ */
SPI_SETMODE(dev, CONFIG_AT25_SPIMODE); SPI_SETMODE(dev, CONFIG_AT25_SPIMODE);
@@ -207,18 +221,18 @@ static void at25_lock(FAR struct spi_dev_s *dev)
SPI_SETFREQUENCY(dev, CONFIG_AT25_SPIFREQUENCY); SPI_SETFREQUENCY(dev, CONFIG_AT25_SPIFREQUENCY);
} }
/************************************************************************************ /****************************************************************************
* Name: at25_unlock * Name: at25_unlock
************************************************************************************/ ****************************************************************************/
static inline void at25_unlock(FAR struct spi_dev_s *dev) static inline void at25_unlock(FAR struct spi_dev_s *dev)
{ {
SPI_LOCK(dev, false); SPI_LOCK(dev, false);
} }
/************************************************************************************ /****************************************************************************
* Name: at25_readid * Name: at25_readid
************************************************************************************/ ****************************************************************************/
static inline int at25_readid(struct at25_dev_s *priv) static inline int at25_readid(struct at25_dev_s *priv)
{ {
@@ -248,7 +262,8 @@ static inline int at25_readid(struct at25_dev_s *priv)
/* Check for a valid manufacturer and memory type */ /* Check for a valid manufacturer and memory type */
if (manufacturer == AT25_MANUFACTURER && memory == AT25_AT25DF081A_TYPE) if (manufacturer == AT25_MANUFACTURER &&
memory == AT25_AT25DF081A_TYPE)
{ {
priv->sectorshift = AT25_AT25DF081A_SECTOR_SHIFT; priv->sectorshift = AT25_AT25DF081A_SECTOR_SHIFT;
priv->nsectors = AT25_AT25DF081A_NSECTORS; priv->nsectors = AT25_AT25DF081A_NSECTORS;
@@ -256,7 +271,8 @@ static inline int at25_readid(struct at25_dev_s *priv)
priv->npages = AT25_AT25DF081A_NPAGES; priv->npages = AT25_AT25DF081A_NPAGES;
return OK; return OK;
} }
else if (manufacturer == AT25_MANUFACTURER && memory == AT25_AT25DF321_TYPE) else if (manufacturer == AT25_MANUFACTURER &&
memory == AT25_AT25DF321_TYPE)
{ {
priv->sectorshift = AT25_AT25DF321_SECTOR_SHIFT; priv->sectorshift = AT25_AT25DF321_SECTOR_SHIFT;
priv->nsectors = AT25_AT25DF321_NSECTORS; priv->nsectors = AT25_AT25DF321_NSECTORS;
@@ -268,9 +284,9 @@ static inline int at25_readid(struct at25_dev_s *priv)
return -ENODEV; return -ENODEV;
} }
/************************************************************************************ /****************************************************************************
* Name: at25_waitwritecomplete * Name: at25_waitwritecomplete
************************************************************************************/ ****************************************************************************/
static void at25_waitwritecomplete(struct at25_dev_s *priv) static void at25_waitwritecomplete(struct at25_dev_s *priv)
{ {
@@ -288,7 +304,9 @@ static void at25_waitwritecomplete(struct at25_dev_s *priv)
SPI_SEND(priv->dev, AT25_RDSR); SPI_SEND(priv->dev, AT25_RDSR);
/* Send a dummy byte to generate the clock needed to shift out the status */ /* Send a dummy byte to generate the clock needed to shift out
* the status
*/
status = SPI_SEND(priv->dev, AT25_DUMMY); status = SPI_SEND(priv->dev, AT25_DUMMY);
@@ -296,9 +314,10 @@ static void at25_waitwritecomplete(struct at25_dev_s *priv)
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false); SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
/* Given that writing could take up to few tens of milliseconds, and erasing /* Given that writing could take up to few tens of milliseconds,
* could take more. The following short delay in the "busy" case will allow * and erasing could take more.
* other peripherals to access the SPI bus. * The following short delay in the "busy" case will allow other
* peripherals to access the SPI bus.
*/ */
if ((status & AT25_SR_BUSY) != 0) if ((status & AT25_SR_BUSY) != 0)
@@ -318,9 +337,9 @@ static void at25_waitwritecomplete(struct at25_dev_s *priv)
finfo("Complete, status: 0x%02x\n", status); finfo("Complete, status: 0x%02x\n", status);
} }
/************************************************************************************ /****************************************************************************
* Name: at25_writeenable * Name: at25_writeenable
************************************************************************************/ ****************************************************************************/
static void at25_writeenable(struct at25_dev_s *priv) static void at25_writeenable(struct at25_dev_s *priv)
{ {
@@ -330,9 +349,9 @@ static void at25_writeenable(struct at25_dev_s *priv)
finfo("Enabled\n"); finfo("Enabled\n");
} }
/************************************************************************************ /****************************************************************************
* Name: at25_sectorerase * Name: at25_sectorerase
************************************************************************************/ ****************************************************************************/
static inline void at25_sectorerase(struct at25_dev_s *priv, off_t sector) static inline void at25_sectorerase(struct at25_dev_s *priv, off_t sector)
{ {
@@ -375,9 +394,9 @@ static inline void at25_sectorerase(struct at25_dev_s *priv, off_t sector)
finfo("Erased\n"); finfo("Erased\n");
} }
/************************************************************************************ /****************************************************************************
* Name: at25_bulkerase * Name: at25_bulkerase
************************************************************************************/ ****************************************************************************/
static inline int at25_bulkerase(struct at25_dev_s *priv) static inline int at25_bulkerase(struct at25_dev_s *priv)
{ {
@@ -410,11 +429,12 @@ static inline int at25_bulkerase(struct at25_dev_s *priv)
return OK; return OK;
} }
/************************************************************************************ /****************************************************************************
* Name: at25_pagewrite * Name: at25_pagewrite
************************************************************************************/ ****************************************************************************/
static inline void at25_pagewrite(struct at25_dev_s *priv, FAR const uint8_t *buffer, static inline void at25_pagewrite(struct at25_dev_s *priv,
FAR const uint8_t *buffer,
off_t page) off_t page)
{ {
off_t offset = page << 8; off_t offset = page << 8;
@@ -457,11 +477,13 @@ static inline void at25_pagewrite(struct at25_dev_s *priv, FAR const uint8_t *bu
finfo("Written\n"); finfo("Written\n");
} }
/************************************************************************************ /****************************************************************************
* Name: at25_erase * Name: at25_erase
************************************************************************************/ ****************************************************************************/
static int at25_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks) static int at25_erase(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks)
{ {
FAR struct at25_dev_s *priv = (FAR struct at25_dev_s *)dev; FAR struct at25_dev_s *priv = (FAR struct at25_dev_s *)dev;
size_t blocksleft = nblocks; size_t blocksleft = nblocks;
@@ -483,9 +505,9 @@ static int at25_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblock
return (int)nblocks; return (int)nblocks;
} }
/************************************************************************************ /****************************************************************************
* Name: at25_bread * Name: at25_bread
************************************************************************************/ ****************************************************************************/
static ssize_t at25_bread(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t at25_bread(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, size_t nblocks,
@@ -496,7 +518,9 @@ static ssize_t at25_bread(FAR struct mtd_dev_s *dev, off_t startblock,
finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
/* On this device, we can handle the block read just like the byte-oriented read */ /* On this device, we can handle the block read just like the byte-oriented
* read
*/
nbytes = at25_read(dev, startblock << priv->pageshift, nbytes = at25_read(dev, startblock << priv->pageshift,
nblocks << priv->pageshift, buffer); nblocks << priv->pageshift, buffer);
@@ -508,9 +532,9 @@ static ssize_t at25_bread(FAR struct mtd_dev_s *dev, off_t startblock,
return (int)nbytes; return (int)nbytes;
} }
/************************************************************************************ /****************************************************************************
* Name: at25_bwrite * Name: at25_bwrite
************************************************************************************/ ****************************************************************************/
static ssize_t at25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t at25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, FAR const uint8_t *buffer) size_t nblocks, FAR const uint8_t *buffer)
@@ -535,11 +559,13 @@ static ssize_t at25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
return nblocks; return nblocks;
} }
/************************************************************************************ /****************************************************************************
* Name: at25_read * Name: at25_read
************************************************************************************/ ****************************************************************************/
static ssize_t at25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t at25_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer) FAR uint8_t *buffer)
{ {
FAR struct at25_dev_s *priv = (FAR struct at25_dev_s *)dev; FAR struct at25_dev_s *priv = (FAR struct at25_dev_s *)dev;
@@ -587,9 +613,9 @@ static ssize_t at25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
return nbytes; return nbytes;
} }
/************************************************************************************ /****************************************************************************
* Name: at25_ioctl * Name: at25_ioctl
************************************************************************************/ ****************************************************************************/
static int at25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) static int at25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{ {
@@ -607,13 +633,15 @@ static int at25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
if (geo != NULL) if (geo != NULL)
{ {
/* Populate the geometry structure with information need to know /* Populate the geometry structure with information need to
* the capacity and how to access the device. * know the capacity and how to access the device.
* *
* NOTE: that the device is treated as though it where just an array * NOTE:
* of fixed size blocks. That is most likely not true, but the client * that the device is treated as though it where just an array
* will expect the device logic to do whatever is necessary to make it * of fixed size blocks.
* appear so. * That is most likely not true, but the client will expect the
* device logic to do whatever is necessary to make it appear
* so.
*/ */
geo->blocksize = (1 << priv->pageshift); geo->blocksize = (1 << priv->pageshift);
@@ -648,11 +676,11 @@ static int at25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
return ret; return ret;
} }
/************************************************************************************ /****************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: at25_initialize * Name: at25_initialize
* *
* Description: * Description:
@@ -660,7 +688,7 @@ static int at25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
* in the file system, but are created as instances that can be bound to * in the file system, but are created as instances that can be bound to
* other functions (such as a block or character driver front end). * other functions (such as a block or character driver front end).
* *
************************************************************************************/ ****************************************************************************/
FAR struct mtd_dev_s *at25_initialize(FAR struct spi_dev_s *dev) FAR struct mtd_dev_s *at25_initialize(FAR struct spi_dev_s *dev)
{ {
@@ -672,8 +700,8 @@ FAR struct mtd_dev_s *at25_initialize(FAR struct spi_dev_s *dev)
/* Allocate a state structure (we allocate the structure instead of using /* Allocate a state structure (we allocate the structure instead of using
* a fixed, static allocation so that we can handle multiple FLASH devices. * a fixed, static allocation so that we can handle multiple FLASH devices.
* The current implementation would handle only one FLASH part per SPI * The current implementation would handle only one FLASH part per SPI
* device (only because of the SPIDEV_FLASH(0) definition) and so would have * device (only because of the SPIDEV_FLASH(0) definition) and so would
* to be extended to handle multiple FLASH parts on the same SPI bus. * have to be extended to handle multiple FLASH parts on the same SPI bus.
*/ */
priv = (FAR struct at25_dev_s *)kmm_zalloc(sizeof(struct at25_dev_s)); priv = (FAR struct at25_dev_s *)kmm_zalloc(sizeof(struct at25_dev_s));
@@ -700,7 +728,9 @@ FAR struct mtd_dev_s *at25_initialize(FAR struct spi_dev_s *dev)
ret = at25_readid(priv); ret = at25_readid(priv);
if (ret != OK) if (ret != OK)
{ {
/* Unrecognized! Discard all of that work we just did and return NULL */ /* Unrecognized!
* Discard all of that work we just did and return NULL
*/
ferr("ERROR: Unrecognized\n"); ferr("ERROR: Unrecognized\n");
kmm_free(priv); kmm_free(priv);
+183 -142
View File
File diff suppressed because it is too large Load Diff
+146 -99
View File
@@ -1,4 +1,4 @@
/************************************************************************************ /****************************************************************************
* drivers/mtd/gd5f.c * drivers/mtd/gd5f.c
* Driver for GigaDevice SPI nand flash. * Driver for GigaDevice SPI nand flash.
* *
@@ -32,11 +32,11 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Included Files * Included Files
************************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
@@ -54,11 +54,11 @@
#include <nuttx/spi/spi.h> #include <nuttx/spi/spi.h>
#include <nuttx/mtd/mtd.h> #include <nuttx/mtd/mtd.h>
/************************************************************************************ /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ****************************************************************************/
/* Configuration ********************************************************************/ /* Configuration ************************************************************/
#ifndef CONFIG_GD5F_SPIMODE #ifndef CONFIG_GD5F_SPIMODE
# define CONFIG_GD5F_SPIMODE SPIDEV_MODE0 # define CONFIG_GD5F_SPIMODE SPIDEV_MODE0
@@ -68,9 +68,10 @@
# define CONFIG_GD5F_SPIFREQUENCY 20000000 # define CONFIG_GD5F_SPIFREQUENCY 20000000
#endif #endif
/* GD5F Instructions ****************************************************************/ /* GD5F Instructions ********************************************************/
/* Command Value Description Addr Data */ /* Command Value Description Addr Data */
/* Dummy */ /* Dummy */
#define GD5F_GET_FEATURE 0x0f /* Get features 1 0 1 */ #define GD5F_GET_FEATURE 0x0f /* Get features 1 0 1 */
@@ -91,10 +92,9 @@
#define GD5F_WRITE_ENABLE 0x06 /* 0 0 0 */ #define GD5F_WRITE_ENABLE 0x06 /* 0 0 0 */
#define GD5F_WRITE_DISABLE 0x04 /* 0 0 0 */ #define GD5F_WRITE_DISABLE 0x04 /* 0 0 0 */
#define GD5F_RESET 0xff /* Reset the device 0 0 0 */ #define GD5F_RESET 0xff /* Reset the device 0 0 0 */
#define GD5F_DUMMY 0x00 /* No Operation 0 0 0 */ #define GD5F_DUMMY 0x00 /* No Operation 0 0 0 */
/* Feature register *****************************************************************/ /* Feature register *********************************************************/
/* JEDEC Read ID register values */ /* JEDEC Read ID register values */
@@ -153,9 +153,9 @@
#define GD5F_FEATURE_ECC_OFFSET 4 #define GD5F_FEATURE_ECC_OFFSET 4
#define GD5F_ECC_STATUS_MASK 0x0f #define GD5F_ECC_STATUS_MASK 0x0f
/************************************************************************************ /****************************************************************************
* Private Types * Private Types
************************************************************************************/ ****************************************************************************/
/* This type represents the state of the MTD device. The struct mtd_dev_s /* This type represents the state of the MTD device. The struct mtd_dev_s
* must appear at the beginning of the definition so that you can freely * must appear at the beginning of the definition so that you can freely
@@ -173,9 +173,9 @@ struct gd5f_dev_s
uint8_t eccstatus; /* Internal ECC status */ uint8_t eccstatus; /* Internal ECC status */
}; };
/************************************************************************************ /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
************************************************************************************/ ****************************************************************************/
/* Helpers */ /* Helpers */
@@ -183,18 +183,26 @@ static inline void gd5f_lock(FAR struct spi_dev_s *dev);
static inline void gd5f_unlock(FAR struct spi_dev_s *dev); static inline void gd5f_unlock(FAR struct spi_dev_s *dev);
static int gd5f_readid(FAR struct gd5f_dev_s *priv); static int gd5f_readid(FAR struct gd5f_dev_s *priv);
static bool gd5f_waitstatus(FAR struct gd5f_dev_s *priv, uint8_t mask, static bool gd5f_waitstatus(FAR struct gd5f_dev_s *priv,
uint8_t mask,
bool successif); bool successif);
static inline void gd5f_writeenable(FAR struct gd5f_dev_s *priv); static inline void gd5f_writeenable(FAR struct gd5f_dev_s *priv);
static inline void gd5f_writedisable(FAR struct gd5f_dev_s *priv); static inline void gd5f_writedisable(FAR struct gd5f_dev_s *priv);
static bool gd5f_sectorerase(FAR struct gd5f_dev_s *priv, off_t startsector); static bool gd5f_sectorerase(FAR struct gd5f_dev_s *priv,
static void gd5f_readbuffer(FAR struct gd5f_dev_s *priv, uint32_t address, off_t startsector);
uint8_t *buffer, size_t length); static void gd5f_readbuffer(FAR struct gd5f_dev_s *priv,
static bool gd5f_read_page(FAR struct gd5f_dev_s *priv, uint32_t position); uint32_t address,
uint8_t *buffer,
size_t length);
static bool gd5f_read_page(FAR struct gd5f_dev_s *priv,
uint32_t position);
static void gd5f_write_to_cache(FAR struct gd5f_dev_s *priv, uint32_t address, static void gd5f_write_to_cache(FAR struct gd5f_dev_s *priv,
const uint8_t *buffer, size_t length); uint32_t address,
static bool gd5f_execute_write(FAR struct gd5f_dev_s *priv, uint32_t position); const uint8_t *buffer,
size_t length);
static bool gd5f_execute_write(FAR struct gd5f_dev_s *priv,
uint32_t position);
static inline void gd5f_eccstatusread(FAR struct gd5f_dev_s *priv); static inline void gd5f_eccstatusread(FAR struct gd5f_dev_s *priv);
static inline void gd5f_enable_ecc(FAR struct gd5f_dev_s *priv); static inline void gd5f_enable_ecc(FAR struct gd5f_dev_s *priv);
@@ -202,24 +210,36 @@ static inline void gd5f_unlockblocks(FAR struct gd5f_dev_s *priv);
/* MTD driver methods */ /* MTD driver methods */
static ssize_t gd5f_bread(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t gd5f_bread(FAR struct mtd_dev_s *dev,
size_t nblocks, FAR uint8_t *buffer); off_t startblock,
static ssize_t gd5f_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, size_t nblocks,
FAR uint8_t *buffer); FAR uint8_t *buffer);
static ssize_t gd5f_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t gd5f_read(FAR struct mtd_dev_s *dev,
size_t nblocks, FAR const uint8_t *buffer); off_t offset,
static ssize_t gd5f_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, size_t nbytes,
FAR uint8_t *buffer);
static ssize_t gd5f_bwrite(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
FAR const uint8_t *buffer); FAR const uint8_t *buffer);
static int gd5f_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); static ssize_t gd5f_write(FAR struct mtd_dev_s *dev,
static int gd5f_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks); off_t offset,
size_t nbytes,
FAR const uint8_t *buffer);
static int gd5f_ioctl(FAR struct mtd_dev_s *dev,
int cmd,
unsigned long arg);
static int gd5f_erase(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks);
/************************************************************************************ /****************************************************************************
* Private Functions * Private Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: gd5f_lock * Name: gd5f_lock
************************************************************************************/ ****************************************************************************/
static inline void gd5f_lock(FAR struct spi_dev_s *dev) static inline void gd5f_lock(FAR struct spi_dev_s *dev)
{ {
@@ -231,18 +251,18 @@ static inline void gd5f_lock(FAR struct spi_dev_s *dev)
SPI_SETFREQUENCY(dev, CONFIG_GD5F_SPIFREQUENCY); SPI_SETFREQUENCY(dev, CONFIG_GD5F_SPIFREQUENCY);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_unlock * Name: gd5f_unlock
************************************************************************************/ ****************************************************************************/
static inline void gd5f_unlock(FAR struct spi_dev_s *dev) static inline void gd5f_unlock(FAR struct spi_dev_s *dev)
{ {
SPI_LOCK(dev, false); SPI_LOCK(dev, false);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_readid * Name: gd5f_readid
************************************************************************************/ ****************************************************************************/
static int gd5f_readid(FAR struct gd5f_dev_s *priv) static int gd5f_readid(FAR struct gd5f_dev_s *priv)
{ {
@@ -303,11 +323,13 @@ static int gd5f_readid(FAR struct gd5f_dev_s *priv)
return -ENODEV; return -ENODEV;
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_waitstatus * Name: gd5f_waitstatus
************************************************************************************/ ****************************************************************************/
static bool gd5f_waitstatus(FAR struct gd5f_dev_s *priv, uint8_t mask, bool successif) static bool gd5f_waitstatus(FAR struct gd5f_dev_s *priv,
uint8_t mask,
bool successif)
{ {
uint8_t status; uint8_t status;
@@ -337,9 +359,9 @@ static bool gd5f_waitstatus(FAR struct gd5f_dev_s *priv, uint8_t mask, bool succ
return successif ? ((status & mask) != 0) : ((status & mask) == 0); return successif ? ((status & mask) != 0) : ((status & mask) == 0);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_writeenable * Name: gd5f_writeenable
************************************************************************************/ ****************************************************************************/
static inline void gd5f_writeenable(FAR struct gd5f_dev_s *priv) static inline void gd5f_writeenable(FAR struct gd5f_dev_s *priv)
{ {
@@ -356,9 +378,9 @@ static inline void gd5f_writeenable(FAR struct gd5f_dev_s *priv)
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false); SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_writedisable * Name: gd5f_writedisable
************************************************************************************/ ****************************************************************************/
static inline void gd5f_writedisable(FAR struct gd5f_dev_s *priv) static inline void gd5f_writedisable(FAR struct gd5f_dev_s *priv)
{ {
@@ -375,13 +397,15 @@ static inline void gd5f_writedisable(FAR struct gd5f_dev_s *priv)
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false); SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_sectorerase (128K) * Name: gd5f_sectorerase (128K)
************************************************************************************/ ****************************************************************************/
static bool gd5f_sectorerase(FAR struct gd5f_dev_s *priv, off_t startsector) static bool gd5f_sectorerase(FAR struct gd5f_dev_s *priv,
off_t startsector)
{ {
const uint32_t block = startsector << (priv->sectorshift - priv->pageshift); const uint32_t block = startsector << (priv->sectorshift -
priv->pageshift);
finfo("block sector: %08lx\n", (long)block); finfo("block sector: %08lx\n", (long)block);
@@ -408,16 +432,20 @@ static bool gd5f_sectorerase(FAR struct gd5f_dev_s *priv, off_t startsector)
return gd5f_waitstatus(priv, GD5F_SR_E_FAIL, false); return gd5f_waitstatus(priv, GD5F_SR_E_FAIL, false);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_erase * Name: gd5f_erase
************************************************************************************/ ****************************************************************************/
static int gd5f_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks) static int gd5f_erase(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks)
{ {
FAR struct gd5f_dev_s *priv = (FAR struct gd5f_dev_s *)dev; FAR struct gd5f_dev_s *priv = (FAR struct gd5f_dev_s *)dev;
size_t blocksleft = nblocks; size_t blocksleft = nblocks;
finfo("Erase: startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); finfo("Erase: startblock: %08lx nblocks: %d\n",
(long)startblock,
(int)nblocks);
/* Lock access to the SPI bus until we complete the erase */ /* Lock access to the SPI bus until we complete the erase */
@@ -442,12 +470,14 @@ static int gd5f_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblock
return nblocks - blocksleft; return nblocks - blocksleft;
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_readbuffer * Name: gd5f_readbuffer
************************************************************************************/ ****************************************************************************/
static void gd5f_readbuffer(FAR struct gd5f_dev_s *priv, uint32_t address, static void gd5f_readbuffer(FAR struct gd5f_dev_s *priv,
uint8_t *buffer, size_t length) uint32_t address,
uint8_t *buffer,
size_t length)
{ {
const uint16_t offset = address & ((1 << priv->pageshift) - 1); const uint16_t offset = address & ((1 << priv->pageshift) - 1);
@@ -475,9 +505,9 @@ static void gd5f_readbuffer(FAR struct gd5f_dev_s *priv, uint32_t address,
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false); SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_read_page * Name: gd5f_read_page
************************************************************************************/ ****************************************************************************/
static bool gd5f_read_page(FAR struct gd5f_dev_s *priv, uint32_t pageaddress) static bool gd5f_read_page(FAR struct gd5f_dev_s *priv, uint32_t pageaddress)
{ {
@@ -515,11 +545,13 @@ static bool gd5f_read_page(FAR struct gd5f_dev_s *priv, uint32_t pageaddress)
return true; return true;
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_read * Name: gd5f_read
************************************************************************************/ ****************************************************************************/
static ssize_t gd5f_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t gd5f_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer) FAR uint8_t *buffer)
{ {
FAR struct gd5f_dev_s *priv = (FAR struct gd5f_dev_s *)dev; FAR struct gd5f_dev_s *priv = (FAR struct gd5f_dev_s *)dev;
@@ -538,9 +570,12 @@ static ssize_t gd5f_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
while (bytesleft) while (bytesleft)
{ {
const uint32_t pageaddress = (position >> priv->pageshift) << priv->pageshift; const uint32_t pageaddress =
const uint32_t spaceleft = pageaddress + (1 << priv->pageshift) - position; (position >> priv->pageshift) << priv->pageshift;
const size_t chunklength = bytesleft < spaceleft ? bytesleft : spaceleft; const uint32_t spaceleft =
pageaddress + (1 << priv->pageshift) - position;
const size_t chunklength =
bytesleft < spaceleft ? bytesleft : spaceleft;
if (!gd5f_read_page(priv, pageaddress)) if (!gd5f_read_page(priv, pageaddress))
{ {
@@ -560,9 +595,9 @@ static ssize_t gd5f_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
return nbytes - bytesleft; return nbytes - bytesleft;
} }
/************************************************************************** /****************************************************************************
* Name: gd5f_bread * Name: gd5f_bread
**************************************************************************/ ****************************************************************************/
static ssize_t gd5f_bread(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t gd5f_bread(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, FAR uint8_t *buffer) size_t nblocks, FAR uint8_t *buffer)
@@ -583,12 +618,14 @@ static ssize_t gd5f_bread(FAR struct mtd_dev_s *dev, off_t startblock,
return nbytes; return nbytes;
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_write_to_cache * Name: gd5f_write_to_cache
************************************************************************************/ ****************************************************************************/
static void gd5f_write_to_cache(FAR struct gd5f_dev_s *priv, uint32_t address, static void gd5f_write_to_cache(FAR struct gd5f_dev_s *priv,
const uint8_t *buffer, size_t length) uint32_t address,
const uint8_t *buffer,
size_t length)
{ {
const uint16_t offset = address & ((1 << priv->pageshift) - 1); const uint16_t offset = address & ((1 << priv->pageshift) - 1);
@@ -614,11 +651,12 @@ static void gd5f_write_to_cache(FAR struct gd5f_dev_s *priv, uint32_t address,
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false); SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_execute_write * Name: gd5f_execute_write
************************************************************************************/ ****************************************************************************/
static bool gd5f_execute_write(FAR struct gd5f_dev_s *priv, uint32_t pageaddress) static bool gd5f_execute_write(FAR struct gd5f_dev_s *priv,
uint32_t pageaddress)
{ {
const uint32_t row = pageaddress >> priv->pageshift; const uint32_t row = pageaddress >> priv->pageshift;
@@ -640,11 +678,13 @@ static bool gd5f_execute_write(FAR struct gd5f_dev_s *priv, uint32_t pageaddress
return gd5f_waitstatus(priv, GD5F_SR_P_FAIL, false); return gd5f_waitstatus(priv, GD5F_SR_P_FAIL, false);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_write * Name: gd5f_write
************************************************************************************/ ****************************************************************************/
static ssize_t gd5f_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t gd5f_write(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR const uint8_t *buffer) FAR const uint8_t *buffer)
{ {
FAR struct gd5f_dev_s *priv = (FAR struct gd5f_dev_s *)dev; FAR struct gd5f_dev_s *priv = (FAR struct gd5f_dev_s *)dev;
@@ -660,9 +700,12 @@ static ssize_t gd5f_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes
while (bytesleft) while (bytesleft)
{ {
const uint32_t pageaddress = (position >> priv->pageshift) << priv->pageshift; const uint32_t pageaddress =
const uint32_t spaceleft = pageaddress + (1 << priv->pageshift) - position; (position >> priv->pageshift) << priv->pageshift;
const size_t chunklength = bytesleft < spaceleft ? bytesleft : spaceleft; const uint32_t spaceleft =
pageaddress + (1 << priv->pageshift) - position;
const size_t chunklength =
bytesleft < spaceleft ? bytesleft : spaceleft;
gd5f_write_to_cache(priv, position, buffer, chunklength); gd5f_write_to_cache(priv, position, buffer, chunklength);
gd5f_writeenable(priv); gd5f_writeenable(priv);
@@ -681,9 +724,9 @@ static ssize_t gd5f_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes
return nbytes - bytesleft; return nbytes - bytesleft;
} }
/************************************************************************** /****************************************************************************
* Name: gd5f_bwrite * Name: gd5f_bwrite
**************************************************************************/ ****************************************************************************/
static ssize_t gd5f_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t gd5f_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, FAR const uint8_t *buffer) size_t nblocks, FAR const uint8_t *buffer)
@@ -707,9 +750,9 @@ static ssize_t gd5f_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
return nbytes; return nbytes;
} }
/************************************************************************************ /****************************************************************************
* Name: mx25l_ioctl * Name: mx25l_ioctl
************************************************************************************/ ****************************************************************************/
static int gd5f_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) static int gd5f_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{ {
@@ -750,7 +793,8 @@ static int gd5f_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{ {
uint8_t *result = (uint8_t *)arg; uint8_t *result = (uint8_t *)arg;
*result = *result =
(priv->eccstatus & GD5F_FEATURE_ECC_MASK) >> GD5F_FEATURE_ECC_OFFSET; (priv->eccstatus & GD5F_FEATURE_ECC_MASK)
>> GD5F_FEATURE_ECC_OFFSET;
ret = OK; ret = OK;
} }
@@ -765,9 +809,9 @@ static int gd5f_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
return ret; return ret;
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_eccstatusread * Name: gd5f_eccstatusread
************************************************************************************/ ****************************************************************************/
static inline void gd5f_eccstatusread(FAR struct gd5f_dev_s *priv) static inline void gd5f_eccstatusread(FAR struct gd5f_dev_s *priv)
{ {
@@ -778,9 +822,9 @@ static inline void gd5f_eccstatusread(FAR struct gd5f_dev_s *priv)
SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false); SPI_SELECT(priv->dev, SPIDEV_FLASH(priv->spi_devid), false);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_enable_ecc * Name: gd5f_enable_ecc
************************************************************************************/ ****************************************************************************/
static inline void gd5f_enable_ecc(FAR struct gd5f_dev_s *priv) static inline void gd5f_enable_ecc(FAR struct gd5f_dev_s *priv)
{ {
@@ -799,9 +843,9 @@ static inline void gd5f_enable_ecc(FAR struct gd5f_dev_s *priv)
gd5f_unlock(priv->dev); gd5f_unlock(priv->dev);
} }
/************************************************************************************ /****************************************************************************
* Name: gd5f_unlockblocks * Name: gd5f_unlockblocks
************************************************************************************/ ****************************************************************************/
static inline void gd5f_unlockblocks(FAR struct gd5f_dev_s *priv) static inline void gd5f_unlockblocks(FAR struct gd5f_dev_s *priv)
{ {
@@ -820,19 +864,20 @@ static inline void gd5f_unlockblocks(FAR struct gd5f_dev_s *priv)
gd5f_unlock(priv->dev); gd5f_unlock(priv->dev);
} }
/************************************************************************************ /****************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: gd5f_initialize * Name: gd5f_initialize
* *
* Description: * Description:
* Create an initialize MTD device instance. MTD devices are not registered * Create an initialize MTD device instance.
* in the file system, but are created as instances that can be bound to * MTD devices are not registered in the file system, but are created
* other functions (such as a block or character driver front end). * as instances that can be bound to other functions(such as a block
* or character driver front end).
* *
************************************************************************************/ ****************************************************************************/
FAR struct mtd_dev_s *gd5f_initialize(FAR struct spi_dev_s *dev, FAR struct mtd_dev_s *gd5f_initialize(FAR struct spi_dev_s *dev,
uint32_t spi_devid) uint32_t spi_devid)
@@ -876,7 +921,9 @@ FAR struct mtd_dev_s *gd5f_initialize(FAR struct spi_dev_s *dev,
ret = gd5f_readid(priv); ret = gd5f_readid(priv);
if (ret != OK) if (ret != OK)
{ {
/* Unrecognized! Discard all of that work we just did and return NULL */ /* Unrecognized! Discard all of that work we just did and
* return NULL
*/
ferr("ERROR: Unrecognized\n"); ferr("ERROR: Unrecognized\n");
kmm_free(priv); kmm_free(priv);
+6 -2
View File
@@ -80,6 +80,7 @@ static unsigned int hamming_bitsinbyte(uint8_t byte)
{ {
count++; count++;
} }
byte >>= 1; byte >>= 1;
} }
@@ -194,7 +195,8 @@ static void hamming_compute256(FAR const uint8_t *data, FAR uint8_t *code)
colsum >>= 1; colsum >>= 1;
} }
/* Now, we must interleave the parity values, to obtain the following layout: /* Now, we must interleave the parity values,
* to obtain the following layout:
* Code[0] = Line1 * Code[0] = Line1
* Code[1] = Line2 * Code[1] = Line2
* Code[2] = Column * Code[2] = Column
@@ -415,7 +417,9 @@ void hamming_compute256x(FAR const uint8_t *data, size_t size, uint8_t *code)
* *
****************************************************************************/ ****************************************************************************/
int hamming_verify256x(FAR uint8_t *data, size_t size, FAR const uint8_t *code) int hamming_verify256x(FAR uint8_t *data,
size_t size,
FAR const uint8_t *code)
{ {
ssize_t remaining = (ssize_t)size; ssize_t remaining = (ssize_t)size;
int result = HAMMING_SUCCESS; int result = HAMMING_SUCCESS;
+143 -94
View File
@@ -1,4 +1,4 @@
/************************************************************************************ /****************************************************************************
* drivers/mtd/is25xp.c * drivers/mtd/is25xp.c
* Driver for SPI-based IS25LPxx parts 32MBit and larger. * Driver for SPI-based IS25LPxx parts 32MBit and larger.
* *
@@ -37,11 +37,11 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Included Files * Included Files
************************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
@@ -59,15 +59,16 @@
#include <nuttx/spi/spi.h> #include <nuttx/spi/spi.h>
#include <nuttx/mtd/mtd.h> #include <nuttx/mtd/mtd.h>
/************************************************************************************ /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ****************************************************************************/
/* Configuration ********************************************************************/ /* Configuration ************************************************************/
/* Per the data sheet, IS25xP parts can be driven with either SPI mode 0 (CPOL=0 and
* CPHA=0) or mode 3 (CPOL=1 and CPHA=1). So you may need to specify /* Per the data sheet, IS25xP parts can be driven with either SPI mode 0
* CONFIG_IS25XP_SPIMODE to select the best mode for your device. If * (CPOL=0 and CPHA=0) or mode 3 (CPOL=1 and CPHA=1). So you may need to
* CONFIG_IS25XP_SPIMODE is not defined, mode 0 will be used. * specify CONFIG_IS25XP_SPIMODE to select the best mode for your device.
* If CONFIG_IS25XP_SPIMODE is not defined, mode 0 will be used.
*/ */
#ifndef CONFIG_IS25XP_SPIMODE #ifndef CONFIG_IS25XP_SPIMODE
@@ -80,7 +81,8 @@
#define CONFIG_IS25XP_SPIFREQUENCY 20000000 #define CONFIG_IS25XP_SPIFREQUENCY 20000000
#endif #endif
/* IS25 Registers *******************************************************************/ /* IS25 Registers ***********************************************************/
/* Identification register values */ /* Identification register values */
#define IS25_MANUFACTURER 0x9d #define IS25_MANUFACTURER 0x9d
@@ -108,14 +110,16 @@
#define IS25_IS25LP128_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */ #define IS25_IS25LP128_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */
#define IS25_IS25LP128_NPAGES 65536 #define IS25_IS25LP128_NPAGES 65536
/* Instructions */ /* Instructions */
/* Command Value N Description Addr Dummy Data */ /* Command Value N Description Addr Dummy Data */
#define IS25_WREN 0x06 /* 1 Write Enable 0 0 0 */ #define IS25_WREN 0x06 /* 1 Write Enable 0 0 0 */
#define IS25_WRDI 0x04 /* 1 Write Disable 0 0 0 */ #define IS25_WRDI 0x04 /* 1 Write Disable 0 0 0 */
#define IS25_RDID 0x9f /* 1 Read Identification 0 0 1-3 */ #define IS25_RDID 0x9f /* 1 Read Identification 0 0 1-3 */
#define IS25_RDSR 0x05 /* 1 Read Status Register 0 0 >=1 */ #define IS25_RDSR 0x05 /* 1 Read Status Register 0 0 >=1 */
//#define IS25_EWSR 0x50 /* 1 Write enable status 0 0 0 */
/* #define IS25_EWSR 0x50 1 Write enable status 0 0 0 */
#define IS25_WRSR 0x01 /* 1 Write Status Register 0 0 1 */ #define IS25_WRSR 0x01 /* 1 Write Status Register 0 0 1 */
#define IS25_READ 0x03 /* 1 Read Data Bytes 3 0 >=1 */ #define IS25_READ 0x03 /* 1 Read Data Bytes 3 0 >=1 */
#define IS25_FAST_READ 0x0b /* 1 Higher speed read 3 1 >=1 */ #define IS25_FAST_READ 0x0b /* 1 Higher speed read 3 1 >=1 */
@@ -151,9 +155,9 @@
#define IS25_DUMMY 0xa5 #define IS25_DUMMY 0xa5
/************************************************************************************ /****************************************************************************
* Private Types * Private Types
************************************************************************************/ ****************************************************************************/
/* This type represents the state of the MTD device. The struct mtd_dev_s /* This type represents the state of the MTD device. The struct mtd_dev_s
* must appear at the beginning of the definition so that you can freely * must appear at the beginning of the definition so that you can freely
@@ -171,9 +175,9 @@ struct is25xp_dev_s
uint8_t lastwaswrite; /* Indicates if last operation was write */ uint8_t lastwaswrite; /* Indicates if last operation was write */
}; };
/************************************************************************************ /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
************************************************************************************/ ****************************************************************************/
/* Helpers */ /* Helpers */
@@ -182,29 +186,42 @@ static inline void is25xp_unlock(FAR struct spi_dev_s *dev);
static inline int is25xp_readid(struct is25xp_dev_s *priv); static inline int is25xp_readid(struct is25xp_dev_s *priv);
static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv); static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv);
static void is25xp_writeenable(struct is25xp_dev_s *priv); static void is25xp_writeenable(struct is25xp_dev_s *priv);
static inline void is25xp_sectorerase(struct is25xp_dev_s *priv, off_t offset, uint8_t type); static inline void is25xp_sectorerase(struct is25xp_dev_s *priv,
off_t offset,
uint8_t type);
static inline int is25xp_bulkerase(struct is25xp_dev_s *priv); static inline int is25xp_bulkerase(struct is25xp_dev_s *priv);
static inline void is25xp_pagewrite(struct is25xp_dev_s *priv, FAR const uint8_t *buffer, static inline void is25xp_pagewrite(struct is25xp_dev_s *priv,
FAR const uint8_t *buffer,
off_t offset); off_t offset);
/* MTD driver methods */ /* MTD driver methods */
static int is25xp_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks); static int is25xp_erase(FAR struct mtd_dev_s *dev,
static ssize_t is25xp_bread(FAR struct mtd_dev_s *dev, off_t startblock, off_t startblock,
size_t nblocks);
static ssize_t is25xp_bread(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks, FAR uint8_t *buf); size_t nblocks, FAR uint8_t *buf);
static ssize_t is25xp_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t is25xp_bwrite(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks, FAR const uint8_t *buf); size_t nblocks, FAR const uint8_t *buf);
static ssize_t is25xp_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t is25xp_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer); FAR uint8_t *buffer);
#ifdef CONFIG_MTD_BYTE_WRITE #ifdef CONFIG_MTD_BYTE_WRITE
static ssize_t is25xp_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t is25xp_write(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR const uint8_t *buffer); FAR const uint8_t *buffer);
#endif #endif
static int is25xp_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); static int is25xp_ioctl(FAR struct mtd_dev_s *dev,
int cmd,
unsigned long arg);
/************************************************************************************ /****************************************************************************
* Name: is25xp_lock * Name: is25xp_lock
************************************************************************************/ ****************************************************************************/
static void is25xp_lock(FAR struct spi_dev_s *dev) static void is25xp_lock(FAR struct spi_dev_s *dev)
{ {
@@ -212,16 +229,18 @@ static void is25xp_lock(FAR struct spi_dev_s *dev)
* lock SPI to have exclusive access to the buses for a sequence of * lock SPI to have exclusive access to the buses for a sequence of
* transfers. The bus should be locked before the chip is selected. * transfers. The bus should be locked before the chip is selected.
* *
* This is a blocking call and will not return until we have exclusive access to * This is a blocking call and will not return until we have exclusive
* the SPI bus. We will retain that exclusive access until the bus is unlocked. * access to the SPI bus. We will retain that exclusive access until the
* bus is unlocked.
*/ */
SPI_LOCK(dev, true); SPI_LOCK(dev, true);
/* After locking the SPI bus, the we also need call the setfrequency, setbits, and /* After locking the SPI bus, the we also need call the setfrequency,
* setmode methods to make sure that the SPI is properly configured for the device. * setbits, and setmode methods to make sure that the SPI is properly
* If the SPI bus is being shared, then it may have been left in an incompatible * configured for the device.
* state. * If the SPI bus is being shared, then it may have been left in an
* incompatible state.
*/ */
SPI_SETMODE(dev, CONFIG_IS25XP_SPIMODE); SPI_SETMODE(dev, CONFIG_IS25XP_SPIMODE);
@@ -230,18 +249,18 @@ static void is25xp_lock(FAR struct spi_dev_s *dev)
SPI_SETFREQUENCY(dev, CONFIG_IS25XP_SPIFREQUENCY); SPI_SETFREQUENCY(dev, CONFIG_IS25XP_SPIFREQUENCY);
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_unlock * Name: is25xp_unlock
************************************************************************************/ ****************************************************************************/
static inline void is25xp_unlock(FAR struct spi_dev_s *dev) static inline void is25xp_unlock(FAR struct spi_dev_s *dev)
{ {
SPI_LOCK(dev, false); SPI_LOCK(dev, false);
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_readid * Name: is25xp_readid
************************************************************************************/ ****************************************************************************/
static inline int is25xp_readid(struct is25xp_dev_s *priv) static inline int is25xp_readid(struct is25xp_dev_s *priv)
{ {
@@ -302,9 +321,9 @@ static inline int is25xp_readid(struct is25xp_dev_s *priv)
return -ENODEV; return -ENODEV;
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_waitwritecomplete * Name: is25xp_waitwritecomplete
************************************************************************************/ ****************************************************************************/
static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv) static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv)
{ {
@@ -335,7 +354,9 @@ static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv)
do do
{ {
/* Send a dummy byte to generate the clock needed to shift out the status */ /* Send a dummy byte to generate the clock needed to shift out
* the status
*/
status = SPI_SEND(priv->dev, IS25_DUMMY); status = SPI_SEND(priv->dev, IS25_DUMMY);
} }
@@ -359,7 +380,9 @@ static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv)
SPI_SEND(priv->dev, IS25_RDSR); SPI_SEND(priv->dev, IS25_RDSR);
/* Send a dummy byte to generate the clock needed to shift out the status */ /* Send a dummy byte to generate the clock needed to shift out
* the status
*/
status = SPI_SEND(priv->dev, IS25_DUMMY); status = SPI_SEND(priv->dev, IS25_DUMMY);
@@ -367,9 +390,9 @@ static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv)
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false); SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
/* Given that writing could take up to few tens of milliseconds, and erasing /* Given that writing could take up to few tens of milliseconds,
* could take more. The following short delay in the "busy" case will allow * and erasing could take more. The following short delay in the
* other peripherals to access the SPI bus. * "busy" case will allow other peripherals to access the SPI bus.
*/ */
if ((status & IS25_SR_WIP) != 0) if ((status & IS25_SR_WIP) != 0)
@@ -387,9 +410,9 @@ static void is25xp_waitwritecomplete(struct is25xp_dev_s *priv)
finfo("Complete\n"); finfo("Complete\n");
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_writeenable * Name: is25xp_writeenable
************************************************************************************/ ****************************************************************************/
static void is25xp_writeenable(struct is25xp_dev_s *priv) static void is25xp_writeenable(struct is25xp_dev_s *priv)
{ {
@@ -407,9 +430,9 @@ static void is25xp_writeenable(struct is25xp_dev_s *priv)
finfo("Enabled\n"); finfo("Enabled\n");
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_unprotect * Name: is25xp_unprotect
************************************************************************************/ ****************************************************************************/
static void is25xp_unprotect(struct is25xp_dev_s *priv) static void is25xp_unprotect(struct is25xp_dev_s *priv)
{ {
@@ -429,11 +452,13 @@ static void is25xp_unprotect(struct is25xp_dev_s *priv)
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false); SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_sectorerase * Name: is25xp_sectorerase
************************************************************************************/ ****************************************************************************/
static void is25xp_sectorerase(struct is25xp_dev_s *priv, off_t sector, uint8_t type) static void is25xp_sectorerase(struct is25xp_dev_s *priv,
off_t sector,
uint8_t type)
{ {
off_t offset; off_t offset;
@@ -479,9 +504,9 @@ static void is25xp_sectorerase(struct is25xp_dev_s *priv, off_t sector, uint8_t
finfo("Erased\n"); finfo("Erased\n");
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_bulkerase * Name: is25xp_bulkerase
************************************************************************************/ ****************************************************************************/
static inline int is25xp_bulkerase(struct is25xp_dev_s *priv) static inline int is25xp_bulkerase(struct is25xp_dev_s *priv)
{ {
@@ -516,11 +541,12 @@ static inline int is25xp_bulkerase(struct is25xp_dev_s *priv)
return OK; return OK;
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_pagewrite * Name: is25xp_pagewrite
************************************************************************************/ ****************************************************************************/
static inline void is25xp_pagewrite(struct is25xp_dev_s *priv, FAR const uint8_t *buffer, static inline void is25xp_pagewrite(struct is25xp_dev_s *priv,
FAR const uint8_t *buffer,
off_t page) off_t page)
{ {
off_t offset = page << priv->pageshift; off_t offset = page << priv->pageshift;
@@ -564,9 +590,9 @@ static inline void is25xp_pagewrite(struct is25xp_dev_s *priv, FAR const uint8_t
finfo("Written\n"); finfo("Written\n");
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_bytewrite * Name: is25xp_bytewrite
************************************************************************************/ ****************************************************************************/
#ifdef CONFIG_MTD_BYTE_WRITE #ifdef CONFIG_MTD_BYTE_WRITE
static inline void is25xp_bytewrite(struct is25xp_dev_s *priv, static inline void is25xp_bytewrite(struct is25xp_dev_s *priv,
@@ -613,11 +639,13 @@ static inline void is25xp_bytewrite(struct is25xp_dev_s *priv,
} }
#endif #endif
/************************************************************************************ /****************************************************************************
* Name: is25xp_erase * Name: is25xp_erase
************************************************************************************/ ****************************************************************************/
static int is25xp_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks) static int is25xp_erase(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks)
{ {
FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev; FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev;
size_t blocksleft = nblocks; size_t blocksleft = nblocks;
@@ -689,11 +717,13 @@ static int is25xp_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblo
return (int)nblocks; return (int)nblocks;
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_bread * Name: is25xp_bread
************************************************************************************/ ****************************************************************************/
static ssize_t is25xp_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, static ssize_t is25xp_bread(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
FAR uint8_t *buffer) FAR uint8_t *buffer)
{ {
FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev; FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev;
@@ -701,9 +731,14 @@ static ssize_t is25xp_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t
finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
/* On this device, we can handle the block read just like the byte-oriented read */ /* On this device, we can handle the block read just like the byte-oriented
* read
*/
nbytes = is25xp_read(dev, startblock << priv->pageshift, nblocks << priv->pageshift, buffer); nbytes = is25xp_read(dev,
startblock << priv->pageshift,
nblocks << priv->pageshift,
buffer);
if (nbytes > 0) if (nbytes > 0)
{ {
return nbytes >> priv->pageshift; return nbytes >> priv->pageshift;
@@ -712,11 +747,13 @@ static ssize_t is25xp_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t
return (int)nbytes; return (int)nbytes;
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_bwrite * Name: is25xp_bwrite
************************************************************************************/ ****************************************************************************/
static ssize_t is25xp_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, static ssize_t is25xp_bwrite(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
FAR const uint8_t *buffer) FAR const uint8_t *buffer)
{ {
FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev; FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev;
@@ -739,11 +776,13 @@ static ssize_t is25xp_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t
return nblocks; return nblocks;
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_read * Name: is25xp_read
************************************************************************************/ ****************************************************************************/
static ssize_t is25xp_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t is25xp_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer) FAR uint8_t *buffer)
{ {
FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev; FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev;
@@ -794,12 +833,14 @@ static ssize_t is25xp_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyte
return nbytes; return nbytes;
} }
/************************************************************************************ /****************************************************************************
* Name: is25xp_write * Name: is25xp_write
************************************************************************************/ ****************************************************************************/
#ifdef CONFIG_MTD_BYTE_WRITE #ifdef CONFIG_MTD_BYTE_WRITE
static ssize_t is25xp_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t is25xp_write(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR const uint8_t *buffer) FAR const uint8_t *buffer)
{ {
FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev; FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev;
@@ -870,11 +911,13 @@ static ssize_t is25xp_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt
} }
#endif /* CONFIG_MTD_BYTE_WRITE */ #endif /* CONFIG_MTD_BYTE_WRITE */
/************************************************************************************ /****************************************************************************
* Name: is25xp_ioctl * Name: is25xp_ioctl
************************************************************************************/ ****************************************************************************/
static int is25xp_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) static int is25xp_ioctl(FAR struct mtd_dev_s *dev,
int cmd,
unsigned long arg)
{ {
FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev; FAR struct is25xp_dev_s *priv = (FAR struct is25xp_dev_s *)dev;
int ret = -EINVAL; /* Assume good command with bad parameters */ int ret = -EINVAL; /* Assume good command with bad parameters */
@@ -885,16 +928,18 @@ static int is25xp_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{ {
case MTDIOC_GEOMETRY: case MTDIOC_GEOMETRY:
{ {
FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg); FAR struct mtd_geometry_s *geo =
(FAR struct mtd_geometry_s *)((uintptr_t)arg);
if (geo) if (geo)
{ {
/* Populate the geometry structure with information need to know /* Populate the geometry structure with information need to
* the capacity and how to access the device. * know the capacity and how to access the device.
* *
* NOTE: that the device is treated as though it where just an array * NOTE:
* of fixed size blocks. That is most likely not true, but the client * that the device is treated as though it where just an array
* will expect the device logic to do whatever is necessary to make it * of fixed size blocks. That is most likely not true, but the
* appear so. * client will expect the device logic to do whatever is
* necessary to make it appear so.
*/ */
geo->blocksize = (1 << priv->pageshift); geo->blocksize = (1 << priv->pageshift);
@@ -929,11 +974,11 @@ static int is25xp_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
return ret; return ret;
} }
/************************************************************************************ /****************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: is25xp_initialize * Name: is25xp_initialize
* *
* Description: * Description:
@@ -941,7 +986,7 @@ static int is25xp_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
* in the file system, but are created as instances that can be bound to * in the file system, but are created as instances that can be bound to
* other functions (such as a block or character driver front end). * other functions (such as a block or character driver front end).
* *
************************************************************************************/ ****************************************************************************/
FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev) FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev)
{ {
@@ -953,8 +998,8 @@ FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev)
/* Allocate a state structure (we allocate the structure instead of using /* Allocate a state structure (we allocate the structure instead of using
* a fixed, static allocation so that we can handle multiple FLASH devices. * a fixed, static allocation so that we can handle multiple FLASH devices.
* The current implementation would handle only one FLASH part per SPI * The current implementation would handle only one FLASH part per SPI
* device (only because of the SPIDEV_FLASH(0) definition) and so would have * device (only because of the SPIDEV_FLASH(0) definition) and so would
* to be extended to handle multiple FLASH parts on the same SPI bus. * have to be extended to handle multiple FLASH parts on the same SPI bus.
*/ */
priv = (FAR struct is25xp_dev_s *)kmm_zalloc(sizeof(struct is25xp_dev_s)); priv = (FAR struct is25xp_dev_s *)kmm_zalloc(sizeof(struct is25xp_dev_s));
@@ -985,7 +1030,9 @@ FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev)
ret = is25xp_readid(priv); ret = is25xp_readid(priv);
if (ret != OK) if (ret != OK)
{ {
/* Unrecognized! Discard all of that work we just did and return NULL */ /* Unrecognized! Discard all of that work we just did and
* return NULL
*/
ferr("ERROR: Unrecognized\n"); ferr("ERROR: Unrecognized\n");
kmm_free(priv); kmm_free(priv);
@@ -993,7 +1040,9 @@ FAR struct mtd_dev_s *is25xp_initialize(FAR struct spi_dev_s *dev)
} }
else else
{ {
/* Make sure that the FLASH is unprotected so that we can write into it */ /* Make sure that the FLASH is unprotected so that we can
* write into it
*/
is25xp_unprotect(priv); is25xp_unprotect(priv);
} }
+137 -100
View File
@@ -1,7 +1,7 @@
/************************************************************************************ /****************************************************************************
* drivers/mtd/m25px.c * drivers/mtd/m25px.c
* Driver for SPI-based M25P1 (128Kbit), M25P64 (32Mbit), M25P64 (64Mbit), and * Driver for SPI-based M25P1 (128Kbit), M25P64 (32Mbit), M25P64 (64Mbit),
* M25P128 (128Mbit) FLASH (and compatible). * and M25P128 (128Mbit) FLASH (and compatible).
* *
* Copyright (C) 2009-2011, 2013, 2017 Gregory Nutt. All rights reserved. * Copyright (C) 2009-2011, 2013, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
@@ -33,11 +33,11 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Included Files * Included Files
************************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
@@ -56,17 +56,18 @@
#include <nuttx/spi/spi.h> #include <nuttx/spi/spi.h>
#include <nuttx/mtd/mtd.h> #include <nuttx/mtd/mtd.h>
/************************************************************************************ /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ****************************************************************************/
/* Configuration ********************************************************************/ /* Configuration ************************************************************/
/* Per the data sheet, M25P10 parts can be driven with either SPI mode 0 (CPOL=0 and /* Per the data sheet, M25P10 parts can be driven with either SPI mode 0
* CPHA=0) or mode 3 (CPOL=1 and CPHA=1). But I have heard that other devices can * (CPOL=0 and CPHA=0) or mode 3 (CPOL=1 and CPHA=1). But I have heard that
* operated in mode 0 or 1. So you may need to specify CONFIG_M25P_SPIMODE to * other devices can operated in mode 0 or 1.
* select the best mode for your device. If CONFIG_M25P_SPIMODE is not defined, * So you may need to specify CONFIG_M25P_SPIMODE to
* mode 0 will be used. * select the best mode for your device.
* If CONFIG_M25P_SPIMODE is not defined, mode 0 will be used.
*/ */
#ifndef CONFIG_M25P_SPIMODE #ifndef CONFIG_M25P_SPIMODE
@@ -77,9 +78,10 @@
# define CONFIG_M25P_SPIFREQUENCY 20000000 # define CONFIG_M25P_SPIFREQUENCY 20000000
#endif #endif
/* Various manufacturers may have produced the parts. 0x20 is the manufacturer ID /* Various manufacturers may have produced the parts.
* for the STMicro MP25x serial FLASH. If, for example, you are using the a Macronix * 0x20 is the manufacturer ID for the STMicro MP25x serial FLASH.
* International MX25 serial FLASH, the correct manufacturer ID would be 0xc2. * If, for example, you are using the a Macronix International MX25
* serial FLASH, the correct manufacturer ID would be 0xc2.
*/ */
#ifndef CONFIG_M25P_MANUFACTURER #ifndef CONFIG_M25P_MANUFACTURER
@@ -94,7 +96,7 @@
# define CONFIG_MT25Q_MEMORY_TYPE 0xBA # define CONFIG_MT25Q_MEMORY_TYPE 0xBA
#endif #endif
/* M25P Registers *******************************************************************/ /* M25P Registers ***********************************************************/
/* Identification register values */ /* Identification register values */
@@ -227,9 +229,9 @@
#define M25P_DUMMY 0xa5 #define M25P_DUMMY 0xa5
/************************************************************************************ /****************************************************************************
* Private Types * Private Types
************************************************************************************/ ****************************************************************************/
/* This type represents the state of the MTD device. The struct mtd_dev_s /* This type represents the state of the MTD device. The struct mtd_dev_s
* must appear at the beginning of the definition so that you can freely * must appear at the beginning of the definition so that you can freely
@@ -249,9 +251,9 @@ struct m25p_dev_s
#endif #endif
}; };
/************************************************************************************ /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
************************************************************************************/ ****************************************************************************/
/* Helpers */ /* Helpers */
@@ -260,38 +262,51 @@ static inline void m25p_unlock(FAR struct spi_dev_s *dev);
static inline int m25p_readid(struct m25p_dev_s *priv); static inline int m25p_readid(struct m25p_dev_s *priv);
static void m25p_waitwritecomplete(struct m25p_dev_s *priv); static void m25p_waitwritecomplete(struct m25p_dev_s *priv);
static void m25p_writeenable(struct m25p_dev_s *priv); static void m25p_writeenable(struct m25p_dev_s *priv);
static inline void m25p_sectorerase(struct m25p_dev_s *priv, off_t offset, static inline void m25p_sectorerase(struct m25p_dev_s *priv,
off_t offset,
uint8_t type); uint8_t type);
static inline int m25p_bulkerase(struct m25p_dev_s *priv); static inline int m25p_bulkerase(struct m25p_dev_s *priv);
static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer, static inline void m25p_pagewrite(struct m25p_dev_s *priv,
FAR const uint8_t *buffer,
off_t offset); off_t offset);
/* MTD driver methods */ /* MTD driver methods */
static int m25p_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks); static int m25p_erase(FAR struct mtd_dev_s *dev,
static ssize_t m25p_bread(FAR struct mtd_dev_s *dev, off_t startblock, off_t startblock,
size_t nblocks, FAR uint8_t *buf); size_t nblocks);
static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t m25p_bread(FAR struct mtd_dev_s *dev,
size_t nblocks, FAR const uint8_t *buf); off_t startblock,
static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, size_t nblocks,
FAR uint8_t *buf);
static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
FAR const uint8_t *buf);
static ssize_t m25p_read(FAR struct mtd_dev_s *dev,
off_t offset, size_t nbytes,
FAR uint8_t *buffer); FAR uint8_t *buffer);
#ifdef CONFIG_MTD_BYTE_WRITE #ifdef CONFIG_MTD_BYTE_WRITE
static ssize_t m25p_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t m25p_write(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR const uint8_t *buffer); FAR const uint8_t *buffer);
#endif #endif
static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); static int m25p_ioctl(FAR struct mtd_dev_s *dev,
int cmd,
unsigned long arg);
/************************************************************************************ /****************************************************************************
* Private Data * Private Data
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Private Functions * Private Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: m25p_lock * Name: m25p_lock
************************************************************************************/ ****************************************************************************/
static void m25p_lock(FAR struct spi_dev_s *dev) static void m25p_lock(FAR struct spi_dev_s *dev)
{ {
@@ -299,16 +314,18 @@ static void m25p_lock(FAR struct spi_dev_s *dev)
* lock SPI to have exclusive access to the buses for a sequence of * lock SPI to have exclusive access to the buses for a sequence of
* transfers. The bus should be locked before the chip is selected. * transfers. The bus should be locked before the chip is selected.
* *
* This is a blocking call and will not return until we have exclusive access to * This is a blocking call and will not return until we have exclusive
* the SPI bus. We will retain that exclusive access until the bus is unlocked. * access to the SPI bus. We will retain that exclusive access until the
* bus is unlocked.
*/ */
SPI_LOCK(dev, true); SPI_LOCK(dev, true);
/* After locking the SPI bus, the we also need call the setfrequency, setbits, and /* After locking the SPI bus, the we also need call the setfrequency,
* setmode methods to make sure that the SPI is properly configured for the device. * setbits, and setmode methods to make sure that the SPI is properly
* If the SPI bus is being shared, then it may have been left in an incompatible * configured for the device.
* state. * If the SPI bus is being shared, then it may have been left in an
* incompatible state.
*/ */
SPI_SETMODE(dev, CONFIG_M25P_SPIMODE); SPI_SETMODE(dev, CONFIG_M25P_SPIMODE);
@@ -317,18 +334,18 @@ static void m25p_lock(FAR struct spi_dev_s *dev)
SPI_SETFREQUENCY(dev, CONFIG_M25P_SPIFREQUENCY); SPI_SETFREQUENCY(dev, CONFIG_M25P_SPIFREQUENCY);
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_unlock * Name: m25p_unlock
************************************************************************************/ ****************************************************************************/
static inline void m25p_unlock(FAR struct spi_dev_s *dev) static inline void m25p_unlock(FAR struct spi_dev_s *dev)
{ {
SPI_LOCK(dev, false); SPI_LOCK(dev, false);
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_readid * Name: m25p_readid
************************************************************************************/ ****************************************************************************/
static inline int m25p_readid(struct m25p_dev_s *priv) static inline int m25p_readid(struct m25p_dev_s *priv)
{ {
@@ -463,9 +480,9 @@ static inline int m25p_readid(struct m25p_dev_s *priv)
return -ENODEV; return -ENODEV;
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_waitwritecomplete * Name: m25p_waitwritecomplete
************************************************************************************/ ****************************************************************************/
static void m25p_waitwritecomplete(struct m25p_dev_s *priv) static void m25p_waitwritecomplete(struct m25p_dev_s *priv)
{ {
@@ -483,7 +500,9 @@ static void m25p_waitwritecomplete(struct m25p_dev_s *priv)
SPI_SEND(priv->dev, M25P_RDSR); SPI_SEND(priv->dev, M25P_RDSR);
/* Send a dummy byte to generate the clock needed to shift out the status */ /* Send a dummy byte to generate the clock needed to shift out the
* status
*/
status = SPI_SEND(priv->dev, M25P_DUMMY); status = SPI_SEND(priv->dev, M25P_DUMMY);
@@ -491,9 +510,10 @@ static void m25p_waitwritecomplete(struct m25p_dev_s *priv)
SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false); SPI_SELECT(priv->dev, SPIDEV_FLASH(0), false);
/* Given that writing could take up to few tens of milliseconds, and erasing /* Given that writing could take up to few tens of milliseconds, and
* could take more. The following short delay in the "busy" case will allow * erasing could take more.
* other peripherals to access the SPI bus. * The following short delay in the "busy" case will allow other
* peripherals to access the SPI bus.
*/ */
if ((status & M25P_SR_WIP) != 0) if ((status & M25P_SR_WIP) != 0)
@@ -508,9 +528,9 @@ static void m25p_waitwritecomplete(struct m25p_dev_s *priv)
finfo("Complete\n"); finfo("Complete\n");
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_writeenable * Name: m25p_writeenable
************************************************************************************/ ****************************************************************************/
static void m25p_writeenable(struct m25p_dev_s *priv) static void m25p_writeenable(struct m25p_dev_s *priv)
{ {
@@ -528,11 +548,13 @@ static void m25p_writeenable(struct m25p_dev_s *priv)
finfo("Enabled\n"); finfo("Enabled\n");
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_sectorerase * Name: m25p_sectorerase
************************************************************************************/ ****************************************************************************/
static void m25p_sectorerase(struct m25p_dev_s *priv, off_t sector, uint8_t type) static void m25p_sectorerase(struct m25p_dev_s *priv,
off_t sector,
uint8_t type)
{ {
off_t offset; off_t offset;
@@ -586,9 +608,9 @@ static void m25p_sectorerase(struct m25p_dev_s *priv, off_t sector, uint8_t type
finfo("Erased\n"); finfo("Erased\n");
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_bulkerase * Name: m25p_bulkerase
************************************************************************************/ ****************************************************************************/
static inline int m25p_bulkerase(struct m25p_dev_s *priv) static inline int m25p_bulkerase(struct m25p_dev_s *priv)
{ {
@@ -621,11 +643,12 @@ static inline int m25p_bulkerase(struct m25p_dev_s *priv)
return OK; return OK;
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_pagewrite * Name: m25p_pagewrite
************************************************************************************/ ****************************************************************************/
static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer, static inline void m25p_pagewrite(struct m25p_dev_s *priv,
FAR const uint8_t *buffer,
off_t page) off_t page)
{ {
off_t offset = page << priv->pageshift; off_t offset = page << priv->pageshift;
@@ -668,13 +691,15 @@ static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *bu
finfo("Written\n"); finfo("Written\n");
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_bytewrite * Name: m25p_bytewrite
************************************************************************************/ ****************************************************************************/
#ifdef CONFIG_MTD_BYTE_WRITE #ifdef CONFIG_MTD_BYTE_WRITE
static inline void m25p_bytewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer, static inline void m25p_bytewrite(struct m25p_dev_s *priv,
off_t offset, uint16_t count) FAR const uint8_t *buffer,
off_t offset,
uint16_t count)
{ {
finfo("offset: %08lx count:%d\n", (long)offset, count); finfo("offset: %08lx count:%d\n", (long)offset, count);
@@ -715,11 +740,13 @@ static inline void m25p_bytewrite(struct m25p_dev_s *priv, FAR const uint8_t *bu
} }
#endif #endif
/************************************************************************************ /****************************************************************************
* Name: m25p_erase * Name: m25p_erase
************************************************************************************/ ****************************************************************************/
static int m25p_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks) static int m25p_erase(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks)
{ {
FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev; FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev;
size_t blocksleft = nblocks; size_t blocksleft = nblocks;
@@ -782,9 +809,9 @@ static int m25p_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblock
return (int)nblocks; return (int)nblocks;
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_bread * Name: m25p_bread
************************************************************************************/ ****************************************************************************/
static ssize_t m25p_bread(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t m25p_bread(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, size_t nblocks,
@@ -809,9 +836,9 @@ static ssize_t m25p_bread(FAR struct mtd_dev_s *dev, off_t startblock,
return (int)nbytes; return (int)nbytes;
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_bwrite * Name: m25p_bwrite
************************************************************************************/ ****************************************************************************/
static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks, size_t nblocks,
@@ -837,11 +864,13 @@ static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
return nblocks; return nblocks;
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_read * Name: m25p_read
************************************************************************************/ ****************************************************************************/
static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t m25p_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer) FAR uint8_t *buffer)
{ {
FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev; FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev;
@@ -889,12 +918,14 @@ static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
return nbytes; return nbytes;
} }
/************************************************************************************ /****************************************************************************
* Name: m25p_write * Name: m25p_write
************************************************************************************/ ****************************************************************************/
#ifdef CONFIG_MTD_BYTE_WRITE #ifdef CONFIG_MTD_BYTE_WRITE
static ssize_t m25p_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t m25p_write(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR const uint8_t *buffer) FAR const uint8_t *buffer)
{ {
FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev; FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev;
@@ -963,9 +994,9 @@ static ssize_t m25p_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes
} }
#endif /* CONFIG_MTD_BYTE_WRITE */ #endif /* CONFIG_MTD_BYTE_WRITE */
/************************************************************************************ /****************************************************************************
* Name: m25p_ioctl * Name: m25p_ioctl
************************************************************************************/ ****************************************************************************/
static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{ {
@@ -982,13 +1013,15 @@ static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
((uintptr_t)arg); ((uintptr_t)arg);
if (geo) if (geo)
{ {
/* Populate the geometry structure with information need to know /* Populate the geometry structure with information need to
* the capacity and how to access the device. * know the capacity and how to access the device.
* *
* NOTE: that the device is treated as though it where just an array * NOTE:
* of fixed size blocks. That is most likely not true, but the client * that the device is treated as though it where just an array
* will expect the device logic to do whatever is necessary to make it * of fixed size blocks.
* appear so. * That is most likely not true, but the client will expect the
* device logic to do whatever is necessary to make it appear
* so.
*/ */
geo->blocksize = (1 << priv->pageshift); geo->blocksize = (1 << priv->pageshift);
@@ -996,7 +1029,8 @@ static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
if (priv->subsectorshift > 0) if (priv->subsectorshift > 0)
{ {
geo->erasesize = (1 << priv->subsectorshift); geo->erasesize = (1 << priv->subsectorshift);
geo->neraseblocks = priv->nsectors * (1 << (priv->sectorshift - geo->neraseblocks = priv->nsectors *
(1 << (priv->sectorshift -
priv->subsectorshift)); priv->subsectorshift));
} }
else else
@@ -1035,19 +1069,20 @@ static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
return ret; return ret;
} }
/************************************************************************************ /****************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: m25p_initialize * Name: m25p_initialize
* *
* Description: * Description:
* Create an initialize MTD device instance. MTD devices are not registered * Create an initialize MTD device instance.
* in the file system, but are created as instances that can be bound to * MTD devices are not registered in the file system, but are created as
* other functions (such as a block or character driver front end). * instances that can be bound to other functions (such as a block or
* character driver front end).
* *
************************************************************************************/ ****************************************************************************/
FAR struct mtd_dev_s *m25p_initialize(FAR struct spi_dev_s *dev) FAR struct mtd_dev_s *m25p_initialize(FAR struct spi_dev_s *dev)
{ {
@@ -1059,8 +1094,8 @@ FAR struct mtd_dev_s *m25p_initialize(FAR struct spi_dev_s *dev)
/* Allocate a state structure (we allocate the structure instead of using /* Allocate a state structure (we allocate the structure instead of using
* a fixed, static allocation so that we can handle multiple FLASH devices. * a fixed, static allocation so that we can handle multiple FLASH devices.
* The current implementation would handle only one FLASH part per SPI * The current implementation would handle only one FLASH part per SPI
* device (only because of the SPIDEV_FLASH(0) definition) and so would have * device (only because of the SPIDEV_FLASH(0) definition) and so would
* to be extended to handle multiple FLASH parts on the same SPI bus. * have to be extended to handle multiple FLASH parts on the same SPI bus.
*/ */
priv = (FAR struct m25p_dev_s *)kmm_zalloc(sizeof(struct m25p_dev_s)); priv = (FAR struct m25p_dev_s *)kmm_zalloc(sizeof(struct m25p_dev_s));
@@ -1090,7 +1125,9 @@ FAR struct mtd_dev_s *m25p_initialize(FAR struct spi_dev_s *dev)
ret = m25p_readid(priv); ret = m25p_readid(priv);
if (ret != OK) if (ret != OK)
{ {
/* Unrecognized! Discard all of that work we just did and return NULL */ /* Unrecognized!
* Discard all of that work we just did and return NULL
*/
ferr("ERROR: Unrecognized\n"); ferr("ERROR: Unrecognized\n");
kmm_free(priv); kmm_free(priv);
+65 -78
View File
@@ -1,4 +1,4 @@
/************************************************************************************************** /****************************************************************************
* drivers/mtd/mtd_modeltab.c * drivers/mtd/mtd_modeltab.c
* *
* Copyright (C) 2013 Gregory Nutt. All rights reserved. * Copyright (C) 2013 Gregory Nutt. All rights reserved.
@@ -37,11 +37,11 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
**************************************************************************************************/ ****************************************************************************/
/************************************************************************************************** /****************************************************************************
* Included Files * Included Files
**************************************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/mtd/nand_config.h> #include <nuttx/mtd/nand_config.h>
@@ -49,19 +49,19 @@
#include <nuttx/mtd/nand_scheme.h> #include <nuttx/mtd/nand_scheme.h>
#include <nuttx/mtd/nand_model.h> #include <nuttx/mtd/nand_model.h>
/************************************************************************************************** /****************************************************************************
* Public Data * Public Data
**************************************************************************************************/ ****************************************************************************/
/* List of NandFlash models which can be recognized by the software */ /* List of NandFlash models which can be recognized by the software */
/****************************************************************************
* ID OPTIONS PAGE SPARE DEV BLOCK | SCHEME
* SIZE SIZE SIZE SIZE |
****************************************************************************/
const struct nand_model_s g_nandmodels[NAND_NMODELS] = const struct nand_model_s g_nandmodels[NAND_NMODELS] =
{ {
/*----------|------------------------------+------+-------+------+-------+------------------------
* | ID | OPTIONS | PAGE | SPARE | DEV | BLOCK | SCHEME
* | | | SIZE | SIZE | SIZE | SIZE |
*----------|------------------------------+------+-------+------+-------+------------------------*/
{0x6e, NANDMODEL_DATAWIDTH8, 256, 0, 1, 4, &g_nand_sparescheme256}, {0x6e, NANDMODEL_DATAWIDTH8, 256, 0, 1, 4, &g_nand_sparescheme256},
{0x64, NANDMODEL_DATAWIDTH8, 256, 0, 2, 4, &g_nand_sparescheme256}, {0x64, NANDMODEL_DATAWIDTH8, 256, 0, 2, 4, &g_nand_sparescheme256},
{0x68, NANDMODEL_DATAWIDTH8, 4096, 0, 224, 1024, &g_nand_sparescheme4096}, {0x68, NANDMODEL_DATAWIDTH8, 4096, 0, 224, 1024, &g_nand_sparescheme4096},
@@ -73,37 +73,22 @@ const struct nand_model_s g_nandmodels[NAND_NMODELS] =
{0xe3, NANDMODEL_DATAWIDTH8, 512, 0, 4, 8, &g_nand_sparescheme512}, {0xe3, NANDMODEL_DATAWIDTH8, 512, 0, 4, 8, &g_nand_sparescheme512},
{0xe5, NANDMODEL_DATAWIDTH8, 512, 0, 4, 8, &g_nand_sparescheme512}, {0xe5, NANDMODEL_DATAWIDTH8, 512, 0, 4, 8, &g_nand_sparescheme512},
{0xd6, NANDMODEL_DATAWIDTH8, 512, 0, 8, 8, &g_nand_sparescheme512}, {0xd6, NANDMODEL_DATAWIDTH8, 512, 0, 8, 8, &g_nand_sparescheme512},
/*----------|------------------------------+------+-------+------+-------+------------------------*/
{0x39, NANDMODEL_DATAWIDTH8, 512, 0, 8, 8, &g_nand_sparescheme512}, {0x39, NANDMODEL_DATAWIDTH8, 512, 0, 8, 8, &g_nand_sparescheme512},
{0xe6, NANDMODEL_DATAWIDTH8, 512, 0, 8, 8, &g_nand_sparescheme512}, {0xe6, NANDMODEL_DATAWIDTH8, 512, 0, 8, 8, &g_nand_sparescheme512},
{0x49, NANDMODEL_DATAWIDTH16, 512, 0, 8, 8, &g_nand_sparescheme512}, {0x49, NANDMODEL_DATAWIDTH16, 512, 0, 8, 8, &g_nand_sparescheme512},
{0x59, NANDMODEL_DATAWIDTH16, 512, 0, 8, 8, &g_nand_sparescheme512}, {0x59, NANDMODEL_DATAWIDTH16, 512, 0, 8, 8, &g_nand_sparescheme512},
/*----------|------------------------------+------+-------+------+-------+------------------------*/
{0x33, NANDMODEL_DATAWIDTH8, 512, 0, 16, 16, &g_nand_sparescheme512}, {0x33, NANDMODEL_DATAWIDTH8, 512, 0, 16, 16, &g_nand_sparescheme512},
{0x73, NANDMODEL_DATAWIDTH8, 512, 0, 16, 16, &g_nand_sparescheme512}, {0x73, NANDMODEL_DATAWIDTH8, 512, 0, 16, 16, &g_nand_sparescheme512},
{0x43, NANDMODEL_DATAWIDTH16, 512, 0, 16, 16, &g_nand_sparescheme512}, {0x43, NANDMODEL_DATAWIDTH16, 512, 0, 16, 16, &g_nand_sparescheme512},
{0x53, NANDMODEL_DATAWIDTH16, 512, 0, 16, 16, &g_nand_sparescheme512}, {0x53, NANDMODEL_DATAWIDTH16, 512, 0, 16, 16, &g_nand_sparescheme512},
/*----------|------------------------------+------+-------+------+-------+------------------------*/
{0x35, NANDMODEL_DATAWIDTH8, 512, 0, 32, 16, &g_nand_sparescheme512}, {0x35, NANDMODEL_DATAWIDTH8, 512, 0, 32, 16, &g_nand_sparescheme512},
{0x75, NANDMODEL_DATAWIDTH8, 512, 0, 32, 16, &g_nand_sparescheme512}, {0x75, NANDMODEL_DATAWIDTH8, 512, 0, 32, 16, &g_nand_sparescheme512},
{0x45, NANDMODEL_DATAWIDTH16, 512, 0, 32, 16, &g_nand_sparescheme512}, {0x45, NANDMODEL_DATAWIDTH16, 512, 0, 32, 16, &g_nand_sparescheme512},
{0x55, NANDMODEL_DATAWIDTH16, 512, 0, 32, 16, &g_nand_sparescheme512}, {0x55, NANDMODEL_DATAWIDTH16, 512, 0, 32, 16, &g_nand_sparescheme512},
/*----------|------------------------------+------+-------+------+-------+------------------------*/
{0x36, NANDMODEL_DATAWIDTH8, 512, 0, 64, 16, &g_nand_sparescheme512}, {0x36, NANDMODEL_DATAWIDTH8, 512, 0, 64, 16, &g_nand_sparescheme512},
{0x76, NANDMODEL_DATAWIDTH8, 512, 0, 64, 16, &g_nand_sparescheme512}, {0x76, NANDMODEL_DATAWIDTH8, 512, 0, 64, 16, &g_nand_sparescheme512},
{0x46, NANDMODEL_DATAWIDTH16, 512, 0, 64, 16, &g_nand_sparescheme512}, {0x46, NANDMODEL_DATAWIDTH16, 512, 0, 64, 16, &g_nand_sparescheme512},
{0x56, NANDMODEL_DATAWIDTH16, 512, 0, 64, 16, &g_nand_sparescheme512}, {0x56, NANDMODEL_DATAWIDTH16, 512, 0, 64, 16, &g_nand_sparescheme512},
/*----------|------------------------------+------+-------+------+-------+------------------------*/
{0x78, NANDMODEL_DATAWIDTH8, 512, 0, 128, 16, &g_nand_sparescheme512}, {0x78, NANDMODEL_DATAWIDTH8, 512, 0, 128, 16, &g_nand_sparescheme512},
{0x39, NANDMODEL_DATAWIDTH8, 512, 0, 128, 16, &g_nand_sparescheme512}, {0x39, NANDMODEL_DATAWIDTH8, 512, 0, 128, 16, &g_nand_sparescheme512},
{0x79, NANDMODEL_DATAWIDTH8, 512, 0, 128, 16, &g_nand_sparescheme512}, {0x79, NANDMODEL_DATAWIDTH8, 512, 0, 128, 16, &g_nand_sparescheme512},
@@ -111,60 +96,62 @@ const struct nand_model_s g_nandmodels[NAND_NMODELS] =
{0x49, NANDMODEL_DATAWIDTH16, 512, 0, 128, 16, &g_nand_sparescheme512}, {0x49, NANDMODEL_DATAWIDTH16, 512, 0, 128, 16, &g_nand_sparescheme512},
{0x74, NANDMODEL_DATAWIDTH16, 512, 0, 128, 16, &g_nand_sparescheme512}, {0x74, NANDMODEL_DATAWIDTH16, 512, 0, 128, 16, &g_nand_sparescheme512},
{0x59, NANDMODEL_DATAWIDTH16, 512, 0, 128, 16, &g_nand_sparescheme512}, {0x59, NANDMODEL_DATAWIDTH16, 512, 0, 128, 16, &g_nand_sparescheme512},
/*----------|------------------------------+------+-------+------+-------+------------------------*/
{0x71, NANDMODEL_DATAWIDTH8, 512, 0, 256, 16, &g_nand_sparescheme512}, {0x71, NANDMODEL_DATAWIDTH8, 512, 0, 256, 16, &g_nand_sparescheme512},
/* Large blocks devices. Parameters must be fetched from the extended I */ /* Large blocks devices. Parameters must be fetched from the extended I */
#define OPTIONS NANDMODEL_COPYBACK #define OPTIONS NANDMODEL_COPYBACK
{0xa2, NANDMODEL_DATAWIDTH8 | OPTIONS,
/*----------|------------------------------+------+-------+------+-------+------------------------ 0, 0, 64, 0, &g_nand_sparescheme2048},
* | ID | OPTIONS | PAGE | SPARE | DEV | BLOCK | SCHEME {0xf2, NANDMODEL_DATAWIDTH8 | OPTIONS,
* | | | SIZE | SIZE | SIZE | SIZE | 0, 0, 64, 0, &g_nand_sparescheme2048},
*----------|------------------------------+------+-------+------+-------+------------------------*/ {0xb2, NANDMODEL_DATAWIDTH16 | OPTIONS,
0, 0, 64, 0, &g_nand_sparescheme2048},
{0xA2, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 64, 0, &g_nand_sparescheme2048}, {0xc2, NANDMODEL_DATAWIDTH16 | OPTIONS,
{0xF2, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 64, 0, &g_nand_sparescheme2048}, 0, 0, 64, 0, &g_nand_sparescheme2048},
{0xB2, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 64, 0, &g_nand_sparescheme2048}, {0xa1, NANDMODEL_DATAWIDTH8 | OPTIONS,
{0xC2, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 64, 0, &g_nand_sparescheme2048}, 0, 0, 128, 0, &g_nand_sparescheme2048},
{0xf1, NANDMODEL_DATAWIDTH8 | OPTIONS,
/*----------|------------------------------+------+-------+------+-------+------------------------*/ 0, 0, 128, 0, &g_nand_sparescheme2048},
{0xb1, NANDMODEL_DATAWIDTH16 | OPTIONS,
{0xA1, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 128, 0, &g_nand_sparescheme2048}, 0, 0, 128, 0, &g_nand_sparescheme2048},
{0xF1, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 128, 0, &g_nand_sparescheme2048}, {0xc1, NANDMODEL_DATAWIDTH16 | OPTIONS,
{0xB1, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 128, 0, &g_nand_sparescheme2048}, 0, 0, 128, 0, &g_nand_sparescheme2048},
{0xC1, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 128, 0, &g_nand_sparescheme2048}, {0xaa, NANDMODEL_DATAWIDTH8 | OPTIONS,
0, 0, 256, 0, &g_nand_sparescheme2048},
/*----------|------------------------------+------+-------+------+-------+------------------------*/ {0xda, NANDMODEL_DATAWIDTH8 | OPTIONS,
0, 0, 256, 0, &g_nand_sparescheme2048},
{0xAA, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 256, 0, &g_nand_sparescheme2048}, {0xba, NANDMODEL_DATAWIDTH16 | OPTIONS,
{0xDA, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 256, 0, &g_nand_sparescheme2048}, 0, 0, 256, 0, &g_nand_sparescheme2048},
{0xBA, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 256, 0, &g_nand_sparescheme2048}, {0xca, NANDMODEL_DATAWIDTH16 | OPTIONS,
{0xCA, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 256, 0, &g_nand_sparescheme2048}, 0, 0, 256, 0, &g_nand_sparescheme2048},
{0xac, NANDMODEL_DATAWIDTH8 | OPTIONS,
/*----------|------------------------------+------+-------+------+-------+------------------------*/ 0, 0, 512, 0, &g_nand_sparescheme2048},
{0xdc, NANDMODEL_DATAWIDTH8 | OPTIONS,
{0xAC, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 512, 0, &g_nand_sparescheme2048}, 0, 0, 512, 0, &g_nand_sparescheme2048},
{0xDC, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 512, 0, &g_nand_sparescheme2048}, {0xbc, NANDMODEL_DATAWIDTH16 | OPTIONS,
{0xBC, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 512, 0, &g_nand_sparescheme2048}, 0, 0, 512, 0, &g_nand_sparescheme2048},
{0xCC, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 512, 0, &g_nand_sparescheme2048}, {0xcc, NANDMODEL_DATAWIDTH16 | OPTIONS,
0, 0, 512, 0, &g_nand_sparescheme2048},
/*----------|------------------------------+------+-------+------+-------+------------------------*/ {0xa3, NANDMODEL_DATAWIDTH8 | OPTIONS,
0, 0, 1024, 0, &g_nand_sparescheme2048},
{0xA3, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 1024, 0, &g_nand_sparescheme2048}, {0xd3, NANDMODEL_DATAWIDTH8 | OPTIONS,
{0xD3, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 1024, 0, &g_nand_sparescheme2048}, 0, 0, 1024, 0, &g_nand_sparescheme2048},
{0xB3, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 1024, 0, &g_nand_sparescheme2048}, {0xb3, NANDMODEL_DATAWIDTH16 | OPTIONS,
{0xC3, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 1024, 0, &g_nand_sparescheme2048}, 0, 0, 1024, 0, &g_nand_sparescheme2048},
{0xd3, NANDMODEL_DATAWIDTH16 | OPTIONS,
/*----------|------------------------------+------+-------+------+-------+------------------------*/ 0, 0, 1024, 0, &g_nand_sparescheme2048},
{0xa5, NANDMODEL_DATAWIDTH8 | OPTIONS,
{0xA5, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 2048, 0, &g_nand_sparescheme2048}, 0, 0, 2048, 0, &g_nand_sparescheme2048},
{0xD5, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 2048, 0, &g_nand_sparescheme2048}, {0xd5, NANDMODEL_DATAWIDTH8 | OPTIONS,
{0xB5, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 2048, 0, &g_nand_sparescheme2048}, 0, 0, 2048, 0, &g_nand_sparescheme2048},
{0xC5, NANDMODEL_DATAWIDTH16 | OPTIONS, 0, 0, 2048, 0, &g_nand_sparescheme2048}, {0xb5, NANDMODEL_DATAWIDTH16 | OPTIONS,
{0x38, NANDMODEL_DATAWIDTH8 | OPTIONS, 0, 0, 1024, 0, &g_nand_sparescheme4096} 0, 0, 2048, 0, &g_nand_sparescheme2048},
{0xc5, NANDMODEL_DATAWIDTH16 | OPTIONS,
/*----------|------------------------------+------+-------+------+-------+------------------------*/ 0, 0, 2048, 0, &g_nand_sparescheme2048},
{0x38, NANDMODEL_DATAWIDTH8 | OPTIONS,
0, 0, 1024, 0, &g_nand_sparescheme4096}
}; };
/****************************************************************************
* Public Functions
****************************************************************************/
+10 -2
View File
@@ -97,7 +97,11 @@ int nandecc_readpage(FAR struct nand_dev_s *nand, off_t block,
unsigned int sparesize; unsigned int sparesize;
int ret; int ret;
finfo("block=%d page=%d data=%p spare=%d\n", (int)block, page, data, spare); finfo("block=%d page=%d data=%p spare=%d\n",
(int)block,
page,
data,
spare);
/* Get convenience pointers */ /* Get convenience pointers */
@@ -189,7 +193,11 @@ int nandecc_writepage(FAR struct nand_dev_s *nand, off_t block,
unsigned int sparesize; unsigned int sparesize;
int ret; int ret;
finfo("block=%d page=%d data=%p spare=%d\n", (int)block, page, data, spare); finfo("block=%d page=%d data=%p spare=%d\n",
(int)block,
page,
data,
spare);
/* Get convenience pointers */ /* Get convenience pointers */
+2 -1
View File
@@ -73,7 +73,8 @@
* Input Parameters: * Input Parameters:
* modeltab List of nand_model_s instances. * modeltab List of nand_model_s instances.
* size Number of models in list. * size Number of models in list.
* chipid Identifier returned by the Nand(id1|(id2<<8)|(id3<<16)|(id4<<24)). * chipid Identifier returned by the Nand
* (id1|(id2<<8)|(id3<<16)|(id4<<24)).
* model nand_model_s instance to update with the model parameters. * model nand_model_s instance to update with the model parameters.
* *
* Returned Value: * Returned Value:
+98 -72
View File
@@ -1,7 +1,7 @@
/************************************************************************************ /****************************************************************************
* drivers/mtd/mtd_rwbuffer.c * drivers/mtd/mtd_rwbuffer.c
* MTD driver that contains another MTD driver and provides read-ahead and/or write * MTD driver that contains another MTD driver and provides read-ahead
* buffering. * and/or write buffering.
* *
* Copyright (C) 2014 Gregory Nutt. All rights reserved. * Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
@@ -33,11 +33,11 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Included Files * Included Files
************************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
@@ -59,9 +59,9 @@
#if defined(CONFIG_DRVR_WRITEBUFFER) || defined(CONFIG_DRVR_READAHEAD) #if defined(CONFIG_DRVR_WRITEBUFFER) || defined(CONFIG_DRVR_READAHEAD)
/************************************************************************************ /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ****************************************************************************/
#ifndef CONFIG_DRVR_INVALIDATE #ifndef CONFIG_DRVR_INVALIDATE
# error This driver requires CONFIG_DRVR_INVALIDATE # error This driver requires CONFIG_DRVR_INVALIDATE
@@ -79,13 +79,14 @@
# define CONFIG_MTD_NRDBLOCKS 4 # define CONFIG_MTD_NRDBLOCKS 4
#endif #endif
/************************************************************************************ /****************************************************************************
* Private Types * Private Types
************************************************************************************/ ****************************************************************************/
/* This type represents the state of the MTD device. The struct mtd_dev_s must /* This type represents the state of the MTD device.
* appear at the beginning of the definition so that you can freely cast between * The struct mtd_dev_s must appear at the beginning of the definition so
* pointers to struct mtd_dev_s and struct mtd_rwbuffer_s. * that you can freely cast between pointers to struct mtd_dev_s and struct
* mtd_rwbuffer_s.
*/ */
struct mtd_rwbuffer_s struct mtd_rwbuffer_s
@@ -96,45 +97,61 @@ struct mtd_rwbuffer_s
uint16_t spb; /* Number of sectors per block */ uint16_t spb; /* Number of sectors per block */
}; };
/************************************************************************************ /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
************************************************************************************/ ****************************************************************************/
/* rwbuffer callouts */ /* rwbuffer callouts */
static ssize_t mtd_reload(FAR void *dev, FAR uint8_t *buffer, off_t startblock, static ssize_t mtd_reload(FAR void *dev,
FAR uint8_t *buffer,
off_t startblock,
size_t nblocks); size_t nblocks);
static ssize_t mtd_flush(FAR void *dev, FAR const uint8_t *buffer, off_t startblock, static ssize_t mtd_flush(FAR void *dev,
FAR const uint8_t *buffer,
off_t startblock,
size_t nblocks); size_t nblocks);
/* MTD driver methods */ /* MTD driver methods */
static int mtd_erase(FAR struct mtd_dev_s *dev, off_t block, size_t nsectors); static int mtd_erase(FAR struct mtd_dev_s *dev,
static ssize_t mtd_bread(FAR struct mtd_dev_s *dev, off_t block, off_t block,
size_t nsectors, FAR uint8_t *buf); size_t nsectors);
static ssize_t mtd_bwrite(FAR struct mtd_dev_s *dev, off_t block, static ssize_t mtd_bread(FAR struct mtd_dev_s *dev,
size_t nsectors, FAR const uint8_t *buf); off_t block,
static ssize_t mtd_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, size_t nsectors,
FAR uint8_t *buf);
static ssize_t mtd_bwrite(FAR struct mtd_dev_s *dev,
off_t block,
size_t nsectors,
FAR const uint8_t *buf);
static ssize_t mtd_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer); FAR uint8_t *buffer);
static int mtd_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); static int mtd_ioctl(FAR struct mtd_dev_s *dev,
int cmd,
unsigned long arg);
/************************************************************************************ /****************************************************************************
* Private Data * Private Data
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Private Functions * Private Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: mtd_reload * Name: mtd_reload
* *
* Description: * Description:
* Reload the read-ahead buffer * Reload the read-ahead buffer
* *
************************************************************************************/ ****************************************************************************/
static ssize_t mtd_reload(FAR void *dev, FAR uint8_t *buffer, off_t startblock, static ssize_t mtd_reload(FAR void *dev,
FAR uint8_t *buffer,
off_t startblock,
size_t nblocks) size_t nblocks)
{ {
FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev; FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev;
@@ -145,15 +162,17 @@ static ssize_t mtd_reload(FAR void *dev, FAR uint8_t *buffer, off_t startblock,
return priv->dev->bread(priv->dev, startblock, nblocks, buffer); return priv->dev->bread(priv->dev, startblock, nblocks, buffer);
} }
/************************************************************************************ /****************************************************************************
* Name: mtd_flush * Name: mtd_flush
* *
* Description: * Description:
* Flush the write buffer to hardware * Flush the write buffer to hardware
* *
************************************************************************************/ ****************************************************************************/
static ssize_t mtd_flush(FAR void *dev, FAR const uint8_t *buffer, off_t startblock, static ssize_t mtd_flush(FAR void *dev,
FAR const uint8_t *buffer,
off_t startblock,
size_t nblocks) size_t nblocks)
{ {
FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev; FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev;
@@ -164,11 +183,13 @@ static ssize_t mtd_flush(FAR void *dev, FAR const uint8_t *buffer, off_t startbl
return priv->dev->bwrite(priv->dev, startblock, nblocks, buffer); return priv->dev->bwrite(priv->dev, startblock, nblocks, buffer);
} }
/************************************************************************************ /****************************************************************************
* Name: mtd_erase * Name: mtd_erase
************************************************************************************/ ****************************************************************************/
static int mtd_erase(FAR struct mtd_dev_s *dev, off_t block, size_t nblocks) static int mtd_erase(FAR struct mtd_dev_s *dev,
off_t block,
size_t nblocks)
{ {
FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev; FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev;
off_t sector; off_t sector;
@@ -197,57 +218,60 @@ static int mtd_erase(FAR struct mtd_dev_s *dev, off_t block, size_t nblocks)
return priv->dev->erase(priv->dev, block, nblocks); return priv->dev->erase(priv->dev, block, nblocks);
} }
/************************************************************************************ /****************************************************************************
* Name: mtd_bread * Name: mtd_bread
************************************************************************************/ ****************************************************************************/
static ssize_t mtd_bread(FAR struct mtd_dev_s *dev, off_t sector, static ssize_t mtd_bread(FAR struct mtd_dev_s *dev, off_t sector,
size_t nsectors, FAR uint8_t *buffer) size_t nsectors, FAR uint8_t *buffer)
{ {
FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev; FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev;
/* Let the rwbuffer logic do it real work. It will call out to mtd_reload if is /* Let the rwbuffer logic do it real work.
* needs to read any data. * It will call out to mtd_reload if is needs to read any data.
*/ */
return rwb_read(&priv->rwb, sector, nsectors, buffer); return rwb_read(&priv->rwb, sector, nsectors, buffer);
} }
/************************************************************************************ /****************************************************************************
* Name: mtd_bwrite * Name: mtd_bwrite
************************************************************************************/ ****************************************************************************/
static ssize_t mtd_bwrite(FAR struct mtd_dev_s *dev, off_t block, size_t nsectors, static ssize_t mtd_bwrite(FAR struct mtd_dev_s *dev, off_t block,
size_t nsectors,
FAR const uint8_t *buffer) FAR const uint8_t *buffer)
{ {
FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev; FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev;
/* Let the rwbuffer logic do it real work. It will call out to wrb_reload it is /* Let the rwbuffer logic do it real work.
* needs to read any data. * It will call out to wrb_reload it is needs to read any data.
*/ */
return rwb_write(&priv->rwb, block, nsectors, buffer); return rwb_write(&priv->rwb, block, nsectors, buffer);
} }
/************************************************************************************ /****************************************************************************
* Name: mtd_read * Name: mtd_read
************************************************************************************/ ****************************************************************************/
static ssize_t mtd_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t mtd_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer) FAR uint8_t *buffer)
{ {
FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev; FAR struct mtd_rwbuffer_s *priv = (FAR struct mtd_rwbuffer_s *)dev;
/* Let the rwbuffer logic do it real work. It will call out to mtd_reload it is /* Let the rwbuffer logic do it real work.
* needs to read any data. * It will call out to mtd_reload it is needs to read any data.
*/ */
return rwb_readbytes(&priv->rwb, offset, nbytes, buffer); return rwb_readbytes(&priv->rwb, offset, nbytes, buffer);
} }
/************************************************************************************ /****************************************************************************
* Name: mtd_ioctl * Name: mtd_ioctl
************************************************************************************/ ****************************************************************************/
static int mtd_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) static int mtd_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{ {
@@ -264,13 +288,14 @@ static int mtd_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
((uintptr_t)arg); ((uintptr_t)arg);
if (geo) if (geo)
{ {
/* Populate the geometry structure with information need to know /* Populate the geometry structure with information need to
* the capacity and how to access the device. * know the capacity and how to access the device.
* *
* NOTE: that the device is treated as though it where just an array * NOTE:
* of fixed size blocks. That is most likely not true, but the client * that the device is treated as though it where just an array
* will expect the device logic to do whatever is necessary to make it * of fixed size blocks. That is most likely not true, but the
* appear so. * client will expect the device logic to do whatever is
* necessary to make it appear so.
*/ */
geo->blocksize = priv->rwb.blocksize; geo->blocksize = priv->rwb.blocksize;
@@ -315,23 +340,23 @@ static int mtd_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
return ret; return ret;
} }
/************************************************************************************ /****************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: mtd_rwb_initialize * Name: mtd_rwb_initialize
* *
* Description: * Description:
* Create an initialized MTD device instance. This MTD driver contains another * Create an initialized MTD device instance.
* MTD driver and converts a larger sector size to a standard 512 byte sector * This MTD driver contains another MTD driver and converts a larger
* size. * sector size to a standard 512 byte sector size.
* *
* MTD devices are not registered in the file system, but are created as instances * MTD devices are not registered in the file system, but are created as
* that can be bound to other functions (such as a block or character driver front * instances that can be bound to other functions (such as a block or
* end). * character driver front end).
* *
************************************************************************************/ ****************************************************************************/
FAR struct mtd_dev_s *mtd_rwb_initialize(FAR struct mtd_dev_s *mtd) FAR struct mtd_dev_s *mtd_rwb_initialize(FAR struct mtd_dev_s *mtd)
{ {
@@ -354,11 +379,12 @@ FAR struct mtd_dev_s *mtd_rwb_initialize(FAR struct mtd_dev_s *mtd)
/* Allocate a state structure (we allocate the structure instead of using /* Allocate a state structure (we allocate the structure instead of using
* a fixed, static allocation so that we can handle multiple FLASH devices. * a fixed, static allocation so that we can handle multiple FLASH devices.
* The current implementation would handle only one FLASH part per SPI * The current implementation would handle only one FLASH part per SPI
* device (only because of the SPIDEV_FLASH(0) definition) and so would have * device (only because of the SPIDEV_FLASH(0) definition) and so would
* to be extended to handle multiple FLASH parts on the same SPI bus. * have to be extended to handle multiple FLASH parts on the same SPI bus.
*/ */
priv = (FAR struct mtd_rwbuffer_s *)kmm_zalloc(sizeof(struct mtd_rwbuffer_s)); priv = (FAR struct mtd_rwbuffer_s *)
kmm_zalloc(sizeof(struct mtd_rwbuffer_s));
if (!priv) if (!priv)
{ {
ferr("ERROR: Failed to allocate mtd_rwbuffer\n"); ferr("ERROR: Failed to allocate mtd_rwbuffer\n");
+172 -124
View File
File diff suppressed because it is too large Load Diff
+94 -70
View File
@@ -1,4 +1,4 @@
/************************************************************************************ /****************************************************************************
* drivers/mtd/mx25rxx.c * drivers/mtd/mx25rxx.c
* *
* Copyright (C) 201, 2019 Gregory Nutt. All rights reserved. * Copyright (C) 201, 2019 Gregory Nutt. All rights reserved.
@@ -34,11 +34,11 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Included Files * Included Files
************************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <errno.h> #include <errno.h>
@@ -59,9 +59,9 @@
#include <nuttx/spi/qspi.h> #include <nuttx/spi/qspi.h>
#include <nuttx/mtd/mtd.h> #include <nuttx/mtd/mtd.h>
/************************************************************************************ /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ****************************************************************************/
/* MX25RXX Commands */ /* MX25RXX Commands */
@@ -146,7 +146,7 @@
#define MX25R_CR_TB (1 << 3) /* Bit 3: Top/bottom selected */ #define MX25R_CR_TB (1 << 3) /* Bit 3: Top/bottom selected */
#define MX25R_CR_DC (1 << 6) /* Bit 6: Dummy cycle */ #define MX25R_CR_DC (1 << 6) /* Bit 6: Dummy cycle */
/* Cache flags **********************************************************************/ /* Cache flags **************************************************************/
#define MX25RXX_CACHE_VALID (1 << 0) /* 1=Cache has valid data */ #define MX25RXX_CACHE_VALID (1 << 0) /* 1=Cache has valid data */
#define MX25RXX_CACHE_DIRTY (1 << 1) /* 1=Cache is dirty */ #define MX25RXX_CACHE_DIRTY (1 << 1) /* 1=Cache is dirty */
@@ -164,15 +164,15 @@
#define CLR_DIRTY(p) do { (p)->flags &= ~MX25RXX_CACHE_DIRTY; } while (0) #define CLR_DIRTY(p) do { (p)->flags &= ~MX25RXX_CACHE_DIRTY; } while (0)
#define CLR_ERASED(p) do { (p)->flags &= ~MX25RXX_CACHE_ERASED; } while (0) #define CLR_ERASED(p) do { (p)->flags &= ~MX25RXX_CACHE_ERASED; } while (0)
/* 512 byte sector support **********************************************************/ /* 512 byte sector support **************************************************/
#define MX25RXX_SECTOR512_SHIFT 9 #define MX25RXX_SECTOR512_SHIFT 9
#define MX25RXX_SECTOR512_SIZE (1 << 9) #define MX25RXX_SECTOR512_SIZE (1 << 9)
#define MX25RXX_ERASED_STATE 0xff #define MX25RXX_ERASED_STATE 0xff
/************************************************************************************ /****************************************************************************
* Private Types * Private Types
************************************************************************************/ ****************************************************************************/
/* Internal state of the MTD device */ /* Internal state of the MTD device */
@@ -194,9 +194,9 @@ struct mx25rxx_dev_s
#endif #endif
}; };
/************************************************************************************ /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
************************************************************************************/ ****************************************************************************/
/* MTD driver methods */ /* MTD driver methods */
@@ -234,7 +234,9 @@ static void mx25rxx_write_status_config(FAR struct mx25rxx_dev_s *dev,
static void mx25rxx_write_enable(FAR struct mx25rxx_dev_s *dev, bool enable); static void mx25rxx_write_enable(FAR struct mx25rxx_dev_s *dev, bool enable);
static int mx25rxx_write_page(struct mx25rxx_dev_s *priv, static int mx25rxx_write_page(struct mx25rxx_dev_s *priv,
FAR const uint8_t *buffer, off_t address, size_t buflen); FAR const uint8_t *buffer,
off_t address,
size_t buflen);
static int mx25rxx_erase_sector(struct mx25rxx_dev_s *priv, off_t sector); static int mx25rxx_erase_sector(struct mx25rxx_dev_s *priv, off_t sector);
#if 0 /* FIXME: Not used */ #if 0 /* FIXME: Not used */
static int mx25rxx_erase_block(struct mx25rxx_dev_s *priv, off_t block); static int mx25rxx_erase_block(struct mx25rxx_dev_s *priv, off_t block);
@@ -243,15 +245,16 @@ static int mx25rxx_erase_chip(struct mx25rxx_dev_s *priv);
#ifdef CONFIG_MX25RXX_SECTOR512 #ifdef CONFIG_MX25RXX_SECTOR512
static int mx25rxx_flush_cache(struct mx25rxx_dev_s *priv); static int mx25rxx_flush_cache(struct mx25rxx_dev_s *priv);
static FAR uint8_t *mx25rxx_read_cache(struct mx25rxx_dev_s *priv, off_t sector); static FAR uint8_t *mx25rxx_read_cache(struct mx25rxx_dev_s *priv,
off_t sector);
static void mx25rxx_erase_cache(struct mx25rxx_dev_s *priv, off_t sector); static void mx25rxx_erase_cache(struct mx25rxx_dev_s *priv, off_t sector);
static int mx25rxx_write_cache(FAR struct mx25rxx_dev_s *priv, static int mx25rxx_write_cache(FAR struct mx25rxx_dev_s *priv,
FAR const uint8_t *buffer, off_t sector, size_t nsectors); FAR const uint8_t *buffer, off_t sector, size_t nsectors);
#endif #endif
/************************************************************************************ /****************************************************************************
* Private Functions * Private Functions
************************************************************************************/ ****************************************************************************/
void mx25rxx_lock(FAR struct qspi_dev_s *qspi, bool read) void mx25rxx_lock(FAR struct qspi_dev_s *qspi, bool read)
{ {
@@ -259,23 +262,24 @@ void mx25rxx_lock(FAR struct qspi_dev_s *qspi, bool read)
* lock SPI to have exclusive access to the buses for a sequence of * lock SPI to have exclusive access to the buses for a sequence of
* transfers. The bus should be locked before the chip is selected. * transfers. The bus should be locked before the chip is selected.
* *
* This is a blocking call and will not return until we have exclusive access * This is a blocking call and will not return until we have exclusive
* to the SPI bus. We will retain that exclusive access until the bus is * access to the SPI bus. We will retain that exclusive access until the
* unlocked. * bus is unlocked.
*/ */
QSPI_LOCK(qspi, true); QSPI_LOCK(qspi, true);
/* After locking the SPI bus, the we also need call the setfrequency, setbits /* After locking the SPI bus, the we also need call the setfrequency,
* and setmode methods to make sure that the SPI is properly configured for * setbits and setmode methods to make sure that the SPI is properly
* the device. If the SPI bus is being shared, then it may have been left * configured for the device. If the SPI bus is being shared, then it
* in an incompatible state. * may have been left in an incompatible state.
*/ */
QSPI_SETMODE(qspi, CONFIG_MX25RXX_QSPIMODE); QSPI_SETMODE(qspi, CONFIG_MX25RXX_QSPIMODE);
QSPI_SETBITS(qspi, 8); QSPI_SETBITS(qspi, 8);
QSPI_SETFREQUENCY(qspi, QSPI_SETFREQUENCY(qspi,
read ? CONFIG_MX25RXX_QSPI_READ_FREQUENCY : CONFIG_MX25RXX_QSPI_FREQUENCY); read ? CONFIG_MX25RXX_QSPI_READ_FREQUENCY :
CONFIG_MX25RXX_QSPI_FREQUENCY);
} }
void mx25rxx_unlock(FAR struct qspi_dev_s *qspi) void mx25rxx_unlock(FAR struct qspi_dev_s *qspi)
@@ -538,7 +542,8 @@ int mx25rxx_read_configuration(FAR struct mx25rxx_dev_s *dev)
return mx25rxx_command_read(dev->qspi, MX25R_RDCR, dev->cmdbuf, 4); return mx25rxx_command_read(dev->qspi, MX25R_RDCR, dev->cmdbuf, 4);
} }
void mx25rxx_write_status_config(FAR struct mx25rxx_dev_s *dev, uint8_t status, void mx25rxx_write_status_config(FAR struct mx25rxx_dev_s *dev,
uint8_t status,
uint16_t config) uint16_t config)
{ {
mx25rxx_write_enable(dev, true); mx25rxx_write_enable(dev, true);
@@ -555,7 +560,9 @@ void mx25rxx_write_status_config(FAR struct mx25rxx_dev_s *dev, uint8_t status,
mx25rxx_write_enable(dev, false); mx25rxx_write_enable(dev, false);
} }
int mx25rxx_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks) int mx25rxx_erase(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks)
{ {
FAR struct mx25rxx_dev_s *priv = (FAR struct mx25rxx_dev_s *)dev; FAR struct mx25rxx_dev_s *priv = (FAR struct mx25rxx_dev_s *)dev;
size_t blocksleft = nblocks; size_t blocksleft = nblocks;
@@ -636,7 +643,9 @@ ssize_t mx25rxx_bread(FAR struct mtd_dev_s *dev, off_t startblock,
finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); finfo("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
/* On this device, we can handle the block read just like the byte-oriented read */ /* On this device, we can handle the block read just like the
* byte-oriented read
*/
#ifdef CONFIG_MX25RXX_SECTOR512 #ifdef CONFIG_MX25RXX_SECTOR512
nbytes = mx25rxx_read(dev, startblock << MX25RXX_SECTOR512_SHIFT, nbytes = mx25rxx_read(dev, startblock << MX25RXX_SECTOR512_SHIFT,
@@ -730,20 +739,22 @@ int mx25rxx_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
if (geo) if (geo)
{ {
/* Populate the geometry structure with information need to know /* Populate the geometry structure with information need to
* the capacity and how to access the device. * know the capacity and how to access the device.
* *
* NOTE: that the device is treated as though it where just an array * NOTE:
* of fixed size blocks. That is most likely not true, but the client * that the device is treated as though it where just an
* will expect the device logic to do whatever is necessary to make it * array of fixed size blocks. That is most likely not true,
* appear so. * but the client will expect the device logic to do whatever
* is necessary to make it appear so.
*/ */
#ifdef CONFIG_MX25RXX_SECTOR512 #ifdef CONFIG_MX25RXX_SECTOR512
geo->blocksize = (1 << MX25RXX_SECTOR512_SHIFT); geo->blocksize = (1 << MX25RXX_SECTOR512_SHIFT);
geo->erasesize = (1 << MX25RXX_SECTOR512_SHIFT); geo->erasesize = (1 << MX25RXX_SECTOR512_SHIFT);
geo->neraseblocks = priv->nsectors << geo->neraseblocks = priv->nsectors <<
(priv->sectorshift - MX25RXX_SECTOR512_SHIFT); (priv->sectorshift -
MX25RXX_SECTOR512_SHIFT);
#else #else
geo->blocksize = (1 << priv->pageshift); geo->blocksize = (1 << priv->pageshift);
geo->erasesize = (1 << priv->sectorshift); geo->erasesize = (1 << priv->sectorshift);
@@ -823,18 +834,18 @@ int mx25rxx_readid(struct mx25rxx_dev_s *dev)
return OK; return OK;
} }
/************************************************************************************ /****************************************************************************
* Name: mx25rxx_flush_cache * Name: mx25rxx_flush_cache
************************************************************************************/ ****************************************************************************/
#ifdef CONFIG_MX25RXX_SECTOR512 #ifdef CONFIG_MX25RXX_SECTOR512
static int mx25rxx_flush_cache(struct mx25rxx_dev_s *priv) static int mx25rxx_flush_cache(struct mx25rxx_dev_s *priv)
{ {
int ret = OK; int ret = OK;
/* If the cache is dirty (meaning that it no longer matches the old FLASH contents) /* If the cache is dirty (meaning that it no longer matches the old FLASH
* or was erased (with the cache containing the correct FLASH contents), then write * contents) or was erased (with the cache containing the correct FLASH
* the cached erase block to FLASH. * contents), then write the cached erase block to FLASH.
*/ */
if (IS_DIRTY(priv) || IS_ERASED(priv)) if (IS_DIRTY(priv) || IS_ERASED(priv))
@@ -847,7 +858,10 @@ static int mx25rxx_flush_cache(struct mx25rxx_dev_s *priv)
/* Write entire erase block to FLASH */ /* Write entire erase block to FLASH */
ret = mx25rxx_write_page(priv, priv->sector, address, 1 << priv->sectorshift); ret = mx25rxx_write_page(priv,
priv->sector,
address,
1 << priv->sectorshift);
if (ret < 0) if (ret < 0)
{ {
ferr("ERROR: mx25rxx_write_page failed: %d\n", ret); ferr("ERROR: mx25rxx_write_page failed: %d\n", ret);
@@ -863,21 +877,23 @@ static int mx25rxx_flush_cache(struct mx25rxx_dev_s *priv)
} }
#endif /* CONFIG_MX25RXX_SECTOR512 */ #endif /* CONFIG_MX25RXX_SECTOR512 */
/************************************************************************************ /****************************************************************************
* Name: mx25rxx_read_cache * Name: mx25rxx_read_cache
************************************************************************************/ ****************************************************************************/
#ifdef CONFIG_MX25RXX_SECTOR512 #ifdef CONFIG_MX25RXX_SECTOR512
static FAR uint8_t *mx25rxx_read_cache(struct mx25rxx_dev_s *priv, off_t sector) static FAR uint8_t *mx25rxx_read_cache(struct mx25rxx_dev_s *priv,
off_t sector)
{ {
off_t esectno; off_t esectno;
int shift; int shift;
int index; int index;
int ret; int ret;
/* Convert from the 512 byte sector to the erase sector size of the device. For /* Convert from the 512 byte sector to the erase sector size of the device.
* example, if the actual erase sector size is 4Kb (1 << 12), then we first * For example, if the actual erase sector size is 4Kb (1 << 12), then we
* shift to the right by 3 to get the sector number in 4096 increments. * first shift to the right by 3 to get the sector number in 4096
* increments.
*/ */
shift = priv->sectorshift - MX25RXX_SECTOR512_SHIFT; shift = priv->sectorshift - MX25RXX_SECTOR512_SHIFT;
@@ -918,7 +934,9 @@ static FAR uint8_t *mx25rxx_read_cache(struct mx25rxx_dev_s *priv, off_t sector)
CLR_ERASED(priv); /* The underlying FLASH has not been erased */ CLR_ERASED(priv); /* The underlying FLASH has not been erased */
} }
/* Get the index to the 512 sector in the erase block that holds the argument */ /* Get the index to the 512 sector in the erase block that holds the
* argument
*/
index = sector & ((1 << shift) - 1); index = sector & ((1 << shift) - 1);
@@ -928,17 +946,17 @@ static FAR uint8_t *mx25rxx_read_cache(struct mx25rxx_dev_s *priv, off_t sector)
} }
#endif /* CONFIG_MX25RXX_SECTOR512 */ #endif /* CONFIG_MX25RXX_SECTOR512 */
/************************************************************************************ /****************************************************************************
* Name: mx25rxx_erase_cache * Name: mx25rxx_erase_cache
************************************************************************************/ ****************************************************************************/
#ifdef CONFIG_MX25RXX_SECTOR512 #ifdef CONFIG_MX25RXX_SECTOR512
static void mx25rxx_erase_cache(struct mx25rxx_dev_s *priv, off_t sector) static void mx25rxx_erase_cache(struct mx25rxx_dev_s *priv, off_t sector)
{ {
FAR uint8_t *dest; FAR uint8_t *dest;
/* First, make sure that the erase block containing the 512 byte sector is in /* First, make sure that the erase block containing the 512 byte sector is
* the cache. * in the cache.
*/ */
dest = mx25rxx_read_cache(priv, sector); dest = mx25rxx_read_cache(priv, sector);
@@ -950,7 +968,8 @@ static void mx25rxx_erase_cache(struct mx25rxx_dev_s *priv, off_t sector)
if (!IS_ERASED(priv)) if (!IS_ERASED(priv))
{ {
off_t esectno = sector >> (priv->sectorshift - MX25RXX_SECTOR512_SHIFT); off_t esectno = sector >>
(priv->sectorshift - MX25RXX_SECTOR512_SHIFT);
finfo("sector: %jd esectno: %jd\n", finfo("sector: %jd esectno: %jd\n",
(intmax_t)sector, (intmax_t)esectno); (intmax_t)sector, (intmax_t)esectno);
@@ -958,9 +977,9 @@ static void mx25rxx_erase_cache(struct mx25rxx_dev_s *priv, off_t sector)
SET_ERASED(priv); SET_ERASED(priv);
} }
/* Put the cached sector data into the erase state and mark the cache as dirty /* Put the cached sector data into the erase state and mark the cache as
* (but don't update the FLASH yet. The caller will do that at a more optimal * dirty (but don't update the FLASH yet. The caller will do that at a
* time). * more optimal time).
*/ */
memset(dest, MX25RXX_ERASED_STATE, MX25RXX_SECTOR512_SIZE); memset(dest, MX25RXX_ERASED_STATE, MX25RXX_SECTOR512_SIZE);
@@ -968,9 +987,9 @@ static void mx25rxx_erase_cache(struct mx25rxx_dev_s *priv, off_t sector)
} }
#endif /* CONFIG_MX25RXX_SECTOR512 */ #endif /* CONFIG_MX25RXX_SECTOR512 */
/************************************************************************************ /****************************************************************************
* Name: mx25rxx_write_cache * Name: mx25rxx_write_cache
************************************************************************************/ ****************************************************************************/
#ifdef CONFIG_MX25RXX_SECTOR512 #ifdef CONFIG_MX25RXX_SECTOR512
static int mx25rxx_write_cache(FAR struct mx25rxx_dev_s *priv, static int mx25rxx_write_cache(FAR struct mx25rxx_dev_s *priv,
@@ -982,20 +1001,21 @@ static int mx25rxx_write_cache(FAR struct mx25rxx_dev_s *priv,
for (; nsectors > 0; nsectors--) for (; nsectors > 0; nsectors--)
{ {
/* First, make sure that the erase block containing 512 byte sector is in /* First, make sure that the erase block containing 512 byte sector is
* memory. * in memory.
*/ */
dest = mx25rxx_read_cache(priv, sector); dest = mx25rxx_read_cache(priv, sector);
/* Erase the block containing this sector if it is not already erased. /* Erase the block containing this sector if it is not already erased.
* The erased indicated will be cleared when the data from the erase sector * The erased indicated will be cleared when the data from the erase
* is read into the cache and set here when we erase the sector. * sector is read into the cache and set here when we erase the sector.
*/ */
if (!IS_ERASED(priv)) if (!IS_ERASED(priv))
{ {
off_t esectno = sector >> (priv->sectorshift - MX25RXX_SECTOR512_SHIFT); off_t esectno = sector >>
(priv->sectorshift - MX25RXX_SECTOR512_SHIFT);
finfo("sector: %jd esectno: %jd\n", finfo("sector: %jd esectno: %jd\n",
(intmax_t)sector, (intmax_t)esectno); (intmax_t)sector, (intmax_t)esectno);
@@ -1030,11 +1050,11 @@ static int mx25rxx_write_cache(FAR struct mx25rxx_dev_s *priv,
} }
#endif /* CONFIG_MX25RXX_SECTOR512 */ #endif /* CONFIG_MX25RXX_SECTOR512 */
/************************************************************************************ /****************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: mx25rxx_initialize * Name: mx25rxx_initialize
* *
* Description: * Description:
@@ -1044,9 +1064,10 @@ static int mx25rxx_write_cache(FAR struct mx25rxx_dev_s *priv,
* instances that can be bound to other functions (such as a block or * instances that can be bound to other functions (such as a block or
* character driver front end). * character driver front end).
* *
************************************************************************************/ ****************************************************************************/
FAR struct mtd_dev_s *mx25rxx_initialize(FAR struct qspi_dev_s *qspi, bool unprotect) FAR struct mtd_dev_s *mx25rxx_initialize(FAR struct qspi_dev_s *qspi,
bool unprotect)
{ {
FAR struct mx25rxx_dev_s *dev; FAR struct mx25rxx_dev_s *dev;
int ret; int ret;
@@ -1058,8 +1079,9 @@ FAR struct mtd_dev_s *mx25rxx_initialize(FAR struct qspi_dev_s *qspi, bool unpro
/* Allocate a state structure (we allocate the structure instead of using /* Allocate a state structure (we allocate the structure instead of using
* a fixed, static allocation so that we can handle multiple FLASH devices. * a fixed, static allocation so that we can handle multiple FLASH devices.
* The current implementation would handle only one FLASH part per QuadSPI * The current implementation would handle only one FLASH part per QuadSPI
* device (only because of the QSPIDEV_FLASH(0) definition) and so would have * device (only because of the QSPIDEV_FLASH(0) definition) and so would
* to be extended to handle multiple FLASH parts on the same QuadSPI bus. * have to be extended to handle multiple FLASH parts on the same QuadSPI
* bus.
*/ */
dev = (FAR struct mx25rxx_dev_s *)kmm_zalloc(sizeof(*dev)); dev = (FAR struct mx25rxx_dev_s *)kmm_zalloc(sizeof(*dev));
@@ -1104,7 +1126,9 @@ FAR struct mtd_dev_s *mx25rxx_initialize(FAR struct qspi_dev_s *qspi, bool unpro
dev->sector = (FAR uint8_t *)QSPI_ALLOC(qspi, 1 << dev->sectorshift); dev->sector = (FAR uint8_t *)QSPI_ALLOC(qspi, 1 << dev->sectorshift);
if (dev->sector == NULL) if (dev->sector == NULL)
{ {
/* Allocation failed! Discard all of that work we just did and return NULL */ /* Allocation failed! Discard all of that work we just did and
* return NULL
*/
ferr("ERROR: Sector allocation failed\n"); ferr("ERROR: Sector allocation failed\n");
goto exit_free_cmdbuf; goto exit_free_cmdbuf;
+167 -125
View File
File diff suppressed because it is too large Load Diff
+239 -178
View File
File diff suppressed because it is too large Load Diff
+26 -11
View File
@@ -53,6 +53,7 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* Configuration ************************************************************/ /* Configuration ************************************************************/
#ifndef CONFIG_RAMMTD_BLOCKSIZE #ifndef CONFIG_RAMMTD_BLOCKSIZE
@@ -117,18 +118,29 @@ static void *ram_write(FAR void *dest, FAR const void *src, size_t len);
/* MTD driver methods */ /* MTD driver methods */
static int ram_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks); static int ram_erase(FAR struct mtd_dev_s *dev,
static ssize_t ram_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, off_t startblock,
size_t nblocks);
static ssize_t ram_bread(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
FAR uint8_t *buf); FAR uint8_t *buf);
static ssize_t ram_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, static ssize_t ram_bwrite(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
FAR const uint8_t *buf); FAR const uint8_t *buf);
static ssize_t ram_byteread(FAR struct mtd_dev_s *dev, off_t offset, static ssize_t ram_byteread(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes, FAR uint8_t *buf); size_t nbytes, FAR uint8_t *buf);
#ifdef CONFIG_MTD_BYTE_WRITE #ifdef CONFIG_MTD_BYTE_WRITE
static ssize_t ram_bytewrite(FAR struct mtd_dev_s *dev, off_t offset, static ssize_t ram_bytewrite(FAR struct mtd_dev_s *dev,
size_t nbytes, FAR const uint8_t *buf); off_t offset,
size_t nbytes,
FAR const uint8_t *buf);
#endif #endif
static int ram_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); static int ram_ioctl(FAR struct mtd_dev_s *dev,
int cmd,
unsigned long arg);
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
@@ -232,7 +244,9 @@ static int ram_erase(FAR struct mtd_dev_s *dev, off_t startblock,
* Name: ram_bread * Name: ram_bread
****************************************************************************/ ****************************************************************************/
static ssize_t ram_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, static ssize_t ram_bread(FAR struct mtd_dev_s *dev,
off_t startblock,
size_t nblocks,
FAR uint8_t *buf) FAR uint8_t *buf)
{ {
FAR struct ram_dev_s *priv = (FAR struct ram_dev_s *)dev; FAR struct ram_dev_s *priv = (FAR struct ram_dev_s *)dev;
@@ -371,11 +385,12 @@ static int ram_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{ {
case MTDIOC_GEOMETRY: case MTDIOC_GEOMETRY:
{ {
FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg); FAR struct mtd_geometry_s *geo =
(FAR struct mtd_geometry_s *)((uintptr_t)arg);
if (geo) if (geo)
{ {
/* Populate the geometry structure with information need to know /* Populate the geometry structure with information need to
* the capacity and how to access the device. * know the capacity and how to access the device.
*/ */
geo->blocksize = CONFIG_RAMMTD_BLOCKSIZE; geo->blocksize = CONFIG_RAMMTD_BLOCKSIZE;
+163 -109
View File
File diff suppressed because it is too large Load Diff
+249 -169
View File
File diff suppressed because it is too large Load Diff
+95 -73
View File
@@ -1,7 +1,7 @@
/************************************************************************************ /****************************************************************************
* drivers/mtd/sector512.c * drivers/mtd/sector512.c
* MTD driver that contains another MTD driver and converts a larger sector size * MTD driver that contains another MTD driver and converts a larger sector
* to a standard 512 byte sector size. * size to a standard 512 byte sector size.
* *
* Copyright (C) 2014 Gregory Nutt. All rights reserved. * Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
@@ -33,11 +33,11 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Included Files * Included Files
************************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
@@ -57,9 +57,9 @@
#include <nuttx/fs/ioctl.h> #include <nuttx/fs/ioctl.h>
#include <nuttx/mtd/mtd.h> #include <nuttx/mtd/mtd.h>
/************************************************************************************ /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ****************************************************************************/
/* Configuration */ /* Configuration */
@@ -91,13 +91,13 @@
#define CLR_DIRTY(p) do { (p)->flags &= ~SST25_CACHE_DIRTY; } while (0) #define CLR_DIRTY(p) do { (p)->flags &= ~SST25_CACHE_DIRTY; } while (0)
#define CLR_ERASED(p) do { (p)->flags &= ~SST25_CACHE_DIRTY; } while (0) #define CLR_ERASED(p) do { (p)->flags &= ~SST25_CACHE_DIRTY; } while (0)
/************************************************************************************ /****************************************************************************
* Private Types * Private Types
************************************************************************************/ ****************************************************************************/
/* This type represents the state of the MTD device. The struct mtd_dev_s must /* This type represents the state of the MTD device. The struct mtd_dev_s
* appear at the beginning of the definition so that you can freely cast between * must appear at the beginning of the definition so that you can freely
* pointers to struct mtd_dev_s and struct s512_dev_s. * cast between pointers to struct mtd_dev_s and struct s512_dev_s.
*/ */
struct s512_dev_s struct s512_dev_s
@@ -113,9 +113,9 @@ struct s512_dev_s
FAR uint8_t *eblock; /* Allocated erase block */ FAR uint8_t *eblock; /* Allocated erase block */
}; };
/************************************************************************************ /****************************************************************************
* Private Function Prototypes * Private Function Prototypes
************************************************************************************/ ****************************************************************************/
/* Helpers */ /* Helpers */
@@ -126,26 +126,36 @@ static void s512_cacheflush(struct s512_dev_s *priv);
/* MTD driver methods */ /* MTD driver methods */
static int s512_erase(FAR struct mtd_dev_s *dev, off_t sector512, size_t nsectors); static int s512_erase(FAR struct mtd_dev_s *dev,
static ssize_t s512_bread(FAR struct mtd_dev_s *dev, off_t sector512, off_t sector512,
size_t nsectors, FAR uint8_t *buf); size_t nsectors);
static ssize_t s512_bwrite(FAR struct mtd_dev_s *dev, off_t sector512, static ssize_t s512_bread(FAR struct mtd_dev_s *dev,
size_t nsectors, FAR const uint8_t *buf); off_t sector512,
static ssize_t s512_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, size_t nsectors,
FAR uint8_t *buf);
static ssize_t s512_bwrite(FAR struct mtd_dev_s *dev,
off_t sector512,
size_t nsectors,
FAR const uint8_t *buf);
static ssize_t s512_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer); FAR uint8_t *buffer);
static int s512_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); static int s512_ioctl(FAR struct mtd_dev_s *dev,
int cmd,
unsigned long arg);
/************************************************************************************ /****************************************************************************
* Private Data * Private Data
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Private Functions * Private Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: s512_cacheread * Name: s512_cacheread
************************************************************************************/ ****************************************************************************/
static FAR uint8_t *s512_cacheread(struct s512_dev_s *priv, off_t sector512) static FAR uint8_t *s512_cacheread(struct s512_dev_s *priv, off_t sector512)
{ {
@@ -191,7 +201,9 @@ static FAR uint8_t *s512_cacheread(struct s512_dev_s *priv, off_t sector512)
CLR_ERASED(priv); /* The underlying FLASH has not been erased */ CLR_ERASED(priv); /* The underlying FLASH has not been erased */
} }
/* Get the index to the 512 sector in the erase block that holds the argument */ /* Get the index to the 512 sector in the erase block that holds the
* argument
*/
index = sector512 % priv->stdperblock; index = sector512 % priv->stdperblock;
@@ -200,9 +212,9 @@ static FAR uint8_t *s512_cacheread(struct s512_dev_s *priv, off_t sector512)
return &priv->eblock[index << SHIFT_512]; return &priv->eblock[index << SHIFT_512];
} }
/************************************************************************************ /****************************************************************************
* Name: s512_cacheflush * Name: s512_cacheflush
************************************************************************************/ ****************************************************************************/
#if !defined(CONFIG_MTD_SECT512_READONLY) #if !defined(CONFIG_MTD_SECT512_READONLY)
static void s512_cacheflush(struct s512_dev_s *priv) static void s512_cacheflush(struct s512_dev_s *priv)
@@ -239,11 +251,13 @@ static void s512_cacheflush(struct s512_dev_s *priv)
} }
#endif #endif
/************************************************************************************ /****************************************************************************
* Name: s512_erase * Name: s512_erase
************************************************************************************/ ****************************************************************************/
static int s512_erase(FAR struct mtd_dev_s *dev, off_t sector512, size_t nsectors) static int s512_erase(FAR struct mtd_dev_s *dev,
off_t sector512,
size_t nsectors)
{ {
#ifdef CONFIG_MTD_SECT512_READONLY #ifdef CONFIG_MTD_SECT512_READONLY
return -EACESS return -EACESS
@@ -258,21 +272,22 @@ static int s512_erase(FAR struct mtd_dev_s *dev, off_t sector512, size_t nsector
while (sectorsleft-- > 0) while (sectorsleft-- > 0)
{ {
/* Erase each sector. First, make sure that the erase block containing the /* Erase each sector. First, make sure that the erase block containing
* 512 byte sector is in the cache. * the 512 byte sector is in the cache.
*/ */
dest = s512_cacheread(priv, sector512); dest = s512_cacheread(priv, sector512);
if (!dest) if (!dest)
{ {
ferr("ERROR: s512_cacheread(%lu) failed\n", (unsigned long)sector512); ferr("ERROR: s512_cacheread(%lu) failed\n",
(unsigned long)sector512);
DEBUGPANIC(); DEBUGPANIC();
return -EIO; return -EIO;
} }
/* Erase the block containing this sector if it is not already erased. /* Erase the block containing this sector if it is not already erased.
* The erased indicator will be cleared when the data from the erase sector * The erased indicator will be cleared when the data from the erase
* is read into the cache and set here when we erase the block. * sector is read into the cache and set here when we erase the block.
*/ */
if (!IS_ERASED(priv)) if (!IS_ERASED(priv))
@@ -310,9 +325,9 @@ static int s512_erase(FAR struct mtd_dev_s *dev, off_t sector512, size_t nsector
#endif #endif
} }
/************************************************************************************ /****************************************************************************
* Name: s512_bread * Name: s512_bread
************************************************************************************/ ****************************************************************************/
static ssize_t s512_bread(FAR struct mtd_dev_s *dev, off_t sector512, static ssize_t s512_bread(FAR struct mtd_dev_s *dev, off_t sector512,
size_t nsectors, FAR uint8_t *buffer) size_t nsectors, FAR uint8_t *buffer)
@@ -333,7 +348,8 @@ static ssize_t s512_bread(FAR struct mtd_dev_s *dev, off_t sector512,
src = s512_cacheread(priv, sector512); src = s512_cacheread(priv, sector512);
if (!src) if (!src)
{ {
ferr("ERROR: s512_cacheread(%lu) failed\n", (unsigned long)sector512); ferr("ERROR: s512_cacheread(%lu) failed\n",
(unsigned long)sector512);
DEBUGPANIC(); DEBUGPANIC();
result = (ssize_t)nsectors - remaining; result = (ssize_t)nsectors - remaining;
@@ -345,7 +361,9 @@ static ssize_t s512_bread(FAR struct mtd_dev_s *dev, off_t sector512,
break; break;
} }
/* Copy the sector data from the erase block cache into the user buffer */ /* Copy the sector data from the erase block cache into the user
* buffer
*/
memcpy(buffer, src, SECTOR_512); memcpy(buffer, src, SECTOR_512);
@@ -356,9 +374,9 @@ static ssize_t s512_bread(FAR struct mtd_dev_s *dev, off_t sector512,
return result; return result;
} }
/************************************************************************************ /****************************************************************************
* Name: s512_bwrite * Name: s512_bwrite
************************************************************************************/ ****************************************************************************/
static ssize_t s512_bwrite(FAR struct mtd_dev_s *dev, off_t sector512, static ssize_t s512_bwrite(FAR struct mtd_dev_s *dev, off_t sector512,
size_t nsectors, size_t nsectors,
@@ -378,8 +396,8 @@ static ssize_t s512_bwrite(FAR struct mtd_dev_s *dev, off_t sector512,
for (remaining = nsectors; remaining > 0; remaining--) for (remaining = nsectors; remaining > 0; remaining--)
{ {
/* First, make sure that the erase block containing 512 byte sector is in /* First, make sure that the erase block containing 512 byte sector is
* memory. * in memory.
*/ */
dest = s512_cacheread(priv, sector512); dest = s512_cacheread(priv, sector512);
@@ -395,8 +413,8 @@ static ssize_t s512_bwrite(FAR struct mtd_dev_s *dev, off_t sector512,
} }
/* Erase the block containing this sector if it is not already erased. /* Erase the block containing this sector if it is not already erased.
* The erased indicated will be cleared when the data from the erase sector * The erased indicated will be cleared when the data from the erase
* is read into the cache and set here when we erase the sector. * sector is read into the cache and set here when we erase the sector.
*/ */
if (!IS_ERASED(priv)) if (!IS_ERASED(priv))
@@ -434,11 +452,13 @@ static ssize_t s512_bwrite(FAR struct mtd_dev_s *dev, off_t sector512,
#endif #endif
} }
/************************************************************************************ /****************************************************************************
* Name: s512_read * Name: s512_read
************************************************************************************/ ****************************************************************************/
static ssize_t s512_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes, static ssize_t s512_read(FAR struct mtd_dev_s *dev,
off_t offset,
size_t nbytes,
FAR uint8_t *buffer) FAR uint8_t *buffer)
{ {
FAR struct s512_dev_s *priv = (FAR struct s512_dev_s *)dev; FAR struct s512_dev_s *priv = (FAR struct s512_dev_s *)dev;
@@ -495,9 +515,9 @@ static ssize_t s512_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
return nbytes; return nbytes;
} }
/************************************************************************************ /****************************************************************************
* Name: s512_ioctl * Name: s512_ioctl
************************************************************************************/ ****************************************************************************/
static int s512_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg) static int s512_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
{ {
@@ -514,13 +534,14 @@ static int s512_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
((uintptr_t)arg); ((uintptr_t)arg);
if (geo) if (geo)
{ {
/* Populate the geometry structure with information need to know /* Populate the geometry structure with information need to
* the capacity and how to access the device. * know the capacity and how to access the device.
* *
* NOTE: that the device is treated as though it where just an array * NOTE:
* of fixed size blocks. That is most likely not true, but the client * that the device is treated as though it where just an
* will expect the device logic to do whatever is necessary to make it * array of fixed size blocks. That is most likely not true,
* appear so. * but the client will expect the device logic to do whatever
* is necessary to make it appear so.
*/ */
geo->blocksize = SECTOR_512; geo->blocksize = SECTOR_512;
@@ -559,23 +580,23 @@ static int s512_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
return ret; return ret;
} }
/************************************************************************************ /****************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ****************************************************************************/
/************************************************************************************ /****************************************************************************
* Name: s512_initialize * Name: s512_initialize
* *
* Description: * Description:
* Create an initialized MTD device instance. This MTD driver contains another * Create an initialized MTD device instance. This MTD driver contains
* MTD driver and converts a larger sector size to a standard 512 byte sector * another MTD driver and converts a larger sector size to a standard 512
* size. * byte sector size.
* *
* MTD devices are not registered in the file system, but are created as instances * MTD devices are not registered in the file system, but are created as
* that can be bound to other functions (such as a block or character driver front * instances that can be bound to other functions (such as a block or
* end). * character driver front end).
* *
************************************************************************************/ ****************************************************************************/
FAR struct mtd_dev_s *s512_initialize(FAR struct mtd_dev_s *mtd) FAR struct mtd_dev_s *s512_initialize(FAR struct mtd_dev_s *mtd)
{ {
@@ -595,7 +616,8 @@ FAR struct mtd_dev_s *s512_initialize(FAR struct mtd_dev_s *mtd)
if (ret < 0 || geo.erasesize <= SECTOR_512 || if (ret < 0 || geo.erasesize <= SECTOR_512 ||
(geo.erasesize & ~MASK_512) != geo.erasesize) (geo.erasesize & ~MASK_512) != geo.erasesize)
{ {
ferr("ERROR: MTDIOC_GEOMETRY ioctl returned %d, eraseize=%" PRId32 "\n", ferr(
"ERROR: MTDIOC_GEOMETRY ioctl returned %d, eraseize=%" PRId32 "\n",
ret, geo.erasesize); ret, geo.erasesize);
DEBUGPANIC(); DEBUGPANIC();
return NULL; return NULL;
@@ -604,8 +626,8 @@ FAR struct mtd_dev_s *s512_initialize(FAR struct mtd_dev_s *mtd)
/* Allocate a state structure (we allocate the structure instead of using /* Allocate a state structure (we allocate the structure instead of using
* a fixed, static allocation so that we can handle multiple FLASH devices. * a fixed, static allocation so that we can handle multiple FLASH devices.
* The current implementation would handle only one FLASH part per SPI * The current implementation would handle only one FLASH part per SPI
* device (only because of the SPIDEV_FLASH(0) definition) and so would have * device (only because of the SPIDEV_FLASH(0) definition) and so would
* to be extended to handle multiple FLASH parts on the same SPI bus. * have to be extended to handle multiple FLASH parts on the same SPI bus.
*/ */
priv = (FAR struct s512_dev_s *)kmm_zalloc(sizeof(struct s512_dev_s)); priv = (FAR struct s512_dev_s *)kmm_zalloc(sizeof(struct s512_dev_s));
+8 -6
View File
@@ -90,6 +90,7 @@ static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd,
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
/* This structure holds the state of the MTD driver */ /* This structure holds the state of the MTD driver */
static struct skel_dev_s g_skeldev = static struct skel_dev_s g_skeldev =
@@ -255,13 +256,14 @@ static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)arg; FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)arg;
if (geo) if (geo)
{ {
/* Populate the geometry structure with information needed to know /* Populate the geometry structure with information needed to
* the capacity and how to access the device. * know the capacity and how to access the device.
* *
* NOTE: that the device is treated as though it where just an array * NOTE:
* of fixed size blocks. That is most likely not true, but the client * that the device is treated as though it where just an array
* will expect the device logic to do whatever is necessary to make it * of fixed size blocks. That is most likely not true, but the
* appear so. * client will expect the device logic to do whatever is
* necessary to make it appear so.
*/ */
geo->blocksize = 512; /* Size of one read/write block */ geo->blocksize = 512; /* Size of one read/write block */
+216 -151
View File
File diff suppressed because it is too large Load Diff
+134 -101
View File
File diff suppressed because it is too large Load Diff
+205 -151
View File
File diff suppressed because it is too large Load Diff
+248 -178
View File
File diff suppressed because it is too large Load Diff