# HG changeset patch # User asl # Date 1091712061 0 # Node ID 773d77981a7db887a173f89aa223402d183069f1 # Parent bbdd4a302a64bc4d5183a1b959056f17ed6489a9 * 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. diff --git a/packages/devs/flash/sst/39vfxxx/current/ChangeLog b/packages/devs/flash/sst/39vfxxx/current/ChangeLog --- 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 + + * include/flash_sst_39vfxxx.inl: Added support for the SST39VF160 + device. + +2004-07-16 Andrew Lunn + + * include/flash_sst_39vfxxx.inl: Modified the driver to make use + of the new flash device API. + 2003-10-02 Roland Caßebohm * include/flash_sst_39vfxxx.inl: diff --git a/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl b/packages/devs/flash/sst/39vfxxx/current/cdl/flash_sst_39vfxxx.cdl --- 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 } diff --git a/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl b/packages/devs/flash/sst/39vfxxx/current/include/flash_sst_39vfxxx.inl --- 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 #include #include +#include #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 //---------------------------------------------------------------------------- +// 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