File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 #ifndef TESTING
0074 #include <rtems.h>
0075 #include <bsp/flashPgm.h>
0076 #include <bsp/flashPgmPvt.h>
0077 #else
0078 #include "flashPgm.h"
0079 #include "flashPgmPvt.h"
0080 #endif
0081
0082 #include <unistd.h>
0083 #include <stdio.h>
0084 #include <inttypes.h>
0085 #include <ctype.h>
0086 #include <fcntl.h>
0087 #include <stdlib.h>
0088
0089 #define DEBUG 0
0090 #undef DEBUG
0091
0092 #ifdef DEBUG
0093 #define STATIC
0094 #else
0095 #define STATIC static
0096 #endif
0097
0098
0099
0100 STATIC uint32_t
0101 BSP_flashProbeSize(struct bankdesc *b);
0102
0103 STATIC struct bankdesc *
0104 bankValidate(int bank, int quiet);
0105
0106 static struct bankdesc *
0107 argcheck(int bank, uint32_t offset, const char *src, uint32_t size);
0108
0109
0110
0111 union bconv {
0112 uint32_t u;
0113 uint16_t s[2];
0114 char c[4];
0115 };
0116
0117
0118
0119
0120 static void
0121 rd_par(struct bankdesc *b, union bconv *pv, uint32_t a)
0122 {
0123 if ( 4 == FLASH_STRIDE(b) ) {
0124 pv->u = *(_u32_a_t*)a;
0125 } else if ( 2 == FLASH_STRIDE(b) ) {
0126 pv->s[0] = *(_u16_a_t*)a;
0127 } else {
0128 pv->c[0] = *(_u8_a_t*)a;
0129 }
0130 }
0131
0132
0133 STATIC int
0134 getUc(void)
0135 {
0136 fseek(stdin, 0, SEEK_END);
0137 return toupper(getchar());
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 static unsigned flip(unsigned x)
0155 {
0156 static char bar[]= { '/', '-', '\\', '|' };
0157 putchar('\b');
0158 putchar(bar[ x & 3]);
0159 fflush(stdout);
0160 return x+1;
0161 }
0162
0163
0164
0165
0166
0167 static void wipe(unsigned f)
0168 {
0169 if ( f ) {
0170 putchar('\b');
0171 putchar(' ');
0172 putchar('\b');
0173 fflush(stdout);
0174 }
0175 }
0176
0177
0178
0179
0180 STATIC struct vendesc *
0181 knownVendor(struct bankdesc *b, uint32_t addr, uint32_t *pd, unsigned quiet)
0182 {
0183 uint32_t v;
0184 struct vendesc *rval;
0185
0186 for ( rval=b->knownVendors; rval->name; rval++ ) {
0187
0188 if ( rval->ops->get_id(b, addr, &v, pd) ) {
0189 if ( quiet < 2 )
0190 fprintf(stderr,"Unable to read vendor/device info at 0x%08"PRIx32"\n", addr);
0191 return 0;
0192 }
0193
0194 if ( rval->id == v ) {
0195 return rval;
0196 }
0197 }
0198 if ( quiet < 2 )
0199 fprintf(stderr,"Unknown vendor id (0x%04"PRIx32") at 0x%08"PRIx32"\n",v, addr);
0200 return 0;
0201 }
0202
0203
0204 STATIC struct devdesc *
0205 knownDevice(struct vendesc *v, uint32_t d)
0206 {
0207 struct devdesc *rval;
0208 for ( rval=v->known_devs; rval->name; rval++ ) {
0209 if ( rval->id == d ) {
0210 return rval;
0211 }
0212 }
0213 return 0;
0214 }
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225 STATIC uint32_t
0226 BSP_flashWriteDataRaw(struct bankdesc *b, uint32_t addr, const char *src, uint32_t n_words, int quiet)
0227 {
0228 uint32_t sta;
0229 uint32_t N;
0230 uint32_t nxt, a, i, bufsz;
0231 uint32_t then, now;
0232 unsigned f;
0233 const char *s;
0234
0235 #ifdef DEBUG
0236 printf("\nflashWriteDataRaw(0x%08"PRIx32", %p, 0x%"PRIx32")\n", addr, src, n_words);
0237 #endif
0238
0239 if ( 0 == n_words ) {
0240 return 0;
0241 }
0242
0243 if ( !b ) {
0244 fprintf(stderr,"Missing bank descriptor argument\n");
0245 return -1;
0246 }
0247 if ( !b->dd ) {
0248 fprintf(stderr,"Bank descriptor not initialized\n");
0249 return -1;
0250 }
0251
0252 if ( addr & (FLASH_STRIDE(b)-1) ) {
0253 fprintf(stderr,"Misaligned address (not on word boundary) 0x%08"PRIx32"\n", addr);
0254 return -1;
0255 }
0256
0257 if ( (sta = b->ops->check_ready(b, addr)) ) {
0258
0259 return addr;
0260 }
0261
0262 bufsz = FLASH_NDEVS(b) * b->dd->bufsz;
0263
0264 then = BSP_flashBspOps.read_us_timer();
0265
0266 for ( f = 0, a = addr, s=src, i = n_words; i ; s+=N ) {
0267
0268 nxt = (a + bufsz) & ~(bufsz-1);
0269
0270
0271 N = (nxt - a);
0272
0273 if ( N > i * FLASH_STRIDE(b) )
0274 N = i * FLASH_STRIDE(b);
0275
0276 i -= N/FLASH_STRIDE(b);
0277
0278 if ( (sta = b->ops->write_line(b, a, s, N)) )
0279 goto bail;
0280
0281 if ( ! quiet && (now = BSP_flashBspOps.read_us_timer()) - then > 500000 ) {
0282 f = flip(f);
0283 then = now;
0284 }
0285
0286 a = nxt;
0287 }
0288
0289 sta = 0;
0290
0291
0292 for ( i=0, a=addr; i < n_words * FLASH_STRIDE(b); i++, a++ ) {
0293 if ( *(char*)a != src[i] ) {
0294 sta = -2;
0295 goto bail;
0296 }
0297 }
0298
0299 bail:
0300 if ( ! quiet ) {
0301 wipe(f);
0302 }
0303 if ( sta ) {
0304 switch ( sta ) {
0305 default:
0306 fprintf(stderr,"Error (flashWriteDataRaw): write error\n");
0307 b->ops->print_stat(b, sta,0);
0308 break;
0309
0310 case -1:
0311 fprintf(stderr,"Error (flashWriteDataRaw): Timeout\n");
0312 break;
0313
0314 case -2:
0315 fprintf(stderr,"Error (flashWriteDataRaw): write verification failed at 0x%08"PRIx32"\n", a);
0316 break;
0317 }
0318 b->ops->array_mode(b, a);
0319 } else {
0320
0321 a = 0;
0322 }
0323 return a;
0324 }
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338 STATIC struct devdesc *
0339 BSP_flashCheckId(struct bankdesc *b, uint32_t addr, unsigned quiet)
0340 {
0341 uint8_t x;
0342 uint32_t d;
0343 struct vendesc *vd;
0344 struct devdesc *dd;
0345
0346
0347 x = *(A8)addr;
0348 *(A8)addr = ~x;
0349 if ( x != *(A8)addr ) {
0350
0351 *(A8)addr = x;
0352 if ( quiet < 3 )
0353 fprintf(stderr,"Addr 0x%08"PRIx32" seems to be RAM!\n", addr);
0354 return 0;
0355 }
0356
0357 if ( !(vd = knownVendor(b, addr, &d, quiet)) ) {
0358 return 0;
0359 }
0360
0361
0362 b->ops = vd->ops;
0363
0364 if ( !quiet )
0365 printf("Flash device, vendor: %s", vd->name);
0366
0367 if ( !(dd = knownDevice(vd, d)) ) {
0368 if ( !quiet )
0369 printf("\n");
0370 if ( quiet < 2 )
0371 fprintf(stderr,"Unknown device id (0x%04"PRIx32") at 0x%08"PRIx32"\n",d, addr);
0372 return 0;
0373 }
0374
0375
0376
0377
0378 b->fblksz = dd->fblksz * FLASH_NDEVS(b);
0379
0380 if ( !quiet )
0381 printf(", device: %s -- size 0x%08"PRIx32" bytes\n", dd->name, dd->size);
0382 return dd;
0383 }
0384
0385
0386
0387
0388 #define SCAN_BACK_OFFSET 0x10000
0389
0390
0391
0392
0393
0394
0395 STATIC uint32_t
0396 BSP_flashProbeSize(struct bankdesc *b)
0397 {
0398 int max = b->max_size;
0399 uint32_t rval;
0400 struct devdesc *dd;
0401 unsigned q;
0402 if ( max > 0 ) {
0403 for ( rval = 0, q=1; rval < max && (dd = BSP_flashCheckId(b, b->start + rval, q)); q=3 ) {
0404 rval += dd->size * FLASH_NDEVS(b);
0405 }
0406 } else {
0407
0408 max = -max;
0409 for ( rval = 0, q=1; rval < max && (dd = BSP_flashCheckId(b, b->start + max - SCAN_BACK_OFFSET - rval, q)); q=3 ) {
0410 rval += dd->size * FLASH_NDEVS(b);
0411 }
0412 b->start += max - rval;
0413 }
0414 return rval;
0415 }
0416
0417 uint32_t
0418 BSP_flashStart(int bank)
0419 {
0420 struct bankdesc *b;
0421 if ( ! ( b = argcheck(bank, 0, 0, 0) ) )
0422 return -1;
0423 return b->start;
0424 }
0425
0426 uint32_t
0427 BSP_flashSize(int bank)
0428 {
0429 struct bankdesc *b;
0430 if ( ! ( b = argcheck(bank, 0, 0, 0) ) )
0431 return -1;
0432 return b->size;
0433 }
0434
0435 uint32_t
0436 BSP_flashBlockSize(int bank)
0437 {
0438 struct bankdesc *b;
0439 if ( ! ( b = argcheck(bank, 0, 0, 0) ) )
0440 return -1;
0441 return b->fblksz;
0442 }
0443
0444
0445 #ifndef TESTING
0446
0447
0448 STATIC struct bankdesc *
0449 bankValidate(int bank, int quiet)
0450 {
0451 struct bankdesc *b = BSP_flashBspOps.bankcheck(bank, quiet);
0452
0453
0454 if ( BSP_flashBspOps.flash_wp(bank, -1) ) {
0455 fprintf(stderr,"Flash bank #%i is write-protected; use 'BSP_flashWriteEnable(int bank)' and/or jumper\n", bank);
0456 return 0;
0457 }
0458
0459 if ( !b->size && !(b->size = BSP_flashProbeSize(b)) ) {
0460 fprintf(stderr,"Configuration Error - unable to determine flash size\n");
0461 return 0;
0462 }
0463
0464 if ( !b->dd && !(b->dd = BSP_flashCheckId(b, b->start,1)) ) {
0465 fprintf(stderr,"Error: unable to detect flash device in bank #%i\n", bank);
0466 return 0;
0467 }
0468 return b;
0469 }
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484 static struct bankdesc *
0485 argcheck(int bank, uint32_t offset, const char *src, uint32_t size)
0486 {
0487 struct bankdesc *b;
0488
0489 if ( !(b=bankValidate(bank, 0)) ) {
0490 return 0;
0491 }
0492
0493 if ( offset + size > b->size ) {
0494 fprintf(stderr,"Error: requested size exceeds available flash (0x%08"PRIx32" bytes)\n", b->size);
0495 return 0;
0496 }
0497
0498 if ( src && ( src + size > (char*)b->start && src < (char*)(b->start + b->size) ) ) {
0499 fprintf(stderr,"Error: cannot copy data within flash bank\n");
0500 return 0;
0501 }
0502
0503
0504 return b;
0505 }
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517 STATIC int
0518 regionCheckAndErase(int bank, uint32_t offset, const char *src, uint32_t n_bytes, int quiet)
0519 {
0520 struct bankdesc *b;
0521 uint32_t i;
0522 char *p;
0523 uint32_t a,e;
0524
0525 if ( ! (b = argcheck(bank, offset, src, n_bytes)) )
0526 return -1;
0527
0528 a = offset & ~(b->fblksz - 1);
0529 e = (offset + n_bytes + b->fblksz - 1) & ~ (b->fblksz - 1);
0530
0531
0532
0533
0534 if ( a != offset ) {
0535 a += b->fblksz;
0536 i = ( a > offset + n_bytes ) ? offset + n_bytes : a;
0537 for ( p = (char*)(b->start + offset); p < (char*)(b->start + i); p++ ) {
0538 if ( (char)0xff != *p ) {
0539 if ( ! quiet ) {
0540 fprintf(stderr,"Starting offset not block-aligned and destination area not empty.\n");
0541 fprintf(stderr,"I'll need to erase data below destination start\n");
0542 }
0543 a -= b->fblksz;
0544 break;
0545 }
0546 }
0547 }
0548 if ( e != offset + n_bytes ) {
0549 e -= b->fblksz;
0550 i = ( e < offset ) ? offset : e;
0551 for ( p = (char*)(b->start + i); p < (char*)(b->start + offset + n_bytes); p++ ) {
0552 if ( (char)0xff != *p ) {
0553 if ( ! quiet ) {
0554 fprintf(stderr,"Ending offset not block-aligned and destination area not empty.\n");
0555 fprintf(stderr,"I'll need to erase data beyond destination end\n");
0556 }
0557 e += b->fblksz;
0558 break;
0559 }
0560 }
0561 }
0562 if ( ! quiet ) {
0563 if ( e > a )
0564 printf("ERASING 0x%08"PRIx32" .. 0x%08"PRIx32"\n", (b->start+a), (b->start + e - 1));
0565 printf("WRITING 0x%08"PRIx32" .. 0x%08"PRIx32"\n", (b->start+offset), (b->start + offset + n_bytes - 1));
0566 printf("OK to proceed y/[n]?"); fflush(stdout);
0567 if ( 'Y' != getUc() ) {
0568 printf("ABORTED\n");
0569 return -1;
0570 }
0571 }
0572 if ( e > a ) {
0573 if ( quiet < 2 ) {
0574 printf("ERASING "); fflush(stdout);
0575 }
0576
0577 if ( (i = BSP_flashErase(bank, a, e-a, quiet ? quiet : 1)) )
0578 return i;
0579
0580 if ( quiet < 2 ) {
0581 printf("DONE\n");
0582 }
0583 }
0584
0585 return 0;
0586 }
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597 STATIC int
0598 BSP_flashWriteRegion(int bank, uint32_t offset, const char *src, uint32_t n_bytes, int quiet)
0599 {
0600 struct bankdesc *b = BSP_flashBspOps.bankcheck(bank, 0);
0601 uint32_t ab = offset & ~(b->fblksz - 1);
0602 uint32_t eb = (offset + n_bytes + b->fblksz - 1) & ~(b->fblksz - 1);
0603 uint32_t o,i,a,e;
0604 int err;
0605 const char *p;
0606 union bconv buf;
0607
0608
0609 for ( i=ab; i<eb; i+=b->fblksz ) {
0610 b->ops->unlock_block(b, b->start + i );
0611 }
0612
0613 err = 0;
0614 p = src;
0615
0616
0617 o = b->start + offset;
0618 a = o & ~(FLASH_STRIDE(b)-1);
0619 e = (o + n_bytes) & ~(FLASH_STRIDE(b)-1);
0620
0621 if ( o > a ) {
0622 i = o - a;
0623
0624 rd_par(b, &buf, a);
0625
0626 while ( i < FLASH_STRIDE(b) && p < src + n_bytes ) {
0627 buf.c[i++] = *p++;
0628 }
0629 if ( (err = BSP_flashWriteDataRaw(b, a, buf.c, 1, quiet)) )
0630 goto bail;
0631 a += FLASH_STRIDE(b);
0632 }
0633
0634
0635
0636
0637 if ( e > a ) {
0638 i = (e-a);
0639 if ( (err = BSP_flashWriteDataRaw(b, a, p, i/FLASH_STRIDE(b), quiet)) )
0640 goto bail;
0641 p += i;
0642 }
0643
0644
0645 if ( o + n_bytes > e) {
0646 rd_par(b, &buf, e);
0647 for ( i=0; p < src + n_bytes; ) {
0648 buf.c[i++] = *p++;
0649 }
0650 if ( (err = BSP_flashWriteDataRaw(b, e, buf.c, 1, quiet)) )
0651 goto bail;
0652 }
0653
0654 bail:
0655
0656 for ( i=ab; i<eb; i+=b->fblksz ) {
0657 b->ops->lock_block(b, b->start + i );
0658 }
0659
0660
0661 if ( !err ) {
0662 for ( i=0; i<n_bytes; i++ ) {
0663 if ( ((char*)(b->start + offset))[i] != src[i] ) {
0664 fprintf(stderr,"Final verification failed at offset 0x%08"PRIx32"\n", (offset + i));
0665 return b->start + offset + i;
0666 }
0667 }
0668 }
0669
0670 return err;
0671 }
0672
0673 int
0674 BSP_flashErase(int bank, uint32_t offset, uint32_t size, int quiet)
0675 {
0676 struct bankdesc *b;
0677 uint32_t a,i;
0678 int f;
0679
0680 if ( ! (b = argcheck(bank, offset, 0, size)) )
0681 return -1;
0682
0683 if ( offset & (b->fblksz - 1) ) {
0684 fprintf(stderr,"Offset misaligned (needs to be multiple of 0x%08"PRIx32")\n", b->fblksz);
0685 return -1;
0686 }
0687 if ( size & (b->fblksz - 1) ) {
0688 fprintf(stderr,"Size misaligned (needs to be multiple of 0x%08"PRIx32")\n", b->fblksz);
0689 return -1;
0690 }
0691
0692 a = b->start + offset;
0693
0694 if ( !quiet ) {
0695 printf("ERASING Flash (Bank #%i)\n from 0x%08"PRIx32" .. 0x%08"PRIx32"\nproceed y/[n]?",
0696 bank, a, (a+size-1));
0697 fflush(stdout);
0698 if ( 'Y' != getUc() ) {
0699 printf("ABORTED\n");
0700 return -1;
0701 }
0702 }
0703 f = 0;
0704 while ( size ) {
0705
0706 for ( i = 0; i<b->fblksz; i++ ) {
0707 if ( (char)0xff != ((char*)a)[i] ) {
0708 b->ops->unlock_block(b, a);
0709 i = b->ops->erase_block(b, a);
0710 b->ops->lock_block(b, a);
0711 if (i) {
0712 wipe(f);
0713 return a;
0714 }
0715 break;
0716 }
0717 }
0718
0719 if ( quiet < 2 ) {
0720 f = flip(f);
0721 }
0722
0723 a += b->fblksz;
0724 size -= b->fblksz;
0725 }
0726 b->ops->array_mode(b, a);
0727 if ( quiet < 2 ) {
0728 wipe(f);
0729 }
0730 return 0;
0731 }
0732
0733 int
0734 BSP_flashWrite(int bank, uint32_t offset, const char *src, uint32_t n_bytes, int quiet)
0735 {
0736 int rval;
0737
0738 if ( !src ) {
0739 fprintf(stderr,"Error: Data source pointer is NULL\n");
0740 return -1;
0741 }
0742
0743 if ( (rval = regionCheckAndErase(bank, offset, src, n_bytes, quiet)) )
0744 return rval;
0745
0746 if ( ! quiet ) {
0747 printf("WRITING "); fflush(stdout);
0748 }
0749
0750 rval = BSP_flashWriteRegion(bank, offset, src, n_bytes, quiet);
0751
0752 if ( !quiet && !rval ) {
0753 printf("DONE");
0754 }
0755 if ( !quiet )
0756 printf("\n");
0757 return rval;
0758 }
0759
0760 static int
0761 bfill(int fd, char *buf, int size)
0762 {
0763 int got, avail;
0764 for (avail = size; (got = read(fd, buf, avail)) > 0; avail-=got ) {
0765 buf += got;
0766 }
0767 return size - avail;
0768 }
0769
0770 int
0771 BSP_flashWriteFile(int bank, uint32_t offset, const char *fname, int quiet)
0772 {
0773 int fd = -1;
0774 struct stat sb;
0775 uint32_t sz;
0776 int rval = -1;
0777 char *buf = 0;
0778 uint32_t got;
0779 struct bankdesc *b;
0780 unsigned f = 0;
0781
0782 if ( ! (b = bankValidate(bank, 0)) )
0783 return -1;
0784
0785 for ( sz = 0; -1 == fd ; ) {
0786 if ( (fd = open(fname,O_RDONLY)) < 0 ) {
0787 perror("Opening file");
0788 return -1;
0789 }
0790
0791 if ( sz )
0792 break;
0793
0794 if ( fstat(fd, &sb) ) {
0795 fprintf(stderr,"Warning: fstat doesn't work; need to slurp file to determine size; please be patient.\n");
0796 FILE *f;
0797 close(fd); fd = -1;
0798 f = fopen(fname,"r");
0799 if ( !f ) {
0800 perror("fdopen");
0801 return -1;
0802 }
0803 while ( EOF != fgetc(f) )
0804 sz++;
0805 fclose(f);
0806
0807 } else {
0808 sz = sb.st_size;
0809 }
0810 if ( 0 == sz ) {
0811 fprintf(stderr,"Error: zero file size (?)\n");
0812 goto bail;
0813 }
0814 }
0815
0816 if ( !(buf = malloc(b->fblksz)) ) {
0817 perror("buffer allocation");
0818 goto bail;
0819 }
0820
0821
0822 if ( (rval = regionCheckAndErase(bank, offset, buf, sz, quiet)) )
0823 goto bail;
0824
0825
0826 if ( quiet < 2 ) {
0827 printf("WRITING "); fflush(stdout);
0828 }
0829
0830 while ( (got = bfill(fd, buf, b->fblksz)) > 0 && sz ) {
0831 if ( (rval = BSP_flashWriteRegion(bank, offset, buf, got, 1)) ) {
0832 wipe(f);
0833 goto bail;
0834 }
0835 offset += got;
0836 sz -= got;
0837 if ( quiet < 2 ) {
0838 f = flip(f);
0839 }
0840 }
0841 if ( got < 0 ) {
0842 perror("reading file");
0843 rval = offset;
0844 goto bail;
0845 }
0846
0847 if ( quiet < 2 ) {
0848 wipe(f);
0849 printf("DONE");
0850 }
0851 bail:
0852 if ( quiet < 2 ) {
0853 printf("\n");
0854 }
0855 if ( fd > -1 )
0856 close(fd);
0857 free(buf);
0858 return rval;
0859 }
0860
0861 int
0862 BSP_flashWriteEnable(int bank)
0863 {
0864 return BSP_flashBspOps.flash_wp(bank,0);
0865 }
0866
0867 int
0868 BSP_flashWriteDisable(int bank)
0869 {
0870 return BSP_flashBspOps.flash_wp(bank,1);
0871 }
0872
0873 int
0874 BSP_flashDumpInfo(FILE *f)
0875 {
0876 struct bankdesc *b;
0877 int bank;
0878
0879 if ( !f )
0880 f = stdout;
0881
0882
0883
0884
0885 for ( bank = 0; BSP_flashBspOps.bankcheck(bank,1); bank++ ) {
0886 if ( (b=argcheck(bank,0,0,0)) ) {
0887 fprintf(f,"Flash Bank #%i; 0x%08"PRIx32" .. 0x%08"PRIx32" (%"PRId32" bytes)\n",
0888 bank, b->start, (b->start + b->size - 1), b->size);
0889 fprintf(f,"%i * %i-bit devices in parallel; block size 0x%"PRIx32"\n", FLASH_NDEVS(b), FLASH_WIDTH(b)*8, b->fblksz);
0890 BSP_flashCheckId(b, b->start, 0);
0891 }
0892 }
0893
0894 return 0;
0895 }
0896
0897 #else
0898
0899 int
0900 main(int argc, char **argv)
0901 {
0902 uint32_t fla[1000];
0903 uint32_t qqq[1000];
0904 int i;
0905 for ( i=0; i<sizeof(qqq)/sizeof(qqq[0]); i++ )
0906 qqq[i] = 0xdada<<16 | i;
0907 BSP_flashWriteDataRaw(0, (uint32_t)fla, (char*)qqq, 32, 0);
0908 }
0909 #endif