1 //==========================================================================
5 // ARM PID7 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: gthomas
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>
69 extern void diag_printf(const char *, ...);
70 int identify_FLASH(void);
71 void write_sector(int, char *);
73 char *flash_buffer = (char *)0x60000;
74 char *flash_buffer_end = (char *)0x80000;
77 #define BUF(x) buf[x^3]
85 cyg_package_start( void )
92 } // cyg_package_start()
95 main( int argc, char *argv[] )
99 diag_printf("FLASH here!\n");
100 while (identify_FLASH() == 0) {
101 diag_printf("... Please change FLASH jumper\n");
102 cyg_thread_delay(5*100);
104 diag_printf("About to program FLASH using data at %x..%x\n", flash_buffer, flash_buffer_end);
105 diag_printf("*** Press RESET now to abort!\n");
106 cyg_thread_delay(5*100);
108 diag_printf("...Programming FLASH\n");
111 while (flash_buffer < flash_buffer_end) {
112 write_sector(i++, flash_buffer);
115 diag_printf("All done!\n");
119 // Adapted from ARM sample code
120 #define SEQ_ADD1 0x5555
121 #define SEQ_ADD2 0xAAAA
122 #define START_CMD1 0xAA
123 #define START_CMD2 0x55
125 #define PROG_CMD 0xA0
126 #define STOP_CMD 0xF0
128 #define MAN_ATMEL 0x1F
129 #define ATMEL_AT29C040_ID 0X5B
130 #define ATMEL_AT29C040A_ID 0XA4
131 #define ATMEL_AT29C1024_ID 0X25
132 #define ATMEL_SECTOR_SIZE 256
133 #define ATMEL_MAX_SECTORS 2048
135 int manuf_code, device_code, sector_size, max_no_of_sectors, word_mode;
136 volatile char *FLASH = (volatile char *)0x04000000;
139 identify_FLASH(void )
141 // Enter Software Product Identification Mode
142 FLASH[SEQ_ADD1] = START_CMD1;
143 FLASH[SEQ_ADD2] = START_CMD2;
144 FLASH[SEQ_ADD1] = ID_CMD;
146 // Wait at least 10ms
149 // Read Manufacturer and device code from the device
150 manuf_code = FLASH[0];
151 device_code = FLASH[1];
153 diag_printf("manuf: %x, device: %x\n", manuf_code, device_code);
155 // Exit Software Product Identification Mode
156 FLASH[SEQ_ADD1] = START_CMD1;
157 FLASH[SEQ_ADD2] = START_CMD2;
158 FLASH[SEQ_ADD1] = STOP_CMD;
160 // Wait at least 10ms
163 if (manuf_code != MAN_ATMEL) {
164 diag_printf ( "Error: Wrong Manufaturer: %02x\n",manuf_code );
168 switch (device_code) {
169 case ATMEL_AT29C040A_ID:
170 diag_printf ("AT29C040A recognised\n");
171 sector_size = ATMEL_SECTOR_SIZE;
172 max_no_of_sectors = ATMEL_MAX_SECTORS;
175 case ATMEL_AT29C1024_ID:
176 diag_printf ("AT29C1024 recognised\n");
177 sector_size = ATMEL_SECTOR_SIZE;
178 max_no_of_sectors = ATMEL_MAX_SECTORS;
182 diag_printf ( "Error: Unsupported device: %02x\n", device_code);
189 write_sector(int num, char *buf)
192 volatile char *wrt = (volatile char *)&FLASH[num*sector_size];
194 // diag_printf("Writing to %08x\n", wrt);
195 // Enter Program Mode
196 FLASH[SEQ_ADD1] = START_CMD1;
197 FLASH[SEQ_ADD2] = START_CMD2;
198 FLASH[SEQ_ADD1] = PROG_CMD;
200 // Note: write bytes as longs regardless of bus width
201 for (i = 0; i < sector_size; i++) {
205 // Wait for sector to program
208 while (wrt[i] != BUF(i)) {
209 if (cnt++ > 0x01000000) break;
211 // diag_printf("Out - i: %d, wrt[i] = %08X.%08X, BUF(i) = %08X, count = %x\n", i, &wrt[i], wrt[i], BUF(i), cnt);
214 for (i = 0; i < sector_size; i++) {
215 for (cnt = 0; cnt < 10; cnt++) {
216 if (wrt[i] == BUF(i)) break;
220 diag_printf("Can't program at 0x%08X: %02X not %02X\n", wrt, *wrt, BUF(0));