LP43xx SPIFI MTD driver update

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4971 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo
2012-07-23 20:08:56 +00:00
parent 1e15a6d1cf
commit 464f8d822b
7 changed files with 150 additions and 13 deletions
+6 -2
View File
@@ -3052,6 +3052,10 @@
Bxxx definitions are again encoded; cf[set|get][o|i]speed now deal with only the Bxxx definitions are again encoded; cf[set|get][o|i]speed now deal with only the
encoded values. If the encoed baud is set to BOTHER, then the values in the (non- encoded values. If the encoed baud is set to BOTHER, then the values in the (non-
standard) c_ispeed and c_ospeed baud values may be accessed directly. standard) c_ispeed and c_ospeed baud values may be accessed directly.
* arch/arm/src/stm32/stm32_serial.c: Add minimal termios support for the STM32
(BOTHER style baud settings only). Contributed by Mike Smith.
* configs/lpc4343-xplorer/src: Clean up SPIFI-library based build to that it
actually works.
* arch/arm/src/lpc43xx/lpc43_spifi.c: Add support for verification to writes.
Add debug option to dump buffers. Several bugfixes... almost works.
+19 -5
View File
@@ -124,6 +124,12 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/* Protection/sector descriptors */ /* Protection/sector descriptors */
struct spfi_desc_s struct spfi_desc_s
@@ -237,25 +243,33 @@ struct spifi_driver_s
#endif #endif
/**************************************************************************** /****************************************************************************
* Private Data * Public Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** #undef EXTERN
* Private Functions #if defined(__cplusplus)
****************************************************************************/ #define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_SPIFI_LIBRARY
EXTERN int32_t spifi_init(struct spifi_dev_s *dev, uint32_t cshigh, EXTERN int32_t spifi_init(struct spifi_dev_s *dev, uint32_t cshigh,
uint32_t options, uint32_t mhz); uint32_t options, uint32_t mhz);
EXTERN int32_t spifi_program(struct spifi_dev_s *dev, const uint8_t *source, EXTERN int32_t spifi_program(struct spifi_dev_s *dev, const uint8_t *source,
struct spifi_operands_s *opers); struct spifi_operands_s *opers);
EXTERN int32_t spifi_erase(struct spifi_dev_s *dev, EXTERN int32_t spifi_erase(struct spifi_dev_s *dev,
struct spifi_operands_s *opers); struct spifi_operands_s *opers);
#undef EXTERN
#ifdef __cplusplus
}
#endif #endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SPIFI_H */ #endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_SPIFI_H */
+75 -4
View File
@@ -81,6 +81,14 @@
* FAT friendly 512 byte sector size and will manage the read-modify-write * FAT friendly 512 byte sector size and will manage the read-modify-write
* operations on the larger erase block. * operations on the larger erase block.
* CONFIG_SPIFI_READONLY - Define to support only read-only operations. * CONFIG_SPIFI_READONLY - Define to support only read-only operations.
* CONFIG_SPIFI_LIBRARY - Don't use the LPC43xx ROM routines but, instead,
* use an external library implementation of the SPIFI interface.
* CONFIG_SPIFI_VERIFY - Verify all spi_program() operations by reading
* from the SPI address space after each write.
* CONFIG_DEBUG_SPIFI_DUMP - Debug option to dump read/write buffers. You
* probably do not want to enable this unless you want to dig through a
* *lot* of debug output! Also required CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE,
* and CONFIG_DEBUG_FS,
*/ */
/* This is where the LPC43xx address where random-access reads begin */ /* This is where the LPC43xx address where random-access reads begin */
@@ -157,15 +165,15 @@
#define IS_VALID(p) ((((p)->flags) & SST25_CACHE_VALID) != 0) #define IS_VALID(p) ((((p)->flags) & SST25_CACHE_VALID) != 0)
#define IS_DIRTY(p) ((((p)->flags) & SST25_CACHE_DIRTY) != 0) #define IS_DIRTY(p) ((((p)->flags) & SST25_CACHE_DIRTY) != 0)
#define IS_ERASED(p) ((((p)->flags) & SST25_CACHE_DIRTY) != 0) #define IS_ERASED(p) ((((p)->flags) & SST25_CACHE_ERASED) != 0)
#define SET_VALID(p) do { (p)->flags |= SST25_CACHE_VALID; } while (0) #define SET_VALID(p) do { (p)->flags |= SST25_CACHE_VALID; } while (0)
#define SET_DIRTY(p) do { (p)->flags |= SST25_CACHE_DIRTY; } while (0) #define SET_DIRTY(p) do { (p)->flags |= SST25_CACHE_DIRTY; } while (0)
#define SET_ERASED(p) do { (p)->flags |= SST25_CACHE_DIRTY; } while (0) #define SET_ERASED(p) do { (p)->flags |= SST25_CACHE_ERASED; } while (0)
#define CLR_VALID(p) do { (p)->flags &= ~SST25_CACHE_VALID; } while (0) #define CLR_VALID(p) do { (p)->flags &= ~SST25_CACHE_VALID; } while (0)
#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_ERASED; } while (0)
/* Select the divider to use as SPIFI input based on definitions in the /* Select the divider to use as SPIFI input based on definitions in the
* board.h header file. * board.h header file.
@@ -246,6 +254,20 @@
#define SCLK_MHZ (BOARD_SPIFI_FREQUENCY + (1000000 / 2)) / 1000000 #define SCLK_MHZ (BOARD_SPIFI_FREQUENCY + (1000000 / 2)) / 1000000
/* DEBUG options to dump read/write buffers. You probably do not want to
* enable this unless you want to dig through a *lot* of debug output!
*/
#if !defined(CONFIG_DEBUG) || !defined(CONFIG_DEBUG_VERBOSE) || !defined(CONFIG_DEBUG_FS)
# undef CONFIG_DEBUG_SPIFI_DUMP
#endif
#ifdef CONFIG_DEBUG_SPIFI_DUMP
# define lpc43_dumpbuffer(m,b,n) lib_dumpbuffer(m,b,n);
#else
# define lpc43_dumpbuffer(m,b,n)
#endif
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
@@ -288,6 +310,10 @@ static inline void lpc43_pageread(FAR struct lpc43_dev_s *priv,
FAR uint8_t *dest, FAR const uint8_t *src, FAR uint8_t *dest, FAR const uint8_t *src,
size_t nbytes); size_t nbytes);
#ifndef CONFIG_SPIFI_READONLY #ifndef CONFIG_SPIFI_READONLY
#ifdef CONFIG_SPIFI_VERIFY
static int lpc43_verify(FAR struct lpc43_dev_s *priv, FAR uint8_t *dest,
FAR const uint8_t *src, size_t nbytes);
#endif
static int lpc43_pagewrite(FAR struct lpc43_dev_s *priv, FAR uint8_t *dest, static int lpc43_pagewrite(FAR struct lpc43_dev_s *priv, FAR uint8_t *dest,
FAR const uint8_t *src, size_t nbytes); FAR const uint8_t *src, size_t nbytes);
#ifdef CONFIG_SPIFI_SECTOR512 #ifdef CONFIG_SPIFI_SECTOR512
@@ -351,6 +377,9 @@ static void lpc43_blockerase(struct lpc43_dev_s *priv, off_t sector)
priv->operands.dest = SPIFI_BASE + (sector << SPIFI_BLKSHIFT); priv->operands.dest = SPIFI_BASE + (sector << SPIFI_BLKSHIFT);
priv->operands.length = SPIFI_BLKSIZE; priv->operands.length = SPIFI_BLKSIZE;
fvdbg("SPIFI_ERASE: dest=%p length=%d\n",
priv->operands.dest, priv->operands.length);
result = SPIFI_ERASE(priv, &priv->rom, &priv->operands); result = SPIFI_ERASE(priv, &priv->rom, &priv->operands);
if (result != 0) if (result != 0)
{ {
@@ -377,6 +406,9 @@ static inline int lpc43_chiperase(struct lpc43_dev_s *priv)
priv->operands.dest = SPIFI_BASE; priv->operands.dest = SPIFI_BASE;
priv->operands.length = SPIFI_BLKSIZE * priv->nblocks; priv->operands.length = SPIFI_BLKSIZE * priv->nblocks;
fvdbg("SPIFI_ERASE: dest=%p length=%d\n",
priv->operands.dest, priv->operands.length);
result = SPIFI_ERASE(priv, &priv->rom, &priv->operands); result = SPIFI_ERASE(priv, &priv->rom, &priv->operands);
if (result != 0) if (result != 0)
{ {
@@ -387,6 +419,18 @@ static inline int lpc43_chiperase(struct lpc43_dev_s *priv)
return OK; return OK;
} }
/****************************************************************************
* Name: lpc43_pagewrite
****************************************************************************/
#if !defined(CONFIG_SPIFI_READONLY) && defined(CONFIG_SPIFI_VERIFY)
static int lpc43_verify(FAR struct lpc43_dev_s *priv, FAR uint8_t *dest,
FAR const uint8_t *src, size_t nbytes)
{
return memcmp(src, dest, nbytes) != 0 ? -EIO : OK;
}
#endif
/**************************************************************************** /****************************************************************************
* Name: lpc43_pagewrite * Name: lpc43_pagewrite
****************************************************************************/ ****************************************************************************/
@@ -408,6 +452,9 @@ static int lpc43_pagewrite(FAR struct lpc43_dev_s *priv, FAR uint8_t *dest,
priv->operands.dest = dest; priv->operands.dest = dest;
priv->operands.length = nbytes; priv->operands.length = nbytes;
fvdbg("SPIFI_PROGRAM: src=%p dest=%p length=%d\n",
src, priv->operands.dest, priv->operands.length);
result = SPIFI_PROGRAM(priv, &priv->rom, src, &priv->operands); result = SPIFI_PROGRAM(priv, &priv->rom, src, &priv->operands);
if (result != 0) if (result != 0)
{ {
@@ -415,6 +462,19 @@ static int lpc43_pagewrite(FAR struct lpc43_dev_s *priv, FAR uint8_t *dest,
return -EIO; return -EIO;
} }
/* Verify the data that was written by comparing to the data visible in the
* SPIFI address space.
*/
#ifdef CONFIG_SPIFI_VERIFY
result = lpc43_verify(priv, dest, src, nbytes);
if (result != 0)
{
fdbg("ERROR: lpc43_verify failed: %05x\n", result);
return -EIO;
}
#endif
return OK; return OK;
} }
#endif #endif
@@ -427,6 +487,7 @@ static inline void lpc43_pageread(FAR struct lpc43_dev_s *priv,
FAR uint8_t *dest, FAR const uint8_t *src, FAR uint8_t *dest, FAR const uint8_t *src,
size_t nbytes) size_t nbytes)
{ {
fvdbg("src=%p dest=%p length=%d\n", src, dest, nbytes);
memcpy(dest, src, nbytes); memcpy(dest, src, nbytes);
} }
@@ -445,6 +506,7 @@ static void lpc43_cacheflush(struct lpc43_dev_s *priv)
* the cached erase block to FLASH. * the cached erase block to FLASH.
*/ */
fvdbg("flags: %02x blkno: %d\n", priv->flags, priv->blkno);
if (IS_DIRTY(priv) || IS_ERASED(priv)) if (IS_DIRTY(priv) || IS_ERASED(priv))
{ {
/* Get the SPIFI address corresponding to the cached erase block */ /* Get the SPIFI address corresponding to the cached erase block */
@@ -579,6 +641,9 @@ static void lpc43_cachewrite(FAR struct lpc43_dev_s *priv, FAR const uint8_t *bu
dest = lpc43_cacheread(priv, sector); dest = lpc43_cacheread(priv, sector);
fvdbg("dest=%p src=%p sector: %ld flags: %02x\n",
dest, buffer, sector, priv->flags);
/* 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 sector
* is read into the cache and set here when we erase the sector. * is read into the cache and set here when we erase the sector.
@@ -660,9 +725,11 @@ static ssize_t lpc43_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t n
/* 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 = lpc43_read(dev, startblock << SPIFI_512SHIFT, nblocks << SPIFI_512SHIFT, buffer); nbytes = lpc43_read(dev, startblock << SPIFI_512SHIFT,
nblocks << SPIFI_512SHIFT, buffer);
if (nbytes > 0) if (nbytes > 0)
{ {
lpc43_dumpbuffer(__func__, buffer, nbytes)
return nbytes >> SPIFI_512SHIFT; return nbytes >> SPIFI_512SHIFT;
} }
@@ -679,6 +746,7 @@ static ssize_t lpc43_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t n
nblocks << SPIFI_BLKSHIFT, buffer); nblocks << SPIFI_BLKSHIFT, buffer);
if (nbytes > 0) if (nbytes > 0)
{ {
lpc43_dumpbuffer(__func__, buffer, nbytes)
return nbytes >> SPIFI_BLKSHIFT; return nbytes >> SPIFI_BLKSHIFT;
} }
@@ -704,6 +772,8 @@ static ssize_t lpc43_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t
fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
lpc43_cachewrite(priv, buffer, startblock, nblocks); lpc43_cachewrite(priv, buffer, startblock, nblocks);
lpc43_dumpbuffer(__func__, buffer, nblocks << SPIFI_512SHIFT)
return nblocks; return nblocks;
#else #else
@@ -726,6 +796,7 @@ static ssize_t lpc43_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t
return ret; return ret;
} }
lpc43_dumpbuffer(__func__, buffer, nblocks << SPIFI_BLKSHIFT)
return nblocks; return nblocks;
#endif #endif
+17
View File
@@ -92,6 +92,17 @@
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif
/**************************************************************************** /****************************************************************************
* Name: lpc43_spifi_initialize * Name: lpc43_spifi_initialize
* *
@@ -114,6 +125,12 @@
FAR struct mtd_dev_s *lpc43_spifi_initialize(void); FAR struct mtd_dev_s *lpc43_spifi_initialize(void);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_LPC43_SPIFI */ #endif /* CONFIG_LPC43_SPIFI */
#endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_SPIFI_H */ #endif /* __ARCH_ARM_SRC_LPC43XX_LPC43_SPIFI_H */
+6
View File
@@ -926,6 +926,12 @@ Where <subdir> is one of the following:
CONFIG_SPIFI_READONLY - Define to support only read-only operations. CONFIG_SPIFI_READONLY - Define to support only read-only operations.
CONFIG_SPIFI_LIBRARY - Don't use the LPC43xx ROM routines but, instead, CONFIG_SPIFI_LIBRARY - Don't use the LPC43xx ROM routines but, instead,
use an external library implementation of the SPIFI interface. use an external library implementation of the SPIFI interface.
CONFIG_SPIFI_VERIFY - Verify all spi_program() operations by reading
from the SPI address space after each write.
CONFIG_DEBUG_SPIFI_DUMP - Debug option to dump read/write buffers. You
probably do not want to enable this unless you want to dig through a
*lot* of debug output! Also required CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE,
and CONFIG_DEBUG_FS,
In my experience, there were some missing function pointers in the LPC43xx In my experience, there were some missing function pointers in the LPC43xx
SPIFI ROM routines and the SPIFI configuration could only be built with SPIFI ROM routines and the SPIFI configuration could only be built with
+9 -2
View File
@@ -674,7 +674,7 @@ CONFIG_MMCSD_MMCSUPPORT=n
CONFIG_MMCSD_HAVECARDDETECT=n CONFIG_MMCSD_HAVECARDDETECT=n
# #
# The SPIFI drvier has some special options that can be used to # The SPIFI driver has some special options that can be used to
# create an MTD 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:
# #
@@ -696,13 +696,20 @@ CONFIG_MMCSD_HAVECARDDETECT=n
# CONFIG_SPIFI_READONLY - Define to support only read-only operations. # CONFIG_SPIFI_READONLY - Define to support only read-only operations.
# CONFIG_SPIFI_LIBRARY - Don't use the LPC43xx ROM routines but, instead, # CONFIG_SPIFI_LIBRARY - Don't use the LPC43xx ROM routines but, instead,
# use an external library implementation of the SPIFI interface. # use an external library implementation of the SPIFI interface.
# CONFIG_SPIFI_VERIFY - Verify all spi_program() operations by reading
# from the SPI address space after each write.
# CONFIG_DEBUG_SPIFI_DUMP - Debug option to dump read/write buffers. You
# probably do not want to enable this unless you want to dig through a
# *lot* of debug output! Also required CONFIG_DEBUG, CONFIG_DEBUG_VERBOSE,
# and CONFIG_DEBUG_FS,#
# #
CONFIG_SPIFI_OFFSET=0 CONFIG_SPIFI_OFFSET=0
CONFIG_SPIFI_BLKSIZE=4096 CONFIG_SPIFI_BLKSIZE=4096
CONFIG_SPIFI_SECTOR512=y CONFIG_SPIFI_SECTOR512=y
CONFIG_SPIFI_RDONLY=n CONFIG_SPIFI_RDONLY=n
CONFIG_SPIFI_LIBRARY=n CONFIG_SPIFI_LIBRARY=n
CONFIG_SPIFI_VERIFY=n
CONFIG_DEBUG_SPIFI_DUMP=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
# CONFIG_NET_IPv6 - Build in support for IPv6 # CONFIG_NET_IPv6 - Build in support for IPv6
@@ -62,6 +62,24 @@ ifeq ($(CONFIG_USBMSC),y)
CSRCS += up_usbmsc.c CSRCS += up_usbmsc.c
endif endif
ifeq ($(CONFIG_SPIFI_LIBRARY),y)
CFLAGS += -DEUROBIRD
SPIFI_LIB = spifi_lib
CSRCS += $(SPIFI_LIB)/spifi_rom_api.c
#CSRCS += $(SPIFI_LIB)/amic.c
#CSRCS += $(SPIFI_LIB)/atmel.c
#CSRCS += $(SPIFI_LIB)/chi.c
#CSRCS += $(SPIFI_LIB)/eon.c
#CSRCS += $(SPIFI_LIB)/esmt.c
#CSRCS += $(SPIFI_LIB)/esmt.c
#CSRCS += $(SPIFI_LIB)/giga.c
#CSRCS += $(SPIFI_LIB)/macronix.c
#CSRCS += $(SPIFI_LIB)/numonyx.c
CSRCS += $(SPIFI_LIB)/spansion.c
#CSRCS += $(SPIFI_LIB)/sst.c
#CSRCS += $(SPIFI_LIB)/winbond.c
endif
AOBJS = $(ASRCS:.S=$(OBJEXT)) AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT))