changeset 1701:773d77981a7d

* include/flash_sst_39vfxxx.inl: Added support for the SST39VF160 device. * include/flash_sst_39vfxxx.inl: Modified the driver to make use of the new flash device API.
author asl
date Thu, 05 Aug 2004 13:21:01 +0000
parents bbdd4a302a64
children 0673c75f3a08
files packages/devs/flash/sst/39vfxxx/current/ChangeLog packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
diffstat 3 files changed, 97 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/flash/sst/39vfxxx/current/ChangeLog
+++ b/packages/devs/flash/sst/39vfxxx/current/ChangeLog
@@ -1,3 +1,13 @@
+2004-08-04  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* include/flash_sst_39vfxxx.inl: Added support for the SST39VF160
+	device.
+
+2004-07-16  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+	* include/flash_sst_39vfxxx.inl: Modified the driver to make use
+	of the new flash device API.
+
 2003-10-02  Roland Caßebohm <r.cassebohm@visionsystems.de>
 
 	* include/flash_sst_39vfxxx.inl: 
--- a/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl
+++ b/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl
@@ -57,6 +57,7 @@ cdl_package CYGPKG_DEVS_FLASH_SST_39VFXX
     active_if     CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED
 
     implements    CYGHWR_IO_FLASH_DEVICE
-
+    implements    CYFHSR_IO_FLASH_DEVICE_V2
+        
     include_dir   cyg/io
 }
--- a/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
+++ b/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
@@ -11,6 +11,7 @@
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2004 Andrew Lunn
 //
 // 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
@@ -43,7 +44,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    gthomas
-// Contributors: gthomas, jskov, rcassebohm
+// Contributors: gthomas, jskov, rcassebohm, Andrew Lunn
 // Date:         2001-02-21
 // Purpose:      
 // Description:  
@@ -57,6 +58,7 @@
 #include <pkgconf/hal.h>
 #include <cyg/hal/hal_arch.h>
 #include <cyg/hal/hal_cache.h>
+#include <cyg/infra/cyg_ass.h>
 #include CYGHWR_MEMORY_LAYOUT_H
 
 #define  _FLASH_PRIVATE_
@@ -85,7 +87,6 @@
 // Platform code must define the below
 // #define CYGNUM_FLASH_INTERLEAVE      : Number of interleaved devices (in parallel)
 // #define CYGNUM_FLASH_SERIES          : Number of devices in series
-// #define CYGNUM_FLASH_BASE            : Address of first device
 // And select one of the below device variants
 
 #ifdef CYGPKG_DEVS_FLASH_SST_39VF080
@@ -115,6 +116,15 @@
 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x2780)
 #endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF160
+# define FLASH_BLOCK_SIZE               (0x1000*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS              (0x200000/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK         (0xFFE00000u) // 512kB devices
+# define CYGNUM_FLASH_WIDTH             (16)
+# define CYGNUM_FLASH_BLANK             (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x2782)
+#endif
 
 #define FLASH_DEVICE_SIZE               (FLASH_BLOCK_SIZE*FLASH_NUM_REGIONS)
 #define CYGNUM_FLASH_DEVICES            (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
@@ -125,75 +135,75 @@
 #include <cyg/io/flash_dev.h>
 
 //----------------------------------------------------------------------------
+// Private structure used by the device
+struct cyg_flash_sst_priv 
+{
+  cyg_block_info_t block_info[1];
+};
+//----------------------------------------------------------------------------
 // Functions that put the flash device into non-read mode must reside
 // in RAM.
-void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
-int  flash_erase_block(void* block, unsigned int size) 
-    __attribute__ ((section (".2ram.flash_erase_block")));
-int  flash_program_buf(void* addr, void* data, int len)
-    __attribute__ ((section (".2ram.flash_program_buf")));
+static size_t sst_query(struct cyg_flash_dev *dev, void* data, const size_t len)
+  __attribute__ ((section (".2ram.flash_query")));
+static int sst_erase_block(struct cyg_flash_dev *dev, cyg_flashaddr_t block_base)
+  __attribute__ ((section (".2ram.flash_erase_block")));
+static int sst_program(struct cyg_flash_dev *dev, cyg_flashaddr_t base, 
+            const void* data, const size_t length)
+  __attribute__ ((section (".2ram.flash_program_buf")));
 
 
 //----------------------------------------------------------------------------
 // Initialize driver details
-int
-flash_hwr_init(void)
+static int
+sst_init(struct cyg_flash_dev *dev)
 {
-    flash_data_t id[2];
+  struct cyg_flash_sst_priv *priv = dev->priv;
+  flash_data_t id[2];
 
-    flash_dev_query(id);
+  dev->funs->flash_query(dev,id,sizeof(id));
 
-    // Check that flash_id data is matching the one the driver was
-    // configured for.
-    if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER
-        || id[1] != CYGNUM_FLASH_ID_DEVICE)
-        return FLASH_ERR_DRV_WRONG_PART;
-
-    // Hard wired for now
-    flash_info.block_size = FLASH_BLOCK_SIZE;
-    flash_info.blocks = FLASH_NUM_REGIONS;
-    flash_info.start = (void *)CYGNUM_FLASH_BASE;
-    flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (FLASH_NUM_REGIONS * FLASH_BLOCK_SIZE * CYGNUM_FLASH_SERIES));
-    return FLASH_ERR_OK;
+  // Check that flash_id data is matching the one the driver was
+  // configured for.
+  if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER
+      || id[1] != CYGNUM_FLASH_ID_DEVICE)
+    return CYG_FLASH_ERR_DRV_WRONG_PART;
+  
+  // Hard wired for now
+  dev->end = dev->start + 
+    (FLASH_NUM_REGIONS * FLASH_BLOCK_SIZE * CYGNUM_FLASH_SERIES);
+  dev->num_block_infos = 1;
+  priv->block_info[0].blocks = FLASH_NUM_REGIONS * CYGNUM_FLASH_SERIES;
+  priv->block_info[0].block_size = FLASH_BLOCK_SIZE;
+  dev->block_info = priv->block_info;
+  return CYG_FLASH_ERR_OK;
 }
 
 //----------------------------------------------------------------------------
 // Map a hardware status to a package error
-int
-flash_hwr_map_error(int e)
+static int
+sst_hwr_map_error(struct cyg_flash_dev *dev, int err)
 {
-    return e;
+    return err;
 }
 
 
 //----------------------------------------------------------------------------
-// See if a range of FLASH addresses overlaps currently running code
-bool
-flash_code_overlaps(void *start, void *end)
-{
-    extern unsigned char _stext[], _etext[];
-
-    return ((((unsigned long)&_stext >= (unsigned long)start) &&
-             ((unsigned long)&_stext < (unsigned long)end)) ||
-            (((unsigned long)&_etext >= (unsigned long)start) &&
-             ((unsigned long)&_etext < (unsigned long)end)));
-}
-
-//----------------------------------------------------------------------------
 // Flash Query
 //
 // Only reads the manufacturer and part number codes for the first
 // device(s) in series. It is assumed that any devices in series
 // will be of the same type.
 
-void
-flash_query(void* data)
+static size_t
+sst_query(struct cyg_flash_dev *dev, void* data, const size_t len)
 {
     volatile flash_data_t *ROM;
     flash_data_t* id = (flash_data_t*) data;
     int i;
+    
+    CYG_ASSERT(len == 2, "Invalid length");
 
-    ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
+    ROM = (volatile flash_data_t*) dev->start;
 
     ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
     ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
@@ -213,24 +223,26 @@ flash_query(void* data)
 
     // FIXME: 10ms delay
     for (i = 10000; i > 0; i--);
+    
+    return len;
 }
 
 //----------------------------------------------------------------------------
 // Erase Block
-int
-flash_erase_block(void* block, unsigned int len)
+static int
+sst_erase_block(struct cyg_flash_dev *dev, cyg_flashaddr_t block_base)
 {
     volatile flash_data_t* ROM;
-    volatile flash_data_t* addr_ptr = (volatile flash_data_t*) block;
+    volatile flash_data_t* addr_ptr = (volatile flash_data_t*) block_base;
+    int len = dev->block_info[0].block_size;
+    int res = CYG_FLASH_ERR_OK;
 
-    int res = FLASH_ERR_OK;
-
-    while ((FLASH_ERR_OK == res) && (len > 0)) {
+    while ((CYG_FLASH_ERR_OK == res) && (len > 0)) {
 	int timeout;
         flash_data_t state, prev_state;
 
         // Base address of device(s) being programmed. 
-        ROM = (volatile flash_data_t*)((unsigned long)block & ~(FLASH_DEVICE_SIZE-1));
+        ROM = (volatile flash_data_t*)((unsigned long)block_base & ~(FLASH_DEVICE_SIZE-1));
 
         // Program data [byte] - 6 step sequence
         ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
@@ -249,7 +261,7 @@ flash_erase_block(void* block, unsigned 
                 break;
             }
             if (--timeout == 0) {
-                res = FLASH_ERR_DRV_TIMEOUT;
+                res = CYG_FLASH_ERR_DRV_TIMEOUT;
                 break;
             }
             prev_state = state;
@@ -259,7 +271,7 @@ flash_erase_block(void* block, unsigned 
         while (len > 0) {
             if (*addr_ptr != FLASH_BlankValue) {
                 // Only update return value if erase operation was OK
-                if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
+                if (CYG_FLASH_ERR_OK == res) res = CYG_FLASH_ERR_DRV_VERIFY;
                 break;
             }
             addr_ptr++;
@@ -267,19 +279,20 @@ flash_erase_block(void* block, unsigned 
         }
     }
 
-    return FLASH_ERR_OK;
+    return CYG_FLASH_ERR_OK;
 }
 
 //----------------------------------------------------------------------------
 // Program Buffer
-int
-flash_program_buf(void* addr, void* data, int len)
+static int
+sst_program(struct cyg_flash_dev *dev, cyg_flashaddr_t base, 
+            const void* data, const size_t length)
 {
     volatile flash_data_t* ROM;
-    volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr;
+    volatile flash_data_t* addr_ptr = (volatile flash_data_t*) base;
     volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
-
-    int res = FLASH_ERR_OK;
+    size_t len = length;
+    int res = CYG_FLASH_ERR_OK;
 
 #if 0
     CYG_ASSERT((unsigned long)data_ptr & (sizeof(flash_data_t)-1) == 0, 
@@ -287,13 +300,12 @@ flash_program_buf(void* addr, void* data
     CYG_ASSERT((unsigned long)addr_ptr & (CYGNUM_FLASH_INTERLEAVE*sizeof(flash_data_t)-1) == 0, 
                "Addr not properly aligned (to first interleaved device)");
 #endif
-
-    while ((FLASH_ERR_OK == res) && (len > 0)) {
+    while ((CYG_FLASH_ERR_OK == res) && (len > 0)) {
 	int timeout;
         flash_data_t state, prev_state;
 
         // Base address of device(s) being programmed. 
-        ROM = (volatile flash_data_t*)((unsigned long)addr & ~(FLASH_DEVICE_SIZE-1));
+        ROM = (volatile flash_data_t*)((unsigned long)base & ~(FLASH_DEVICE_SIZE-1));
 
         // Program data [byte] - 4 step sequence
         ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
@@ -310,7 +322,7 @@ flash_program_buf(void* addr, void* data
                 break;
             }
             if (--timeout == 0) {
-                res = FLASH_ERR_DRV_TIMEOUT;
+                res = CYG_FLASH_ERR_DRV_TIMEOUT;
                 break;
             }
             prev_state = state;
@@ -319,18 +331,27 @@ flash_program_buf(void* addr, void* data
         // Verify loaded data bytes
         if (*addr_ptr != *data_ptr) {
             // Only update return value if program operation was OK
-            if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
-                break;
+            if (CYG_FLASH_ERR_OK == res) res = CYG_FLASH_ERR_DRV_VERIFY;
+            break;
         }
         addr_ptr++;
         data_ptr++;
         len -= sizeof(*data_ptr);
     }
 
-
     // Ideally, we'd want to return not only the failure code, but also
     // the address/device that reported the error.
     return res;
 }
 
+CYG_FLASH_FUNS(cyg_sst_funs,
+               sst_init,
+               sst_query,
+               sst_erase_block,
+               sst_program,
+               NULL,              // read
+               sst_hwr_map_error,
+               NULL,              // block_lock
+               NULL);             // block_unlock
+
 #endif // CYGONCE_DEVS_FLASH_SST_39VFXXX_INL