1 //==========================================================================
5 // ARM INTEGRATOR eval board FLASH program tool
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors: Philippe Robin
45 // Date: November 7, 2000
46 // Description: Tool used to program onboard FLASH image
47 //####DESCRIPTIONEND####
50 // This program will program the FLASH on the PID board
51 // It is similar to 'flash' (which also downloads S records) but it always
52 // programs from a fixed buffer. This is sufficient to load/update the GDB
53 // stubs on the board.
56 #include <pkgconf/libc.h> // Configuration header
58 #include <cyg/kernel/kapi.h>
61 #include <cyg/infra/testcase.h>
62 #include <sys/cstartup.h>
63 #include <cyg/hal/hal_integrator.h>
71 #define INVALID_FTYPE 0x00000000
72 #define UNKNOWN_FTYPE 0xFFFFFFFF
73 #define ATMEL_FTYPE 0x00000001
74 #define INTEL_FTYPE 0x00000002
76 #define FLASH_TYPE_MASK (ATMEL_FTYPE | INTEL_FTYPE)
78 // On Some platforms Boot and program flash may be part of the same device
79 #define INTEGRATED_FTYPE 0x80000000
80 #define BOOT_FTYPE 0x40000000
81 #define APP_FTYPE 0x20000000
83 #define FLASH_USAGE_MASK (BOOT_FTYPE | APP_FTYPE)
85 #define DEFAULT_FLASH_MASK 0xFFFFFFF8
86 #define FLASH_BLOCK_SIZE 0x00020000 // 128Kb
87 #define EPROM_BASE 0x20000000
88 #define EPROM_SIZE 0x00080000 // 512Kb
89 #define FLASH_BASE 0x24000000
90 #define FLASH_SIZE 0x02000000 // 32Mb
92 typedef struct flashType {
93 char *base; // Base Address of flash
94 char *physicalBase; // before mem initialisation
95 unsigned int size; // Size of flash, in bytes
96 unsigned int type; // Atmel / Intel (CFI) / Unknown
97 unsigned int writeSize; // Size of physical block
98 unsigned int eraseSize; // Size of block erase
99 unsigned int logicalSize; // Size of logical block
100 char *ident; // identification string
103 tFlash Integrator_Flash[2] =
106 (char *)EPROM_BASE, // Base Address of flash
107 (char *)EPROM_BASE, // Physical Address of flash
108 EPROM_SIZE, // Size of flash, in bytes (512K)
109 BOOT_FTYPE | ATMEL_FTYPE, // Flash type
110 FLASH_BLOCK_SIZE, // Size of physical block
111 FLASH_BLOCK_SIZE, // Size of block erase
112 FLASH_BLOCK_SIZE, // Size of logical block
113 "Atmel", // Null terminated Info string
116 (char *)FLASH_BASE, // Base Address of flash
117 (char *)FLASH_BASE, // Physical Address of flash
118 FLASH_SIZE, // Size of flash, in bytes
119 APP_FTYPE | INTEL_FTYPE, // Flash type
120 FLASH_BLOCK_SIZE, // Size of physical block
121 FLASH_BLOCK_SIZE, // Size of block erase
122 FLASH_BLOCK_SIZE, // Size of logical block
123 "Intel 28F320S3", // Null terminated Info string
128 extern void diag_printf(const char *, ...);
129 int identify_FLASH(void);
130 void write_sector(int, char *);
132 char *flash_buffer = (char *)0x60000;
133 char *flash_buffer_end = (char *)0x80000;
136 #define BUF(x) buf[x^3]
138 #define BUF(x) buf[x]
144 cyg_package_start( void )
151 } // cyg_package_start()
154 main( int argc, char *argv[] )
158 diag_printf("FLASH here!\n");
159 while (identify_FLASH() == 0) {
160 diag_printf("... Please change FLASH jumper\n");
161 cyg_thread_delay(5*100);
163 diag_printf("About to program FLASH using data at %x..%x\n", flash_buffer, flash_buffer_end);
164 diag_printf("*** Press RESET now to abort!\n");
165 cyg_thread_delay(5*100);
167 diag_printf("...Programming FLASH\n");
170 while (flash_buffer < flash_buffer_end) {
171 write_sector(i++, flash_buffer);
174 diag_printf("All done!\n");
178 // Adapted from ARM sample code
179 #define SEQ_ADD1 0x5555
180 #define SEQ_ADD2 0x2aaa
181 #define START_CMD1 0xaaaaaaaa
182 #define START_CMD2 0x55555555
183 #define ID_CMD 0x90909090
184 #define PROG_CMD 0xA0
185 #define STOP_CMD 0xf0f0f0f0
187 #define MAN_ATMEL 0x1F
188 #define ATMEL_AT29C040_ID 0X5B
189 #define ATMEL_AT29C040A_ID 0XA4
190 #define ATMEL_AT29C1024_ID 0X25
191 #define ATMEL_SECTOR_SIZE 256
192 #define ATMEL_MAX_SECTORS 2048
194 #define MAN_INTEL 0xB0
195 #define INTEL_28F320S3_ID 0xD4
197 int manuf_code, device_code;
198 int sector_size, max_no_of_sectors, word_mode;
199 volatile unsigned int *FLASH = (volatile unsigned int *)0x24000000;
202 identify_FLASH(void )
204 unsigned int *ptr = (unsigned int *)FLASH;
206 HAL_FLASH_WRITE_ENABLE();
208 // Enter Software Product Identification Mode
209 FLASH[SEQ_ADD1] = START_CMD1;
210 FLASH[SEQ_ADD2] = START_CMD2;
211 FLASH[SEQ_ADD1] = ID_CMD;
213 // Wait at least 10ms
216 // Read Manufacturer and device code from the device
217 manuf_code = *ptr++ & 0xff;
218 device_code = *ptr & 0xff;
220 diag_printf("manuf: 0x%x, device: 0x%x\n", manuf_code, device_code);
222 // Exit Software Product Identification Mode
223 FLASH[SEQ_ADD1] = START_CMD1;
224 FLASH[SEQ_ADD2] = START_CMD2;
225 FLASH[SEQ_ADD1] = STOP_CMD;
227 // Wait at least 10ms
230 HAL_FLASH_WRITE_DISABLE();
232 if (manuf_code != MAN_ATMEL || manuf_code != MAN_INTEL) {
233 diag_printf ( "Error: Wrong Manufaturer: %02x\n", manuf_code );
237 switch (device_code) {
238 case ATMEL_AT29C040A_ID:
239 diag_printf ("AT29C040A recognised\n");
240 sector_size = ATMEL_SECTOR_SIZE;
241 max_no_of_sectors = ATMEL_MAX_SECTORS;
245 case ATMEL_AT29C1024_ID:
246 diag_printf ("AT29C1024 recognised\n");
247 sector_size = ATMEL_SECTOR_SIZE;
248 max_no_of_sectors = ATMEL_MAX_SECTORS;
252 case INTEL_28F320S3_ID:
253 diag_printf ("INTEL_28F320S3 recognised\n");
254 sector_size = FLASH_BLOCK_SIZE;
255 // max_no_of_sectors = ATMEL_MAX_SECTORS;
260 diag_printf ( "Error: Unsupported device: %02x\n", device_code);
267 write_sector(int num, char *buf)
270 volatile char *wrt = (volatile char *)&FLASH[num*sector_size];
272 // diag_printf("Writing to %08x\n", wrt);
273 // Enter Program Mode
274 FLASH[SEQ_ADD1] = START_CMD1;
275 FLASH[SEQ_ADD2] = START_CMD2;
276 FLASH[SEQ_ADD1] = PROG_CMD;
278 // Note: write bytes as longs regardless of bus width
279 for (i = 0; i < sector_size; i++) {
283 // Wait for sector to program
286 while (wrt[i] != BUF(i)) {
287 if (cnt++ > 0x01000000) break;
289 // diag_printf("Out - i: %d, wrt[i] = %08X.%08X, BUF(i) = %08X, count = %x\n", i, &wrt[i], wrt[i], BUF(i), cnt);
292 for (i = 0; i < sector_size; i++) {
293 for (cnt = 0; cnt < 10; cnt++) {
294 if (wrt[i] == BUF(i)) break;
298 diag_printf("Can't program at 0x%08X: %02X not %02X\n", wrt, *wrt, BUF(0));