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 + + * 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 * 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