diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index b3a4dd7c06..3a3b8b7709 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -266,7 +266,7 @@ config RAMMTD_FLASHSIM RAMMTD_FLASHSIM will add some extra logic to improve the level of FLASH simulation. -endif +endif # RAMMTD config FILEMTD bool "File-based MTD driver" @@ -288,7 +288,7 @@ config FILEMTD_ERASESTATE hex "Simulated erase state" default 0xff -endif +endif # FILEMTD config MTD_AT24XX bool "I2C-based AT24xx eeprom" @@ -353,11 +353,11 @@ config AT24XX_FREQUENCY int "AT24xx I2C bus frequency" default 100000 ---help--- - Set the I2C frequency to use when accessing the AT24CXX EEPROM. This value - must represent a valid I2C speed (normally less than 400.000) or the driver - might fail. + Set the I2C frequency to use when accessing the AT24CXX EEPROM. This value + must represent a valid I2C speed (normally less than 400.000) or the driver + might fail. -endif +endif # MTD_AT24XX config MTD_AT25 bool "SPI-based AT25 FLASH" @@ -374,7 +374,7 @@ config AT25_SPIFREQUENCY int "AT25 SPI Frequency" default 20000000 -endif +endif # MTD_AT25 config MTD_AT45DB bool "SPI-based AT45DB flash" @@ -395,7 +395,7 @@ config AT45DB_PWRSAVE bool "Enable power save" default n -endif +endif # MTD_AT45DB config MTD_M25P bool "SPI-based M25P FLASH" @@ -437,7 +437,7 @@ config M25P_SUBSECTOR_ERASE size (4K vs 64K). This option enables support for sub-sector erase. The SMART file system can take advantage of this option if it is enabled. -endif +endif # MTD_M25P config MTD_S25FL1 bool "QuadSPI-based S25FL1 FLASH" @@ -489,7 +489,7 @@ config S25FL1_SCRAMBLE_KEY default 0x0baddead depends on S25FL1_SCRAMBLE -endif +endif # MTD_S25FL1 config MTD_N25QXXX bool "QuadSPI-based Micron N25QXXX family FLASH" @@ -519,7 +519,7 @@ config N25QXXX_SECTOR512 bool "Simulate 512 byte Erase Blocks" default n -endif +endif # MTD_N25QXXX config MTD_SMART bool "Sector Mapped Allocation for Really Tiny (SMART) Flash support" @@ -583,7 +583,7 @@ config MTD_SMART_CONVERT_WEAR_FORMAT CRC versions use a different header format and require a mksmartfs on the device even if an existing format is there. -endif +endif # MTD_SMART_WEAR_LEVEL && !SMART_CRC_16 config MTD_SMART_ENABLE_CRC bool "Enable Sector CRC error detection" @@ -618,7 +618,7 @@ config SMART_CRC_8 config SMART_CRC_16 bool "CRC-16" -endchoice +endchoice # CRC level selection config MTD_SMART_MINIMIZE_RAM bool "Minimize SMART RAM usage using logical sector cache" @@ -706,7 +706,7 @@ config RAMTRON_SETSPEED Select an option to provide an ioctl, MTDIOC_SETSPEED call that supports dynamic selection of the RAMTRON bus speed. -endif +endif # MTD_RAMTRON config MTD_SST25 bool "SPI-based SST25 FLASH" @@ -745,7 +745,7 @@ config SST25_SLOWREAD bool default n -endif +endif # MTD_SST25 config MTD_SST25XX bool "SPI-based SST25XX FLASH (64-MBit and larger)" @@ -781,7 +781,7 @@ config SST25XX_MEMORY_TYPE The memory type for SST25VF065 series is 0x25, but this can be modified if needed to support compatible devices from different manufacturers. -endif +endif # MTD_SST25XX config MTD_SST39FV bool "SST39FV NOR FLASH" @@ -800,7 +800,7 @@ config SST39VF_BASE_ADDRESS ---help--- This is the address where the SST29VF FLASH can be found in memory. -endif +endif # MTD_SST39FV config MTD_W25 bool "SPI-based W25 FLASH" @@ -829,4 +829,4 @@ config W25_SLOWREAD bool default n -endif +endif # MTD_W25 diff --git a/drivers/mtd/Make.defs b/drivers/mtd/Make.defs index 4bbd1eb1ff..a3a6eb7f20 100644 --- a/drivers/mtd/Make.defs +++ b/drivers/mtd/Make.defs @@ -3,7 +3,7 @@ # These driver supports various Memory Technology Devices (MTD) using the # NuttX MTD interface. # -# Copyright (C) 2009-2013, 2015 Gregory Nutt. All rights reserved. +# Copyright (C) 2009-2013, 2015-2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without diff --git a/drivers/mtd/n25qxxx.c b/drivers/mtd/n25qxxx.c index 31bab580d2..d79f2877b9 100644 --- a/drivers/mtd/n25qxxx.c +++ b/drivers/mtd/n25qxxx.c @@ -2,7 +2,7 @@ * drivers/mtd/n25qxxx.c * Driver for QuadSPI-based N25QxxxA * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: dev@ziggurat29.com * * Redistribution and use in source and binary forms, with or without @@ -59,6 +59,7 @@ /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ + /* Configuration ********************************************************************/ /* QuadSPI Mode. Per data sheet, either Mode 0 or Mode 3 may be used. */ @@ -66,23 +67,22 @@ # define CONFIG_N25QXXX_QSPIMODE QSPIDEV_MODE0 #endif -/* QuadSPI Frequency per data sheet:: - * +/* QuadSPI Frequency per data sheet: * * In this implementation, only "Quad" reads are performed. */ #ifndef CONFIG_N25QXXX_QSPI_FREQUENCY -/* if you haven't specified frequency, default to 40 MHz which will work with all - commands. +/* If you haven't specified frequency, default to 40 MHz which will work with all + * commands. */ # define CONFIG_N25QXXX_QSPI_FREQUENCY 40000000 #endif #ifndef CONFIG_N25QXXX_DUMMIES -/* if you haven't specified the number of dummy cycles for quad reads, provide a - reasonable default. The actual number of dummies needed is clock and IO command - dependent. +/* If you haven't specified the number of dummy cycles for quad reads, provide a + * reasonable default. The actual number of dummies needed is clock and IO command + * dependent. */ # define CONFIG_N25QXXX_DUMMIES 6 #endif @@ -175,10 +175,11 @@ /* Chip Geometries ******************************************************************/ /* All members of the family support uniform 4K-byte 'sub sectors'; they also support - 64k (and sometimes 32k) 'sectors' proper, but we won't be using those here. + * 64k (and sometimes 32k) 'sectors' proper, but we won't be using those here. */ /* N25Q016 (2 MB) memory capacity */ + #define N25Q016_SECTOR_SIZE (4*1024) #define N25Q016_SECTOR_SHIFT (12) #define N25Q016_SECTOR_COUNT (512) @@ -186,6 +187,7 @@ #define N25Q016_PAGE_SHIFT (8) /* N25Q032 (4 MB) memory capacity */ + #define N25Q032_SECTOR_SIZE (4*1024) #define N25Q032_SECTOR_SHIFT (12) #define N25Q032_SECTOR_COUNT (1024) @@ -193,6 +195,7 @@ #define N25Q032_PAGE_SHIFT (8) /* N25Q064 (8 MB) memory capacity */ + #define N25Q064_SECTOR_SIZE (4*1024) #define N25Q064_SECTOR_SHIFT (12) #define N25Q064_SECTOR_COUNT (2048) @@ -200,6 +203,7 @@ #define N25Q064_PAGE_SHIFT (8) /* N25Q128 (16 MB) memory capacity */ + #define N25Q128_SECTOR_SIZE (4*1024) #define N25Q128_SECTOR_SHIFT (12) #define N25Q128_SECTOR_COUNT (4096) @@ -207,6 +211,7 @@ #define N25Q128_PAGE_SHIFT (8) /* N25Q256 (32 MB) memory capacity */ + #define N25Q256_SECTOR_SIZE (4*1024) #define N25Q256_SECTOR_SHIFT (12) #define N25Q256_SECTOR_COUNT (8196) @@ -214,6 +219,7 @@ #define N25Q256_PAGE_SHIFT (8) /* N25Q512 (64 MB) memory capacity */ + #define N25Q512_SECTOR_SIZE (4*1024) #define N25Q512_SECTOR_SHIFT (12) #define N25Q512_SECTOR_COUNT (16384) @@ -221,6 +227,7 @@ #define N25Q512_PAGE_SHIFT (8) /* N25Q00 (128 MB) memory capacity */ + #define N25Q00_SECTOR_SIZE (4*1024) #define N25Q00_SECTOR_SHIFT (12) #define N25Q00_SECTOR_COUNT (32768) @@ -233,17 +240,17 @@ #define N25QXXX_CACHE_DIRTY (1 << 1) /* 1=Cache is dirty */ #define N25QXXX_CACHE_ERASED (1 << 2) /* 1=Backing FLASH is erased */ -#define IS_VALID(p) ((((p)->flags) & N25QXXX_CACHE_VALID) != 0) -#define IS_DIRTY(p) ((((p)->flags) & N25QXXX_CACHE_DIRTY) != 0) -#define IS_ERASED(p) ((((p)->flags) & N25QXXX_CACHE_DIRTY) != 0) +#define IS_VALID(p) ((((p)->flags) & N25QXXX_CACHE_VALID) != 0) +#define IS_DIRTY(p) ((((p)->flags) & N25QXXX_CACHE_DIRTY) != 0) +#define IS_ERASED(p) ((((p)->flags) & N25QXXX_CACHE_DIRTY) != 0) -#define SET_VALID(p) do { (p)->flags |= N25QXXX_CACHE_VALID; } while (0) -#define SET_DIRTY(p) do { (p)->flags |= N25QXXX_CACHE_DIRTY; } while (0) -#define SET_ERASED(p) do { (p)->flags |= N25QXXX_CACHE_DIRTY; } while (0) +#define SET_VALID(p) do { (p)->flags |= N25QXXX_CACHE_VALID; } while (0) +#define SET_DIRTY(p) do { (p)->flags |= N25QXXX_CACHE_DIRTY; } while (0) +#define SET_ERASED(p) do { (p)->flags |= N25QXXX_CACHE_DIRTY; } while (0) -#define CLR_VALID(p) do { (p)->flags &= ~N25QXXX_CACHE_VALID; } while (0) -#define CLR_DIRTY(p) do { (p)->flags &= ~N25QXXX_CACHE_DIRTY; } while (0) -#define CLR_ERASED(p) do { (p)->flags &= ~N25QXXX_CACHE_DIRTY; } while (0) +#define CLR_VALID(p) do { (p)->flags &= ~N25QXXX_CACHE_VALID; } while (0) +#define CLR_DIRTY(p) do { (p)->flags &= ~N25QXXX_CACHE_DIRTY; } while (0) +#define CLR_ERASED(p) do { (p)->flags &= ~N25QXXX_CACHE_DIRTY; } while (0) /* 512 byte sector support **********************************************************/ @@ -335,10 +342,6 @@ static ssize_t n25qxxx_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt FAR uint8_t *buffer); static int n25qxxx_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg); -/************************************************************************************ - * Private Data - ************************************************************************************/ - /************************************************************************************ * Private Functions ************************************************************************************/ @@ -354,15 +357,16 @@ static void n25qxxx_lock(FAR struct qspi_dev_s *qspi) * 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 - * the QuadSPI buss. We will retain that exclusive access until the bus is unlocked. + * the QuadSPI buss. We will retain that exclusive access until the bus is + * unlocked. */ (void)QSPI_LOCK(qspi, true); - /* After locking the QuadSPI bus, the we also need call the setfrequency, setbits, and - * setmode methods to make sure that the QuadSPI is properly configured for the device. - * If the QuadSPI buss is being shared, then it may have been left in an incompatible - * state. + /* After locking the QuadSPI bus, the we also need call the setfrequency, setbits, + * and setmode methods to make sure that the QuadSPI is properly configured for + * the device. If the QuadSPI buss is being shared, then it may have been left in + * an incompatible state. */ QSPI_SETMODE(qspi, CONFIG_N25QXXX_QSPIMODE); @@ -480,11 +484,11 @@ static uint8_t n25qxxx_read_status(FAR struct n25qxxx_dev_s *priv) static void n25qxxx_write_status(FAR struct n25qxxx_dev_s *priv) { n25qxxx_write_enable(priv); - + /* take care to mask of the SRP bit; it is one-time-programmable */ - + priv->cmdbuf[0] &= ~STATUS_SRP0_MASK; - + n25qxxx_command_write(priv->qspi, N25QXXX_WRITE_STATUS, (FAR const void *)priv->cmdbuf, 1); n25qxxx_write_disable(priv); @@ -584,31 +588,37 @@ static inline int n25qxxx_readid(struct n25qxxx_dev_s *priv) priv->pageshift = N25Q016_PAGE_SHIFT; priv->nsectors = N25Q016_SECTOR_COUNT; break; + case N25Q032_JEDEC_CAPACITY: priv->sectorshift = N25Q032_SECTOR_SHIFT; priv->pageshift = N25Q032_PAGE_SHIFT; priv->nsectors = N25Q032_SECTOR_COUNT; break; + case N25Q064_JEDEC_CAPACITY: priv->sectorshift = N25Q064_SECTOR_SHIFT; priv->pageshift = N25Q064_PAGE_SHIFT; priv->nsectors = N25Q064_SECTOR_COUNT; break; + case N25Q128_JEDEC_CAPACITY: priv->sectorshift = N25Q128_SECTOR_SHIFT; priv->pageshift = N25Q128_PAGE_SHIFT; priv->nsectors = N25Q128_SECTOR_COUNT; break; + case N25Q256_JEDEC_CAPACITY: priv->sectorshift = N25Q256_SECTOR_SHIFT; priv->pageshift = N25Q256_PAGE_SHIFT; priv->nsectors = N25Q256_SECTOR_COUNT; break; + case N25Q512_JEDEC_CAPACITY: priv->sectorshift = N25Q512_SECTOR_SHIFT; priv->pageshift = N25Q512_PAGE_SHIFT; priv->nsectors = N25Q512_SECTOR_COUNT; break; + case N25Q00_JEDEC_CAPACITY: priv->sectorshift = N25Q00_SECTOR_SHIFT; priv->pageshift = N25Q00_PAGE_SHIFT; @@ -658,13 +668,14 @@ static int n25qxxx_protect(FAR struct n25qxxx_dev_s *priv, * necessary to protect the range of sectors. */ - priv->cmdbuf[0] |= (STATUS_BP3_MASK|STATUS_BP_MASK); + priv->cmdbuf[0] |= (STATUS_BP3_MASK | STATUS_BP_MASK); n25qxxx_write_status(priv); /* Check the new status */ priv->cmdbuf[0] = n25qxxx_read_status(priv); - if ((priv->cmdbuf[0] & (STATUS_BP3_MASK|STATUS_BP_MASK)) != (STATUS_BP3_MASK|STATUS_BP_MASK)) + if ((priv->cmdbuf[0] & (STATUS_BP3_MASK | STATUS_BP_MASK)) != + (STATUS_BP3_MASK | STATUS_BP_MASK)) { return -EACCES; } @@ -695,8 +706,9 @@ static int n25qxxx_unprotect(FAR struct n25qxxx_dev_s *priv, if ((priv->cmdbuf[0] & STATUS_SRP0_MASK) == STATUS_SRP0_LOCKED) { /* the SRP bit is one time programmable; if it's set, there's nothing that - you can do to unset it. + * you can do to unset it. */ + return -EACCES; } @@ -715,7 +727,7 @@ static int n25qxxx_unprotect(FAR struct n25qxxx_dev_s *priv, { return -EACCES; } - + return OK; } @@ -738,11 +750,11 @@ static bool n25qxxx_isprotected(FAR struct n25qxxx_dev_s *priv, uint8_t status, { bp |= 8; } - + /* the BP field is essentially the power-of-two of the number of 64k sectors, - saturated to the device size. + * saturated to the device size. */ - + if ( 0 == bp ) { return false; @@ -1215,8 +1227,6 @@ static ssize_t n25qxxx_bread(FAR struct mtd_dev_s *dev, off_t startblock, #endif return nbytes; - -return 0; } /************************************************************************************ @@ -1254,8 +1264,6 @@ static ssize_t n25qxxx_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, n25qxxx_unlock(priv->qspi); return ret < 0 ? ret : nblocks; - -return 0; } /************************************************************************************ @@ -1284,8 +1292,6 @@ static ssize_t n25qxxx_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt fvdbg("return nbytes: %d\n", (int)nbytes); return (ssize_t)nbytes; - -return 0; } /************************************************************************************ @@ -1448,8 +1454,10 @@ FAR struct mtd_dev_s *n25qxxx_initialize(FAR struct qspi_dev_s *qspi, bool unpro goto errout_with_readbuf; } - /* specify the number of dummy cycles via the 'volatile configuration register' */ - + /* Specify the number of dummy cycles via the 'volatile configuration + * register' + */ + priv->cmdbuf[0] = n25qxxx_read_volcfg(priv); priv->cmdbuf[0] &= 0x0f; priv->cmdbuf[0] |= (CONFIG_N25QXXX_DUMMIES<<4); diff --git a/include/nuttx/mtd/mtd.h b/include/nuttx/mtd/mtd.h index bd41688c35..80b1c4215d 100644 --- a/include/nuttx/mtd/mtd.h +++ b/include/nuttx/mtd/mtd.h @@ -524,7 +524,7 @@ FAR struct mtd_dev_s *s25fl1_initialize(FAR struct qspi_dev_s *qspi, struct qspi_dev_s; /* Forward reference */ FAR struct mtd_dev_s *n25qxxx_initialize(FAR struct qspi_dev_s *qspi, - bool unprotect); + bool unprotect); /**************************************************************************** * Name: up_flashinitialize