This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

New M25Pxx SPI Flash driver.


Attached is a patch which adds the M25Pxx SPI flash driver.  I've placed
the driver in devs/flash/spi because even though it only currently
supports the Numonyx devices, it should also work with Atmel's AT25DFxx
series and any other compatibles that are out there.  However, I didn't
want to add the Atmel device definitions until the driver has been
properly tested against them.

Headers should be up to date with the new FSF copyright notice and I've
included the ChangeLog files this time ;-)

Chris.

diff -r -u5 -N cvs-05.02.09/ecos/packages//ChangeLog working-05.02.09/ecos/packages//ChangeLog
--- cvs-05.02.09/ecos/packages//ChangeLog	2009-02-05 11:12:45.000000000 +0000
+++ working-05.02.09/ecos/packages//ChangeLog	2009-02-05 16:07:40.000000000 +0000
@@ -1,5 +1,10 @@
+2009-02-05  Chris Holgate  <chris@zynaptic.com>
+
+	* ecos.db: Added M25Pxx SPI flash driver.  Included M25pxx driver in
+	STM3210E eval board template.
+
 2009-02-05  John Dallaway  <john@dallaway.org.uk>
 
 	* ecos.db: Remove package and target records for the deprecated
 	ColdFire port to avoid confusion. Add the CYGPKG_IO_SPI hardware
 	package to all relevant target records.
diff -r -u5 -N cvs-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/cdl/m25pxx.cdl working-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/cdl/m25pxx.cdl
--- cvs-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/cdl/m25pxx.cdl	1970-01-01 01:00:00.000000000 +0100
+++ working-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/cdl/m25pxx.cdl	2009-02-05 16:00:12.000000000 +0000
@@ -0,0 +1,77 @@
+##=============================================================================
+##
+##      m25pxx.cdl
+##
+##      M25Pxx SPI flash driver configuration options.
+##
+##=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####                                            
+## -------------------------------------------                              
+## This file is part of eCos, the Embedded Configurable Operating System.   
+## Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under    
+## the terms of the GNU General Public License as published by the Free     
+## Software Foundation; either version 2 or (at your option) any later      
+## version.                                                                 
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT      
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+## for more details.                                                        
+##
+## You should have received a copy of the GNU General Public License        
+## along with eCos; if not, write to the Free Software Foundation, Inc.,    
+## 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+##
+## As a special exception, if other files instantiate templates or use      
+## macros or inline functions from this file, or you compile this file      
+## and link it with other works to produce a work based on this file,       
+## this file does not by itself cause the resulting work to be covered by   
+## the GNU General Public License. However the source code for this file    
+## must still be made available in accordance with section (3) of the GNU   
+## General Public License v2.                                               
+##
+## This exception does not invalidate any other reasons why a work based    
+## on this file might be covered by the GNU General Public License.         
+## -------------------------------------------                              
+## ####ECOSGPLCOPYRIGHTEND####                                              
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):   Chris Holgate
+## Date:        2008-12-22
+## Purpose:     Configure M25Pxx SPI flash driver.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_SPI_M25PXX {
+    display	"M25PXX flash memory support"
+    parent	CYGPKG_IO_FLASH
+    active_if	CYGPKG_IO_FLASH CYGPKG_IO_SPI
+    implements	CYGHWR_IO_FLASH_DEVICE
+    implements  CYGHWR_IO_FLASH_INDIRECT_READS 
+    include_dir	cyg/io
+    compile	m25pxx.c
+
+    description "
+        Flash memory support for Numonyx M25Pxx SPI flash devices and 
+        compatibles.  This driver implements the V2 flash driver API"
+
+cdl_option CYGNUM_DEVS_FLASH_SPI_M25PXX_READ_BLOCK_SIZE {
+    display       "Maximum read block size"
+    description   "
+        In theory it is possible to read back the entire flash contents using
+        a single SPI transaction.  However, some SPI bus drivers have a maximum 
+        transaction size - for example transactions may be limited to the 
+        length of a DMA bounce buffer.  Setting this option to a non-zero value 
+        specifies the maximum SPI bus transfer size which will be used when 
+        reading back data.  Read requests for areas larger than this block size 
+        will automatically be split into a series of smaller SPI bus transactions.
+    "
+    flavor        data 
+    default_value 0
+}
+}
diff -r -u5 -N cvs-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/ChangeLog working-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/ChangeLog
--- cvs-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/ChangeLog	1970-01-01 01:00:00.000000000 +0100
+++ working-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/ChangeLog	2009-02-05 16:00:12.000000000 +0000
@@ -0,0 +1,34 @@
+2009-02-05  Chris Holgate  <chris@zynaptic.com>
+
+	* cdl/m25pxx.cdl: 
+	* include/m25pxx.h: 
+	* src/m25pxx.c: 
+	* test/m25pxx_test.c:
+	New package - SPI flash driver for M25Pxx devices and compatibles. 
+	Driver contributed by Chris Holgate.  Includes a soak test which is
+	not part of the default tests as it requires a specific configuration
+	to be used - see test/m25pxx_test.c for details.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####                                                
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify     
+// it under the terms of the GNU General Public License as published by     
+// the Free Software Foundation; either version 2 or (at your option) any   
+// later version.                                                           
+//
+// This program is distributed in the hope that it will be useful, but      
+// WITHOUT ANY WARRANTY; without even the implied warranty of               
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        
+// General Public License for more details.                                 
+//
+// You should have received a copy of the GNU General Public License        
+// along with this program; if not, write to the                            
+// Free Software Foundation, Inc., 51 Franklin Street,                      
+// Fifth Floor, Boston, MA  02110-1301, USA.                                
+// -------------------------------------------                              
+// ####GPLCOPYRIGHTEND####                                                  
+//===========================================================================
diff -r -u5 -N cvs-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/include/m25pxx.h working-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/include/m25pxx.h
--- cvs-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/include/m25pxx.h	1970-01-01 01:00:00.000000000 +0100
+++ working-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/include/m25pxx.h	2009-02-05 16:00:12.000000000 +0000
@@ -0,0 +1,78 @@
+#ifndef CYGONCE_DEVS_FLASH_SPI_M25PXX_H
+#define CYGONCE_DEVS_FLASH_SPI_M25PXX_H
+
+//=============================================================================
+//
+//      m25pxx.h
+//
+//      SPI flash driver for Numonyx M25Pxx devices and compatibles.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####                                            
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under    
+// the terms of the GNU General Public License as published by the Free     
+// Software Foundation; either version 2 or (at your option) any later      
+// version.                                                                 
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT      
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+// for more details.                                                        
+//
+// You should have received a copy of the GNU General Public License        
+// along with eCos; if not, write to the Free Software Foundation, Inc.,    
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+//
+// As a special exception, if other files instantiate templates or use      
+// macros or inline functions from this file, or you compile this file      
+// and link it with other works to produce a work based on this file,       
+// this file does not by itself cause the resulting work to be covered by   
+// the GNU General Public License. However the source code for this file    
+// must still be made available in accordance with section (3) of the GNU   
+// General Public License v2.                                               
+//
+// This exception does not invalidate any other reasons why a work based    
+// on this file might be covered by the GNU General Public License.         
+// -------------------------------------------                              
+// ####ECOSGPLCOPYRIGHTEND####                                              
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   Chris Holgate
+// Date:        2008-12-22
+// Purpose:     Numonyx M25Pxx SPI flash driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// Required data structures.
+#include <cyg/io/flash_dev.h>
+
+// Exported handle on the driver function table.
+externC struct cyg_flash_dev_funs cyg_devs_flash_spi_m25pxx_funs;
+
+//-----------------------------------------------------------------------------
+// Macro used to generate a flash device object with the default M25PXX 
+// settings.  Even though the block info data structure is declared here, the 
+// details are not filled in until the device type is inferred during 
+// initialisation.  This also applies to the 'end' field which is calculated 
+// using the _start_ address and the inferred size of the device.
+// _name_   is the root name of the instantiated data structures.
+// _start_  is the base address of the device - for SPI based devices this can
+//          have an arbitrary value, since the device is not memory mapped.
+// _spidev_ is a pointer to a SPI device object of type cyg_spi_device.  This
+//          is not typechecked during compilation so be careful!
+
+#define CYG_DEVS_FLASH_SPI_M25PXX_DRIVER(_name_, _start_, _spidev_) \
+struct cyg_flash_block_info _name_ ##_block_info; \
+CYG_FLASH_DRIVER(_name_, &cyg_devs_flash_spi_m25pxx_funs, 0, \
+  _start_, _start_, 1, & _name_ ##_block_info, (void*) _spidev_)
+
+//=============================================================================
+
+#endif // CYGONCE_DEVS_FLASH_SPI_M25PXX_H
diff -r -u5 -N cvs-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/src/m25pxx.c working-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/src/m25pxx.c
--- cvs-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/src/m25pxx.c	1970-01-01 01:00:00.000000000 +0100
+++ working-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/src/m25pxx.c	2009-02-05 16:00:12.000000000 +0000
@@ -0,0 +1,473 @@
+//=============================================================================
+//
+//      m25pxx.c
+//
+//      SPI flash driver for Numonyx M25Pxx devices and compatibles.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####                                            
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under    
+// the terms of the GNU General Public License as published by the Free     
+// Software Foundation; either version 2 or (at your option) any later      
+// version.                                                                 
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT      
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+// for more details.                                                        
+//
+// You should have received a copy of the GNU General Public License        
+// along with eCos; if not, write to the Free Software Foundation, Inc.,    
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+//
+// As a special exception, if other files instantiate templates or use      
+// macros or inline functions from this file, or you compile this file      
+// and link it with other works to produce a work based on this file,       
+// this file does not by itself cause the resulting work to be covered by   
+// the GNU General Public License. However the source code for this file    
+// must still be made available in accordance with section (3) of the GNU   
+// General Public License v2.                                               
+//
+// This exception does not invalidate any other reasons why a work based    
+// on this file might be covered by the GNU General Public License.         
+// -------------------------------------------                              
+// ####ECOSGPLCOPYRIGHTEND####                                              
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   Chris Holgate
+// Date:        2008-12-22
+// Purpose:     Numonyx M25Pxx SPI flash driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/io/spi.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <pkgconf/devs_flash_spi_m25pxx.h>
+
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// Enable polled SPI operation for non-kernel builds.
+
+#ifdef CYGPKG_KERNEL
+#define M25PXX_POLLED false
+
+#else
+#define M25PXX_POLLED true
+#endif
+
+//-----------------------------------------------------------------------------
+// Implement delay functions for kernel and non-kernel builds.  The kernel
+// build assumes that the API calls are made in the thread context.
+
+#ifdef CYGPKG_KERNEL
+#define M25PXX_DELAY_MS(_msdelay_) cyg_thread_delay (\
+  1 + ((1000 * _msdelay_ * CYGNUM_HAL_RTC_DENOMINATOR) / (CYGNUM_HAL_RTC_NUMERATOR / 1000)))
+
+#else
+#define M25PXX_DELAY_MS(_msdelay_) CYGACC_CALL_IF_DELAY_US (_msdelay_ * 1000)
+#endif
+
+//-----------------------------------------------------------------------------
+// Maintenance and debug macros.
+
+#define TODO_M25P(_msg_) CYG_ASSERT(false, "TODO (M25P) : " _msg_)
+#define FAIL_M25P(_msg_) CYG_ASSERT(false, "FAIL (M25P) : " _msg_)
+#define ASSERT_M25P(_test_, _msg_) CYG_ASSERT(_test_, "FAIL (M25P) : " _msg_)
+#define TRACE_M25P(_msg_, _args_...) if (dev->pf) dev->pf ("M25PXX : " _msg_, ##_args_)
+
+//=============================================================================
+// Define M25Pxx SPI protocol.
+//=============================================================================
+
+typedef enum m25pxx_cmd { 
+  M25PXX_CMD_WREN  = 0x06,  // Write enable.
+  M25PXX_CMD_WDRI  = 0x04,  // Write disable.
+  M25PXX_CMD_RDID  = 0x9F,  // Read identification.
+  M25PXX_CMD_RDSR  = 0x05,  // Read status register.
+  M25PXX_CMD_WRSR  = 0x01,  // Write status register.
+  M25PXX_CMD_READ  = 0x03,  // Read data.
+  M25PXX_CMD_FREAD = 0x0B,  // Read data (fast transaction).
+  M25PXX_CMD_PP    = 0x02,  // Page program.
+  M25PXX_CMD_SE    = 0xD8,  // Sector erase.
+  M25PXX_CMD_BE    = 0xC7,  // Bulk erase.
+  M25PXX_CMD_RES   = 0xAB,  // Read electronic signature.
+} m25pxx_cmd;
+
+// Status register bitfields.
+#define M25PXX_STATUS_WIP  0x01  /* Write in progress. */
+#define M25PXX_STATUS_WEL  0x02  /* Write enable latch. */
+#define M25PXX_STATUS_BP0  0x04  /* Block protect 0. */
+#define M25PXX_STATUS_BP1  0x08  /* Block protect 1. */
+#define M25PXX_STATUS_BP2  0x10  /* Block protect 2. */
+#define M25PXX_STATUS_SRWD 0x80  /* Status register write protect. */
+
+// Page size of 256 bytes appears to be common for all devices.
+#define M25PXX_PAGE_SIZE 256
+
+//=============================================================================
+// Array containing a list of supported devices.  This allows the device
+// parameters to be dynamically detected on initialisation.
+//=============================================================================
+
+typedef struct m25pxx_params {
+  cyg_uint16 sector_size;   // Number of pages in a sector.
+  cyg_uint16 sector_count;  // Number of sectors on device.  
+  cyg_uint32 jedec_id;      // 3 byte JEDEC identifier for this device.
+} m25pxx_params;
+
+static const m25pxx_params m25pxx_supported_devices [] = {
+  { // Support for Numonyx 128 MBit devices.
+    sector_size  : 1024,
+    sector_count : 64,
+    jedec_id     : 0x00202018
+  },
+  { // Support for Numonyx 64 MBit devices.
+    sector_size  : 256,
+    sector_count : 128,
+    jedec_id     : 0x00202017
+  },
+  { // Support for Numonyx 16 MBit devices.
+    sector_size  : 256,
+    sector_count : 64,
+    jedec_id     : 0x00202016
+  },
+  { // Support for Numonyx 16 MBit devices.
+    sector_size  : 256,
+    sector_count : 32,
+    jedec_id     : 0x00202015
+  },
+  { // Support for Numonyx 8 MBit devices.
+    sector_size  : 256,
+    sector_count : 16,
+    jedec_id     : 0x00202014
+  },
+  { // Support for Numonyx 4 MBit devices.
+    sector_size  : 256,
+    sector_count : 8,
+    jedec_id     : 0x00202013
+  },
+  { // Support for Numonyx 2 MBit devices.
+    sector_size  : 256,
+    sector_count : 4,
+    jedec_id     : 0x00202012
+  },
+  { // Support for Numonyx 1 MBit devices.
+    sector_size  : 128,
+    sector_count : 4,
+    jedec_id     : 0x00202011
+  },
+  { // Support for Numonyx 512 KBit devices.
+    sector_size  : 128,
+    sector_count : 2,
+    jedec_id     : 0x00202010
+  },
+  { // Null terminating entry.
+    sector_size  : 0,
+    sector_count : 0,
+    jedec_id     : 0
+  }
+};
+
+//=============================================================================
+// Utility functions for address calculations.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Strips out any device address offset to give address within device.
+
+static cyg_bool m25pxx_to_local_addr
+  (struct cyg_flash_dev* dev, cyg_flashaddr_t* addr)
+{
+  cyg_bool retval = false;
+
+  // Range check address before modifying it.
+  if ((*addr >= dev->start) && (*addr <= dev->end)) {
+    *addr -= dev->start;
+    retval = true;
+  }
+  return retval;
+}
+
+//=============================================================================
+// Wrapper functions for various SPI transactions.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Read back the 3-byte JEDEC ID, returning it as a 32-bit integer.
+// This function is called during flash initialisation, which can often be
+// called from the startup/idle thread.  This means that we should always use
+// SPI polled mode in order to prevent the thread from attempting to sleep.
+
+static inline cyg_uint32 m25pxx_spi_rdid
+  (struct cyg_flash_dev *dev)
+{
+  cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+  const cyg_uint8 tx_buf [4] = { M25PXX_CMD_RDID, 0, 0, 0 };
+  cyg_uint8 rx_buf [4];
+  cyg_uint32 retval = 0;
+
+  // Carry out SPI transfer.
+  cyg_spi_transfer (spi_device, true, 4, tx_buf, rx_buf);
+
+  // Convert 3-byte ID to 32-bit integer.
+  retval |= ((cyg_uint32) rx_buf[1]) << 16;   
+  retval |= ((cyg_uint32) rx_buf[2]) << 8;   
+  retval |= ((cyg_uint32) rx_buf[3]);   
+
+  return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Send write enable command.
+
+static inline void m25pxx_spi_wren
+  (struct cyg_flash_dev *dev)
+{
+  cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+  const cyg_uint8 tx_buf [1] = { M25PXX_CMD_WREN };
+  cyg_spi_transfer (spi_device, M25PXX_POLLED, 1, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Send sector erase command.  The address parameter is a device local address 
+// within the sector to be erased.
+
+static inline void m25pxx_spi_se
+  (struct cyg_flash_dev *dev, cyg_flashaddr_t addr)
+{
+  cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+  const cyg_uint8 tx_buf [4] = { M25PXX_CMD_SE,
+    (cyg_uint8) (addr >> 16), (cyg_uint8) (addr >> 8), (cyg_uint8) (addr) };
+  cyg_spi_transfer (spi_device, M25PXX_POLLED, 4, tx_buf, NULL);
+}
+
+//-----------------------------------------------------------------------------
+// Read and return the 8-bit device status register.
+
+static inline cyg_uint8 m25pxx_spi_rdsr
+  (struct cyg_flash_dev *dev)
+{
+  cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+  const cyg_uint8 tx_buf [2] = { M25PXX_CMD_RDSR, 0 };
+  cyg_uint8 rx_buf [2];
+
+  // Carry out SPI transfer and return the status byte.
+  cyg_spi_transfer (spi_device, M25PXX_POLLED, 2, tx_buf, rx_buf);
+  return rx_buf [1];
+}
+
+//-----------------------------------------------------------------------------
+// Program a single page.
+
+static inline void m25pxx_spi_pp
+  (struct cyg_flash_dev *dev, cyg_flashaddr_t addr, cyg_uint8* wbuf, cyg_uint32 wbuf_len)
+{
+  cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+  const cyg_uint8 tx_buf [4] = { M25PXX_CMD_PP,
+    (cyg_uint8) (addr >> 16), (cyg_uint8) (addr >> 8), (cyg_uint8) (addr) };
+
+  // Implement the program operation as a multistage SPI transaction.
+  cyg_spi_transaction_begin (spi_device);
+  cyg_spi_transaction_transfer (spi_device, M25PXX_POLLED, 4, tx_buf, NULL, false);
+  cyg_spi_transaction_transfer (spi_device, M25PXX_POLLED, wbuf_len, wbuf, NULL, false);
+  cyg_spi_transaction_end (spi_device);
+}
+
+//-----------------------------------------------------------------------------
+// Implement fast reads to the specified buffer.
+
+static inline void m25pxx_spi_fread
+  (struct cyg_flash_dev *dev, cyg_flashaddr_t addr, cyg_uint8* rbuf, cyg_uint32 rbuf_len)
+{
+  cyg_spi_device* spi_device = (cyg_spi_device*) dev->priv;
+  const cyg_uint8 tx_buf [5] = { M25PXX_CMD_FREAD,
+    (cyg_uint8) (addr >> 16), (cyg_uint8) (addr >> 8), (cyg_uint8) (addr), 0 };
+
+  // Implement the read operation as a multistage SPI transaction.
+  cyg_spi_transaction_begin (spi_device);
+  cyg_spi_transaction_transfer (spi_device, M25PXX_POLLED, 5, tx_buf, NULL, false);
+  cyg_spi_transaction_transfer (spi_device, M25PXX_POLLED, rbuf_len, NULL, rbuf, false);
+  cyg_spi_transaction_end (spi_device);
+}
+
+//=============================================================================
+// Standard Flash device API.  All the following functions assume that a valid
+// SPI device handle is passed in the 'priv' reference of the flash device
+// data structure.
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Initialise the SPI flash, reading back the flash parameters.
+
+static int m25pxx_init 
+  (struct cyg_flash_dev *dev)
+{
+  m25pxx_params* dev_params = (m25pxx_params*) m25pxx_supported_devices;
+  cyg_uint32 device_id;
+  int retval = FLASH_ERR_INVALID;
+
+  // Find the device in the supported devices list.
+  device_id = m25pxx_spi_rdid (dev);
+  while ((dev_params->jedec_id != 0) && (dev_params->jedec_id != device_id)) {
+    dev_params ++;
+  }
+
+  // Found supported device - update device parameters.  M25PXX devices have a 
+  // uniform sector distribution, so only 1 block info record is required.
+  if (dev_params->jedec_id != 0) {
+    ASSERT_M25P (dev->num_block_infos == 1, "Only 1 block info record required.");
+    ASSERT_M25P (dev->block_info != NULL, "Null pointer to block info record.");
+    if ((dev->num_block_infos == 1) && (dev->block_info != NULL)) { 
+      TRACE_M25P ("Init device with JEDEC ID 0x%06X.\n", device_id);
+      dev->end = dev->start + (M25PXX_PAGE_SIZE * (cyg_flashaddr_t) dev_params->sector_size * 
+        (cyg_flashaddr_t) dev_params->sector_count) - 1;
+
+      // Strictly speaking the block info fields are 'read only'.  However, we
+      // have a legitimate reason for updating the contents here and can cast
+      // away the const.
+      ((cyg_flash_block_info_t*) dev->block_info)->block_size = 
+        M25PXX_PAGE_SIZE * (size_t) dev_params->sector_size; 
+      ((cyg_flash_block_info_t*) dev->block_info)->blocks = 
+        (cyg_uint32) dev_params->sector_count;
+      retval = FLASH_ERR_OK;
+    }
+  }
+  return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Erase a single sector of the flash.
+
+static int m25pxx_erase_block 
+  (struct cyg_flash_dev *dev, cyg_flashaddr_t block_base)
+{
+  cyg_flashaddr_t local_base = block_base;
+  int retval = FLASH_ERR_INVALID;
+  cyg_uint8 dev_status;
+
+  // Fix up the block address and send the sector erase command.
+  if (m25pxx_to_local_addr (dev, &local_base)) {
+    m25pxx_spi_wren (dev);
+    m25pxx_spi_se (dev, local_base);
+
+    // Spin waiting for the erase to complete.  This can take between 1 and 3
+    // seconds, so we use a polling interval of 1/2 sec.
+    do {
+      M25PXX_DELAY_MS (500);
+      dev_status = m25pxx_spi_rdsr (dev);
+    } while (dev_status & M25PXX_STATUS_WIP);
+
+    retval = FLASH_ERR_OK;    
+  }
+  return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Program an arbitrary number of pages into flash and verify written data.
+
+static int m25pxx_program 
+  (struct cyg_flash_dev *dev, cyg_flashaddr_t base, const void* data, size_t len)
+{
+  cyg_flashaddr_t local_base = base;
+  int retval = FLASH_ERR_OK;
+  cyg_uint8* tx_ptr = (cyg_uint8*) data;
+  cyg_uint32 tx_bytes_left = (cyg_uint32) len;
+  cyg_uint32 tx_bytes;
+  cyg_uint8  dev_status;
+
+  // Fix up the block address.
+  if (!m25pxx_to_local_addr (dev, &local_base)) {
+    retval = FLASH_ERR_INVALID;
+    goto out;
+  }
+
+  // The start of the transaction may not be page aligned, so we need to work
+  // out how many bytes to transmit before we hit the first page boundary.
+  tx_bytes = M25PXX_PAGE_SIZE - (((cyg_uint32) local_base) & (M25PXX_PAGE_SIZE - 1));
+  if (tx_bytes > tx_bytes_left) tx_bytes = tx_bytes_left;
+
+  // Perform page program operations.
+  while (tx_bytes_left) {
+    m25pxx_spi_wren (dev);
+    m25pxx_spi_pp (dev, local_base, tx_ptr, tx_bytes);
+
+    // Spin waiting for write to complete.  This can take up to 5ms, so
+    // we use a polling interval of 1ms - which may get rounded up to the
+    // RTC tick granularity.
+    do {
+      M25PXX_DELAY_MS (1);
+      dev_status = m25pxx_spi_rdsr (dev);
+    } while (dev_status & M25PXX_STATUS_WIP);
+    
+    // Update counters and data pointers for the next page.
+    tx_bytes_left -= tx_bytes;
+    tx_ptr += tx_bytes;
+    local_base += tx_bytes; 
+    tx_bytes = (tx_bytes_left > M25PXX_PAGE_SIZE) ? M25PXX_PAGE_SIZE : tx_bytes_left;
+  }
+
+out:
+  return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Read back an arbitrary amount of data from flash.
+
+static int m25pxx_read 
+  (struct cyg_flash_dev *dev, const cyg_flashaddr_t base, void* data, size_t len)
+{
+  cyg_flashaddr_t local_base = base;
+  int retval = FLASH_ERR_INVALID;
+  cyg_uint8* rx_ptr = (cyg_uint8*) data;
+  cyg_uint32 rx_bytes_left = (cyg_uint32) len;
+  cyg_uint32 rx_bytes;
+
+  // Determine the maximum transfer size to use.
+  cyg_uint32 rx_block_size = (CYGNUM_DEVS_FLASH_SPI_M25PXX_READ_BLOCK_SIZE == 0) ? 
+    0xFFFFFFFF : CYGNUM_DEVS_FLASH_SPI_M25PXX_READ_BLOCK_SIZE;
+
+  // Fix up the block address and fill the read buffer.
+  if (m25pxx_to_local_addr (dev, &local_base)) {
+    while (rx_bytes_left) {
+      rx_bytes = (rx_bytes_left < rx_block_size) ? rx_bytes_left : rx_block_size;
+      m25pxx_spi_fread (dev, local_base, rx_ptr, rx_bytes);
+
+      // Update counters and data pointers for next read block.
+      rx_bytes_left -= rx_bytes;
+      rx_ptr += rx_bytes;
+      local_base += rx_bytes; 
+    }
+    retval = FLASH_ERR_OK;
+  }
+  return retval;
+}
+
+//=============================================================================
+// Fill in the driver data structures.
+//=============================================================================
+
+CYG_FLASH_FUNS (
+  cyg_devs_flash_spi_m25pxx_funs, // Exported name of function pointers.
+  m25pxx_init,                    // Flash initialisation.
+  cyg_flash_devfn_query_nop,      // Query operations not supported.
+  m25pxx_erase_block,             // Sector erase.
+  m25pxx_program,                 // Program multiple pages.
+  m25pxx_read,                    // Read arbitrary amount of data.
+  cyg_flash_devfn_lock_nop,       // Locking not supported (no per-sector locks).
+  cyg_flash_devfn_unlock_nop
+);
+
+//=============================================================================
diff -r -u5 -N cvs-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/test/m25pxx_test.c working-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/test/m25pxx_test.c
--- cvs-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/test/m25pxx_test.c	1970-01-01 01:00:00.000000000 +0100
+++ working-05.02.09/ecos/packages//devs/flash/spi/m25pxx/current/test/m25pxx_test.c	2009-02-05 16:00:12.000000000 +0000
@@ -0,0 +1,395 @@
+//=============================================================================
+//
+//      m25pxx_test.c
+//
+//      SPI flash driver tests for Numonyx M25Pxx devices and compatibles.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####                                            
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under    
+// the terms of the GNU General Public License as published by the Free     
+// Software Foundation; either version 2 or (at your option) any later      
+// version.                                                                 
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT      
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+// for more details.                                                        
+//
+// You should have received a copy of the GNU General Public License        
+// along with eCos; if not, write to the Free Software Foundation, Inc.,    
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+//
+// As a special exception, if other files instantiate templates or use      
+// macros or inline functions from this file, or you compile this file      
+// and link it with other works to produce a work based on this file,       
+// this file does not by itself cause the resulting work to be covered by   
+// the GNU General Public License. However the source code for this file    
+// must still be made available in accordance with section (3) of the GNU   
+// General Public License v2.                                               
+//
+// This exception does not invalidate any other reasons why a work based    
+// on this file might be covered by the GNU General Public License.         
+// -------------------------------------------                              
+// ####ECOSGPLCOPYRIGHTEND####                                              
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   Chris Holgate
+// Date:        2008-12-22
+// Purpose:     Numonyx M25Pxx SPI flash driver stress tests.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/system.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/testcase.h>           // Test macros
+#include <cyg/infra/cyg_ass.h>            // Assertion macros
+#include <cyg/infra/diag.h>               // Diagnostic output
+
+#include <cyg/hal/hal_arch.h>             // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/hal/hal_if.h>
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/io/spi.h>
+#include <cyg/io/flash.h>
+#include <cyg/io/m25pxx.h>
+
+#include <string.h>
+
+#include CYGHWR_MEMORY_LAYOUT_H
+
+//-----------------------------------------------------------------------------
+// Set up the SPI intertface on the ST STM3210E eval board for the STM32.  The 
+// M25PXX device is connected to SPI bus 1.  To configure the board for this 
+// test, jumper JP3 must be open and SPI1 should be set up in configtool so
+// that chip select 1 corresponds to GPIO number 18 (PB2) and 50MHz I/O is
+// enabled.  If the data area is in external RAM, SPI1 must be configured with 
+// bounce buffers of at least 256 bytes and the M25PXX read data block size 
+// should be set to the same size as the bounce buffers.
+
+#ifdef CYGPKG_HAL_CORTEXM_STM32_STM3210E_EVAL
+#include <cyg/io/spi_stm32.h>
+
+CYG_DEVS_SPI_CORTEXM_STM32_DEVICE (
+    m25pxx_spi_device, 1, 0, false, 0, 0, 25000000, 1, 1, 1
+);
+
+#endif
+
+//-----------------------------------------------------------------------------
+// Instantiate the M25Pxx device driver.
+
+CYG_DEVS_FLASH_SPI_M25PXX_DRIVER (
+    m25pxx_flash_device, 0, &m25pxx_spi_device
+);
+
+//-----------------------------------------------------------------------------
+// Thread data structures.
+
+static cyg_uint32 stack [CYGNUM_HAL_STACK_SIZE_TYPICAL / 4];
+static cyg_thread thread_data;
+static cyg_handle_t thread_handle;
+
+//-----------------------------------------------------------------------------
+// Data transfer buffers.
+
+#define BUF_SIZE 1024
+
+static cyg_uint8 wbuf [BUF_SIZE];
+static cyg_uint8 rbuf [BUF_SIZE];
+
+//-----------------------------------------------------------------------------
+// Print out version information.
+
+void do_version (void)
+{
+    char *version = CYGACC_CALL_IF_MONITOR_VERSION();
+    if (version != NULL) diag_printf("%s", version);
+#ifdef HAL_PLATFORM_CPU
+    diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
+#endif
+    diag_printf("RAM: %p-%p, ", (void*)(CYGMEM_REGION_ram), (void*)(CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - 1));
+    diag_printf("(HEAP: %p-%p)\n", (void*)(CYGMEM_SECTION_heap1), (void*)(CYGMEM_SECTION_heap1 + CYGMEM_SECTION_heap1_SIZE - 1));
+}
+
+//-----------------------------------------------------------------------------
+// Run checkerboard and inverse checkerboard writes over each sector in turn.
+
+cyg_uint32 run_test_1
+  (void)
+{
+    int status;
+    cyg_uint32 i, j;
+    cyg_uint32 errors = 0;
+    cyg_flashaddr_t base_addr, err_addr;
+
+    diag_printf ("Test 1 - write and verify checkerboard and inverse checkerboard.\n");
+    
+    // Iterate over all flash sectors.
+    for (i = 0; i < m25pxx_flash_device.block_info->blocks; i++) {
+        base_addr =  m25pxx_flash_device.start + (i * m25pxx_flash_device.block_info->block_size);
+
+        // Erase block.
+        status = cyg_flash_erase (base_addr, 1, &err_addr);
+        if (status != FLASH_ERR_OK) {
+            diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+            errors ++;
+        }
+
+        // Set up buffer with checkerboard.
+        for (j = 0; j < BUF_SIZE;) {
+           wbuf [j++] = 0x55;
+           wbuf [j++] = 0xAA;
+        }
+
+        // Write the checkerboard to the entire sector.
+        for (j = 0; j < m25pxx_flash_device.block_info->block_size; j += BUF_SIZE) {
+            status = cyg_flash_program (base_addr + j, wbuf, BUF_SIZE, &err_addr);
+            if (status != FLASH_ERR_OK) {
+                diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+                errors ++;
+            }
+        }
+
+        // Read back the checkerboard and verify.
+        for (j = 0; j < m25pxx_flash_device.block_info->block_size; j += BUF_SIZE) {
+            status = cyg_flash_read (base_addr + j, rbuf, BUF_SIZE, &err_addr);
+            if (status != FLASH_ERR_OK) {
+                diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+                errors ++;
+            }
+            else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+                diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n", base_addr + j, base_addr + j + BUF_SIZE - 1);
+                errors ++;
+            }
+        }
+
+        // Erase block.
+        status = cyg_flash_erase (base_addr, 1, &err_addr);
+        if (status != FLASH_ERR_OK) {
+            diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+            errors ++;
+        }
+
+        // Set up buffer with inverse checkerboard.
+        for (j = 0; j < BUF_SIZE;) {
+           wbuf [j++] = 0xAA;
+           wbuf [j++] = 0x55;
+        }
+
+        // Write the checkerboard to the entire sector.
+        for (j = 0; j < m25pxx_flash_device.block_info->block_size; j += BUF_SIZE) {
+            status = cyg_flash_program (base_addr + j, wbuf, BUF_SIZE, &err_addr);
+            if (status != FLASH_ERR_OK) {
+                diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+                errors ++;
+            }
+        }
+
+        // Read back the checkerboard and verify.
+        for (j = 0; j < m25pxx_flash_device.block_info->block_size; j += BUF_SIZE) {
+            status = cyg_flash_read (base_addr + j, rbuf, BUF_SIZE, &err_addr);
+            if (status != FLASH_ERR_OK) {
+                diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+                errors ++;
+            }
+            else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+                diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n", base_addr + j, base_addr + j + BUF_SIZE - 1);
+                errors ++;
+            }
+        }
+    }
+    return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Write and verify counting sequence over all device.
+
+cyg_uint32 run_test_2
+  (void)
+{
+    int status;
+    cyg_uint32 i, j;
+    cyg_uint32 errors = 0;
+    cyg_flashaddr_t base_addr, err_addr;
+
+    diag_printf ("Test 2 - write and verify counting sequence.\n");
+    
+    // Erase all flash sectors.
+    for (i = 0; i < m25pxx_flash_device.block_info->blocks; i++) {
+        base_addr =  m25pxx_flash_device.start + (i * m25pxx_flash_device.block_info->block_size);
+
+        // Erase block.
+        status = cyg_flash_erase (base_addr, 1, &err_addr);
+        if (status != FLASH_ERR_OK) {
+            diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+            errors ++;
+        }
+    }
+
+    // Write counting sequence.
+    base_addr =  m25pxx_flash_device.start;
+    for (i = 0; i < (m25pxx_flash_device.end - m25pxx_flash_device.start) / 4;) {
+        for (j = 0; j < BUF_SIZE;) {
+            wbuf [j++] = (cyg_uint8) ((i >> 0) & 0xFF);
+            wbuf [j++] = (cyg_uint8) ((i >> 8) & 0xFF);
+            wbuf [j++] = (cyg_uint8) ((i >> 16) & 0xFF);
+            wbuf [j++] = (cyg_uint8) ((i >> 24) & 0xFF);            
+            i++;
+        }
+        status = cyg_flash_program (base_addr, wbuf, BUF_SIZE, &err_addr);
+        if (status != FLASH_ERR_OK) {
+            diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+            errors ++;
+        }
+        base_addr += BUF_SIZE;
+    }
+
+    // Verify counting sequence.
+    base_addr = m25pxx_flash_device.start;
+    for (i = 0; i < (m25pxx_flash_device.end - m25pxx_flash_device.start) / 4;) {
+        for (j = 0; j < BUF_SIZE;) {
+            wbuf [j++] = (cyg_uint8) ((i >> 0) & 0xFF);
+            wbuf [j++] = (cyg_uint8) ((i >> 8) & 0xFF);
+            wbuf [j++] = (cyg_uint8) ((i >> 16) & 0xFF);
+            wbuf [j++] = (cyg_uint8) ((i >> 24) & 0xFF);            
+            i++;
+        }
+        status = cyg_flash_read (base_addr, rbuf, BUF_SIZE, &err_addr);
+        if (status != FLASH_ERR_OK) {
+            diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+            errors ++;
+        }
+        else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+            diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n", base_addr, base_addr + BUF_SIZE - 1);
+            errors ++;
+        }
+        base_addr += BUF_SIZE;
+    }
+    return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Perform non-aligned buffer read/write tests, spanning sector boundaries.
+
+cyg_uint32 run_test_3
+  (void)
+{
+    int status;
+    cyg_uint32 i, count;
+    cyg_uint32 errors = 0;
+    cyg_flashaddr_t base_addr, err_addr;
+
+    diag_printf ("Test 3 - test non-aligned writes and reads.\n");
+    
+    // Fill the write buffer with a basic counting sequence.
+    count = 0;
+    for (i = 0; i < BUF_SIZE;) {
+        wbuf [i++] = (cyg_uint8) ((count >> 0) & 0xFF);
+        wbuf [i++] = (cyg_uint8) ((count >> 8) & 0xFF);
+        count++;
+    }
+
+    // Assuming 256 byte pages gives 256 possible alignments.
+    base_addr = m25pxx_flash_device.start + m25pxx_flash_device.block_info->block_size;
+    for (i = 1; i <= 256; i++) {
+
+        // Erase sectors either side of sector boundary.
+        status = cyg_flash_erase (base_addr - 1, 1, &err_addr);
+        if (status != FLASH_ERR_OK) {
+            diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+            errors ++;
+        }
+        status = cyg_flash_erase (base_addr, 1, &err_addr);
+        if (status != FLASH_ERR_OK) {
+            diag_printf ("Flash erase error : %s\n", cyg_flash_errmsg (status));
+            errors ++;
+        }
+
+        // Write data spanning sector boundary.        
+        status = cyg_flash_program (base_addr - i, wbuf, BUF_SIZE, &err_addr);
+        if (status != FLASH_ERR_OK) {
+            diag_printf ("Flash write error : %s\n", cyg_flash_errmsg (status));
+            errors ++;
+        }
+
+        // Verify data spanning sector boundary.
+        status = cyg_flash_read (base_addr - i, rbuf, BUF_SIZE, &err_addr);
+        if (status != FLASH_ERR_OK) {
+            diag_printf ("Flash read error : %s\n", cyg_flash_errmsg (status));
+            errors ++;
+        }
+        else if (memcmp (rbuf, wbuf, BUF_SIZE) != 0) {
+            diag_printf ("Flash read data corruption (0x%08X - 0x%08X).\n", base_addr - i, base_addr - i + BUF_SIZE - 1);
+            errors ++;
+        }
+
+        // Use next sector boundary for next test.
+        base_addr += m25pxx_flash_device.block_info->block_size;
+        if (base_addr >= m25pxx_flash_device.end)
+            base_addr = m25pxx_flash_device.start + m25pxx_flash_device.block_info->block_size;
+    }
+    return errors;
+}
+
+//-----------------------------------------------------------------------------
+// Run all M25Pxx SPI interface loopback tests.
+
+void run_tests 
+    (void)
+{
+    cyg_uint32 errors = 0;
+
+    // Check that the device is intialised.
+    if (m25pxx_flash_device.start == m25pxx_flash_device.end) {
+        diag_printf ("M25Pxx device not initialised.\n");
+        errors ++;
+        goto out;
+    }
+
+    // Run the tests.
+    errors += run_test_1 (); 
+    errors += run_test_2 (); 
+    errors += run_test_3 ();
+
+out:
+    diag_printf ("----\nTests complete - detected %d errors in total.\n", errors);
+    if (errors == 0)
+        CYG_TEST_PASS_FINISH ("M25Pxx driver tests ran OK.");
+    else 
+        CYG_TEST_FAIL_FINISH ("M25Pxx driver test FAILED.");
+}
+
+//-----------------------------------------------------------------------------
+// User startup - tests are run in their own thread.
+
+void cyg_user_start
+    (void)
+{
+    do_version();
+    diag_printf ("----\nChecking for M25Pxx compatible devices.\n");
+    cyg_flash_init (&diag_printf);
+    CYG_TEST_INIT();
+    cyg_thread_create(
+        10,                                   // Arbitrary priority
+        (cyg_thread_entry_t*) run_tests,      // Thread entry point
+        0,                                    // 
+        "test_thread",                        // Thread name
+        (cyg_uint8*) stack,                   // Stack
+        CYGNUM_HAL_STACK_SIZE_TYPICAL,        // Stack size
+        &thread_handle,                       // Thread handle
+        &thread_data                          // Thread data structure
+    );
+    cyg_thread_resume(thread_handle);
+    cyg_scheduler_start();
+}
+
+//=============================================================================
diff -r -u5 -N cvs-05.02.09/ecos/packages//ecos.db working-05.02.09/ecos/packages//ecos.db
--- cvs-05.02.09/ecos/packages//ecos.db	2009-02-05 11:12:45.000000000 +0000
+++ working-05.02.09/ecos/packages//ecos.db	2009-02-05 14:25:55.000000000 +0000
@@ -254,10 +254,18 @@
     script      devs_flash_atmel_dataflash.cdl
     hardware
     description "This package contains hardware support for Atmel DataFlash."
 }
 
+package CYGPKG_DEVS_FLASH_SPI_M25PXX {
+        alias           { "M25Pxx SPI Flash" flash_spi_m25pxx }
+        directory       devs/flash/spi/m25pxx
+        script          m25pxx.cdl
+        description "
+        Support for M25Pxx SPI flash devices."
+}
+
 package CYGPKG_DEVS_FLASH_ARM_PID {
 	alias 		{ "Support for flash memory on ARM/PID board" flash_arm_pid }
 	directory	devs/flash/arm/pid
 	script		flash_arm_pid.cdl
 	hardware
@@ -6844,10 +6852,11 @@
         packages { CYGPKG_HAL_CORTEXM
                    CYGPKG_HAL_CORTEXM_STM32
                    CYGPKG_HAL_CORTEXM_STM32_STM3210E_EVAL
                    CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2
                    CYGPKG_DEVS_FLASH_STM32
+                   CYGPKG_DEVS_FLASH_SPI_M25PXX
                    CYGPKG_IO_SERIAL_CORTEXM_STM32
                    CYGPKG_DEVS_WALLCLOCK_STM32
                    CYGPKG_IO_SPI
                    CYGPKG_DEVS_SPI_CORTEXM_STM32
                  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]