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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [integrator/] [current/] [src/] [flash.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//        flash.c
4
//
5
//        ARM INTEGRATOR A/P 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 Free Software Foundation, 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      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     gthomas
43
// Contributors:  Philippe Robin
44
// Date:          November 7, 2000
45
// Description:   Tool used to program onboard FLASH image
46
//####DESCRIPTIONEND####
47
 
48
//
49
// This program will program the FLASH on INTEGRATOR A/P board
50
//
51
 
52
#include <pkgconf/libc.h>   // Configuration header
53
 
54
#include <cyg/kernel/kapi.h>
55
#include <stdlib.h>
56
#include <ctype.h>
57
#include <cyg/infra/testcase.h>
58
#include <sys/cstartup.h>
59
 
60
#ifndef FALSE
61
#define FALSE 0
62
#define TRUE  1
63
#endif
64
 
65
#define PROGRAM_COMMAND    0x00100010
66
#define PROGRAM_VERIFY     0x00D000D0
67
#define READ_STATUS        0x70707070
68
#define SR_MASK            0x00800080
69
#define READ_ARRAY         0x00FF00FF
70
#define BLOCK_ERASE        0x00200020
71
#define BLOCK_WRITE_MODE   0x00E800E8
72
#define BLOCK_LOCK_BITS    0x00600060
73
#define CFI_QUERY_OFFS     0x00000055
74
#define CFI_QUERY_COMMAND  0x00980098
75
#define CFI_DATA_OFFS      0x00000020
76
#define SYS_INFO_SIZE_OFF  0x00000027
77
#define SYS_INFO_WB_OFF    0x0000002A
78
#define SYS_ERASE_SIZE_OFF 0x0000002F
79
#define STATUS_READY_MASK  0x00800080
80
#define BANK_BOUNDARY      0x0001FFFF
81
#define STATUS_ERROR       0x00100010
82
#define MAX_WRITE_BUFF     0xF
83
 
84
// Integrator EBI register definitions
85
 
86
#define INTEGRATOR_EBI_BASE 0x12000000
87
 
88
#define INTEGRATOR_EBI_CSR0_OFFSET      0x00
89
#define INTEGRATOR_EBI_CSR1_OFFSET      0x04
90
#define INTEGRATOR_EBI_CSR2_OFFSET      0x08
91
#define INTEGRATOR_EBI_CSR3_OFFSET      0x0C
92
#define INTEGRATOR_EBI_LOCK_OFFSET      0x20
93
 
94
#define INTEGRATOR_EBI_CSR0 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR0_OFFSET)
95
#define INTEGRATOR_EBI_CSR1 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
96
#define INTEGRATOR_EBI_CSR2 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR2_OFFSET)
97
#define INTEGRATOR_EBI_CSR3 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR3_OFFSET)
98
#define INTEGRATOR_EBI_LOCK (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
99
 
100
#define INTEGRATOR_EBI_8_BIT            0x00
101
#define INTEGRATOR_EBI_16_BIT           0x01
102
#define INTEGRATOR_EBI_32_BIT           0x02
103
#define INTEGRATOR_EBI_WRITE_ENABLE     0x04
104
#define INTEGRATOR_EBI_SYNC             0x08
105
#define INTEGRATOR_EBI_WS_2             0x00
106
#define INTEGRATOR_EBI_WS_3             0x10
107
#define INTEGRATOR_EBI_WS_4             0x20
108
#define INTEGRATOR_EBI_WS_5             0x30
109
#define INTEGRATOR_EBI_WS_6             0x40
110
#define INTEGRATOR_EBI_WS_7             0x50
111
#define INTEGRATOR_EBI_WS_8             0x60
112
#define INTEGRATOR_EBI_WS_9             0x70
113
#define INTEGRATOR_EBI_WS_10            0x80
114
#define INTEGRATOR_EBI_WS_11            0x90
115
#define INTEGRATOR_EBI_WS_12            0xA0
116
#define INTEGRATOR_EBI_WS_13            0xB0
117
#define INTEGRATOR_EBI_WS_14            0xC0
118
#define INTEGRATOR_EBI_WS_15            0xD0
119
#define INTEGRATOR_EBI_WS_16            0xE0
120
#define INTEGRATOR_EBI_WS_17            0xF0
121
 
122
#define FL_SC_CONTROL                   0x06    // Enable Flash Write and Vpp
123
 
124
 
125
#define INVALID_FTYPE           0x00000000
126
#define UNKNOWN_FTYPE           0xFFFFFFFF
127
#define ATMEL_FTYPE             0x00000001
128
#define INTEL_FTYPE             0x00000002
129
 
130
#define FLASH_TYPE_MASK         (ATMEL_FTYPE | INTEL_FTYPE)
131
 
132
// On Some platforms Boot and program flash may be part of the same device
133
#define INTEGRATED_FTYPE        0x80000000
134
#define BOOT_FTYPE              0x40000000
135
#define APP_FTYPE               0x20000000
136
 
137
#define FLASH_USAGE_MASK        (BOOT_FTYPE | APP_FTYPE)
138
 
139
#define DEFAULT_FLASH_MASK 0xFFFFFFF8
140
#define FLASH_BLOCK_SIZE        0x00020000      // 128Kb
141
#define EPROM_BASE              0x20000000
142
#define EPROM_SIZE              0x00080000      // 512Kb
143
#define FLASH_BASE              0x24000000
144
#define FLASH_SIZE              0x02000000      // 32Mb
145
 
146
typedef int flashWrite(char *address, unsignedint  data, char *flash);
147
typedef int flashWriteBlock(char *address, unsigned int *data, unsigned int size, char *flash);
148
typedef int flashRead(char *address, unsigned int *value);
149
typedef int flashReadBlock(char *address, unsigned int *data, unsigned int size);
150
typedef int flashErase(char *address, unsigned size, char *flash);
151
typedef int flashInit(char *address, char *flash);
152
typedef int flashClose(char *address, char *flash);
153
 
154
typedef struct flashType {
155
    char *base;                 // Base Address of flash
156
    char *physicalBase;         // before mem initialisation
157
    unsigned int size;          // Size of flash, in bytes
158
    unsigned int type;          // Atmel / Intel (CFI) / Unknown
159
    unsigned int writeSize;     // Size of physical block
160
    unsigned int eraseSize;     // Size of block erase
161
    unsigned int logicalSize;   // Size of logical block
162
    flashWrite *write;          // Write one word
163
    flashWriteBlock *writeBlock;// Write a block of writeSize bytes
164
    flashRead *read;            // Read one word
165
    flashReadBlock *readBlock;  // Read a block of writeSize bytes
166
    flashErase *erase;          // Erase a block of eraseSize bytes
167
    flashInit *init;            // Lock a flash device
168
    flashClose *close;          // Unlock a flash device
169
    char *ident;                // identification string
170
    struct flashType *next;     // Pointer to next flash device
171
} tFlash;
172
 
173
tFlash Integrator_Flash[2] = {
174
    {
175
        (char *)EPROM_BASE,     // Base Address of flash
176
        (char *)EPROM_BASE,     // Physical Address of flash
177
        EPROM_SIZE,             // Size of flash, in bytes (512K)
178
        BOOT_FTYPE | ATMEL_FTYPE,// Flash type
179
        FLASH_BLOCK_SIZE,       // Size of physical block
180
        FLASH_BLOCK_SIZE,       // Size of block erase
181
        FLASH_BLOCK_SIZE,       // Size of logical block
182
        ATMEL_Write_Word,       // Write one word
183
        ATMEL_Write_Block,      // Write a block of WriteSize
184
        ATMEL_Read_Word,
185
        ATMEL_Read_Block,
186
        ATMEL_Erase_Block,
187
        0,                       // Lock a flash device
188
        0,                       // Unlock a flash device
189
        "Atmel",                // Null terminated Info string
190
        (tFlash *)&Integrator_Flash[1] // Pointer to next tFlash struct
191
    },
192
    {
193
        (char *)FLASH_BASE,     // Base Address of flash
194
        (char *)FLASH_BASE,     // Physical Address of flash
195
        FLASH_SIZE,             // Size of flash, in bytes
196
        APP_FTYPE | INTEL_FTYPE,// Flash type
197
        FLASH_BLOCK_SIZE,       // Size of physical block
198
        FLASH_BLOCK_SIZE,       // Size of block erase
199
        FLASH_BLOCK_SIZE,       // Size of logical block
200
        CFI_Write_Word,         // Write one word
201
        CFI_Write_Block,        // Write a block of writeSize bytes
202
        CFI_Read_Word,          // Read one word
203
        CFI_Read_Block,         // Read a block of writeSize bytes
204
        CFI_Erase_Block,        // Erase a block of eraseSize bytes
205
        0,                       // Lock a flash device
206
        0,                       // Unlock a flash device
207
        "Intel 28F320S3",       // Null terminated Info string
208
 
209
   }
210
};
211
 
212
#define SYNC_COUNT 63
213
 
214
extern void diag_printf(const char *, ...);
215
int identify_FLASH(void);
216
void write_sector(int, char *);
217
bool load_srecords(char (*readc)(), CYG_ADDRESS *start, int *size);
218
 
219
char dbuf[256];
220
char *raw = (char *)0x10000;
221
char *flash_buffer = (char *)0x30000;
222
int pos, len;
223
 
224
// FUNCTIONS
225
 
226
externC void
227
cyg_package_start( void )
228
{
229
#ifdef CYGPKG_LIBC
230
    cyg_iso_c_start();
231
#else
232
    (void)main(0, NULL);
233
#endif
234
} // cyg_package_start()
235
 
236
char nextch(void)
237
{
238
    return (raw[pos++]);
239
}
240
 
241
int
242
main( int argc, char *argv[] )
243
{
244
    int i, j, size;
245
    CYG_ADDRESS entry;
246
    char c;
247
 
248
    diag_printf("FLASH here!\n");
249
 
250
    CFI_Identify_Flash(Integrator_Flash[1]);
251
 
252
    while (identify_FLASH() == 0) {
253
        diag_printf("... Please change FLASH jumper - hit C/R to continue:");
254
        do {
255
            hal_diag_read_char(&c);
256
        } while ((c != '\r') && (c != '\n'));
257
        diag_printf("\n");
258
    }
259
 restart:
260
    diag_printf("Ready file - hit C/R to continue:");
261
    while (TRUE) {
262
        hal_diag_read_char(&c);
263
        if (c == '>') break;
264
    }
265
    i = 0;  j = 0;
266
    while (1) {
267
        hal_diag_read_char(&c);
268
        if (c == '!') {
269
            diag_printf("... Reset\n");
270
            goto restart;
271
        }
272
        raw[i++] = c;
273
        if (++j == SYNC_COUNT) {
274
            hal_diag_write_char(c);
275
            j = 0;
276
        }
277
        if (c == ':') break;
278
    }
279
    diag_printf("\n");
280
    pos = 0;  len = i;
281
    if (load_srecords(nextch, &entry, &size)) {
282
        diag_printf("Read %x bytes, entry: %x\n", size, entry);
283
        dump_buf(flash_buffer, 128);
284
        diag_printf("\nData loaded - hit '!' to continue:");
285
        while (TRUE) {
286
            hal_diag_read_char(&c);
287
            if (c == '!') break;
288
        }
289
        diag_printf("\n");
290
        diag_printf("...Programming FLASH\n");
291
        pos = 0;  i = 0;
292
        while (pos < size) {
293
            write_sector(i++, flash_buffer+pos);
294
            pos += 256;
295
        }
296
    } else {
297
        // Display buffer around failure        
298
        dump_buf(&raw[pos-32], 64);
299
    }
300
    diag_printf("All done!\n");
301
    while (1) ;
302
}
303
 
304
int
305
CFI_Identify_Flash(tFlash * flash)
306
{
307
     int offset = CFI_DATA_OFFS;
308
 
309
     // CFI query to check for CFI string "QRY"
310
     // Write 0x98 to address flash + 55
311
    *(unsigned int *)(flash->base + CFI_QUERY_OFFS) = CFI_QUERY_COMMAND;
312
 
313
    if ( *(flash->base + offset) == 'Q') {
314
         int temp = 0;
315
         offset += 2;
316
 
317
         if ( *(flash->base+ offset) == 'R') {
318
             temp =  *(flash->base+ SYS_INFO_SIZE_OFF); // read block size
319
             flash->size = 2 ^ temp;
320
             temp = *(flash->base+ SYS_ERASE_SIZE_OFF); // Read Erase Regions
321
             temp += ( *(flash->base+ SYS_ERASE_SIZE_OFF + 1) << 4);
322
 
323
             flash->eraseSize = temp * 256;
324
             // Read Max write Buffer (logical Block size)
325
         } else
326
           return FALSE;
327
    }
328
 
329
    // Reset for Read operation
330
   *(unsigned int *)(flash->base)  = READ_ARRAY;
331
 
332
   return TRUE;
333
}
334
 
335
// Adapted from ARM sample code
336
#define SEQ_ADD1                0x5555
337
#define SEQ_ADD2                0xAAAA
338
#define START_CMD1              0xAA
339
#define START_CMD2              0x55
340
#define ID_CMD                  0x90
341
#define PROG_CMD                0xA0
342
#define STOP_CMD                0xF0
343
 
344
#define MAN_ATMEL               0x1F
345
#define ATMEL_AT29C040_ID       0X5B
346
#define ATMEL_AT29C040A_ID      0XA4
347
#define ATMEL_AT29C1024_ID      0X25
348
#define ATMEL_SECTOR_SIZE       256
349
#define ATMEL_MAX_SECTORS       2048
350
 
351
int manuf_code, device_code, sector_size, max_no_of_sectors, word_mode;
352
volatile char *FLASH = (volatile char *)0x24000000;
353
 
354
int
355
identify_FLASH(void )
356
{
357
    // enable write to the Flash
358
    flashWriteEnable();
359
 
360
    // Enter Software Product Identification Mode
361
    FLASH[SEQ_ADD1] = START_CMD1;
362
    FLASH[SEQ_ADD2] = START_CMD2;
363
    FLASH[SEQ_ADD1] = ID_CMD;
364
 
365
    // Wait at least 10ms
366
    cyg_thread_delay(2);
367
 
368
    // Read Manufacturer and device code from the device
369
    manuf_code = FLASH[0];
370
    device_code = FLASH[1];
371
 
372
    diag_printf("manuf: %x, device: %x\n", manuf_code, device_code);
373
 
374
    // Exit Software Product Identification Mode
375
    FLASH[SEQ_ADD1] = START_CMD1;
376
    FLASH[SEQ_ADD2] = START_CMD2;
377
    FLASH[SEQ_ADD1] = STOP_CMD;
378
 
379
    // Wait at least 10ms
380
    cyg_thread_delay(5)
381
 
382
    // disble write to the Flash
383
    flashWriteDisable();;
384
 
385
    if (manuf_code != MAN_ATMEL) {
386
        diag_printf ( "Error: Wrong Manufaturer: %02x\n",manuf_code );
387
        return (0);
388
    }
389
 
390
    switch (device_code) {
391
    case  ATMEL_AT29C040A_ID:
392
        diag_printf ("AT29C040A recognised\n");
393
        sector_size = ATMEL_SECTOR_SIZE;
394
        max_no_of_sectors = ATMEL_MAX_SECTORS;
395
        word_mode = FALSE;
396
        break;
397
    case  ATMEL_AT29C1024_ID:
398
        diag_printf ("AT29C1024 recognised\n");
399
        sector_size = ATMEL_SECTOR_SIZE;
400
        max_no_of_sectors = ATMEL_MAX_SECTORS;
401
        word_mode = TRUE;
402
        break;
403
    default :
404
        diag_printf ( "Error: Unsupported device: %02x\n", device_code);
405
        return (0);
406
    }
407
    return (1);
408
}
409
 
410
void
411
write_sector(int num, char *buf)
412
{
413
    int i, cnt;
414
    volatile char *wrt = (volatile int *)&FLASH[num*sector_size];
415
 
416
//    diag_printf("Writing to %08x\n", wrt);
417
    // Enter Program Mode
418
    FLASH[SEQ_ADD1] = START_CMD1;
419
    FLASH[SEQ_ADD2] = START_CMD2;
420
    FLASH[SEQ_ADD1] = PROG_CMD;
421
 
422
    // Note: write bytes as longs regardless of bus width
423
    for (i = 0;  i < sector_size;  i++) {
424
        wrt[i] = buf[i];
425
    }
426
 
427
    // Wait for sector to program
428
    cnt = 0;
429
    i = sector_size - 1;
430
    while (wrt[i] != buf[i]) {
431
        if (cnt++ > 0x01000000) break;
432
    }
433
//    diag_printf("Out - i: %d, wrt[i] = %08X.%08X, buf[i] = %08X, count = %x\n", i, &wrt[i], wrt[i], buf[i], cnt);
434
 
435
    // Verify
436
    for (i = 0;  i < sector_size;  i++) {
437
        for (cnt = 0;  cnt < 10;  cnt++) {
438
            if (*wrt == *buf) break;
439
            cyg_thread_delay(1);
440
        }
441
        if (cnt == 10) {
442
            diag_printf("Can't program at 0x%08X: %02X not %02X\n", wrt, *wrt, *buf);
443
        }
444
        wrt++;  buf++;
445
    }
446
}
447
 
448
void
449
flashWriteEnable(void)
450
{
451
     volatile unsigned int *ebi_csr1 = (volatile unsigned int *)INTEGRATOR_EBI_CSR1;
452
 
453
     // allow write access to EBI_CSR1 area (Flash)
454
 
455
     *ebi_csr1 |= INTEGRATOR_EBI_WRITE_ENABLE;
456
 
457
     if (!(*ebi_csr1 & INTEGRATOR_EBI_WRITE_ENABLE)) {
458
         *(volatile unsigned int *)INTEGRATOR_EBI_LOCK = 0xA05F;
459
         *ebi_csr1 |= INTEGRATOR_EBI_WRITE_ENABLE;
460
         *(volatile unsigned int *)INTEGRATOR_EBI_LOCK = 0;
461
     }
462
 
463
     /* Enable Vpp and allow write access to Flash in system controller */
464
 
465
     *(volatile unsigned int *)INTEGRATOR_SC_CTRLS = FL_SC_CONTROL;
466
}
467
 
468
//
469
// flashWriteDisable: disable write access to the Flash memory
470
//
471
 
472
void
473
flashWriteDisable(void)
474
{
475
     volatile unsigned int *ebi_csr1 = (volatile unsigned int *)INTEGRATOR_EBI_CSR1;
476
 
477
     // disable write access to EBI_CSR1 area (Flash)
478
 
479
     *ebi_csr1 &= ~INTEGRATOR_EBI_WRITE_ENABLE;
480
 
481
     if (*ebi_csr1 & INTEGRATOR_EBI_WRITE_ENABLE) {
482
         *(volatile unsigned int *)INTEGRATOR_EBI_LOCK = 0xA05F;
483
         *ebi_csr1 &= ~INTEGRATOR_EBI_WRITE_ENABLE;
484
         *(volatile unsigned int *)INTEGRATOR_EBI_LOCK = 1;
485
     }
486
 
487
     // Disable Vpp and disable write access to Flash in system controller
488
 
489
     *(volatile unsigned int *)INTEGRATOR_SC_CTRLS = 0;
490
}
491
 
492
// S-record download code - viciously 'adapted' from "kernel/src/sload/sload.c"
493
 
494
/*---------------------------------------------------------------------------*/
495
/*
496
//
497
//      An srecord looks like this:
498
//
499
// byte count-+     address
500
// start ---+ |        |       data        +- checksum
501
//          | |        |                   |
502
//        S01000006F6B692D746573742E73726563E4
503
//        S315000448600000000000000000FC00005900000000E9
504
//        S31A0004000023C1400037DE00F023604000377B009020825000348D
505
//        S30B0004485A0000000000004E
506
//        S70500040000F6
507
//
508
//      S<type><length><address><data><checksum>
509
//
510
//      Where
511
//      - length (2 characters)
512
//        is the number of bytes following upto the checksum. Note that
513
//        this is not the number of chars following, since it takes two
514
//        chars to represent a byte.
515
//      - type (2 characters)
516
//        is one of:
517
//        0) header record
518
//        1) two byte address data record
519
//        2) three byte address data record
520
//        3) four byte address data record
521
//        5) record containing the number of S1, S2, or S3 records
522
//        7) four byte address termination record
523
//        8) three byte address termination record
524
//        9) two byte address termination record
525
//
526
//      - address (4, 6, or 8 characters)
527
//        is the start address of the data following, or in the case of
528
//        a termination record, the start address of the image
529
//      - data (0-2n characters)
530
//        is the data.
531
//      - checksum (2 characters)
532
//        is the sum of all the raw byte data in the record, from the length
533
//        upwards, modulo 256 and subtracted from 255.
534
//
535
// Useful S-records for testing purposes:
536
//   Start record:
537
//      S00B0000737461303030447563
538
//   This sets the default address to be 0x02005000:
539
//      S31A020050002700801481C4E0B0A15000000100000091D02000018F
540
//      S31A0200501500000001000000010000002700801881C4E2E4A150C1
541
//      S311020080A42407070A090B0A0781050000E1
542
//   Termination record:
543
//      S70502005000A8
544
//
545
*/
546
 
547
#define S0      0
548
#define S1      1
549
#define S2      2
550
#define S3      3
551
#define S5      5
552
#define S7      7
553
#define S8      8
554
#define S9      9
555
 
556
/*---------------------------------------------------------------------------*/
557
 
558
int hex2digit(char c)
559
{
560
    if( c & 0x40 ) c += 9;;
561
    return c &0x0f;
562
 
563
//    return ( c <= '9' ? c - '0' :
564
//             c <= 'Z' ? c - 'A' + 10 :
565
//             c - 'a' + 10);
566
}
567
 
568
/*---------------------------------------------------------------------------*/
569
 
570
bool load_srecords(char (*readc)(),
571
                   CYG_ADDRESS *start,
572
                   int *size)
573
{
574
    CYG_ADDRESS addr, load_addr;
575
    int addrsize;
576
    int length;
577
    int i;
578
    cyg_uint8 chksum, ochksum;
579
    cyg_uint8 val;
580
    cyg_uint8 *tdata;
581
    char s;
582
    char type;
583
    char len0;
584
    char len1;
585
    bool first = true;
586
 
587
 
588
    do {
589
        // Skip whitespace characters until we find something that
590
        // might be an 'S'.
591
        do {
592
            s = readc();
593
        } while( s == '\r' || s == '\n' || s == ' ');
594
 
595
        // Check that this is an S record
596
        if( s != 'S' ) {
597
            diag_printf("Invalid 'S' record\n");
598
            return false;
599
        }
600
 
601
        // First 4 bytes are standard S + type + len
602
        type = readc();
603
        len0 = readc();
604
        len1 = readc();
605
 
606
        // decode the type
607
        type = hex2digit(type);
608
 
609
        // determine address size
610
        switch (type) {
611
        case S0:                        // start records have no address
612
            addrsize = 0;
613
            break;
614
        case S1:                        // two byte address
615
        case S9:
616
            addrsize = 4;
617
            break;
618
        case S2:                        // 3 byte address
619
        case S8:
620
            addrsize = 6;
621
            break;
622
        case S3:                        // 4 byte address
623
        case S7:
624
            addrsize = 8;
625
            break;
626
        }
627
 
628
        length  = hex2digit (len0) << 4;
629
        length |= hex2digit (len1);
630
        chksum = length;
631
 
632
        // read the address
633
        addr = 0;
634
        for (i = 0; i < addrsize; i++) {
635
            val = hex2digit(readc());
636
            addr = (addr << 4) | val;
637
        }
638
 
639
        // calculate the checksum, which is done by the byte, not the digit
640
        for (i = 0; i < addrsize*4; i += 8) {
641
            chksum += ((addr >>  i) & 0xff);
642
        }
643
 
644
        // decide where to load this data
645
        if (first && (type != S0)) {
646
            load_addr = addr;
647
            first = false;
648
        }
649
 
650
        // read the data and put it directly into memory where it belongs
651
        tdata = (cyg_uint8 *)((addr - load_addr) + flash_buffer);
652
        if (type < S7) {
653
            *size = (addr - load_addr);
654
        }
655
        val = 0;
656
        for (i = 0; i < ((length - 1) * 2) - addrsize; i += 2 ) {
657
            val  = hex2digit (readc()) << 4;
658
            val |= hex2digit (readc());
659
            chksum += val;
660
            if( type != S0 ) *tdata++ = val;
661
            if (type < S7) *size = *size + 1;
662
        }
663
 
664
        // now get the old checksum
665
        ochksum = hex2digit(readc()) << 4;
666
        ochksum |= hex2digit(readc());
667
        chksum = ~chksum;
668
        if (chksum != ochksum) {
669
            diag_printf("Bad checksum - addr: %x\n", addr);
670
            return false;
671
        }
672
 
673
    } while( type < S7 );
674
 
675
    *start = addr;
676
    return true;
677
}

powered by: WebSVN 2.1.0

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