Create an MTD driver for SPIFI

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4951 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-07-18 18:38:49 +00:00
parent a7a040f6ec
commit 56f50d59fc
7 changed files with 990 additions and 229 deletions

View File

@ -3017,5 +3017,9 @@
RTC alarm EXTI interrupt. This is work be performed mostly by Diego Sanchez. RTC alarm EXTI interrupt. This is work be performed mostly by Diego Sanchez.
* include/: More stylistic file clean-up. * include/: More stylistic file clean-up.
* arch/arm/src/lpc43xx/lpc43_spifi.c, lpc43_spifi.h, and chip/lpc43_spifi.h: Add * arch/arm/src/lpc43xx/lpc43_spifi.c, lpc43_spifi.h, and chip/lpc43_spifi.h: Add
logic to configure and intialize the SPIFI device (does not yet work). logic to configure and initialize the SPIFI device (does not yet work).
* configs/lpc4330-xplorer/include/board.h: Reduce SPI SCLK value.
* arch/arm/src/lpc43xx/lpc43_spifi.c, lpc43_spifi.h, and chip/lpc43_spifi.h:
Logic completely redesigned. It now creates an MTD driver to access SPIFI...
but the driver still does not work.

View File

@ -92,24 +92,24 @@
* have the same relationship as in the Control register) * have the same relationship as in the Control register)
*/ */
#define SPIFI_MODE3 (1 << 0) #define S_MODE3 (1 << 0)
#define SPIFI_MODE0 (0) #define S_MODE0 (0)
#define SPIFI_MINIMAL (1 << 1) #define S_MINIMAL (1 << 1)
#define SPIFI_MAXIMAL (0) #define S_MAXIMAL (0)
#define SPIFI_FORCE_ERASE (1 << 2) #define S_FORCE_ERASE (1 << 2)
#define SPIFI_ERASE_NOT_REQD (1 << 3) #define S_ERASE_NOT_REQD (1 << 3)
#define SPIFI_CALLER_ERASE (1 << 3) #define S_CALLER_ERASE (1 << 3)
#define SPIFI_ERASE_AS_REQD (0) #define S_ERASE_AS_REQD (0)
#define SPIFI_VERIFY_PROG (1 << 4) #define S_VERIFY_PROG (1 << 4)
#define SPIFI_VERIFY_ERASE (1 << 5) #define S_VERIFY_ERASE (1 << 5)
#define SPIFI_NO_VERIFY (0) #define S_NO_VERIFY (0)
#define SPIFI_FULLCLK (1 << 6) #define S_FULLCLK (1 << 6)
#define SPIFI_HALFCLK (0) #define S_HALFCLK (0)
#define SPIFI_RCVCLK (1 << 7) #define S_RCVCLK (1 << 7)
#define SPIFI_INTCLK (0) #define S_INTCLK (0)
#define SPIFI_DUAL (1 << 8) #define S_DUAL (1 << 8)
#define SPIFI_CALLER_PROT (1 << 9) #define S_CALLER_PROT (1 << 9)
#define SPIFI_DRIVER_PROT (0) #define S_DRIVER_PROT (0)
/* The length of a standard program command is 256 on all devices */ /* The length of a standard program command is 256 on all devices */
@ -178,9 +178,9 @@ struct spifi_dev_s
struct spifi_operands_s struct spifi_operands_s
{ {
char *dest; uint8_t *dest;
uint32_t length; uint32_t length;
char *scratch; uint8_t *scratch;
int32_t protect; int32_t protect;
uint32_t options; uint32_t options;
}; };
@ -191,7 +191,7 @@ struct spifi_driver_s
{ {
int32_t (*spifi_init)(struct spifi_dev_s *dev, uint32_t cshigh, int32_t (*spifi_init)(struct spifi_dev_s *dev, uint32_t cshigh,
uint32_t options, uint32_t mhz); uint32_t options, uint32_t mhz);
int32_t (*spifi_program)(struct spifi_dev_s *dev, char *source, int32_t (*spifi_program)(struct spifi_dev_s *dev, const uint8_t *source,
struct spifi_operands_s *opers); struct spifi_operands_s *opers);
int32_t (*spifi_erase)(struct spifi_dev_s *dev, int32_t (*spifi_erase)(struct spifi_dev_s *dev,
struct spifi_operands_s *opers); struct spifi_operands_s *opers);
@ -206,16 +206,16 @@ struct spifi_driver_s
int32_t (*checkAd)(struct spifi_dev_s *dev, int32_t (*checkAd)(struct spifi_dev_s *dev,
struct spifi_operands_s *opers); struct spifi_operands_s *opers);
int32_t (*setProt)(struct spifi_dev_s *dev, int32_t (*setProt)(struct spifi_dev_s *dev,
struct spifi_operands_s *opers, char *change, char *saveprot); struct spifi_operands_s *opers, uint8_t *change, uint8_t *saveprot);
int32_t (*check_block) (struct spifi_dev_s *dev, char *source, int32_t (*check_block) (struct spifi_dev_s *dev, uint8_t *source,
struct spifi_operands_s *opers, uint32_t check_program); struct spifi_operands_s *opers, uint32_t check_program);
int32_t (*send_erase_cmd)(struct spifi_dev_s *dev, uint8_t op, int32_t (*send_erase_cmd)(struct spifi_dev_s *dev, uint8_t op,
uint32_t addr); uint32_t addr);
uint32_t (*ck_erase) (struct spifi_dev_s *dev, uint32_t *addr, uint32_t (*ck_erase) (struct spifi_dev_s *dev, uint32_t *addr,
uint32_t length); uint32_t length);
int32_t (*prog_block)(struct spifi_dev_s *dev, char *source, int32_t (*prog_block)(struct spifi_dev_s *dev, uint8_t *source,
struct spifi_operands_s *opers, uint32_t *left_in_page); struct spifi_operands_s *opers, uint32_t *left_in_page);
uint32_t (*ck_prog)(struct spifi_dev_s *dev, char *source, char *dest, uint32_t (*ck_prog)(struct spifi_dev_s *dev, uint8_t *source, uint8_t *dest,
uint32_t length); uint32_t length);
/* Low level functions */ /* Low level functions */

File diff suppressed because it is too large Load Diff

View File

@ -41,6 +41,7 @@
****************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/mtd.h>
#include "chip.h" #include "chip.h"
#include "chip/lpc43_spifi.h" #include "chip/lpc43_spifi.h"
@ -50,6 +51,33 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* SPIFI Configuration ******************************************************/
/* This logic supports some special options that can be used to create an
* MTD device on the SPIFI FLASH.
*
* CONFIG_LPC43_SPIFI - Enable SPIFI support
*
* SPIFI device geometry:
*
* CONFIG_SPIFI_OFFSET - Offset the beginning of the block driver this many
* bytes into the device address space. This offset must be an exact
* multiple of the erase block size (CONFIG_SPIFI_BLKSIZE). Default 0.
* CONFIG_SPIFI_BLKSIZE - The size of one device erase block. If not defined
* then the driver will try to determine the correct erase block size by
* examining that data returned from spifi_initialize (which sometimes
* seems bad).
*
* Other SPIFI options
*
* CONFIG_SPIFI_SECTOR512 - If defined, then the driver will report a more
* FAT friendly 512 byte sector size and will manage the read-modify-write
* operations on the larger erase block.
* CONFIG_SPIFI_READONLY - Define to support only read-only operations.
*/
#ifndef CONFIG_SPIFI_OFFSET
# define CONFIG_SPIFI_OFFSET 0
#endif
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
@ -63,21 +91,26 @@
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Function: lpc43_spifi_initialize * Name: lpc43_spifi_initialize
* *
* Description: * Description:
* Initialize the SPIFI interface per settings in the board.h file * Create an initialized MTD device instance for the SPIFI device. MTD
* devices are not registered 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).
*
* SPIFI interface clocking is configured per settings in the board.h file.
* *
* Input Parameters: * Input Parameters:
* None * None
* *
* Returned Value: * Returned value:
* Zero is returned on success; on failure, a negated errno value is * One success, a reference to the initialized MTD device instance is
* returned. * returned; NULL is returned on any failure.
* *
****************************************************************************/ ****************************************************************************/
int lpc43_spifi_initialize(void); FAR struct mtd_dev_s *lpc43_spifi_initialize(void);
#endif /* CONFIG_LPC43_SPIFI */ #endif /* CONFIG_LPC43_SPIFI */
#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_SPIFI_H */ #endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_SPIFI_H */

View File

@ -903,22 +903,20 @@ Where <subdir> is one of the following:
This configuration has some special options that can be used to This configuration has some special options that can be used to
create a block device on the SPIFI FLASH. NOTE: CONFIG_LPC43_SPIFI=y create a block device on the SPIFI FLASH. NOTE: CONFIG_LPC43_SPIFI=y
must also be defined to enable SPIFI setup support: must also be defined to enable SPIFI setup support:
CONFIG_SPIFI_BLKDRVR - Enable to create a block driver on the SPFI SPIFI device geometry:
device.
CONFIG_SPIFI_DEVNO - SPIFI minor device number. The SPFI device will CONFIG_SPIFI_OFFSET - Offset the beginning of the block driver this many
be at /dev/ramN, where N is the value of CONFIG_SPIFI_DEVNO. bytes into the device address space. This offset must be an exact
Default: 0. multiple of the erase block size (CONFIG_SPIFI_BLKSIZE). Default 0.
CONFIG_SPIFI_RDONLY - Create a read only device on SPIFI. CONFIG_SPIFI_BLKSIZE - The size of one device erase block. If not defined
CONFIG_SPIFI_OFFSET - Offset the beginning of the block driver this then the driver will try to determine the correct erase block size by
many bytes into the device address space. Default 0. examining that data returned from spifi_initialize (which sometimes
CONFIG_SPIFI_BLKSIZE - The size of one block. SPIFI is not block seems bad).
oriented, so most any size of the block used in the SPIFI block
device can be used. NOTE: FAT will support only sector sizes of Other SPIFI options
512, 1024, 2048, or 4096. Default: 512
CONFIG_SPIFI_NBLOCKS - The number of blocks in the file system, CONFIG_SPIFI_SECTOR512 - If defined, then the driver will report a more
each of size CONFIG_SPIFI_BLKSIZE. The end of the file system FAT friendly 512 byte sector size and will manage the read-modify-write
will be at device offset: operations on the larger erase block.
CONFIG_SPIFI_OFFSET + CONFIG_SPIFI_BLKSIZE*CONFIG_SPIFI_NBLOCKS CONFIG_SPIFI_READONLY - Define to support only read-only operations.
The must assure that this does offset does not go beyond the end
of the FLASH memory.

View File

@ -658,35 +658,31 @@ CONFIG_MMCSD_MMCSUPPORT=n
CONFIG_MMCSD_HAVECARDDETECT=n CONFIG_MMCSD_HAVECARDDETECT=n
# #
# This configuration has some special options that can be used to # The SPIFI drvier has some special options that can be used to
# create a block device on the SPIFI FLASH. NOTE: CONFIG_LPC43_SPIFI=y # create an MTD device on the SPIFI FLASH. NOTE: CONFIG_LPC43_SPIFI=y
# must also be defined to enable SPIFI setup support: # must also be defined to enable SPIFI setup support:
# #
# CONFIG_SPIFI_BLKDRVR - Enable to create a block driver on the SPFI # SPIFI device geometry:
# device. #
# CONFIG_SPIFI_DEVNO - SPIFI minor device number. The SPFI device will # CONFIG_SPIFI_OFFSET - Offset the beginning of the block driver this many
# be at /dev/rdN, where N is the value of CONFIG_SPIFI_DEVNO. # bytes into the device address space. This offset must be an exact
# Default: 0. # multiple of the erase block size (CONFIG_SPIFI_BLKSIZE). Default 0.
# CONFIG_SPIFI_RDONLY - Create a read only device on SPIFI. # CONFIG_SPIFI_BLKSIZE - The size of one device erase block. If not defined
# CONFIG_SPIFI_OFFSET - Offset the beginning of the block driver this # then the driver will try to determine the correct erase block size by
# many bytes into the device address space. Default 0. # examining that data returned from spifi_initialize (which sometimes
# CONFIG_SPIFI_BLKSIZE - The size of one block. SPIFI is not block # seems bad).
# oriented, so most any size of the block used in the SPIFI block #
# device can be used. NOTE: FAT will support only sector sizes of 512, # Other SPIFI options
# 1024, 2048, or 4096. Default: 512 #
# CONFIG_SPIFI_NBLOCKS - The number of blocks in the file system, # CONFIG_SPIFI_SECTOR512 - If defined, then the driver will report a more
# each of size CONFIG_SPIFI_BLKSIZE. The end of the file system # FAT friendly 512 byte sector size and will manage the read-modify-write
# will be at device offset: # operations on the larger erase block.
# CONFIG_SPIFI_OFFSET + CONFIG_SPIFI_BLKSIZE*CONFIG_SPIFI_NBLOCKS # CONFIG_SPIFI_READONLY - Define to support only read-only operations.
# The must assure that this does offset does not go beyond the end
# of the FLASH memory.
# #
CONFIG_SPIFI_BLKDRVR=n
CONFIG_SPIFI_DEVNO=0
CONFIG_SPIFI_RDONLY=n
CONFIG_SPIFI_OFFSET=0 CONFIG_SPIFI_OFFSET=0
CONFIG_SPIFI_BLKSIZE=512 CONFIG_SPIFI_BLKSIZE=4096
CONFIG_SPIFI_NBLOCKS=(1024*1024/512) CONFIG_SPIFI_SECTOR512=y
CONFIG_SPIFI_RDONLY=n
# TCP/IP and UDP support via uIP # TCP/IP and UDP support via uIP
# CONFIG_NET - Enable or disable all network features # CONFIG_NET - Enable or disable all network features

View File

@ -44,89 +44,25 @@
#include <debug.h> #include <debug.h>
#include <errno.h> #include <errno.h>
#include <nuttx/ramdisk.h>
#include "chip.h" #include "chip.h"
#ifdef CONFIG_SPIFI_BLKDRVR #ifdef CONFIG_LPC43_SPIFI
# include <nuttx/mtd.h>
# include "lpc43_spifi.h" # include "lpc43_spifi.h"
/* This should be removed someday when we are confident in SPIFI */ # ifdef CONFIG_SPFI_NXFFS
# include <sys/mount.h>
# ifdef CONFIG_DEBUG_FS # include <nuttx/fs/nxffs.h>
# include "up_arch.h"
# include "chip/lpc43_cgu.h"
# include "chip/lpc43_ccu.h"
# endif # endif
#endif #endif
/**************************************************************************** /****************************************************************************
* Pre-Processor Definitions * Pre-Processor Definitions
****************************************************************************/ ****************************************************************************/
/* SPIFI Configuration ******************************************************/ /* Configuration ************************************************************/
/* This logic supports some special options that can be used to create a
* block device on the SPIFI FLASH. NOTE: CONFIG_LPC43_SPIFI=y must also
* be defined to enable SPIFI setup support:
*
* CONFIG_SPIFI_BLKDRVR - Enable to create a block driver on the SPFI device.
* CONFIG_SPIFI_DEVNO - SPIFI minor device number. The SPFI device will be
* at /dev/ramN, where N is the value of CONFIG_SPIFI_DEVNO. Default: 0.
* CONFIG_SPIFI_RDONLY - Create a read only device on SPIFI.
* CONFIG_SPIFI_OFFSET - Offset the beginning of the block driver this many
* bytes into the device address space. Default 0.
* CONFIG_SPIFI_BLKSIZE - The size of one block. SPIFI is not block oriented,
* so most any size of the block used in the SPIFI block device can be
* used. NOTE: FAT will support only sector sizes of 512, 1024, 2048, or
* 4096. Default: 512
* CONFIG_SPIFI_NBLOCKS - The number of blocks in the file system, each of
* size CONFIG_SPIFI_BLKSIZE. The end of the file system will be at
* device offset:
* CONFIG_SPIFI_OFFSET + CONFIG_SPIFI_BLKSIZE*CONFIG_SPIFI_NBLOCKS
* The must assure that this does offset does not go beyond the end of
* the FLASH memory.
*/
#ifdef CONFIG_SPIFI_BLKDRVR #ifndef CONFIG_SPIFI_DEVNO
# define CONFIG_SPIFI_DEVNO 0
# ifndef CONFIG_LPC43_SPIFI
# error "SPIFI support is not enabled (CONFIG_LPC43_SPIFI)"
# endif
# ifndef CONFIG_SPIFI_DEVNO
# define CONFIG_SPIFI_DEVNO 0
# endif
# ifndef CONFIG_SPIFI_OFFSET
# define CONFIG_SPIFI_OFFSET 0
# endif
# ifndef CONFIG_SPIFI_BLKSIZE
# define CONFIG_SPIFI_BLKSIZE 512
# endif
# ifndef CONFIG_SPIFI_NBLOCKS
# error "Need number of SPIFI blocks (CONFIG_SPIFI_NBLOCKS)"
# endif
# define SPIFI_BUFFER \
(FAR uint8_t *)(LPC43_LOCSRAM_SPIFI_BASE + CONFIG_SPIFI_OFFSET)
#endif
/* Debug ********************************************************************/
#ifdef CONFIG_CPP_HAVE_VARARGS
# ifdef CONFIG_DEBUG
# define message(...) lib_lowprintf(__VA_ARGS__)
# else
# define message(...) printf(__VA_ARGS__)
# endif
#else
# ifdef CONFIG_DEBUG
# define message lib_lowprintf
# else
# define message printf
# endif
#endif #endif
/**************************************************************************** /****************************************************************************
@ -140,56 +76,53 @@
* Make the SPIFI (or part of it) into a block driver that can hold a * Make the SPIFI (or part of it) into a block driver that can hold a
* file system. * file system.
* *
* SPIFI AHB register clock:
* Base clock = BASE_M4_CLK
* Branch clock = CLK_M4_SPIFI
* SPIFI serial clock input:
* Base clock = BASE_SPIFI_CLK
* Branch clock = SPIFI_CLK
*
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_SPIFI_BLKDRVR #ifdef CONFIG_LPC43_SPIFI
static int nsh_spifi_initialize(void) static int nsh_spifi_initialize(void)
{ {
FAR struct mtd_dev_s *mtd;
int ret; int ret;
/* Initialize the SPIFI interface */ /* Initialize the SPIFI interface and create the MTD driver instance */
ret = lpc43_spifi_initialize(); mtd = lpc43_spifi_initialize();
if (!mtd)
{
fdbg("ERROR: lpc43_spifi_initialize failed\n");
return -ENODEV;
}
#ifndef CONFIG_SPFI_NXFFS
/* And finally, use the FTL layer to wrap the MTD driver as a block driver */
ret = ftl_initialize(CONFIG_SPIFI_DEVNO, mtd);
if (ret < 0) if (ret < 0)
{ {
fdbg("ERROR: lpc43_spifi_initialize failed: %d\n", ret); fdbg("ERROR: Initializing the FTL layer: %d\n", ret);
return ret;
}
#else
/* Initialize to provide NXFFS on the MTD interface */1G
ret = nxffs_initialize(mtd);
if (ret < 0)
{
fdbg("ERROR: NXFFS initialization failed: %d\n", ret);
return ret; return ret;
} }
/* This should be removed someday when we are confident in SPIFI */ /* Mount the file system at /mnt/spifi */
#ifdef CONFIG_DEBUG_FS ret = mount(NULL, "/mnt/spifi", "nxffs", 0, NULL);
fdbg("BASE_SPIFI_CLK=%08x\n", if (ret < 0)
getreg32(LPC43_BASE_SPIFI_CLK)); {
fdbg("SPFI CFG=%08x STAT=%08x\n", fdbg("ERROR: Failed to mount the NXFFS volume: %d\n", errno);
getreg32(LPC43_CCU1_SPIFI_CFG), getreg32(LPC43_CCU1_SPIFI_STAT)); return ret;
fdbg("M4 SPFI CFG=%08x STAT=%08x\n", }
getreg32(LPC43_CCU1_M4_SPIFI_CFG), getreg32(LPC43_CCU1_M4_SPIFI_STAT));
#endif #endif
#ifdef CONFIG_SPIFI_RDONLY return OK;
/* Register a read-only SPIFI RAM disk at /dev/ramN, where N is the
* value of CONFIG_SPIFI_DEVNO.
*/
return romdisk_register(CONFIG_SPIFI_DEVNO, SPIFI_BUFFER,
CONFIG_SPIFI_NBLOCKS, CONFIG_SPIFI_BLKSIZE);
#else
/* Register a write-able SPIFI RAM disk at /dev/ramN, where N is the
* value of CONFIG_SPIFI_DEVNO.
*/
return ramdisk_register(CONFIG_SPIFI_DEVNO, SPIFI_BUFFER,
CONFIG_SPIFI_NBLOCKS, CONFIG_SPIFI_BLKSIZE,
true);
#endif
} }
#else #else
# define nsh_spifi_initialize() (OK) # define nsh_spifi_initialize() (OK)