flash.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. /*
  2. * (C) Copyright 2004-2005
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * (C) Copyright 2002 Jun Gu <jung@artesyncp.com>
  6. * Add support for Am29F016D and dynamic switch setting.
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. /*
  27. * Modified 4/5/2001
  28. * Wait for completion of each sector erase command issued
  29. * 4/5/2001
  30. * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
  31. */
  32. #include <common.h>
  33. #include <ppc4xx.h>
  34. #include <asm/processor.h>
  35. #undef DEBUG
  36. #ifdef DEBUG
  37. #define DEBUGF(x...) printf(x)
  38. #else
  39. #define DEBUGF(x...)
  40. #endif /* DEBUG */
  41. #define BOOT_SMALL_FLASH 0x40 /* 01000000 */
  42. #define FLASH_ONBD_N 2 /* 00000010 */
  43. #define FLASH_SRAM_SEL 1 /* 00000001 */
  44. #define FLASH_ONBD_N 2 /* 00000010 */
  45. #define FLASH_SRAM_SEL 1 /* 00000001 */
  46. #define BOOT_SMALL_FLASH_VAL 4
  47. #define FLASH_ONBD_N_VAL 2
  48. #define FLASH_SRAM_SEL_VAL 1
  49. flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
  50. static unsigned long flash_addr_table[8][CFG_MAX_FLASH_BANKS] = {
  51. {0xFF800000, 0xFF880000, 0xFFC00000}, /* 0:000: configuraton 4 */
  52. {0xFF900000, 0xFF980000, 0xFFC00000}, /* 1:001: configuraton 3 */
  53. {0x00000000, 0x00000000, 0x00000000}, /* 2:010: configuraton 8 */
  54. {0x00000000, 0x00000000, 0x00000000}, /* 3:011: configuraton 7 */
  55. {0xFFE00000, 0xFFF00000, 0xFF800000}, /* 4:100: configuraton 2 */
  56. {0xFFF00000, 0xFFF80000, 0xFF800000}, /* 5:101: configuraton 1 */
  57. {0x00000000, 0x00000000, 0x00000000}, /* 6:110: configuraton 6 */
  58. {0x00000000, 0x00000000, 0x00000000} /* 7:111: configuraton 5 */
  59. };
  60. /*-----------------------------------------------------------------------
  61. * Functions
  62. */
  63. static ulong flash_get_size(vu_long * addr, flash_info_t * info);
  64. static int write_word(flash_info_t * info, ulong dest, ulong data);
  65. #ifdef CONFIG_OCOTEA
  66. #define ADDR0 0x5555
  67. #define ADDR1 0x2aaa
  68. #define FLASH_WORD_SIZE unsigned char
  69. #endif
  70. /*-----------------------------------------------------------------------
  71. */
  72. unsigned long flash_init(void)
  73. {
  74. unsigned long total_b = 0;
  75. unsigned long size_b[CFG_MAX_FLASH_BANKS];
  76. unsigned char *fpga_base = (unsigned char *) CFG_FPGA_BASE;
  77. unsigned char switch_status;
  78. unsigned short index = 0;
  79. int i;
  80. /* read FPGA base register FPGA_REG0 */
  81. switch_status = *fpga_base;
  82. /* check the bitmap of switch status */
  83. if (switch_status & BOOT_SMALL_FLASH) {
  84. index += BOOT_SMALL_FLASH_VAL;
  85. }
  86. if (switch_status & FLASH_ONBD_N) {
  87. index += FLASH_ONBD_N_VAL;
  88. }
  89. if (switch_status & FLASH_SRAM_SEL) {
  90. index += FLASH_SRAM_SEL_VAL;
  91. }
  92. DEBUGF("\n");
  93. DEBUGF("FLASH: Index: %d\n", index);
  94. /* Init: no FLASHes known */
  95. for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
  96. flash_info[i].flash_id = FLASH_UNKNOWN;
  97. flash_info[i].sector_count = -1;
  98. flash_info[i].size = 0;
  99. /* check whether the address is 0 */
  100. if (flash_addr_table[index][i] == 0) {
  101. continue;
  102. }
  103. /* call flash_get_size() to initialize sector address */
  104. size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i], &flash_info[i]);
  105. flash_info[i].size = size_b[i];
  106. if (flash_info[i].flash_id == FLASH_UNKNOWN) {
  107. printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
  108. i, size_b[i], size_b[i] << 20);
  109. flash_info[i].sector_count = -1;
  110. flash_info[i].size = 0;
  111. }
  112. total_b += flash_info[i].size;
  113. }
  114. /* Monitor protection ON by default */
  115. (void)flash_protect(FLAG_PROTECT_SET,
  116. -CFG_MONITOR_LEN,
  117. 0xffffffff,
  118. &flash_info[2]);
  119. return total_b;
  120. }
  121. /*-----------------------------------------------------------------------
  122. */
  123. void flash_print_info(flash_info_t * info)
  124. {
  125. int i;
  126. int k;
  127. int size;
  128. int erased;
  129. volatile unsigned long *flash;
  130. if (info->flash_id == FLASH_UNKNOWN) {
  131. printf("missing or unknown FLASH type\n");
  132. return;
  133. }
  134. switch (info->flash_id & FLASH_VENDMASK) {
  135. case FLASH_MAN_AMD:
  136. printf("AMD ");
  137. break;
  138. case FLASH_MAN_STM:
  139. printf("STM ");
  140. break;
  141. case FLASH_MAN_FUJ:
  142. printf("FUJITSU ");
  143. break;
  144. case FLASH_MAN_SST:
  145. printf("SST ");
  146. break;
  147. default:
  148. printf("Unknown Vendor ");
  149. break;
  150. }
  151. switch (info->flash_id & FLASH_TYPEMASK) {
  152. case FLASH_AM040:
  153. printf("AM29F040 (512 Kbit, uniform sector size)\n");
  154. break;
  155. case FLASH_AM400B:
  156. printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
  157. break;
  158. case FLASH_AM400T:
  159. printf("AM29LV400T (4 Mbit, top boot sector)\n");
  160. break;
  161. case FLASH_AM800B:
  162. printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
  163. break;
  164. case FLASH_AM800T:
  165. printf("AM29LV800T (8 Mbit, top boot sector)\n");
  166. break;
  167. case FLASH_AM160B:
  168. printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
  169. break;
  170. case FLASH_AM160T:
  171. printf("AM29LV160T (16 Mbit, top boot sector)\n");
  172. break;
  173. case FLASH_AM320B:
  174. printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
  175. break;
  176. case FLASH_AM320T:
  177. printf("AM29LV320T (32 Mbit, top boot sector)\n");
  178. break;
  179. case FLASH_AMDLV033C:
  180. printf("AM29LV033C (32 Mbit, top boot sector)\n");
  181. break;
  182. case FLASH_SST800A:
  183. printf("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
  184. break;
  185. case FLASH_SST160A:
  186. printf("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
  187. break;
  188. default:
  189. printf("Unknown Chip Type\n");
  190. break;
  191. }
  192. printf(" Size: %ld KB in %d Sectors\n",
  193. info->size >> 10, info->sector_count);
  194. printf(" Sector Start Addresses:");
  195. for (i = 0; i < info->sector_count; ++i) {
  196. /*
  197. * Check if whole sector is erased
  198. */
  199. if (i != (info->sector_count - 1))
  200. size = info->start[i + 1] - info->start[i];
  201. else
  202. size = info->start[0] + info->size - info->start[i];
  203. erased = 1;
  204. flash = (volatile unsigned long *) info->start[i];
  205. size = size >> 2; /* divide by 4 for longword access */
  206. for (k = 0; k < size; k++) {
  207. if (*flash++ != 0xffffffff) {
  208. erased = 0;
  209. break;
  210. }
  211. }
  212. if ((i % 5) == 0)
  213. printf("\n ");
  214. printf(" %08lX%s%s",
  215. info->start[i],
  216. erased ? " E" : " ", info->protect[i] ? "RO " : " ");
  217. }
  218. printf("\n");
  219. return;
  220. }
  221. /*-----------------------------------------------------------------------
  222. */
  223. /*
  224. * The following code cannot be run from FLASH!
  225. */
  226. static ulong flash_get_size(vu_long * addr, flash_info_t * info)
  227. {
  228. short i;
  229. FLASH_WORD_SIZE value;
  230. ulong base = (ulong) addr;
  231. volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
  232. DEBUGF("FLASH ADDR: %08x\n", (unsigned) addr);
  233. /* Write auto select command: read Manufacturer ID */
  234. udelay(10000);
  235. addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  236. udelay(1000);
  237. addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  238. udelay(1000);
  239. addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00900090;
  240. udelay(1000);
  241. value = addr2[0];
  242. DEBUGF("FLASH MANUFACT: %x\n", value);
  243. switch (value) {
  244. case (FLASH_WORD_SIZE) AMD_MANUFACT:
  245. info->flash_id = FLASH_MAN_AMD;
  246. break;
  247. case (FLASH_WORD_SIZE) FUJ_MANUFACT:
  248. info->flash_id = FLASH_MAN_FUJ;
  249. break;
  250. case (FLASH_WORD_SIZE) SST_MANUFACT:
  251. info->flash_id = FLASH_MAN_SST;
  252. break;
  253. case (FLASH_WORD_SIZE) STM_MANUFACT:
  254. info->flash_id = FLASH_MAN_STM;
  255. break;
  256. default:
  257. info->flash_id = FLASH_UNKNOWN;
  258. info->sector_count = 0;
  259. info->size = 0;
  260. return (0); /* no or unknown flash */
  261. }
  262. value = addr2[1]; /* device ID */
  263. DEBUGF("\nFLASH DEVICEID: %x\n", value);
  264. switch (value) {
  265. case (FLASH_WORD_SIZE) AMD_ID_LV040B:
  266. info->flash_id += FLASH_AM040;
  267. info->sector_count = 8;
  268. info->size = 0x0080000; /* => 512 ko */
  269. break;
  270. case (FLASH_WORD_SIZE) AMD_ID_F040B:
  271. info->flash_id += FLASH_AM040;
  272. info->sector_count = 8;
  273. info->size = 0x0080000; /* => 512 ko */
  274. break;
  275. case (FLASH_WORD_SIZE) STM_ID_M29W040B:
  276. info->flash_id += FLASH_AM040;
  277. info->sector_count = 8;
  278. info->size = 0x0080000; /* => 512 ko */
  279. break;
  280. case (FLASH_WORD_SIZE) AMD_ID_LV033C:
  281. info->flash_id += FLASH_AMDLV033C;
  282. info->sector_count = 64;
  283. info->size = 0x00400000;
  284. break; /* => 4 MB */
  285. default:
  286. info->flash_id = FLASH_UNKNOWN;
  287. return (0); /* => no or unknown flash */
  288. }
  289. /* set up sector start address table */
  290. if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
  291. ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) ||
  292. ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMD016)) {
  293. for (i = 0; i < info->sector_count; i++)
  294. info->start[i] = base + (i * 0x00010000);
  295. } else {
  296. if (info->flash_id & FLASH_BTYPE) {
  297. /* set sector offsets for bottom boot block type */
  298. info->start[0] = base + 0x00000000;
  299. info->start[1] = base + 0x00004000;
  300. info->start[2] = base + 0x00006000;
  301. info->start[3] = base + 0x00008000;
  302. for (i = 4; i < info->sector_count; i++) {
  303. info->start[i] = base + (i * 0x00010000) - 0x00030000;
  304. }
  305. } else {
  306. /* set sector offsets for top boot block type */
  307. i = info->sector_count - 1;
  308. info->start[i--] = base + info->size - 0x00004000;
  309. info->start[i--] = base + info->size - 0x00006000;
  310. info->start[i--] = base + info->size - 0x00008000;
  311. for (; i >= 0; i--) {
  312. info->start[i] = base + i * 0x00010000;
  313. }
  314. }
  315. }
  316. /* check for protected sectors */
  317. for (i = 0; i < info->sector_count; i++) {
  318. /* read sector protection at sector address, (A7 .. A0) = 0x02 */
  319. /* D0 = 1 if protected */
  320. addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]);
  321. /* For AMD29033C flash we need to resend the command of *
  322. * reading flash protection for upper 8 Mb of flash */
  323. if ( i == 32 ) {
  324. addr2[ADDR0] = (FLASH_WORD_SIZE) 0xAAAAAAAA;
  325. addr2[ADDR1] = (FLASH_WORD_SIZE) 0x55555555;
  326. addr2[ADDR0] = (FLASH_WORD_SIZE) 0x90909090;
  327. }
  328. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
  329. info->protect[i] = 0;
  330. else
  331. info->protect[i] = addr2[2] & 1;
  332. }
  333. /* issue bank reset to return to read mode */
  334. addr2[0] = (FLASH_WORD_SIZE) 0x00F000F0;
  335. /*
  336. * Prevent writes to uninitialized FLASH.
  337. */
  338. if (info->flash_id != FLASH_UNKNOWN) {
  339. /* ? ? ? */
  340. }
  341. return (info->size);
  342. }
  343. int wait_for_DQ7(flash_info_t * info, int sect)
  344. {
  345. ulong start, now, last;
  346. volatile FLASH_WORD_SIZE *addr =
  347. (FLASH_WORD_SIZE *) (info->start[sect]);
  348. start = get_timer(0);
  349. last = start;
  350. while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
  351. (FLASH_WORD_SIZE) 0x00800080) {
  352. if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
  353. printf("Timeout\n");
  354. return -1;
  355. }
  356. /* show that we're waiting */
  357. if ((now - last) > 1000) { /* every second */
  358. putc('.');
  359. last = now;
  360. }
  361. }
  362. return 0;
  363. }
  364. /*-----------------------------------------------------------------------
  365. */
  366. int flash_erase(flash_info_t * info, int s_first, int s_last)
  367. {
  368. volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
  369. volatile FLASH_WORD_SIZE *addr2;
  370. int flag, prot, sect, l_sect;
  371. int i;
  372. if ((s_first < 0) || (s_first > s_last)) {
  373. if (info->flash_id == FLASH_UNKNOWN) {
  374. printf("- missing\n");
  375. } else {
  376. printf("- no sectors to erase\n");
  377. }
  378. return 1;
  379. }
  380. if (info->flash_id == FLASH_UNKNOWN) {
  381. printf("Can't erase unknown flash type - aborted\n");
  382. return 1;
  383. }
  384. prot = 0;
  385. for (sect = s_first; sect <= s_last; ++sect) {
  386. if (info->protect[sect]) {
  387. prot++;
  388. }
  389. }
  390. if (prot) {
  391. printf("- Warning: %d protected sectors will not be erased!\n",
  392. prot);
  393. } else {
  394. printf("\n");
  395. }
  396. l_sect = -1;
  397. /* Disable interrupts which might cause a timeout here */
  398. flag = disable_interrupts();
  399. /* Start erase on unprotected sectors */
  400. for (sect = s_first; sect <= s_last; sect++) {
  401. if (info->protect[sect] == 0) { /* not protected */
  402. addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
  403. if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
  404. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  405. addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  406. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
  407. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  408. addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  409. addr2[0] = (FLASH_WORD_SIZE) 0x00500050; /* block erase */
  410. for (i = 0; i < 50; i++)
  411. udelay(1000); /* wait 1 ms */
  412. } else {
  413. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  414. addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  415. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
  416. addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  417. addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  418. addr2[0] = (FLASH_WORD_SIZE) 0x00300030; /* sector erase */
  419. }
  420. l_sect = sect;
  421. /*
  422. * Wait for each sector to complete, it's more
  423. * reliable. According to AMD Spec, you must
  424. * issue all erase commands within a specified
  425. * timeout. This has been seen to fail, especially
  426. * if printf()s are included (for debug)!!
  427. */
  428. wait_for_DQ7(info, sect);
  429. }
  430. }
  431. /* re-enable interrupts if necessary */
  432. if (flag)
  433. enable_interrupts();
  434. /* wait at least 80us - let's wait 1 ms */
  435. udelay(1000);
  436. /* reset to read mode */
  437. addr = (FLASH_WORD_SIZE *) info->start[0];
  438. addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
  439. printf(" done\n");
  440. return 0;
  441. }
  442. /*-----------------------------------------------------------------------
  443. * Copy memory to flash, returns:
  444. * 0 - OK
  445. * 1 - write timeout
  446. * 2 - Flash not erased
  447. */
  448. int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
  449. {
  450. ulong cp, wp, data;
  451. int i, l, rc;
  452. wp = (addr & ~3); /* get lower word aligned address */
  453. /*
  454. * handle unaligned start bytes
  455. */
  456. if ((l = addr - wp) != 0) {
  457. data = 0;
  458. for (i = 0, cp = wp; i < l; ++i, ++cp) {
  459. data = (data << 8) | (*(uchar *) cp);
  460. }
  461. for (; i < 4 && cnt > 0; ++i) {
  462. data = (data << 8) | *src++;
  463. --cnt;
  464. ++cp;
  465. }
  466. for (; cnt == 0 && i < 4; ++i, ++cp) {
  467. data = (data << 8) | (*(uchar *) cp);
  468. }
  469. if ((rc = write_word(info, wp, data)) != 0) {
  470. return (rc);
  471. }
  472. wp += 4;
  473. }
  474. /*
  475. * handle word aligned part
  476. */
  477. while (cnt >= 4) {
  478. data = 0;
  479. for (i = 0; i < 4; ++i) {
  480. data = (data << 8) | *src++;
  481. }
  482. if ((rc = write_word(info, wp, data)) != 0) {
  483. return (rc);
  484. }
  485. wp += 4;
  486. cnt -= 4;
  487. }
  488. if (cnt == 0) {
  489. return (0);
  490. }
  491. /*
  492. * handle unaligned tail bytes
  493. */
  494. data = 0;
  495. for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
  496. data = (data << 8) | *src++;
  497. --cnt;
  498. }
  499. for (; i < 4; ++i, ++cp) {
  500. data = (data << 8) | (*(uchar *) cp);
  501. }
  502. return (write_word(info, wp, data));
  503. }
  504. /*-----------------------------------------------------------------------
  505. * Write a word to Flash, returns:
  506. * 0 - OK
  507. * 1 - write timeout
  508. * 2 - Flash not erased
  509. */
  510. static int write_word(flash_info_t * info, ulong dest, ulong data)
  511. {
  512. volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) (info->start[0]);
  513. volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
  514. volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
  515. ulong start;
  516. int i;
  517. /* Check if Flash is (sufficiently) erased */
  518. if ((*((volatile FLASH_WORD_SIZE *) dest) &
  519. (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
  520. return (2);
  521. }
  522. for (i = 0; i < 4 / sizeof(FLASH_WORD_SIZE); i++) {
  523. int flag;
  524. /* Disable interrupts which might cause a timeout here */
  525. flag = disable_interrupts();
  526. addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
  527. addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
  528. addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
  529. dest2[i] = data2[i];
  530. /* re-enable interrupts if necessary */
  531. if (flag)
  532. enable_interrupts();
  533. /* data polling for D7 */
  534. start = get_timer(0);
  535. while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
  536. (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
  537. if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
  538. return (1);
  539. }
  540. }
  541. }
  542. return (0);
  543. }