1 #ifndef CYGONCE_DEVS_FLASH_SST_39VFXXX_INL
2 #define CYGONCE_DEVS_FLASH_SST_39VFXXX_INL
3 //==========================================================================
5 // flash_sst_39vfxxx.inl
7 // SST 39VFxxx series flash driver
9 //==========================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39 // at http://sources.redhat.com/ecos/ecos-license/
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //==========================================================================
43 //#####DESCRIPTIONBEGIN####
46 // Contributors: gthomas, jskov, rcassebohm
51 // Notes: FLASH_P2V is not properly used.
53 //####DESCRIPTIONEND####
55 //==========================================================================
57 #include <pkgconf/hal.h>
58 #include <cyg/hal/hal_arch.h>
59 #include <cyg/hal/hal_cache.h>
60 #include CYGHWR_MEMORY_LAYOUT_H
62 #define _FLASH_PRIVATE_
63 #include <cyg/io/flash.h>
66 //----------------------------------------------------------------------------
67 // Common device details.
68 #define FLASH_Read_ID FLASHWORD( 0x90 )
69 #define FLASH_Read_ID_Exit FLASHWORD( 0xF0 )
70 #define FLASH_Reset FLASHWORD( 0xFF )
71 #define FLASH_Program FLASHWORD( 0xA0 )
72 #define FLASH_Block_Erase FLASHWORD( 0x30 )
74 #define FLASH_Data FLASHWORD( 0x80 ) // Data complement
75 #define FLASH_Busy FLASHWORD( 0x40 ) // "Toggle" bit
76 #define FLASH_Err FLASHWORD( 0x20 )
77 #define FLASH_Sector_Erase_Timer FLASHWORD( 0x08 )
79 #define FLASH_Setup_Addr1 (0x5555)
80 #define FLASH_Setup_Addr2 (0x2AAA)
81 #define FLASH_Setup_Code1 FLASHWORD( 0xAA )
82 #define FLASH_Setup_Code2 FLASHWORD( 0x55 )
83 #define FLASH_Setup_Erase FLASHWORD( 0x80 )
85 // Platform code must define the below
86 // #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel)
87 // #define CYGNUM_FLASH_SERIES : Number of devices in series
88 // #define CYGNUM_FLASH_BASE : Address of first device
89 // And select one of the below device variants
91 #ifdef CYGPKG_DEVS_FLASH_SST_39VF080
92 # define FLASH_BLOCK_SIZE (0x1000*CYGNUM_FLASH_INTERLEAVE)
93 # define FLASH_NUM_REGIONS (256)
94 # define CYGNUM_FLASH_BASE_MASK (0xFFF00000u) // 1024kB devices
95 # define CYGNUM_FLASH_WIDTH (8)
96 # define CYGNUM_FLASH_BLANK (1)
97 # define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0xBF)
98 # define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0xD8)
100 #ifdef CYGPKG_DEVS_FLASH_SST_39VF016
101 # define FLASH_BLOCK_SIZE (0x1000*CYGNUM_FLASH_INTERLEAVE)
102 # define FLASH_NUM_REGIONS (512)
103 # define CYGNUM_FLASH_BASE_MASK (0xFFE00000u) // 2048kB devices
104 # define CYGNUM_FLASH_WIDTH (8)
105 # define CYGNUM_FLASH_BLANK (1)
106 # define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0xBF)
107 # define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0xD9)
109 #ifdef CYGPKG_DEVS_FLASH_SST_39VF400
110 # define FLASH_BLOCK_SIZE (0x1000*CYGNUM_FLASH_INTERLEAVE)
111 # define FLASH_NUM_REGIONS (0x80000/FLASH_BLOCK_SIZE)
112 # define CYGNUM_FLASH_BASE_MASK (0xFFF80000u) // 512kB devices
113 # define CYGNUM_FLASH_WIDTH (16)
114 # define CYGNUM_FLASH_BLANK (1)
115 # define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x00BF)
116 # define CYGNUM_FLASH_ID_DEVICE FLASHWORD(0x2780)
119 #define FLASH_DEVICE_SIZE (FLASH_BLOCK_SIZE*FLASH_NUM_REGIONS)
120 #define CYGNUM_FLASH_DEVICES (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
122 //----------------------------------------------------------------------------
123 // Now that device properties are defined, include magic for defining
124 // accessor type and constants.
125 #include <cyg/io/flash_dev.h>
127 //----------------------------------------------------------------------------
128 // Functions that put the flash device into non-read mode must reside
130 void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
131 int flash_erase_block(void* block, unsigned int size)
132 __attribute__ ((section (".2ram.flash_erase_block")));
133 int flash_program_buf(void* addr, void* data, int len)
134 __attribute__ ((section (".2ram.flash_program_buf")));
137 //----------------------------------------------------------------------------
138 // Initialize driver details
146 // Check that flash_id data is matching the one the driver was
148 if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER
149 || id[1] != CYGNUM_FLASH_ID_DEVICE)
150 return FLASH_ERR_DRV_WRONG_PART;
152 // Hard wired for now
153 flash_info.block_size = FLASH_BLOCK_SIZE;
154 flash_info.blocks = FLASH_NUM_REGIONS;
155 flash_info.start = (void *)CYGNUM_FLASH_BASE;
156 flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (FLASH_NUM_REGIONS * FLASH_BLOCK_SIZE * CYGNUM_FLASH_SERIES));
160 //----------------------------------------------------------------------------
161 // Map a hardware status to a package error
163 flash_hwr_map_error(int e)
169 //----------------------------------------------------------------------------
170 // See if a range of FLASH addresses overlaps currently running code
172 flash_code_overlaps(void *start, void *end)
174 extern unsigned char _stext[], _etext[];
176 return ((((unsigned long)&_stext >= (unsigned long)start) &&
177 ((unsigned long)&_stext < (unsigned long)end)) ||
178 (((unsigned long)&_etext >= (unsigned long)start) &&
179 ((unsigned long)&_etext < (unsigned long)end)));
182 //----------------------------------------------------------------------------
185 // Only reads the manufacturer and part number codes for the first
186 // device(s) in series. It is assumed that any devices in series
187 // will be of the same type.
190 flash_query(void* data)
192 volatile flash_data_t *ROM;
193 flash_data_t* id = (flash_data_t*) data;
196 ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
198 ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
199 ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
200 ROM[FLASH_Setup_Addr1] = FLASH_Read_ID;
203 for (i = 10000; i > 0; i--);
205 // Manufacturers' code
210 ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
211 ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
212 ROM[FLASH_Setup_Addr1] = FLASH_Read_ID_Exit;
215 for (i = 10000; i > 0; i--);
218 //----------------------------------------------------------------------------
221 flash_erase_block(void* block, unsigned int len)
223 volatile flash_data_t* ROM;
224 volatile flash_data_t* addr_ptr = (volatile flash_data_t*) block;
226 int res = FLASH_ERR_OK;
228 while ((FLASH_ERR_OK == res) && (len > 0)) {
230 flash_data_t state, prev_state;
232 // Base address of device(s) being programmed.
233 ROM = (volatile flash_data_t*)((unsigned long)block & ~(FLASH_DEVICE_SIZE-1));
235 // Program data [byte] - 6 step sequence
236 ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
237 ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
238 ROM[FLASH_Setup_Addr1] = FLASH_Setup_Erase;
239 ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
240 ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
241 *addr_ptr = FLASH_Block_Erase;
243 // Wait for completion (bit 6 stops toggling)
245 prev_state = *addr_ptr & FLASH_Busy;
247 state = *addr_ptr & FLASH_Busy;
248 if (prev_state == state) {
251 if (--timeout == 0) {
252 res = FLASH_ERR_DRV_TIMEOUT;
258 // Verify loaded data bytes
260 if (*addr_ptr != FLASH_BlankValue) {
261 // Only update return value if erase operation was OK
262 if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
266 len -= sizeof(*addr_ptr);
273 //----------------------------------------------------------------------------
276 flash_program_buf(void* addr, void* data, int len)
278 volatile flash_data_t* ROM;
279 volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr;
280 volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
282 int res = FLASH_ERR_OK;
285 CYG_ASSERT((unsigned long)data_ptr & (sizeof(flash_data_t)-1) == 0,
286 "Data not properly aligned");
287 CYG_ASSERT((unsigned long)addr_ptr & (CYGNUM_FLASH_INTERLEAVE*sizeof(flash_data_t)-1) == 0,
288 "Addr not properly aligned (to first interleaved device)");
291 while ((FLASH_ERR_OK == res) && (len > 0)) {
293 flash_data_t state, prev_state;
295 // Base address of device(s) being programmed.
296 ROM = (volatile flash_data_t*)((unsigned long)addr & ~(FLASH_DEVICE_SIZE-1));
298 // Program data [byte] - 4 step sequence
299 ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
300 ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
301 ROM[FLASH_Setup_Addr1] = FLASH_Program;
302 *addr_ptr = *data_ptr;
304 // Wait for completion (bit 6 stops toggling)
306 prev_state = *addr_ptr & FLASH_Busy;
308 state = *addr_ptr & FLASH_Busy;
309 if (prev_state == state) {
312 if (--timeout == 0) {
313 res = FLASH_ERR_DRV_TIMEOUT;
319 // Verify loaded data bytes
320 if (*addr_ptr != *data_ptr) {
321 // Only update return value if program operation was OK
322 if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
327 len -= sizeof(*data_ptr);
331 // Ideally, we'd want to return not only the failure code, but also
332 // the address/device that reported the error.
336 #endif // CYGONCE_DEVS_FLASH_SST_39VFXXX_INL