This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
[flashv2 merge] SST 39vfxxx driver
- From: Jonathan Larmour <jifl at eCosCentric dot com>
- To: eCos Patches List <ecos-patches at ecos dot sourceware dot org>
- Date: Tue, 18 Nov 2008 01:08:21 +0000
- Subject: [flashv2 merge] SST 39vfxxx driver
- Openpgp: id=A5FB74E6
Update to flashv2 by Andrew. 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/sst/39vfxxx/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/sst/39vfxxx/current/ChangeLog,v
retrieving revision 1.2
diff -u -5 -p -r1.2 ChangeLog
--- packages/devs/flash/sst/39vfxxx/current/ChangeLog 22 Dec 2006 21:32:16 -0000 1.2
+++ packages/devs/flash/sst/39vfxxx/current/ChangeLog 18 Nov 2008 01:06:59 -0000
@@ -1,5 +1,45 @@
+2004-11-29 Bart Veer <bartv@ecoscentric.com>
+
+ * include/flash_sst_39vfxxx.inl: eliminate hwr_map_error(), no
+ longer needed by the generic flash code.
+ * include/flash_sst_39vfxxx.inl: use the dummy lock/unlock
+ functions provided by the generic flash code.
+
+2004-11-25 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/flash_sst_39vfxxx.cdl: this V2 driver relies on the generic
+ flash code to handle the cache
+
+2004-11-22 Bart Veer <bartv@ecoscentric.com>
+
+ * include/flash_sst_39vfxxx.inl: assume static initialization and
+ adjust const's in various parameters
+ * include/flash_sst_39vfxxx.inl: rename cyg_block_info to
+ cyg_flash_block_info
+
+2004-09-14 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/flash_sst_39vfxxx.inl: Set the end address to the last
+ valid address in flash, not the first invalid address.
+
+2004-08-06 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/flash_sst_39vfxxx.inl: The structure declared by
+ CYG_FLASH_FUNS should be static so we can instantiate the
+ driver multiple times.
+
+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.
+
2006-12-21 Wang Cui <iucgnaw@msn.com>
* include/flash_sst_39vfxxx.inl: Add supported devices:
SST39VF160, SST39VF1601, SST39VF1602, SST39VF320, SST39VF3201,
SST39VF3202, SST39VF6401, SST39VF6402,
@@ -13,10 +53,11 @@
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
//
// 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.
//
Index: packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl,v
retrieving revision 1.1
diff -u -5 -p -r1.1 flash_sst_39vfxxx.cdl
--- packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl 4 Nov 2003 09:07:04 -0000 1.1
+++ packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl 18 Nov 2008 01:06:59 -0000
@@ -55,8 +55,9 @@ cdl_package CYGPKG_DEVS_FLASH_SST_39VFXX
active_if CYGPKG_IO_FLASH
active_if CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED
implements CYGHWR_IO_FLASH_DEVICE
+ implements CYGHWR_IO_FLASH_DEVICE_NEEDS_CACHE_HANDLED
include_dir cyg/io
}
Index: packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl,v
retrieving revision 1.2
diff -u -5 -p -r1.2 flash_sst_39vfxxx.inl
--- packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl 22 Dec 2006 21:32:16 -0000 1.2
+++ packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl 18 Nov 2008 01:06:59 -0000
@@ -9,10 +9,12 @@
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// 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
+// Copyright (C) 2006 eCosCentric Ltd.
//
// 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.
//
@@ -41,11 +43,11 @@
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
-// Contributors: gthomas, jskov, rcassebohm
+// Contributors: gthomas, jskov, rcassebohm, Andrew Lunn
// Date: 2001-02-21
// Purpose:
// Description:
//
// Notes: FLASH_P2V is not properly used.
@@ -55,16 +57,16 @@
//==========================================================================
#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_
#include <cyg/io/flash.h>
-
//----------------------------------------------------------------------------
// Common device details.
#define FLASH_Read_ID FLASHWORD( 0x90 )
#define FLASH_Read_ID_Exit FLASHWORD( 0xF0 )
#define FLASH_Reset FLASHWORD( 0xFF )
@@ -83,11 +85,10 @@
#define FLASH_Setup_Erase FLASHWORD( 0x80 )
// 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
# define FLASH_BLOCK_SIZE (0x1000*CYGNUM_FLASH_INTERLEAVE)
# define FLASH_NUM_REGIONS (256)
@@ -200,77 +201,53 @@
#include <cyg/io/flash_dev.h>
//----------------------------------------------------------------------------
// 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, 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, 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];
-
- flash_dev_query(id);
+ flash_data_t id[2];
- // 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;
-}
+ dev->funs->flash_query(dev,id,sizeof(id));
-//----------------------------------------------------------------------------
-// Map a hardware status to a package error
-int
-flash_hwr_map_error(int e)
-{
- return e;
-}
-
-
-//----------------------------------------------------------------------------
-// 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)));
+ // 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;
+ return CYG_FLASH_ERR_OK;
}
//----------------------------------------------------------------------------
// 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, 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;
ROM[FLASH_Setup_Addr1] = FLASH_Read_ID;
@@ -286,28 +263,30 @@ flash_query(void* data)
ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
ROM[FLASH_Setup_Addr1] = FLASH_Read_ID_Exit;
// 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;
-
- int res = FLASH_ERR_OK;
+ 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;
- 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;
ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
ROM[FLASH_Setup_Addr1] = FLASH_Setup_Erase;
@@ -322,55 +301,53 @@ flash_erase_block(void* block, unsigned
state = *addr_ptr & FLASH_Busy;
if (prev_state == state) {
break;
}
if (--timeout == 0) {
- res = FLASH_ERR_DRV_TIMEOUT;
+ res = CYG_FLASH_ERR_DRV_TIMEOUT;
break;
}
prev_state = state;
}
-
// Verify loaded data bytes
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++;
len -= sizeof(*addr_ptr);
}
}
-
- 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, 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,
"Data not properly aligned");
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;
ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
ROM[FLASH_Setup_Addr1] = FLASH_Program;
@@ -383,29 +360,37 @@ flash_program_buf(void* addr, void* data
state = *addr_ptr & FLASH_Busy;
if (prev_state == state) {
break;
}
if (--timeout == 0) {
- res = FLASH_ERR_DRV_TIMEOUT;
+ res = CYG_FLASH_ERR_DRV_TIMEOUT;
break;
}
prev_state = state;
}
// 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;
}
+static const CYG_FLASH_FUNS(cyg_sst_funs,
+ sst_init,
+ sst_query,
+ sst_erase_block,
+ sst_program,
+ NULL, // read
+ cyg_flash_devfn_lock_nop,
+ cyg_flash_devfn_unlock_nop);
+
#endif // CYGONCE_DEVS_FLASH_SST_39VFXXX_INL