2 * (C) Copyright 2000, 2001
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 * Wait for completion of each sector erase command issued
28 * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
33 * - adopted for pip405, Denis Peter, MPL AG Switzerland
40 #include <asm/processor.h>
42 #include "../pip405/pip405.h"
45 #include "../mip405/mip405.h"
47 #include "common_util.h"
49 flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
50 /*-----------------------------------------------------------------------
53 static ulong flash_get_size (vu_long *addr, flash_info_t *info);
54 static int write_word (flash_info_t *info, ulong dest, ulong data);
55 static void flash_get_offsets (ulong base, flash_info_t *info);
57 void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt);
63 #define FLASH_WORD_SIZE unsigned char
69 #define FLASH_WORD_SIZE unsigned short
75 #define FLASH_WORD_SIZE unsigned short
81 #define FLASH_WORD_SIZE unsigned short
87 /*-----------------------------------------------------------------------
91 unsigned long flash_init (void)
93 unsigned long size_b0, size_b1;
96 unsigned long base_b0, base_b1;
99 rc=switch_cs(FALSE); /* map Flash High */
102 printf("(MPS Boot) ");
104 printf("(Flash Boot) ");
105 /* Init: no FLASHes known */
106 for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
107 flash_info[i].flash_id = FLASH_UNKNOWN;
110 /* Static FLASH Bank configuration here - FIXME XXX */
112 size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
114 if (flash_info[0].flash_id == FLASH_UNKNOWN) {
115 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
116 size_b0, size_b0<<20);
119 if (CFG_MAX_FLASH_BANKS == 1)
122 /* flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); */
123 /* Monitor protection ON by default */
124 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
125 flash_protect(FLAG_PROTECT_SET,
127 CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
131 flash_info[0].size = size_b0;
137 size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
139 /* Re-do sizing to get full correct info */
143 mtdcr(ebccfga, pb0cr);
144 pbcr = mfdcr(ebccfgd);
145 mtdcr(ebccfga, pb0cr);
147 pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
148 mtdcr(ebccfgd, pbcr);
149 /* printf("pb1cr = %x\n", pbcr); */
154 mtdcr(ebccfga, pb1cr);
155 pbcr = mfdcr(ebccfgd);
156 mtdcr(ebccfga, pb1cr);
157 base_b0 = base_b1 - size_b0;
158 pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
159 mtdcr(ebccfgd, pbcr);
160 /* printf("pb0cr = %x\n", pbcr); */
163 size_b0 = flash_get_size((vu_long *)base_b0, &flash_info[0]);
165 flash_get_offsets (base_b0, &flash_info[0]);
167 /* monitor protection ON by default */
168 (void)flash_protect(FLAG_PROTECT_SET,
169 base_b0+size_b0-CFG_MONITOR_LEN,
174 /* Re-do sizing to get full correct info */
175 size_b1 = flash_get_size((vu_long *)base_b1, &flash_info[1]);
177 flash_get_offsets (base_b1, &flash_info[1]);
179 /* monitor protection ON by default */
180 (void)flash_protect(FLAG_PROTECT_SET,
181 base_b1+size_b1-CFG_MONITOR_LEN,
184 /* monitor protection OFF by default (one is enough) */
185 (void)flash_protect(FLAG_PROTECT_CLEAR,
186 base_b0+size_b0-CFG_MONITOR_LEN,
190 flash_info[1].flash_id = FLASH_UNKNOWN;
191 flash_info[1].sector_count = -1;
194 flash_info[0].size = size_b0;
195 flash_info[1].size = size_b1;
197 switch_cs(rc); /* switch mode back */
198 return (size_b0 + size_b1);
202 static void flash_get_offsets (ulong base, flash_info_t *info)
207 /*-----------------------------------------------------------------------
209 static void flash_get_offsets (ulong base, flash_info_t *info)
213 /* set up sector start address table */
214 if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
215 (info->flash_id == FLASH_AM040)){
216 for (i = 0; i < info->sector_count; i++)
217 info->start[i] = base + (i * 0x00010000);
220 if (info->flash_id & FLASH_BTYPE) {
221 /* set sector offsets for bottom boot block type */
222 info->start[0] = base + 0x00000000;
223 info->start[1] = base + 0x00004000;
224 info->start[2] = base + 0x00006000;
225 info->start[3] = base + 0x00008000;
226 for (i = 4; i < info->sector_count; i++) {
227 info->start[i] = base + (i * 0x00010000) - 0x00030000;
230 /* set sector offsets for top boot block type */
231 i = info->sector_count - 1;
232 info->start[i--] = base + info->size - 0x00004000;
233 info->start[i--] = base + info->size - 0x00006000;
234 info->start[i--] = base + info->size - 0x00008000;
235 for (; i >= 0; i--) {
236 info->start[i] = base + i * 0x00010000;
243 /*-----------------------------------------------------------------------
245 void flash_print_info (flash_info_t *info)
251 volatile unsigned long *flash;
253 if (info->flash_id == FLASH_UNKNOWN) {
254 printf ("missing or unknown FLASH type\n");
258 switch (info->flash_id & FLASH_VENDMASK) {
259 case FLASH_MAN_AMD: printf ("AMD "); break;
260 case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
261 case FLASH_MAN_SST: printf ("SST "); break;
262 case FLASH_MAN_INTEL: printf ("Intel "); break;
263 default: printf ("Unknown Vendor "); break;
266 switch (info->flash_id & FLASH_TYPEMASK) {
267 case FLASH_AM040: printf ("AM29F040 (512 Kbit, uniform sector size)\n");
269 case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
271 case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
273 case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
275 case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
277 case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
279 case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
281 case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
283 case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
285 case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
287 case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
289 case FLASH_INTEL320T: printf ("TE28F320C3 (32 Mbit, top sector size)\n");
291 default: printf ("Unknown Chip Type\n");
295 printf (" Size: %ld KB in %d Sectors\n",
296 info->size >> 10, info->sector_count);
298 printf (" Sector Start Addresses:");
299 for (i=0; i<info->sector_count; ++i) {
301 * Check if whole sector is erased
303 if (i != (info->sector_count-1))
304 size = info->start[i+1] - info->start[i];
306 size = info->start[0] + info->size - info->start[i];
308 flash = (volatile unsigned long *)info->start[i];
309 size = size >> 2; /* divide by 4 for longword access */
310 for (k=0; k<size; k++)
312 if (*flash++ != 0xffffffff)
320 #if 0 /* test-only */
323 info->protect[i] ? " (RO)" : " "
325 printf (" %08lX%s%s",
328 info->protect[i] ? "RO " : " "
336 /*-----------------------------------------------------------------------
340 /*-----------------------------------------------------------------------
344 * The following code cannot be run from FLASH!
346 static ulong flash_get_size (vu_long *addr, flash_info_t *info)
349 FLASH_WORD_SIZE value;
350 ulong base = (ulong)addr;
351 volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
353 /* Write auto select command: read Manufacturer ID */
354 addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
355 addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
356 addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
359 /* printf("flash_get_size value: %x\n",value); */
361 case (FLASH_WORD_SIZE)AMD_MANUFACT:
362 info->flash_id = FLASH_MAN_AMD;
364 case (FLASH_WORD_SIZE)FUJ_MANUFACT:
365 info->flash_id = FLASH_MAN_FUJ;
367 case (FLASH_WORD_SIZE)INTEL_MANUFACT:
368 info->flash_id = FLASH_MAN_INTEL;
370 case (FLASH_WORD_SIZE)SST_MANUFACT:
371 info->flash_id = FLASH_MAN_SST;
374 info->flash_id = FLASH_UNKNOWN;
375 info->sector_count = 0;
377 return (0); /* no or unknown flash */
379 value = addr2[1]; /* device ID */
380 /* printf("Device value %x\n",value); */
382 case (FLASH_WORD_SIZE)AMD_ID_F040B:
383 info->flash_id += FLASH_AM040;
384 info->sector_count = 8;
385 info->size = 0x0080000; /* => 512 ko */
387 case (FLASH_WORD_SIZE)AMD_ID_LV400T:
388 info->flash_id += FLASH_AM400T;
389 info->sector_count = 11;
390 info->size = 0x00080000;
391 break; /* => 0.5 MB */
393 case (FLASH_WORD_SIZE)AMD_ID_LV400B:
394 info->flash_id += FLASH_AM400B;
395 info->sector_count = 11;
396 info->size = 0x00080000;
397 break; /* => 0.5 MB */
399 case (FLASH_WORD_SIZE)AMD_ID_LV800T:
400 info->flash_id += FLASH_AM800T;
401 info->sector_count = 19;
402 info->size = 0x00100000;
405 case (FLASH_WORD_SIZE)AMD_ID_LV800B:
406 info->flash_id += FLASH_AM800B;
407 info->sector_count = 19;
408 info->size = 0x00100000;
411 case (FLASH_WORD_SIZE)AMD_ID_LV160T:
412 info->flash_id += FLASH_AM160T;
413 info->sector_count = 35;
414 info->size = 0x00200000;
417 case (FLASH_WORD_SIZE)AMD_ID_LV160B:
418 info->flash_id += FLASH_AM160B;
419 info->sector_count = 35;
420 info->size = 0x00200000;
422 #if 0 /* enable when device IDs are available */
423 case (FLASH_WORD_SIZE)AMD_ID_LV320T:
424 info->flash_id += FLASH_AM320T;
425 info->sector_count = 67;
426 info->size = 0x00400000;
429 case (FLASH_WORD_SIZE)AMD_ID_LV320B:
430 info->flash_id += FLASH_AM320B;
431 info->sector_count = 67;
432 info->size = 0x00400000;
435 case (FLASH_WORD_SIZE)SST_ID_xF800A:
436 info->flash_id += FLASH_SST800A;
437 info->sector_count = 16;
438 info->size = 0x00100000;
440 case (FLASH_WORD_SIZE)INTEL_ID_28F320C3T:
441 info->flash_id += FLASH_INTEL320T;
442 info->sector_count = 71;
443 info->size = 0x00400000;
447 case (FLASH_WORD_SIZE)SST_ID_xF160A:
448 info->flash_id += FLASH_SST160A;
449 info->sector_count = 32;
450 info->size = 0x00200000;
454 info->flash_id = FLASH_UNKNOWN;
455 return (0); /* => no or unknown flash */
459 /* set up sector start address table */
460 if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
461 (info->flash_id == FLASH_AM040)){
462 for (i = 0; i < info->sector_count; i++)
463 info->start[i] = base + (i * 0x00010000);
465 if (info->flash_id & FLASH_BTYPE) {
466 /* set sector offsets for bottom boot block type */
467 info->start[0] = base + 0x00000000;
468 info->start[1] = base + 0x00004000;
469 info->start[2] = base + 0x00006000;
470 info->start[3] = base + 0x00008000;
471 for (i = 4; i < info->sector_count; i++)
472 info->start[i] = base + (i * 0x00010000) - 0x00030000;
475 /* set sector offsets for top boot block type */
476 i = info->sector_count - 1;
477 if(info->sector_count==71) {
479 info->start[i--] = base + info->size - 0x00002000;
480 info->start[i--] = base + info->size - 0x00004000;
481 info->start[i--] = base + info->size - 0x00006000;
482 info->start[i--] = base + info->size - 0x00008000;
483 info->start[i--] = base + info->size - 0x0000A000;
484 info->start[i--] = base + info->size - 0x0000C000;
485 info->start[i--] = base + info->size - 0x0000E000;
487 info->start[i] = base + i * 0x000010000;
490 info->start[i--] = base + info->size - 0x00004000;
491 info->start[i--] = base + info->size - 0x00006000;
492 info->start[i--] = base + info->size - 0x00008000;
494 info->start[i] = base + i * 0x00010000;
499 /* check for protected sectors */
500 for (i = 0; i < info->sector_count; i++) {
501 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
502 /* D0 = 1 if protected */
503 addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
504 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
505 info->protect[i] = 0;
507 info->protect[i] = addr2[2] & 1;
511 * Prevent writes to uninitialized FLASH.
513 if (info->flash_id != FLASH_UNKNOWN) {
514 #if 0 /* test-only */
516 addr2 = (volatile unsigned char *)info->start[0];
519 addr2[ADDR0] = 0xF0; /* reset bank */
521 addr2 = (FLASH_WORD_SIZE *)info->start[0];
522 *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
524 #else /* test-only */
525 addr2 = (FLASH_WORD_SIZE *)info->start[0];
526 *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
527 #endif /* test-only */
532 int wait_for_DQ7(flash_info_t *info, int sect)
534 ulong start, now, last;
535 volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
537 start = get_timer (0);
539 while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
540 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
541 printf ("Timeout\n");
544 /* show that we're waiting */
545 if ((now - last) > 1000) { /* every second */
553 int intel_wait_for_DQ7(flash_info_t *info, int sect)
555 ulong start, now, last;
556 volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
558 start = get_timer (0);
560 while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
561 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
562 printf ("Timeout\n");
565 /* show that we're waiting */
566 if ((now - last) > 1000) { /* every second */
571 addr[0]=(FLASH_WORD_SIZE)0x00500050;
575 /*-----------------------------------------------------------------------
578 int flash_erase (flash_info_t *info, int s_first, int s_last)
580 volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
581 volatile FLASH_WORD_SIZE *addr2;
582 int flag, prot, sect, l_sect;
586 if ((s_first < 0) || (s_first > s_last)) {
587 if (info->flash_id == FLASH_UNKNOWN) {
588 printf ("- missing\n");
590 printf ("- no sectors to erase\n");
595 if (info->flash_id == FLASH_UNKNOWN) {
596 printf ("Can't erase unknown flash type - aborted\n");
601 for (sect=s_first; sect<=s_last; ++sect) {
602 if (info->protect[sect]) {
608 printf ("- Warning: %d protected sectors will not be erased!\n",
616 /* Disable interrupts which might cause a timeout here */
617 flag = disable_interrupts();
619 /* Start erase on unprotected sectors */
620 for (sect = s_first; sect<=s_last; sect++) {
621 if (info->protect[sect] == 0) { /* not protected */
622 addr2 = (FLASH_WORD_SIZE *)(info->start[sect]);
623 /* printf("Erasing sector %p\n", addr2); */ /* CLH */
624 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
625 addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
626 addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
627 addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
628 addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
629 addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
630 addr2[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */
632 udelay(1000); /* wait 1 ms */
633 wait_for_DQ7(info, sect);
636 if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
637 addr2[0] = (FLASH_WORD_SIZE)0x00600060; /* unlock sector */
638 addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* sector erase */
639 intel_wait_for_DQ7(info, sect);
640 addr2[0] = (FLASH_WORD_SIZE)0x00200020; /* sector erase */
641 addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* sector erase */
642 intel_wait_for_DQ7(info, sect);
645 addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
646 addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
647 addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
648 addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
649 addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
650 addr2[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */
651 wait_for_DQ7(info, sect);
656 * Wait for each sector to complete, it's more
657 * reliable. According to AMD Spec, you must
658 * issue all erase commands within a specified
659 * timeout. This has been seen to fail, especially
660 * if printf()s are included (for debug)!!
662 /* wait_for_DQ7(info, sect); */
666 /* re-enable interrupts if necessary */
670 /* wait at least 80us - let's wait 1 ms */
675 * We wait for the last triggered sector
679 wait_for_DQ7(info, l_sect);
683 /* reset to read mode */
684 addr = (FLASH_WORD_SIZE *)info->start[0];
685 addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
691 void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt)
694 volatile FLASH_WORD_SIZE *addr2;
697 for(i=info->sector_count-1;i>0;i--)
699 if(addr>=info->start[i])
703 addr2 = (FLASH_WORD_SIZE *)(info->start[i]);
704 addr2[0] = (FLASH_WORD_SIZE)0x00600060; /* unlock sector setup */
705 addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* unlock sector */
706 intel_wait_for_DQ7(info, i);
708 c-=(info->start[i]-info->start[i-1]);
715 /*-----------------------------------------------------------------------
716 * Copy memory to flash, returns:
719 * 2 - Flash not erased
722 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
727 if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
728 unlock_intel_sectors(info,addr,cnt);
730 wp = (addr & ~3); /* get lower word aligned address */
732 * handle unaligned start bytes
734 if ((l = addr - wp) != 0) {
736 for (i=0, cp=wp; i<l; ++i, ++cp) {
737 data = (data << 8) | (*(uchar *)cp);
739 for (; i<4 && cnt>0; ++i) {
740 data = (data << 8) | *src++;
744 for (; cnt==0 && i<4; ++i, ++cp) {
745 data = (data << 8) | (*(uchar *)cp);
748 if ((rc = write_word(info, wp, data)) != 0) {
755 * handle word aligned part
759 for (i=0; i<4; ++i) {
760 data = (data << 8) | *src++;
762 if ((rc = write_word(info, wp, data)) != 0) {
766 if((wp % 0x10000)==0)
767 printf("."); /* show Progress */
776 * handle unaligned tail bytes
779 for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
780 data = (data << 8) | *src++;
783 for (; i<4; ++i, ++cp) {
784 data = (data << 8) | (*(uchar *)cp);
786 rc=write_word(info, wp, data);
790 /*-----------------------------------------------------------------------
791 * Write a word to Flash, returns:
794 * 2 - Flash not erased
796 static FLASH_WORD_SIZE *read_val = (FLASH_WORD_SIZE *)0x200000;
798 static int write_word (flash_info_t *info, ulong dest, ulong data)
800 volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]);
801 volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest;
802 volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
807 /* Check if Flash is (sufficiently) erased */
808 if ((*((volatile FLASH_WORD_SIZE *)dest) &
809 (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) {
812 /* Disable interrupts which might cause a timeout here */
813 flag = disable_interrupts();
814 for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
816 if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
817 /* intel style writting */
818 dest2[i] = (FLASH_WORD_SIZE)0x00500050;
819 dest2[i] = (FLASH_WORD_SIZE)0x00400040;
820 *read_val++ = data2[i];
824 /* data polling for D7 */
825 start = get_timer (0);
827 while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080)
829 if (get_timer(start) > CFG_FLASH_WRITE_TOUT)
832 dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */
834 dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */
835 if(dest2[i]!=data2[i])
836 printf("Error at %p 0x%04X != 0x%04X\n",&dest2[i],dest2[i],data2[i]);
839 addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
840 addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
841 addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0;
843 /* re-enable interrupts if necessary */
846 /* data polling for D7 */
847 start = get_timer (0);
848 while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) !=
849 (data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
850 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
859 /*-----------------------------------------------------------------------