OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [edb7xxx/] [v2_0/] [misc/] [prog_flash.c] - Blame information for rev 773

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//        prog_flash.c
4
//
5
//        Cirrus CL7211 eval board FLASH program tool
6
//
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.
12
//
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.
16
//
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
20
// for more details.
21
//
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.
25
//
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.
32
//
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.
35
//
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####
42
//
43
// Author(s):     gthomas
44
// Contributors:  gthomas
45
// Date:          1999-05-12
46
// Description:   Tool used to program onboard FLASH image
47
//####DESCRIPTIONEND####
48
 
49
//
50
// This program will program the FLASH on the CL7211 board from a fixed buffer
51
//
52
 
53
#include <pkgconf/kernel.h>   // Configuration header
54
#include <cyg/kernel/kapi.h>
55
#include <cyg/infra/diag.h>
56
#include <cyg/hal/hal_cache.h>
57
 
58
#ifndef FALSE
59
#define FALSE 0
60
#define TRUE  1
61
#endif
62
 
63
#define STACK_SIZE 4096
64
static char stack[STACK_SIZE];
65
static cyg_thread thread_data;
66
static cyg_handle_t thread_handle;
67
 
68
void identify_FLASH(void);
69
int  write_flash(long *data, volatile long *mem);
70
int  erase_sector(volatile long *mem);
71
 
72
// Note: these are mapped addresses
73
//  0xE0000000 = ROM Bank 0
74
//  0xF0000000 = ROM Bank 1
75
volatile unsigned long *FLASH = (volatile unsigned long *)0xE0000000;
76
 
77
long *flash_buffer =     (long *)0x60000;
78
long *flash_buffer_end = (long *)0x64000;
79
long *ROM_address =      (long *)0xE07E0000;
80
 
81
// Adapted from Cirrus sample code
82
#define ATMEL_SEQ_ADD1                0x00015554>>2
83
#define ATMEL_SEQ_ADD2                0x0000AAA8>>2
84
#define ATMEL_START_CMD1              0xAAAAAAAA
85
#define ATMEL_START_CMD2              0x55555555
86
#define ATMEL_ID_CMD                  0x90909090
87
#define ATMEL_PROG_CMD                0xA0A0A0A0
88
#define ATMEL_ERASE_CMD               0x80808080
89
#define ATMEL_SECTOR_ERASE_CMD        0x30303030
90
#define ATMEL_STOP_CMD                0xF0F0F0F0
91
#define ATMEL_BUSY_TOGGLE             0x00400040
92
#define ATMEL_ERASE_TOGGLE            0x00440044
93
 
94
#define ATMEL_MANUF                   0x1F
95
#define ATMEL_AT29C040_ID             0X5B
96
#define ATMEL_AT29C040A_ID            0XA4
97
#define ATMEL_AT29C1024_ID            0X25
98
#define ATMEL_SECTOR_SIZE             256
99
#define ATMEL_MAX_SECTORS             2048
100
 
101
#define INTEL_MANUF                   0x0089
102
#define INTEL_STOP_CMD                0x00FF00FF
103
#define INTEL_PROG_CMD                0x00400040
104
#define INTEL_ERASE_CMD               0x00200020
105
#define INTEL_ERASE_CONFIRM           0x00D000D0
106
#define INTEL_READ_STATUS             0x00700070
107
#define INTEL_CLEAR_STATUS            0x00500050
108
#define INTEL_SB_WSMS                 0x00800080  // Write state machine = ready
109
#define INTEL_SB_ERASE_ERROR          0x00200020  // Erase failure
110
#define INTEL_SB_PROG_ERROR           0x00100010  // Programming failure
111
 
112
#define ERASE_TIMEOUT                 10          // seconds
113
 
114
int manuf_code, device_code, sector_size, max_no_of_sectors, word_mode;
115
 
116
// FUNCTIONS
117
 
118
static void
119
cyg_test_exit(void)
120
{
121
    while (TRUE) ;
122
}
123
 
124
static void
125
program_flash(cyg_addrword_t arg)
126
{
127
    diag_printf("PROGRAM FLASH here!\n");
128
    HAL_UCACHE_SYNC();     // ROM space is marked cacheable which causes problems!
129
    HAL_UCACHE_DISABLE();  // So, just disable caches.
130
    identify_FLASH();
131
    diag_printf("About to program FLASH using data at %x..%x\n", flash_buffer, flash_buffer_end);
132
    diag_printf("*** Press RESET now to abort!\n");
133
    cyg_thread_delay(5*100);
134
    diag_printf("\n");
135
    diag_printf("... Erase sector\n");
136
    if (erase_sector(ROM_address)) {
137
        diag_printf("... Programming FLASH\n");
138
        while (flash_buffer < flash_buffer_end) {
139
            if (!write_flash(flash_buffer++, ROM_address++)) break;
140
        }
141
    }
142
 
143
    // Exit Program Mode
144
    switch (manuf_code) {
145
    case ATMEL_MANUF:
146
        FLASH[ATMEL_SEQ_ADD1] = ATMEL_START_CMD1;
147
        FLASH[ATMEL_SEQ_ADD2] = ATMEL_START_CMD2;
148
        FLASH[ATMEL_SEQ_ADD1] = ATMEL_STOP_CMD;
149
        break;
150
    case INTEL_MANUF:
151
        FLASH[0] = INTEL_STOP_CMD;
152
        break;
153
    }
154
    diag_printf("All done!\n");
155
    cyg_test_exit();
156
}
157
 
158
void
159
identify_FLASH(void )
160
{
161
    // Enter Software Product Identification Mode
162
    FLASH[ATMEL_SEQ_ADD1] = ATMEL_START_CMD1;
163
    FLASH[ATMEL_SEQ_ADD2] = ATMEL_START_CMD2;
164
    FLASH[ATMEL_SEQ_ADD1] = ATMEL_ID_CMD;
165
 
166
    // Wait at least 10ms
167
    cyg_thread_delay(2);
168
 
169
    // Read Manufacturer and device code from the device
170
    manuf_code = FLASH[0] >> 16;
171
    device_code = FLASH[1] >> 16;
172
 
173
    diag_printf("manufacturer: 0x%04x, device: 0x%04x\n", manuf_code, device_code);
174
 
175
    // Exit Software Product Identification Mode
176
    switch (manuf_code) {
177
    case ATMEL_MANUF:
178
        FLASH[ATMEL_SEQ_ADD1] = ATMEL_START_CMD1;
179
        FLASH[ATMEL_SEQ_ADD2] = ATMEL_START_CMD2;
180
        FLASH[ATMEL_SEQ_ADD1] = ATMEL_STOP_CMD;
181
        break;
182
    case INTEL_MANUF:
183
        FLASH[0] = INTEL_STOP_CMD;
184
        break;
185
    default:
186
        diag_printf("Unrecognized FLASH manufacturer - I give up!\n");
187
        cyg_test_exit();
188
    }
189
}
190
 
191
void
192
spin(void)
193
{
194
    volatile int i;
195
    for (i = 0;  i < 100;  i++) ;
196
}
197
 
198
int
199
write_flash(long *data, volatile long *mem)
200
{
201
    long data1, data2;
202
    long status;
203
    int timer;
204
    switch (manuf_code) {
205
    case ATMEL_MANUF:
206
        // Enter Program Mode
207
        FLASH[ATMEL_SEQ_ADD1] = ATMEL_START_CMD1;
208
        FLASH[ATMEL_SEQ_ADD2] = ATMEL_START_CMD2;
209
        FLASH[ATMEL_SEQ_ADD1] = ATMEL_PROG_CMD;
210
        // Send data to selected address
211
        *mem = *data;
212
        while (TRUE) {
213
            data1 = *mem;  // Read cell back twice
214
            data2 = *mem;
215
            // Bit 6 toggles between reads while programming in progress
216
            if ((data1 & ATMEL_BUSY_TOGGLE) == (data2 & ATMEL_BUSY_TOGGLE)) break;
217
        }
218
        break;
219
    case INTEL_MANUF:
220
        // Clear current errors
221
        FLASH[0] = INTEL_CLEAR_STATUS;
222
        // Issue program command
223
        FLASH[0] = INTEL_PROG_CMD;
224
        // Send data to selected address
225
        *mem = *data;
226
        timer = 10000;
227
        // Read the status register to wait for programming complete
228
        do {
229
            spin();
230
            status = FLASH[0];
231
        } while (((status & INTEL_SB_WSMS) != INTEL_SB_WSMS) &&
232
                 (--timer > 0));
233
        // Check for errors
234
        if (timer == 0) {
235
            diag_printf("Programming at 0x%08x timed out - status: 0x%08x\n", mem, status);
236
        }
237
        if ((status & INTEL_SB_PROG_ERROR) != 0) {
238
            diag_printf("Device reports programming error at 0x%08x - status: 0x%08x\n", mem, status);
239
        }
240
        // Exit program mode
241
        FLASH[0] = INTEL_STOP_CMD;
242
        break;
243
    }
244
    if (*mem != *data) {
245
        diag_printf("Programming failed at 0x%08x - write: 0x%08x, read: 0x%08x\n",
246
                    mem, *data, *mem);
247
        return (FALSE);
248
    }
249
    return (TRUE);
250
}
251
 
252
int
253
erase_sector(volatile long *mem)
254
{
255
    long data1, data2;
256
    long status;
257
    int timer;
258
    switch (manuf_code) {
259
    case ATMEL_MANUF:
260
        // Erase sector command
261
        FLASH[ATMEL_SEQ_ADD1] = ATMEL_START_CMD1;
262
        FLASH[ATMEL_SEQ_ADD2] = ATMEL_START_CMD2;
263
        FLASH[ATMEL_SEQ_ADD1] = ATMEL_ERASE_CMD;
264
        FLASH[ATMEL_SEQ_ADD1] = ATMEL_START_CMD1;
265
        FLASH[ATMEL_SEQ_ADD2] = ATMEL_START_CMD2;
266
        *mem = ATMEL_SECTOR_ERASE_CMD;
267
        while (TRUE) {
268
            data1 = *mem;  // Read cell back twice
269
            data2 = *mem;
270
            // Bits 6+2 toggle between reads while programming in progress
271
            if ((data1 & ATMEL_ERASE_TOGGLE) == (data2 & ATMEL_ERASE_TOGGLE)) break;
272
        }
273
        break;
274
    case INTEL_MANUF:
275
        // Clear current errors
276
        FLASH[0] = INTEL_CLEAR_STATUS;
277
        // Issue erase block command
278
        FLASH[0] = INTEL_ERASE_CMD;
279
        *mem = INTEL_ERASE_CONFIRM;
280
        timer = ERASE_TIMEOUT*50;
281
        // Read the status register while erase in progress
282
        do {
283
            cyg_thread_delay(2);
284
            status = FLASH[0];
285
        } while (((status & INTEL_SB_WSMS) != INTEL_SB_WSMS) &&
286
                 (--timer > 0));
287
        // Check for errors
288
        if (timer == 0) {
289
            diag_printf("Erase not complete after %d seconds - status: 0x%08x\n",
290
                        ERASE_TIMEOUT, status);
291
        }
292
        if ((status & INTEL_SB_ERASE_ERROR) != 0) {
293
            diag_printf("Device reports erase error - status: 0x%08x\n", status);
294
        }
295
        // Exit erase mode
296
        FLASH[0] = INTEL_STOP_CMD;
297
        break;
298
    }
299
    if (*mem != 0xFFFFFFFF) {
300
        diag_printf("Erase failed at 0x%08x - read: 0x%08x\n",
301
                    mem, *mem);
302
        return (FALSE);
303
    }
304
    return (TRUE);
305
}
306
 
307
externC void
308
cyg_start( void )
309
{
310
    // Create a main thread, so we can run the scheduler and have time 'pass'
311
    cyg_thread_create(10,                // Priority - just a number
312
                      program_flash,     // entry
313
                      1,                 // index
314
                      "program_thread",  // Name
315
                      &stack[0],         // Stack
316
                      STACK_SIZE,        // Size
317
                      &thread_handle,    // Handle
318
                      &thread_data       // Thread data structure
319
            );
320
    cyg_thread_resume(thread_handle);  // Start it
321
    cyg_scheduler_start();
322
} // cyg_package_start()
323
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.