This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
Block erasing in SST 39VFXXX flash driver
- From: Jean-Francois Argentino <jf dot argentino at osean dot fr>
- To: ecos-patches at sources dot redhat dot com
- Date: Fri, 05 Nov 2010 10:48:15 +0100
- Subject: Block erasing in SST 39VFXXX flash driver
- Reply-to: jf dot argentino at osean dot fr
Hello all,
It looks like there's a bug in the SST 39VFXXX flash driver: it uses the
command 0x30 tor erase a block instead of 0x50. According to the
datasheet 0x30 is to erase a block of 32 KWord and 0x50 to erase a
sector of 2 KWord, which corresponds to the eCos "block".
Following a patch proposal against the CVS package:
diff -r -U 5 -N -x CVS -x .svn -x '*~' -x '*.swp'
ecos-current/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl
ecos-jfa/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl
---
ecos-current/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl
2010-11-04 17:59:04.000000000 +0100
+++
ecos-jfa/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl
2010-11-04 09:22:32.000000000 +0100
@@ -51,11 +51,12 @@
display "SST 39VFXXX FLASH memory support"
description "FLASH memory device support for SST 39VFXXX"
parent CYGPKG_IO_FLASH
active_if CYGPKG_IO_FLASH
- active_if CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED
+ # JFA 091222: need to comment this for the pkg to be included
+ #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
diff -r -U 5 -N -x CVS -x .svn -x '*~' -x '*.swp'
ecos-current/packages/devs/flash/sst/39vfxxx/current/ChangeLog
ecos-jfa/packages/devs/flash/sst/39vfxxx/current/ChangeLog
--- ecos-current/packages/devs/flash/sst/39vfxxx/current/ChangeLog
2010-11-04 17:59:05.000000000 +0100
+++ ecos-jfa/packages/devs/flash/sst/39vfxxx/current/ChangeLog
2010-11-05 10:15:29.000000000 +0100
@@ -1,5 +1,13 @@
+2009-12-22 JF Argentino <jf.argentino@osean.fr>
+
+ * cdl/flash_sst_39vfxxx.cdl: Fixing package requirement
+ * include/flash_sst_39vfxxx.inl: adding support for 39VF6401B and
39VF6402B
+ devices.
+ * include/flash_sst_39vfxxx.inl (sst_query): fixing the erase block
command
+ code used: FLASH_Sector_Erase (0x50) instead of FLASH_Block_Erase (0x30).
+
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
diff -r -U 5 -N -x CVS -x .svn -x '*~' -x '*.swp'
ecos-current/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
ecos-jfa/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
---
ecos-current/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
2010-11-04 17:59:05.000000000 +0100
+++
ecos-jfa/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
2010-11-04 18:32:20.000000000 +0100
@@ -67,10 +67,11 @@
#define FLASH_Read_ID FLASHWORD( 0x90 )
#define FLASH_Read_ID_Exit FLASHWORD( 0xF0 )
#define FLASH_Reset FLASHWORD( 0xFF )
#define FLASH_Program FLASHWORD( 0xA0 )
#define FLASH_Block_Erase FLASHWORD( 0x30 )
+#define FLASH_Sector_Erase FLASHWORD( 0x50 )
#define FLASH_Data FLASHWORD( 0x80 ) // Data
complement
#define FLASH_Busy FLASHWORD( 0x40 ) // "Toggle" bit
#define FLASH_Err FLASHWORD( 0x20 )
#define FLASH_Sector_Erase_Timer FLASHWORD( 0x08 )
@@ -84,10 +85,12 @@
// 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
// And select one of the below device variants
+// TODO could be great to use the CFI when available
+
#ifdef CYGPKG_DEVS_FLASH_SST_39VF080
# define FLASH_BLOCK_SIZE (0x1000*CYGNUM_FLASH_INTERLEAVE)
# define FLASH_NUM_REGIONS (256)
# define CYGNUM_FLASH_BASE_MASK (0xFFF00000u) // 1024kB devices
# define CYGNUM_FLASH_WIDTH (8)
@@ -187,10 +190,29 @@
# define CYGNUM_FLASH_BLANK (1)
# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x236A)
#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF6401B
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((8*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFF800000u) // 8184kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x236D)
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF6402B
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((8*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFF800000u) // 8184kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x236C)
+#endif
+
#define FLASH_DEVICE_SIZE
(FLASH_BLOCK_SIZE*FLASH_NUM_REGIONS)
#define CYGNUM_FLASH_DEVICES
(CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
//----------------------------------------------------------------------------
// Now that device properties are defined, include magic for defining
@@ -230,11 +252,11 @@
// 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.
-
+// TODO CFI
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;
@@ -287,11 +309,11 @@
ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
ROM[FLASH_Setup_Addr1] = FLASH_Setup_Erase;
ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
- *addr_ptr = FLASH_Block_Erase;
+ *addr_ptr = FLASH_Sector_Erase;
// Wait for completion (bit 6 stops toggling)
timeout = 5000000;
prev_state = *addr_ptr & FLASH_Busy;
while (true) {
@@ -371,10 +393,11 @@
if (CYG_FLASH_ERR_OK == res) res = CYG_FLASH_ERR_DRV_VERIFY;
break;
}
addr_ptr++;
data_ptr++;
+ // FIXME if (length % sizeof(*data_ptr)) it screw up the whole
FLASH
len -= sizeof(*data_ptr);
}
// Ideally, we'd want to return not only the failure code, but also
// the address/device that reported the error.
--
Jean-François Argentino
OSEAN S.A.S
1024 Chemin des Plantades
83130 LA GARDE
FRANCE
Tél.: +33 (0)4 94 03 65 84
Fax : +33 (0)4 94 66 62 32
Web: www.osean.fr
diff -r -U 5 -N -x CVS -x .svn -x '*~' -x '*.swp' ecos-current/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl ecos-jfa/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl
--- ecos-current/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl 2010-11-04 17:59:04.000000000 +0100
+++ ecos-jfa/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl 2010-11-04 09:22:32.000000000 +0100
@@ -51,11 +51,12 @@
display "SST 39VFXXX FLASH memory support"
description "FLASH memory device support for SST 39VFXXX"
parent CYGPKG_IO_FLASH
active_if CYGPKG_IO_FLASH
- active_if CYGINT_DEVS_FLASH_SST_39VFXXX_REQUIRED
+ # JFA 091222: need to comment this for the pkg to be included
+ #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
diff -r -U 5 -N -x CVS -x .svn -x '*~' -x '*.swp' ecos-current/packages/devs/flash/sst/39vfxxx/current/ChangeLog ecos-jfa/packages/devs/flash/sst/39vfxxx/current/ChangeLog
--- ecos-current/packages/devs/flash/sst/39vfxxx/current/ChangeLog 2010-11-04 17:59:05.000000000 +0100
+++ ecos-jfa/packages/devs/flash/sst/39vfxxx/current/ChangeLog 2010-11-05 10:15:29.000000000 +0100
@@ -1,5 +1,13 @@
+2009-12-22 JF Argentino <jf.argentino@osean.fr>
+
+ * cdl/flash_sst_39vfxxx.cdl: Fixing package requirement
+ * include/flash_sst_39vfxxx.inl: adding support for 39VF6401B and 39VF6402B
+ devices.
+ * include/flash_sst_39vfxxx.inl (sst_query): fixing the erase block command
+ code used: FLASH_Sector_Erase (0x50) instead of FLASH_Block_Erase (0x30).
+
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
diff -r -U 5 -N -x CVS -x .svn -x '*~' -x '*.swp' ecos-current/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl ecos-jfa/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl
--- ecos-current/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl 2010-11-04 17:59:05.000000000 +0100
+++ ecos-jfa/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl 2010-11-04 18:32:20.000000000 +0100
@@ -67,10 +67,11 @@
#define FLASH_Read_ID FLASHWORD( 0x90 )
#define FLASH_Read_ID_Exit FLASHWORD( 0xF0 )
#define FLASH_Reset FLASHWORD( 0xFF )
#define FLASH_Program FLASHWORD( 0xA0 )
#define FLASH_Block_Erase FLASHWORD( 0x30 )
+#define FLASH_Sector_Erase FLASHWORD( 0x50 )
#define FLASH_Data FLASHWORD( 0x80 ) // Data complement
#define FLASH_Busy FLASHWORD( 0x40 ) // "Toggle" bit
#define FLASH_Err FLASHWORD( 0x20 )
#define FLASH_Sector_Erase_Timer FLASHWORD( 0x08 )
@@ -84,10 +85,12 @@
// 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
// And select one of the below device variants
+// TODO could be great to use the CFI when available
+
#ifdef CYGPKG_DEVS_FLASH_SST_39VF080
# define FLASH_BLOCK_SIZE (0x1000*CYGNUM_FLASH_INTERLEAVE)
# define FLASH_NUM_REGIONS (256)
# define CYGNUM_FLASH_BASE_MASK (0xFFF00000u) // 1024kB devices
# define CYGNUM_FLASH_WIDTH (8)
@@ -187,10 +190,29 @@
# define CYGNUM_FLASH_BLANK (1)
# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x236A)
#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF6401B
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((8*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFF800000u) // 8184kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x236D)
+#endif
+#ifdef CYGPKG_DEVS_FLASH_SST_39VF6402B
+# define FLASH_BLOCK_SIZE ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
+# define FLASH_NUM_REGIONS ((8*1024*1024)/FLASH_BLOCK_SIZE)
+# define CYGNUM_FLASH_BASE_MASK (0xFF800000u) // 8184kB devices
+# define CYGNUM_FLASH_WIDTH (16)
+# define CYGNUM_FLASH_BLANK (1)
+# define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
+# define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x236C)
+#endif
+
#define FLASH_DEVICE_SIZE (FLASH_BLOCK_SIZE*FLASH_NUM_REGIONS)
#define CYGNUM_FLASH_DEVICES (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
//----------------------------------------------------------------------------
// Now that device properties are defined, include magic for defining
@@ -230,11 +252,11 @@
// 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.
-
+// TODO CFI
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;
@@ -287,11 +309,11 @@
ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
ROM[FLASH_Setup_Addr1] = FLASH_Setup_Erase;
ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
- *addr_ptr = FLASH_Block_Erase;
+ *addr_ptr = FLASH_Sector_Erase;
// Wait for completion (bit 6 stops toggling)
timeout = 5000000;
prev_state = *addr_ptr & FLASH_Busy;
while (true) {
@@ -371,10 +393,11 @@
if (CYG_FLASH_ERR_OK == res) res = CYG_FLASH_ERR_DRV_VERIFY;
break;
}
addr_ptr++;
data_ptr++;
+ // FIXME if (length % sizeof(*data_ptr)) it screw up the whole FLASH
len -= sizeof(*data_ptr);
}
// Ideally, we'd want to return not only the failure code, but also
// the address/device that reported the error.