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]

[flashv2 merge] Dataflash driver


Attached...
-- 
eCosCentric Limited      http://www.eCosCentric.com/     The eCos experts
Barnwell House, Barnwell Drive, Cambridge, UK.       Tel: +44 1223 245571
Registered in England and Wales: Reg No 4422071.
------["Si fractum non sit, noli id reficere"]------       Opinions==mine
Index: packages/devs/flash/atmel/dataflash/current/ChangeLog
===================================================================
RCS file: packages/devs/flash/atmel/dataflash/current/ChangeLog
diff -N packages/devs/flash/atmel/dataflash/current/ChangeLog
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ packages/devs/flash/atmel/dataflash/current/ChangeLog	18 Nov 2008 01:05:46 -0000
@@ -0,0 +1,96 @@
+2005-06-29  Jani Monoses <ani@iv.ro>
+
+	* include/dataflash.h: Allow the package to be compiled without
+	io/flash. Return correct value from cyg_dataflash_get_page_count()
+
+2004-12-02  Bart Veer  <bartv@ecoscentric.com>
+
+	* include/dataflash.h,
+	src/devs_flash_atmel_dataflash_flash_dev_funs.c: include
+	<cyg/io/flash_dev.h> explicitly rather than using _FLASH_PRIVATE_
+
+2004-11-29  Bart Veer  <bartv@ecoscentric.com>
+
+	(df_flash_hwr_map_error): this is now internal to the driver, no
+	longer needed by the generic flash code.
+	* src/devs_flash_atmel_dataflash_flash_dev_funs.c: use the dummy
+	query/lock/unlock functions provided by the generic flash code
+
+2004-11-22  Bart Veer  <bartv@ecoscentric.com>
+
+	* include/dataflash.h, src/devs_flash_atmel_dataflash.c,
+	src/devs_flash_atmel_dataflash_flash_dev_funs.c: merge the config
+	and priv structures, removing the duplicate spi_dev data in the
+	process. Adjust device driver API as per changes to the generic
+	flash code.
+	* src/devs_flash_atmel_dataflash_flash_dev_funs.c (df_flash_init):
+	Rename cyg_block_info to cyg_flash_block_info
+
+2004-11-21  Bart Veer  <bartv@ecoscentric.com>
+
+	* cdl/devs_flash_atmel_dataflash.cdl: CYGHWR_IO_FLASH_DEVICE_V2 is
+	now implicit
+
+2004-11-20  Bart Veer  <bartv@ecoscentric.com>
+
+	* cdl/devs_flash_atmel_dataflash.cdl: data flash requires indirect
+	read support in the main flash code.
+
+2004-10-07  Savin Zlobec  <savin@elatec.si> 
+
+        * include/dataflash.h:
+        * src/devs_flash_atmel_dataflash.c:
+        Changed the API to be more consistent, included error
+        reporting and added blocking/non blocking mode of operation.
+        * src/devs_flash_atmel_dataflash_flash_dev_funs.c:
+        Synced with new API and set the block size to DataFlash's
+        native page size.
+
+2004-10-07  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* cdl/devs_flash_atmel_dataflash.cdl: Remove
+	CYGSEM_IO_FLASH_READ_INDIRECT which only legacy drivers should use
+	when they provide a flash_read_buf function. For V2 drivers
+	providing a read function in the device structure is sufficient.
+
+2004-09-07  Savin Zlobec  <savin@elatec.si> 
+
+        * cdl/devs_flash_atmel_dataflash.cdl:
+        * include/dataflash.h:
+        * src/devs_flash_atmel_dataflash.c:  
+        * src/devs_flash_atmel_dataflash_flash_dev_funs.c:
+        Atmel DataFlash driver implementation.   	 
+
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 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.
+//
+// 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####
+//===========================================================================
Index: packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl
===================================================================
RCS file: packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl
diff -N packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ packages/devs/flash/atmel/dataflash/current/cdl/devs_flash_atmel_dataflash.cdl	18 Nov 2008 01:05:46 -0000
@@ -0,0 +1,71 @@
+# ====================================================================
+#
+#      devs_flash_atmel_dataflash.cdl
+#
+#      Atmel DataFlash parts support
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 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.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      Savin Zlobec <savin@elatec.si> 
+# Date:           2004-08-27
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ATMEL_DATAFLASH {
+    display       "Atmel DataFlash parts support"
+    description   "Support for Atmel DataFlash"
+    active_if	  CYGPKG_IO_SPI
+    requires      CYGPKG_ERROR    
+    hardware
+    compile       devs_flash_atmel_dataflash.c 
+    include_dir   cyg/io
+
+    cdl_interface CYGPKG_DEVS_FLASH_ATMEL_DATAFLASH_FLASH_DEV {
+        display         "Support for DataFlash IO Flash interface"
+        flavor          bool
+        active_if       CYGPKG_IO_FLASH
+        implements      CYGHWR_IO_FLASH_DEVICE
+	implements	CYGHWR_IO_FLASH_INDIRECT_READS
+        compile         devs_flash_atmel_dataflash_flash_dev_funs.c     
+        description     "This option will be enabled by platforms which
+            need to support access to DataFlash through IO Flash API."
+    }
+}
+
+# EOF devs_flash_atmel_dataflash.cdl 
Index: packages/devs/flash/atmel/dataflash/current/include/dataflash.h
===================================================================
RCS file: packages/devs/flash/atmel/dataflash/current/include/dataflash.h
diff -N packages/devs/flash/atmel/dataflash/current/include/dataflash.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ packages/devs/flash/atmel/dataflash/current/include/dataflash.h	18 Nov 2008 01:05:46 -0000
@@ -0,0 +1,249 @@
+#ifndef CYGONCE_DATAFLASH_H
+#define CYGONCE_DATAFLASH_H
+//==========================================================================
+//
+//      dataflash.h
+//
+//      DataFlash series flash driver defines
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 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.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Savin Zlobec <savin@elatec.si> 
+// Date:         2004-08-27
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_atmel_dataflash.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+
+//----------------------------------------------------------------------------
+
+enum {
+    CYG_DATAFLASH_ERR_OK         = 0, // No error
+    CYG_DATAFLASH_ERR_INVALID    = 1, // Invalid address error
+    CYG_DATAFLASH_ERR_WRONG_PART = 2, // Unsupported device error
+    CYG_DATAFLASH_ERR_TIMEOUT    = 3, // Operation timeout error
+    CYG_DATAFLASH_ERR_COMPARE    = 4  // Buffer - main memory compare error
+};
+
+enum {
+    CYG_DATAFLASH_STATE_IDLE = 0,
+    CYG_DATAFLASH_STATE_BUSY = 1
+};
+
+//----------------------------------------------------------------------------
+
+typedef struct cyg_dataflash_dev_info_s
+{
+    cyg_uint8  device_id;        // Device ID 
+    cyg_uint16 page_size;        // Page size in bytes
+    cyg_uint16 page_count;       // Total number of pages
+    cyg_uint8  baddr_bits;       // Bits used for byte address in addressing seq
+    cyg_uint16 block_size;       // Block size in pages
+    cyg_uint16 sector_sizes[64]; // Sector sizes in blocks
+    cyg_uint16 sector_count;     // Total number of sectors 
+} cyg_dataflash_dev_info_t;
+
+typedef struct cyg_dataflash_device_s
+{
+    const cyg_dataflash_dev_info_t *info;     // DataFlash device info
+    cyg_spi_device                 *spi_dev;  // SPI device
+    cyg_drv_mutex_t                 lock;     // Access lock 
+    cyg_bool                        polled;   // Polled mode flag
+    cyg_bool                        blocking; // Blocking mode flag 
+    int                             state;    // Current state (IDLE, BUSY, ...)
+    cyg_uint8                       busy_buf; // Current busy buffer number
+} cyg_dataflash_device_t;
+
+//----------------------------------------------------------------------------
+#ifdef CYGPKG_IO_FLASH
+#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
+
+typedef struct cyg_dataflash_flash_dev_priv_s
+{
+    cyg_int16               start_sector;   // Start sector of flash driver space
+    cyg_int16               end_sector;     // End sector of flash driver space
+    cyg_dataflash_device_t  dev;            // DataFlash device
+    cyg_uint32              start_page;     // Start page of flash driver space
+    cyg_uint32              end_page;       // End page of flash driver space
+    cyg_flash_block_info_t  block_info[1];
+} cyg_dataflash_flash_dev_priv_t;
+
+externC struct cyg_flash_dev_funs cyg_dataflash_flash_dev_funs;
+
+#define CYG_DATAFLASH_FLASH_DRIVER(name, _sdev, _addr, _start, _end)            \
+    static cyg_dataflash_flash_dev_priv_t cyg_dataflash_priv_ ## name = {       \
+        .start_sector = _start,                                                 \
+        .end_sector   = _end,                                                   \
+        .dev.spi_dev  = _sdev,                                                  \
+    };                                                                          \
+    CYG_FLASH_DRIVER(name,                                                      \
+                     &cyg_dataflash_flash_dev_funs,                             \
+                     0,                                                         \
+                     _addr,                                                     \
+                     0,                                                         \
+                     1,                                                         \
+                     cyg_dataflash_priv_ ## name.block_info,                    \
+                     & cyg_dataflash_priv_ ## name                              \
+        )
+    
+#endif
+//----------------------------------------------------------------------------
+
+static inline cyg_uint8
+cyg_dataflash_get_device_id(cyg_dataflash_device_t *dev)
+{
+    return dev->info->device_id;
+}
+
+static inline cyg_uint16
+cyg_dataflash_get_page_size(cyg_dataflash_device_t *dev)
+{
+    return dev->info->page_size;
+}
+
+static inline cyg_uint16
+cyg_dataflash_get_page_count(cyg_dataflash_device_t *dev)
+{
+    return dev->info->page_count;
+}
+
+static inline cyg_uint16
+cyg_dataflash_get_block_size(cyg_dataflash_device_t *dev)
+{
+    return dev->info->block_size;
+}
+
+static inline cyg_uint16
+cyg_dataflash_get_sector_size(cyg_dataflash_device_t *dev, cyg_uint8 sector_num)
+{
+    return dev->info->sector_sizes[sector_num];
+}
+
+static inline cyg_uint16
+cyg_dataflash_get_sector_count(cyg_dataflash_device_t *dev)
+{
+    return dev->info->sector_count;
+}
+
+static inline void
+cyg_dataflash_set_polled_operation(cyg_dataflash_device_t *dev, cyg_bool polled)
+{
+    dev->polled = polled;
+}
+
+static inline void
+cyg_dataflash_set_blocking_operation(cyg_dataflash_device_t *dev, cyg_bool block)
+{
+    dev->blocking = block;
+} 
+
+//----------------------------------------------------------------------------
+
+externC int cyg_dataflash_init(cyg_bool                polled,
+                               cyg_dataflash_device_t *dev);
+
+externC int cyg_dataflash_aquire(cyg_dataflash_device_t *dev);
+
+externC int cyg_dataflash_release(cyg_dataflash_device_t *dev);
+
+externC cyg_uint16 cyg_dataflash_get_sector_start(cyg_dataflash_device_t *dev,
+                                                  cyg_uint16 sector_num);
+
+externC int cyg_dataflash_wait_ready(cyg_dataflash_device_t *dev);
+
+externC int cyg_dataflash_read_buf(cyg_dataflash_device_t *dev,
+                                   cyg_uint8               buf_num,
+                                   cyg_uint8              *buf, 
+                                   cyg_uint32              len, 
+                                   cyg_uint32              pos); 
+                       
+externC int cyg_dataflash_write_buf(cyg_dataflash_device_t *dev,
+                                    cyg_uint8               buf_num,
+                                    const cyg_uint8        *buf,
+                                    cyg_uint32              len,
+                                    cyg_uint32              pos);
+
+externC int cyg_dataflash_mem_to_buf(cyg_dataflash_device_t *dev,
+                                     cyg_uint8               buf_num,
+                                     cyg_uint32              page_num);
+
+externC int cyg_dataflash_program_buf(cyg_dataflash_device_t *dev,
+                                      cyg_uint8               buf_num,
+                                      cyg_uint32              page_num,
+                                      cyg_bool                erase);
+
+externC int cyg_dataflash_compare_buf(cyg_dataflash_device_t *dev,
+                                      cyg_uint8               buf_num,
+                                      cyg_uint32              page_num);
+
+externC int cyg_dataflash_erase(cyg_dataflash_device_t *dev,
+                                cyg_uint32              page_num);
+
+externC int cyg_dataflash_erase_block(cyg_dataflash_device_t *dev,
+                                      cyg_uint32              block_num);
+
+externC int cyg_dataflash_auto_rewrite(cyg_dataflash_device_t *dev,
+                                       cyg_uint8               buf_num,
+                                       cyg_uint32              page_num);
+
+externC int cyg_dataflash_read(cyg_dataflash_device_t *dev, 
+                               cyg_uint8              *buf, 
+                               cyg_uint32              len, 
+                               cyg_uint32              pos);
+
+externC int cyg_dataflash_program(cyg_dataflash_device_t *dev, 
+                                  const cyg_uint8        *buf, 
+                                  cyg_uint32             *len, 
+                                  cyg_uint32              pos,
+                                  cyg_bool                erase,
+                                  cyg_bool                verify);
+
+//----------------------------------------------------------------------------
+
+#endif // CYGONCE_DATAFLASH_H
+
+//----------------------------------------------------------------------------
+// End of dataflash.h
Index: packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c
===================================================================
RCS file: packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c
diff -N packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash.c	18 Nov 2008 01:05:46 -0000
@@ -0,0 +1,923 @@
+//==========================================================================
+//
+//      devs_flash_atmel_dataflash.c 
+//
+//      Atmel DataFlash series flash driver
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 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.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Savin Zlobec <savin@elatec.si> 
+// Date:         2004-08-27
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_atmel_dataflash.h>
+
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/dataflash.h>
+
+// -------------------------------------------------------------------------- 
+// DataFlash command opcodes
+
+// Read commands opcodes
+#define DF_CONT_ARRAY_READ_CMD              0x68
+#define DF_MMEM_PAGE_READ_CMD               0x52
+#define DF_BUF1_READ_CMD                    0x54
+#define DF_BUF2_READ_CMD                    0x56
+#define DF_STATUS_READ_CMD                  0x57
+
+// Program and erase commands opcodes
+#define DF_BUF1_WRITE_CMD                   0x84
+#define DF_BUF2_WRITE_CMD                   0x87
+#define DF_BUF1_PROG_W_ERASE_CMD            0x83
+#define DF_BUF2_PROG_W_ERASE_CMD            0x86
+#define DF_BUF1_PROG_WO_ERASE_CMD           0x88
+#define DF_BUF2_PROG_WO_ERASE_CMD           0x89
+#define DF_PAGE_ERASE_CMD                   0x81
+#define DF_BLOCK_ERASE_CMD                  0x50
+#define DF_PROG_THROUGH_BUF1_CMD            0x82  
+#define DF_PROG_THROUGH_BUF2_CMD            0x85
+
+// Additional commands opcodes
+#define DF_TRANSFER_TO_BUF1_CMD             0x53
+#define DF_TRANSFER_TO_BUF2_CMD             0x55
+#define DF_BUF1_COMPARE_CMD                 0x60
+#define DF_BUF2_COMPARE_CMD                 0x61
+#define DF_AUTO_REWRITE_THROUGH_BUF1_CMD    0x58
+#define DF_AUTO_REWRITE_THROUGH_BUF2_CMD    0x59
+
+//----------------------------------------------------------------------------
+
+#define DATA_BUF_NONE 0x00 // Data buffer number for no buffer
+#define DATA_BUF_ALL  0xFF // Data buffer number for all buffers
+
+//----------------------------------------------------------------------------
+
+typedef struct df_status_s
+{
+    cyg_uint8 reserved:2;
+    cyg_uint8 device_id:4;
+    cyg_uint8 compare_err:1;
+    cyg_uint8 ready:1;
+} df_status_t;
+
+//----------------------------------------------------------------------------
+
+static const cyg_dataflash_dev_info_t df_dev_info[] =
+{
+    {   // AT45DB011B
+        device_id:    0x03,
+        page_size:    264,
+        page_count:   512,
+        baddr_bits:   9,  
+        block_size:   8,
+        sector_sizes: { 1, 31, 32 },          
+        sector_count: 3
+    },
+    {   // AT45DB021B
+        device_id:    0x05,
+        page_size:    264,
+        page_count:   1024, 
+        baddr_bits:   9,
+        block_size:   8,
+        sector_sizes: { 1, 31, 32, 64 },
+        sector_count: 4
+    },
+    {   // AT45DB041B
+        device_id:    0x07,
+        page_size:    264,
+        page_count:   2048, 
+        baddr_bits:   9,
+        block_size:   8,
+        sector_sizes: { 1, 31, 32, 64, 64, 64 },
+        sector_count: 6
+    },
+    {   // AT45DB081B
+        device_id:    0x09,
+        page_size:    264,
+        page_count:   4096, 
+        baddr_bits:   9,
+        block_size:   8,
+        sector_sizes: { 1, 31, 32, 64, 64, 64, 64, 64, 64, 64 },
+        sector_count: 10 
+    },
+    {   // AT45DB161B
+        device_id:    0x0B,
+        page_size:    528,
+        page_count:   4096, 
+        baddr_bits:   10,
+        block_size:   8,
+        sector_sizes: {  1, 31, 32, 32, 32, 32, 32, 32, 
+                        32, 32, 32, 32, 32, 32, 32, 32, 32 },
+        sector_count: 17 
+    },
+    {   // AT45DB321B
+        device_id:    0x0D,
+        page_size:    528,
+        page_count:   8192,
+        baddr_bits:   10,
+        block_size:   8,
+        sector_sizes: {  1, 63, 64, 64, 64, 64, 64, 64, 
+                        64, 64, 64, 64, 64, 64, 64, 64, 64 },
+        sector_count: 17 
+    },
+    {   // AT45DB642
+        device_id:    0x0F,
+        page_size:    1056,
+        page_count:   8192, 
+        baddr_bits:   11,
+        block_size:   8,
+        sector_sizes: {  1, 31, 32, 32, 32, 32, 32, 32,
+                        32, 32, 32, 32, 32, 32, 32, 32,
+                        32, 32, 32, 32, 32, 32, 32, 32,
+                        32, 32, 32, 32, 32, 32, 32, 32, 32 },
+        sector_count: 35
+    },
+    { 0 }
+};
+
+//----------------------------------------------------------------------------
+
+static void
+df_compose_addr(cyg_dataflash_device_t *dev,
+                cyg_uint8              *cmd_buf, 
+                cyg_uint16              page_addr, 
+                cyg_uint16              byte_addr)
+{
+    cyg_uint32 baddr_bits = dev->info->baddr_bits;
+    cyg_uint32 addr; 
+
+    addr = (page_addr << baddr_bits) | (byte_addr & ((1<<baddr_bits) - 1));
+    
+    cmd_buf[1] = (addr >> 16) & 0xFF;
+    cmd_buf[2] = (addr >>  8) & 0xFF;
+    cmd_buf[3] = addr         & 0xFF;
+}
+        
+static df_status_t
+df_read_status(cyg_dataflash_device_t *dev)
+{
+    cyg_spi_device  *spi_dev    = dev->spi_dev;
+    const cyg_uint8  cmd_buf[2] = { DF_STATUS_READ_CMD, 0 };
+    cyg_uint8        rx_buf[2];
+    df_status_t     *status;
+   
+    cyg_spi_transaction_transfer(spi_dev, true, 2, cmd_buf, rx_buf, true);
+
+    status = (df_status_t *) &rx_buf[1];
+
+    return *status;    
+}
+
+static void
+df_set_busy_buf(cyg_dataflash_device_t *dev, cyg_uint8 buf_num)
+{
+    dev->state    = CYG_DATAFLASH_STATE_BUSY;
+    dev->busy_buf = buf_num;
+}
+
+static void
+df_set_busy(cyg_dataflash_device_t *dev)
+{
+    df_set_busy_buf(dev, DATA_BUF_ALL);
+}
+
+static int
+df_wait_ready_buf(cyg_dataflash_device_t *dev, cyg_uint8 buf_num)
+{
+    df_status_t status;
+  
+    if (CYG_DATAFLASH_STATE_IDLE == dev->state)
+        return CYG_DATAFLASH_ERR_OK;
+    
+    if (DATA_BUF_ALL  == buf_num       || 
+        DATA_BUF_ALL  == dev->busy_buf || 
+        dev->busy_buf == buf_num)
+    {
+        // REMIND: this loop should have an timeout 
+        // in case of device malfunction
+
+        do 
+        {
+            status = df_read_status(dev);
+        } while (0 == status.ready); 
+
+        dev->state    = CYG_DATAFLASH_STATE_IDLE;
+        dev->busy_buf = DATA_BUF_NONE;
+    }
+    
+    return CYG_DATAFLASH_ERR_OK;  
+   
+}
+
+static int
+df_wait_ready(cyg_dataflash_device_t *dev)
+{
+    return df_wait_ready_buf(dev, DATA_BUF_ALL);
+}
+
+static void 
+df_detect_device(cyg_dataflash_device_t *dev)
+{
+    const cyg_dataflash_dev_info_t *dev_info;
+    cyg_spi_device                 *spi_dev = dev->spi_dev;
+    df_status_t                     status;
+    
+    cyg_spi_transaction_begin(spi_dev);
+    status = df_read_status(dev);
+    cyg_spi_transaction_end(spi_dev);
+   
+    dev_info = df_dev_info;
+
+    while (dev_info->device_id != 0)
+    {
+        if (status.device_id == dev_info->device_id)
+        {
+            dev->info = dev_info;
+            return;
+        }
+        dev_info++;
+    }
+    dev->info = NULL;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_init()
+
+int
+cyg_dataflash_init(cyg_bool                polled,
+                   cyg_dataflash_device_t *dev)
+{
+    dev->polled   = polled;
+    dev->blocking = false;
+    dev->state    = CYG_DATAFLASH_STATE_IDLE;
+    dev->busy_buf = DATA_BUF_NONE;
+
+    cyg_drv_mutex_init(&dev->lock);
+
+    df_detect_device(dev);
+
+    if (NULL == dev->info)
+        return CYG_DATAFLASH_ERR_WRONG_PART;
+    else
+        return CYG_DATAFLASH_ERR_OK;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_aquire()
+
+int
+cyg_dataflash_aquire(cyg_dataflash_device_t *dev)
+{
+    while (!cyg_drv_mutex_lock(&dev->lock));
+    return CYG_DATAFLASH_ERR_OK; 
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_release()
+
+int
+cyg_dataflash_release(cyg_dataflash_device_t *dev)
+{
+    int err;
+
+    err = df_wait_ready(dev); 
+        
+    cyg_drv_mutex_unlock(&dev->lock);
+
+    return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_get_sector_start()
+
+cyg_uint16
+cyg_dataflash_get_sector_start(cyg_dataflash_device_t *dev, 
+                               cyg_uint16              sector_num)
+{
+    cyg_uint16 res, i;
+    
+    if (sector_num >= dev->info->sector_count)
+        return 0;
+
+    res = 0;
+    for (i = 0; i < sector_num; i++)
+        res += dev->info->sector_sizes[i];
+
+    return res;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_wait_ready()
+
+int 
+cyg_dataflash_wait_ready(cyg_dataflash_device_t *dev)
+{
+    return df_wait_ready(dev);
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_read_buf()
+
+int
+cyg_dataflash_read_buf(cyg_dataflash_device_t *dev,
+                       cyg_uint8               buf_num,
+                       cyg_uint8              *buf, 
+                       cyg_uint32              len, 
+                       cyg_uint32              pos) 
+                       
+{
+    cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
+    cyg_uint8       cmd_buf[5];
+
+    // Check if the position is inside the page 
+    if (pos >= dev->info->page_size)
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
+
+    if (1 == buf_num)      cmd_buf[0] = DF_BUF1_READ_CMD;
+    else if (2 == buf_num) cmd_buf[0] = DF_BUF2_READ_CMD;
+    else 
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    df_compose_addr(dev, cmd_buf, 0, pos);
+
+    cyg_spi_transaction_begin(spi_dev);
+
+    // Wait for the target buffer to become ready
+    err = df_wait_ready_buf(dev, buf_num);
+
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send command and read data
+
+        cyg_spi_transaction_transfer(spi_dev, true, 5, cmd_buf, NULL, false);
+        cyg_spi_transaction_transfer(spi_dev, dev->polled, len, buf, buf, true);
+    }
+    
+    cyg_spi_transaction_end(spi_dev);
+
+    return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_write_buf()
+
+int
+cyg_dataflash_write_buf(cyg_dataflash_device_t *dev,
+                        cyg_uint8               buf_num,
+                        const cyg_uint8        *buf,
+                        cyg_uint32              len,
+                        cyg_uint32              pos)
+{
+    cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
+    cyg_uint8       cmd_buf[4];
+ 
+    // Check if the position is inside the page 
+    if (pos >= dev->info->page_size)
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
+
+    if (1 == buf_num)      cmd_buf[0] = DF_BUF1_WRITE_CMD;
+    else if (2 == buf_num) cmd_buf[0] = DF_BUF2_WRITE_CMD;
+    else 
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    df_compose_addr(dev, cmd_buf, 0, pos);
+
+    cyg_spi_transaction_begin(spi_dev);
+
+    // Wait for the target buffer to become ready
+    err = df_wait_ready_buf(dev, buf_num);
+    
+    if (CYG_DATAFLASH_ERR_OK == err)
+    { 
+        // Send command and data
+
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, false);
+        cyg_spi_transaction_transfer(spi_dev, dev->polled, 
+                                     len, buf, NULL, true);
+    }
+
+    cyg_spi_transaction_end(spi_dev);
+
+    return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_mem_to_buf()
+
+int
+cyg_dataflash_mem_to_buf(cyg_dataflash_device_t *dev,
+                         cyg_uint8               buf_num,
+                         cyg_uint32              page_num)
+{
+    cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
+    cyg_uint8       cmd_buf[4];
+    
+    // Check if the page number is inside the flash
+    if (page_num >= dev->info->page_count)
+        return CYG_DATAFLASH_ERR_INVALID;
+    
+    // Compose DataFlash command
+
+    if (1 == buf_num)      cmd_buf[0] = DF_TRANSFER_TO_BUF1_CMD;
+    else if (2 == buf_num) cmd_buf[0] = DF_TRANSFER_TO_BUF2_CMD;
+    else 
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    df_compose_addr(dev, cmd_buf, page_num, 0);
+
+    cyg_spi_transaction_begin(spi_dev);
+
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+        // Mark the target buffer as busy
+        df_set_busy_buf(dev, buf_num);
+
+        // Wait if in blocking mode     
+        if (dev->blocking)
+            err = df_wait_ready(dev);
+    }
+
+    cyg_spi_transaction_end(spi_dev);
+
+    return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_program_buf()
+
+int
+cyg_dataflash_program_buf(cyg_dataflash_device_t *dev,
+                          cyg_uint8               buf_num,
+                          cyg_uint32              page_num,
+                          cyg_bool                erase)
+{
+    cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
+    cyg_uint8       cmd_buf[4];
+    
+    // Check if the page number is inside the flash
+    if (page_num >= dev->info->page_count)
+        return CYG_DATAFLASH_ERR_INVALID;
+    
+    // Compose DataFlash command
+
+    if (erase)
+    {
+        if (1 == buf_num)      cmd_buf[0] = DF_BUF1_PROG_W_ERASE_CMD;
+        else if (2 == buf_num) cmd_buf[0] = DF_BUF2_PROG_W_ERASE_CMD; 
+        else 
+            return CYG_DATAFLASH_ERR_INVALID;
+    }
+    else
+    {
+        if (1 == buf_num)      cmd_buf[0] = DF_BUF1_PROG_WO_ERASE_CMD;
+        else if (2 == buf_num) cmd_buf[0] = DF_BUF2_PROG_WO_ERASE_CMD; 
+        else 
+            return CYG_DATAFLASH_ERR_INVALID;
+    }
+    
+    df_compose_addr(dev, cmd_buf, page_num, 0);
+
+    cyg_spi_transaction_begin(spi_dev);
+
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+    
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+        // Mark the target buffer as busy    
+        df_set_busy_buf(dev, buf_num);
+
+        // Wait if in blocking mode
+        if (dev->blocking)
+            err = df_wait_ready(dev);
+    }
+    
+    cyg_spi_transaction_end(spi_dev);
+
+    return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_compare_buf()
+
+int
+cyg_dataflash_compare_buf(cyg_dataflash_device_t *dev,
+                          cyg_uint8               buf_num,
+                          cyg_uint32              page_num)
+{
+    cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
+    cyg_uint8       cmd_buf[4];
+    df_status_t     status;
+
+    // Check if the page number is inside the flash
+    if (page_num >= dev->info->page_count)
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
+
+    if (1 == buf_num)      cmd_buf[0] = DF_BUF1_COMPARE_CMD;
+    else if (2 == buf_num) cmd_buf[0] = DF_BUF2_COMPARE_CMD; 
+    else 
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    df_compose_addr(dev, cmd_buf, page_num, 0);
+
+    cyg_spi_transaction_begin(spi_dev);
+
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+   
+    if (CYG_DATAFLASH_ERR_OK == err)
+    { 
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+        // Wait for the device to become ready
+        df_set_busy(dev);
+        err = df_wait_ready(dev);
+    
+        // Read the result of memory compare
+
+        if (CYG_DATAFLASH_ERR_OK == err)
+        {
+            status = df_read_status(dev);
+            if (status.compare_err)
+                err = CYG_DATAFLASH_ERR_COMPARE;
+        }
+    }
+
+    cyg_spi_transaction_end(spi_dev);
+
+    return err; 
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_erase()
+
+int
+cyg_dataflash_erase(cyg_dataflash_device_t *dev,
+                    cyg_uint32              page_num)
+{
+    cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
+    cyg_uint8       cmd_buf[4];
+
+    // Check if the page number is inside the flash
+    if (page_num >= dev->info->page_count)
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
+
+    cmd_buf[0] = DF_PAGE_ERASE_CMD;
+    df_compose_addr(dev, cmd_buf, page_num, 0);
+
+    cyg_spi_transaction_begin(spi_dev);
+
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+    
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+        // Set device state to busy
+        df_set_busy_buf(dev, DATA_BUF_NONE);
+        
+        // Wait if in blocking mode
+        if (dev->blocking)
+            err = df_wait_ready(dev);
+    }
+    
+    cyg_spi_transaction_end(spi_dev);
+
+    return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_erase_block()
+
+int
+cyg_dataflash_erase_block(cyg_dataflash_device_t *dev,
+                          cyg_uint32              block_num)
+{
+    cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
+    cyg_uint8       cmd_buf[4];
+
+    // Check if the block number is inside the flash
+    if (block_num >= (dev->info->page_count >> 3))
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
+
+    cmd_buf[0] = DF_BLOCK_ERASE_CMD;
+    df_compose_addr(dev, cmd_buf, block_num << 3, 0);
+
+    cyg_spi_transaction_begin(spi_dev);
+
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+        // Set device state to busy
+        df_set_busy_buf(dev, DATA_BUF_NONE);
+ 
+        // Wait if in blocking mode
+        if (dev->blocking)
+            err = df_wait_ready(dev);
+    }
+    
+    cyg_spi_transaction_end(spi_dev);
+
+    return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_auto_rewrite()
+
+int
+cyg_dataflash_auto_rewrite(cyg_dataflash_device_t *dev,
+                           cyg_uint8               buf_num,
+                           cyg_uint32              page_num)
+{
+    cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
+    cyg_uint8       cmd_buf[4];
+
+    // Check if the page number is inside the flash
+    if (page_num >= dev->info->page_count)
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    // Compose DataFlash command
+
+    if (1 == buf_num)      cmd_buf[0] = DF_AUTO_REWRITE_THROUGH_BUF1_CMD;
+    else if (2 == buf_num) cmd_buf[0] = DF_AUTO_REWRITE_THROUGH_BUF2_CMD; 
+    else 
+        return CYG_DATAFLASH_ERR_INVALID;
+
+    df_compose_addr(dev, cmd_buf, page_num, 0);
+
+    cyg_spi_transaction_begin(spi_dev);
+
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {
+        // Send the command 
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+
+        // Mark the target buffer as busy
+        df_set_busy_buf(dev, buf_num);
+
+        // Wait if in blocking mode
+        if (dev->blocking)
+            err = df_wait_ready(dev);
+    }
+    
+    cyg_spi_transaction_end(spi_dev);
+
+    return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_read()
+
+int
+cyg_dataflash_read(cyg_dataflash_device_t *dev, 
+                   cyg_uint8              *buf, 
+                   cyg_uint32              len, 
+                   cyg_uint32              pos)
+{
+    cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
+    cyg_uint8       cmd_buf[8];
+    cyg_uint32      page_num, page_pos;
+
+    // Calculate page number and position from given absolute position
+
+    page_num = pos / dev->info->page_size;
+    page_pos = pos % dev->info->page_size;
+
+    // Check if the page number is inside the flash
+    if (page_num >= dev->info->page_count) 
+        return CYG_DATAFLASH_ERR_INVALID;
+    
+    // Compose DataFlash command
+
+    cmd_buf[0] = DF_CONT_ARRAY_READ_CMD;
+    df_compose_addr(dev, cmd_buf, page_num, page_pos);
+
+    cyg_spi_transaction_begin(spi_dev);
+
+    // Wait for the device to become ready
+    err = df_wait_ready(dev);
+
+    if (CYG_DATAFLASH_ERR_OK == err)
+    {    
+        // Send the command and read data from DataFlash main memory
+        
+        cyg_spi_transaction_transfer(spi_dev, true, 8, cmd_buf, NULL, false);
+        cyg_spi_transaction_transfer(spi_dev, dev->polled, len, buf, buf, true);
+    }
+    
+    cyg_spi_transaction_end(spi_dev);
+
+    return err;
+}
+
+//----------------------------------------------------------------------------
+// cyg_dataflash_program()
+
+int
+cyg_dataflash_program(cyg_dataflash_device_t *dev, 
+                      const cyg_uint8        *buf, 
+                      cyg_uint32             *len, 
+                      cyg_uint32              pos,
+                      cyg_bool                erase,
+                      cyg_bool                verify)
+{
+    cyg_spi_device *spi_dev = dev->spi_dev;
+    int             err     = CYG_DATAFLASH_ERR_OK;
+    cyg_uint8       cmd_buf[4];
+    cyg_uint32      count, page_num, page_pos;
+   
+    // Calculate page number and position from given absolute position
+
+    page_num = pos / dev->info->page_size;
+    page_pos = pos % dev->info->page_size;
+    count    = *len;
+
+    cyg_spi_transaction_begin(spi_dev);
+
+    // Wait for device to become ready
+    err = df_wait_ready(dev);
+    if (CYG_DATAFLASH_ERR_OK != err)
+        goto out;
+   
+    // Loop until count bytes written
+
+    while (count > 0)
+    { 
+        df_status_t status;
+        cyg_uint32  size;
+
+        // Check if the current page number is inside the flash 
+        if (page_num >= dev->info->page_count)
+        {
+            err = CYG_DATAFLASH_ERR_INVALID;
+            goto out;
+        }
+       
+        // Calculate the number of bytes to write to the current page
+        if ((page_pos + count) > dev->info->page_size)
+            size = dev->info->page_size - page_pos;
+        else
+            size = count;
+        
+        // Compose DataFlash command address
+        df_compose_addr(dev, cmd_buf, page_num, page_pos);
+       
+        // If we are not rewritting the whole page, then first 
+        // read the old data from main memory to the target buffer
+
+        if (page_pos > 0 || size < dev->info->page_size)
+        {
+            cmd_buf[0] = DF_TRANSFER_TO_BUF1_CMD;
+            cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+            df_set_busy(dev);
+            err = df_wait_ready(dev);
+            if (CYG_DATAFLASH_ERR_OK != err)
+                goto out;
+        }
+       
+        // Write data to the target buffer
+
+        cmd_buf[0] = DF_BUF1_WRITE_CMD;
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, false);
+        cyg_spi_transaction_transfer(spi_dev, dev->polled, 
+                                     size, buf, NULL, true);
+        df_set_busy(dev);
+        err = df_wait_ready(dev);
+        if (CYG_DATAFLASH_ERR_OK != err)
+            goto out;
+       
+        // Program data from the target buffer to main memory 
+        // and perform an erase before if requested
+        
+        if (erase)
+            cmd_buf[0] = DF_BUF1_PROG_W_ERASE_CMD;
+        else
+            cmd_buf[0] = DF_BUF1_PROG_WO_ERASE_CMD;
+
+        cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+        df_set_busy(dev);
+        err = df_wait_ready(dev);
+        if (CYG_DATAFLASH_ERR_OK != err)
+            goto out;
+        
+        // Compare the target buffer contents with the freshly 
+        // written main memory page (if requested)
+        
+        if (verify)
+        { 
+            cmd_buf[0] = DF_BUF1_COMPARE_CMD;
+            cyg_spi_transaction_transfer(spi_dev, true, 4, cmd_buf, NULL, true);
+            df_set_busy(dev);
+            err = df_wait_ready(dev);
+            if (CYG_DATAFLASH_ERR_OK != err)
+                goto out;
+            
+            status = df_read_status(dev);
+
+            if (status.compare_err)
+            {
+                err = CYG_DATAFLASH_ERR_COMPARE;
+                goto out;
+            }
+        }
+
+        // Adjust running values
+
+        page_pos  = 0;
+        page_num += 1;
+        count    -= size;
+        buf      += size;
+    }
+
+out:
+    cyg_spi_transaction_end(spi_dev);
+
+    *len -= count;
+    
+    return err; 
+}
+
+//----------------------------------------------------------------------------
+// End of devs_flash_atmel_dataflash.c
Index: packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c
===================================================================
RCS file: packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c
diff -N packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ packages/devs/flash/atmel/dataflash/current/src/devs_flash_atmel_dataflash_flash_dev_funs.c	18 Nov 2008 01:05:46 -0000
@@ -0,0 +1,224 @@
+//==========================================================================
+//
+//      devs_flash_atmel_dataflash_flash_dev_funs.c 
+//
+//      DataFlash flash device funs 
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 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.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Savin Zlobec <savin@elatec.si> 
+// Date:         2004-09-06
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/devs_flash_atmel_dataflash.h>
+#include <pkgconf/io_flash.h>
+
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/dataflash.h>
+
+// -------------------------------------------------------------------------- 
+
+#define RETURN_ON_ERROR(_op_) \
+    if (CYG_DATAFLASH_ERR_OK != (err = _op_)) return df_flash_hwr_map_error(dev, err)
+
+#define GOTO_ON_ERROR(_op_) \
+    if (CYG_DATAFLASH_ERR_OK != (err = _op_)) goto on_error
+    
+static int 
+df_flash_hwr_map_error(struct cyg_flash_dev *dev, int err)
+{
+    switch (err)
+    {
+        case CYG_DATAFLASH_ERR_OK:         return CYG_FLASH_ERR_OK; 
+        case CYG_DATAFLASH_ERR_INVALID:    return CYG_FLASH_ERR_INVALID;  
+        case CYG_DATAFLASH_ERR_WRONG_PART: return CYG_FLASH_ERR_DRV_WRONG_PART; 
+        case CYG_DATAFLASH_ERR_TIMEOUT:    return CYG_FLASH_ERR_DRV_TIMEOUT;
+        case CYG_DATAFLASH_ERR_COMPARE:    return CYG_FLASH_ERR_DRV_VERIFY; 
+        default:                           return CYG_FLASH_ERR_INVALID;
+    }
+}
+
+// -------------------------------------------------------------------------- 
+
+static int 
+df_flash_init(struct cyg_flash_dev *dev)
+{
+    cyg_dataflash_flash_dev_priv_t   *priv;
+    cyg_dataflash_device_t           *df_dev;
+    int sector_cnt;
+    
+    priv   = (cyg_dataflash_flash_dev_priv_t *) dev->priv; 
+    df_dev = &priv->dev;
+   
+#ifdef CYGPKG_REDBOOT    
+    if (cyg_dataflash_init(true, df_dev))
+#else
+    if (cyg_dataflash_init(false, df_dev))
+#endif        
+        return CYG_DATAFLASH_ERR_WRONG_PART; 
+  
+    cyg_dataflash_set_blocking_operation(df_dev, true);
+
+    sector_cnt = cyg_dataflash_get_sector_count(df_dev);
+
+    if (priv->end_sector < 0)
+       priv->end_sector = sector_cnt - 1; 
+    
+    if (priv->start_sector >= sector_cnt ||
+        priv->end_sector   >= sector_cnt ||
+        priv->end_sector   <  priv->start_sector)
+        return CYG_DATAFLASH_ERR_INVALID;        
+    
+    priv->start_page = cyg_dataflash_get_block_size(df_dev) *
+        cyg_dataflash_get_sector_start(df_dev, priv->start_sector);
+
+    priv->end_page = cyg_dataflash_get_block_size(df_dev) *
+        (cyg_dataflash_get_sector_start(df_dev, priv->end_sector) +
+         cyg_dataflash_get_sector_size(df_dev, priv->end_sector));
+    
+    dev->end   = (cyg_flashaddr_t)(dev->start +
+        ((priv->end_page - priv->start_page) *
+         cyg_dataflash_get_page_size(df_dev)) - 1);
+    priv->block_info[0].block_size = cyg_dataflash_get_page_size(df_dev);
+    priv->block_info[0].blocks     = priv->end_page - priv->start_page;
+
+    return CYG_DATAFLASH_ERR_OK;
+}
+
+static int 
+df_flash_erase_block(struct cyg_flash_dev   *dev, 
+                     cyg_flashaddr_t  base)
+{
+    cyg_dataflash_flash_dev_priv_t   *priv;
+    cyg_uint32 page;
+    int        err;
+    
+    priv   = (cyg_dataflash_flash_dev_priv_t *) dev->priv;
+    
+    page = priv->start_page + ((base - dev->start) / 
+           cyg_dataflash_get_page_size(&priv->dev)); 
+   
+    RETURN_ON_ERROR( cyg_dataflash_aquire(&priv->dev)                       );
+    GOTO_ON_ERROR(   cyg_dataflash_erase(&priv->dev, page)                  ); 
+    RETURN_ON_ERROR( cyg_dataflash_release(&priv->dev)                      );
+    
+    return CYG_DATAFLASH_ERR_OK;
+    
+on_error:
+    cyg_dataflash_release(&priv->dev);
+    return df_flash_hwr_map_error(dev, err);
+}
+
+static int
+df_flash_program(struct cyg_flash_dev *dev, 
+                 cyg_flashaddr_t       base, 
+                 const void           *data, 
+                 size_t                len)
+{
+    cyg_dataflash_flash_dev_priv_t   *priv;
+    cyg_uint32 page, pos;
+    int        err;
+ 
+    priv   = (cyg_dataflash_flash_dev_priv_t *) dev->priv;
+    
+    page = priv->start_page + ((base - dev->start) / 
+           cyg_dataflash_get_page_size(&priv->dev)); 
+    pos  = (base - dev->start) % cyg_dataflash_get_page_size(&priv->dev);
+    
+    RETURN_ON_ERROR( cyg_dataflash_aquire(&priv->dev)                       );
+    GOTO_ON_ERROR(   cyg_dataflash_mem_to_buf(&priv->dev, 1, page)          );
+    GOTO_ON_ERROR(   cyg_dataflash_write_buf(&priv->dev, 1, data, len, pos) );
+    GOTO_ON_ERROR(   cyg_dataflash_program_buf(&priv->dev, 1, page, true)   );
+    RETURN_ON_ERROR( cyg_dataflash_release(&priv->dev)                      );
+
+    return CYG_DATAFLASH_ERR_OK;
+
+on_error:
+    cyg_dataflash_release(&priv->dev);
+    return df_flash_hwr_map_error(dev, err);
+}
+
+static int 
+df_flash_read(struct cyg_flash_dev   *dev, 
+              const  cyg_flashaddr_t  base, 
+              void                   *data, 
+              size_t                  len)
+{
+    cyg_dataflash_flash_dev_priv_t   *priv;
+    cyg_uint32 page, pos;
+    int        err;
+ 
+    priv   = (cyg_dataflash_flash_dev_priv_t *) dev->priv;
+    
+    page = priv->start_page + ((base - dev->start) / 
+           cyg_dataflash_get_page_size(&priv->dev)); 
+    pos  = (base - dev->start) % cyg_dataflash_get_page_size(&priv->dev);
+ 
+    RETURN_ON_ERROR( cyg_dataflash_aquire(&priv->dev)                       );
+    GOTO_ON_ERROR(   cyg_dataflash_mem_to_buf(&priv->dev, 1, page)          );
+    GOTO_ON_ERROR(   cyg_dataflash_read_buf(&priv->dev, 1, data, len, pos)  );
+    RETURN_ON_ERROR( cyg_dataflash_release(&priv->dev)                      );
+    
+    return CYG_DATAFLASH_ERR_OK;
+
+on_error:
+    cyg_dataflash_release(&priv->dev);
+    return df_flash_hwr_map_error(dev, err);    
+}
+
+// -------------------------------------------------------------------------- 
+
+CYG_FLASH_FUNS(cyg_dataflash_flash_dev_funs,
+               df_flash_init,
+               cyg_flash_devfn_query_nop,
+               df_flash_erase_block,
+               df_flash_program,
+               df_flash_read,
+               cyg_flash_devfn_lock_nop,
+               cyg_flash_devfn_unlock_nop
+);
+
+//----------------------------------------------------------------------------
+// End of devs_flash_atmel_dataflash_flash_dev_funs.c

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