1 #ifndef CYGONCE_DEVS_FLASH_TOSHIBA_TC58XXX_INL
2 #define CYGONCE_DEVS_FLASH_TOSHIBA_TC58XXX_INL
3 //==========================================================================
7 // Toshiba Tc58xxx series flash driver
9 //==========================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14 // Copyright (C) 2003 Jonathan Larmour
15 // Copyright (C) 2003, 2004 Gary Thomas
17 // eCos is free software; you can redistribute it and/or modify it under
18 // the terms of the GNU General Public License as published by the Free
19 // Software Foundation; either version 2 or (at your option) any later version.
21 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
22 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 // You should have received a copy of the GNU General Public License along
27 // with eCos; if not, write to the Free Software Foundation, Inc.,
28 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
30 // As a special exception, if other files instantiate templates or use macros
31 // or inline functions from this file, or you compile this file and link it
32 // with other works to produce a work based on this file, this file does not
33 // by itself cause the resulting work to be covered by the GNU General Public
34 // License. However the source code for this file must still be made available
35 // in accordance with section (3) of the GNU General Public License.
37 // This exception does not invalidate any other reasons why a work based on
38 // this file might be covered by the GNU General Public License.
40 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
41 // at http://sources.redhat.com/ecos/ecos-license/
42 // -------------------------------------------
43 //####ECOSGPLCOPYRIGHTEND####
45 //==========================================================================
46 //#####DESCRIPTIONBEGIN####
48 // Author(s): Gary Thomas <gary@mlbassoc.com>
52 // Description: FLASH drivers for Toshiba NAND FLASH TC58xxx devices.
53 // Based on Atmel AT49xxxx drivers by Jani Monoses <jani@iv.ro>
55 //####DESCRIPTIONEND####
57 //==========================================================================
59 // FIXME! Someday add support for ECC data & fixups of bad sectors
61 #include <pkgconf/hal.h>
62 #include <cyg/hal/hal_arch.h>
63 #include <cyg/hal/hal_cache.h>
64 #include <cyg/infra/diag.h>
65 #include CYGHWR_MEMORY_LAYOUT_H
67 #define _FLASH_PRIVATE_
68 #include <cyg/io/flash.h>
70 // Low level debugging
71 // 1 - command level - prints messages about read/write/erase commands
72 // 2 - hardware level - shows all NAND device I/O data
75 //----------------------------------------------------------------------------
76 // Common device details.
77 #define FLASH_Read_ID FLASHWORD(0x90)
78 #define FLASH_Reset FLASHWORD(0xFF)
79 #define FLASH_Read_Mode1 FLASHWORD(0x00)
80 #define FLASH_Read_Mode2 FLASHWORD(0x01)
81 #define FLASH_Read_Mode3 FLASHWORD(0x50)
82 #define FLASH_Program FLASHWORD(0x10)
83 #define FLASH_Send_Data FLASHWORD(0x80)
84 #define FLASH_Status FLASHWORD(0x70)
85 #define FLASH_Block_Erase FLASHWORD(0x60)
86 #define FLASH_Start_Erase FLASHWORD(0xD0)
88 #define CYGNUM_FLASH_ID_MANUFACTURER FLASHWORD(0x98)
90 //----------------------------------------------------------------------------
91 // Now that device properties are defined, include magic for defining
92 // accessor type and constants.
93 #include <cyg/io/flash_dev.h>
95 //----------------------------------------------------------------------------
96 // Information about supported devices
97 typedef struct flash_dev_info {
98 flash_data_t device_id;
99 cyg_uint32 block_size;
100 cyg_uint32 page_size;
101 cyg_int32 block_count;
102 cyg_uint32 base_mask;
103 cyg_uint32 device_size;
106 static const flash_dev_info_t* flash_dev_info;
107 static const flash_dev_info_t supported_devices[] = {
108 #include <cyg/io/flash_tc58xxx_parts.inl>
110 #define NUM_DEVICES (sizeof(supported_devices)/sizeof(flash_dev_info_t))
112 //----------------------------------------------------------------------------
113 // Functions that put the flash device into non-read mode must reside
115 void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
116 int flash_erase_block(void* block, unsigned int size)
117 __attribute__ ((section (".2ram.flash_erase_block")));
118 int flash_program_buf(void* addr, void* data, int len)
119 __attribute__ ((section (".2ram.flash_program_buf")));
121 //----------------------------------------------------------------------------
122 // Initialize driver details
129 #ifdef CYGHWR_FLASH_TC58XXX_PLF_INIT
130 CYGHWR_FLASH_TC58XXX_PLF_INIT();
135 // Check that flash_id data is matching the one the driver was
138 // Check manufacturer
139 if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER) {
140 diag_printf("Can't identify FLASH - manufacturer is: %x, should be %x\n",
141 id[0], CYGNUM_FLASH_ID_MANUFACTURER);
142 return FLASH_ERR_DRV_WRONG_PART;
145 // Look through table for device data
146 flash_dev_info = supported_devices;
147 for (i = 0; i < NUM_DEVICES; i++) {
148 if (flash_dev_info->device_id == id[1])
153 // Did we find the device? If not, return error.
154 if (NUM_DEVICES == i) {
155 diag_printf("Can't identify FLASH - device is: %x, supported: ", id[1]);
156 for (i = 0; i < NUM_DEVICES; i++) {
157 diag_printf("%x ", supported_devices[i].device_id);
160 return FLASH_ERR_DRV_WRONG_PART;
163 // Fill in device details
164 flash_info.block_size = flash_dev_info->block_size;
165 flash_info.blocks = flash_dev_info->block_count * CYGNUM_FLASH_SERIES;
166 flash_info.start = (void *)CYGNUM_FLASH_BASE;
167 flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (flash_dev_info->device_size * CYGNUM_FLASH_SERIES));
171 //----------------------------------------------------------------------------
172 // Map a hardware status to a package error
174 flash_hwr_map_error(int e)
180 //----------------------------------------------------------------------------
181 // See if a range of FLASH addresses overlaps currently running code
183 flash_code_overlaps(void *start, void *end)
185 extern unsigned char _stext[], _etext[];
187 return ((((unsigned long)&_stext >= (unsigned long)start) &&
188 ((unsigned long)&_stext < (unsigned long)end)) ||
189 (((unsigned long)&_etext >= (unsigned long)start) &&
190 ((unsigned long)&_etext < (unsigned long)end)));
194 put_NAND(volatile flash_data_t *ROM, flash_data_t val)
198 diag_printf("%02x ", val);
202 //----------------------------------------------------------------------------
205 // Only reads the manufacturer and part number codes for the first
206 // device(s) in series. It is assumed that any devices in series
207 // will be of the same type.
210 flash_query(void* data)
212 flash_data_t* id = (flash_data_t*) data;
213 volatile flash_data_t *ROM;
215 ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
216 // Send initial RESET command
217 CYGHWR_FLASH_TC58XXX_CE(1);
218 CYGHWR_FLASH_TC58XXX_CLE(1);
219 put_NAND(ROM, FLASH_Reset);
220 CYGHWR_FLASH_TC58XXX_CLE(0);
221 CYGHWR_FLASH_TC58XXX_CE(0);
222 // Now, wait for a good while
223 CYGACC_CALL_IF_DELAY_US(10000); // Actually 10ms
224 // Issue device query
225 CYGHWR_FLASH_TC58XXX_CE(1);
226 CYGHWR_FLASH_TC58XXX_CLE(1);
227 put_NAND(ROM, FLASH_Read_ID);
228 CYGHWR_FLASH_TC58XXX_CLE(0);
229 CYGHWR_FLASH_TC58XXX_ALE(1);
230 put_NAND(ROM, 0x00); // Dummy address
231 CYGHWR_FLASH_TC58XXX_ALE(0);
232 // Minimum 100ns delay after deasserting ALE
233 CYGACC_CALL_IF_DELAY_US(10); // Actually 10us
236 CYGHWR_FLASH_TC58XXX_CLE(1);
237 put_NAND(ROM, FLASH_Reset);
238 CYGHWR_FLASH_TC58XXX_CLE(0);
239 CYGHWR_FLASH_TC58XXX_CE(0);
242 //----------------------------------------------------------------------------
245 flash_erase_block(void* block, unsigned int size)
247 volatile flash_data_t* ROM;
248 volatile flash_data_t* b_p = (volatile flash_data_t*) block;
249 int res = FLASH_ERR_OK;
254 diag_printf("%s - block: %x, size: %d\n", __FUNCTION__, block, size);
256 ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
257 // Erase the next block
261 CYGHWR_FLASH_TC58XXX_CE(1);
262 CYGHWR_FLASH_TC58XXX_CLE(1);
263 put_NAND(ROM, FLASH_Block_Erase);
264 CYGHWR_FLASH_TC58XXX_CLE(0);
265 CYGHWR_FLASH_TC58XXX_ALE(1);
266 put_NAND(ROM, ((unsigned long)b_p & 0x0001FE00) >> 9); // A9..A16
267 put_NAND(ROM, ((unsigned long)b_p & 0x01FE0000) >> 17); // A17..A24
268 if (flash_dev_info->device_size > 0x02000000) {
269 put_NAND(ROM, ((unsigned long)b_p & 0x06000000) >> 25); // A26..A27
271 CYGHWR_FLASH_TC58XXX_ALE(0);
272 CYGHWR_FLASH_TC58XXX_CLE(1);
273 put_NAND(ROM, FLASH_Start_Erase);
274 CYGHWR_FLASH_TC58XXX_CLE(0);
275 CYGACC_CALL_IF_DELAY_US(10);
276 while (!CYGHWR_FLASH_TC58XXX_RDY()) cnt++; // Wait for operation to complete
277 CYGHWR_FLASH_TC58XXX_CLE(1);
278 put_NAND(ROM, FLASH_Status);
279 CYGHWR_FLASH_TC58XXX_CLE(0);
281 CYGHWR_FLASH_TC58XXX_CE(0);
286 diag_printf("block: %x, stat: %x, count = %d\n", b_p, stat, cnt);
289 diag_printf("Status after erase: %x\n", stat);
290 if ((stat & 0x80) == 0x00) {
291 res = FLASH_ERR_PROTECT;
293 res = FLASH_ERR_ERASE;
300 // ECC support - adapted from Linux:
302 // drivers/mtd/nand_ecc.c
304 // Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
305 // Toshiba America Electronics Components, Inc.
308 static const unsigned char _nand_ecc_precalc_table[] = {
309 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
310 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
311 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
312 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
313 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
314 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
315 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
316 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
317 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
318 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
319 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
320 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
321 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
322 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
323 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
324 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
328 _nand_trans_result(unsigned char reg2, unsigned char reg3,
329 unsigned char *ecc0, unsigned char *ecc1)
331 unsigned char a, b, i, tmp1, tmp2;
333 /* Initialize variables */
337 /* Calculate first ECC byte */
338 for (i = 0; i < 4; i++) {
339 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
342 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
348 /* Calculate second ECC byte */
350 for (i = 0; i < 4; i++) {
351 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
354 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
360 /* Store two of the ECC bytes */
366 // Calculate 3 byte ECC on 256 bytes of data
369 _nand_page_ECC(unsigned char *data, unsigned char *ecc0,
370 unsigned char *ecc1, unsigned char *ecc2)
372 unsigned char idx, reg1, reg2, reg3;
375 /* Initialize variables */
376 reg1 = reg2 = reg3 = 0;
377 *ecc0 = *ecc1 = *ecc2 = 0;
379 /* Build up column parity */
380 for(j = 0; j < 256; j++) {
381 /* Get CP0 - CP5 from table */
382 idx = _nand_ecc_precalc_table[*data++];
383 reg1 ^= (idx & 0x3f);
384 /* All bit XOR = 1 ? */
386 reg3 ^= (unsigned char) j;
387 reg2 ^= ~((unsigned char) j);
391 /* Create non-inverted ECC code from line parity */
392 _nand_trans_result(reg2, reg3, ecc0, ecc1);
394 /* Calculate final ECC code */
397 *ecc2 = ((~reg1) << 2) | 0x03;
401 // Correct a buffer via ECC (1 bit, 256 byte block)
402 // Return: 0 => No error
404 // 2 => Not corrected, ECC updated
405 // -1 => Not correctable
408 _nand_correct_data(unsigned char *dat, unsigned char *read_ecc, unsigned char *calc_ecc)
410 unsigned char a, b, c, d1, d2, d3, add, bit, i;
412 /* Do error detection */
413 d1 = calc_ecc[0] ^ read_ecc[0];
414 d2 = calc_ecc[1] ^ read_ecc[1];
415 d3 = calc_ecc[2] ^ read_ecc[2];
417 if ((d1 | d2 | d3) == 0) {
421 a = (d1 ^ (d1 >> 1)) & 0x55;
422 b = (d2 ^ (d2 >> 1)) & 0x55;
423 c = (d3 ^ (d3 >> 1)) & 0x54;
425 /* Found and will correct single bit error in the data */
426 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
430 for (i=0; i<4; i++) {
437 for (i=0; i<4; i++) {
446 for (i=0; i<3; i++) {
475 /* ECC Code Error Correction */
476 read_ecc[0] = calc_ecc[0];
477 read_ecc[1] = calc_ecc[1];
478 read_ecc[2] = calc_ecc[2];
481 /* Uncorrectable Error */
487 /* Should never happen */
492 //----------------------------------------------------------------------------
495 flash_program_buf(void* addr, void* data, int len)
497 volatile flash_data_t* ROM;
498 volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr;
499 volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
500 int res = FLASH_ERR_OK;
503 unsigned char oob[16];
505 ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
507 diag_printf("%s - addr: %x, data: %x, len: %d, FLASH: %p/%d\n",
508 __FUNCTION__, addr, data, len, ROM, sizeof(flash_data_t));
511 CYGHWR_FLASH_TC58XXX_CE(1);
512 CYGHWR_FLASH_TC58XXX_CLE(1);
516 put_NAND(ROM, FLASH_Read_Mode1);
517 put_NAND(ROM, FLASH_Send_Data);
518 CYGHWR_FLASH_TC58XXX_CLE(0);
519 CYGHWR_FLASH_TC58XXX_ALE(1);
520 put_NAND(ROM, ((unsigned long)addr_ptr & 0x000000FF) >> 0); // A0..A7
521 put_NAND(ROM, ((unsigned long)addr_ptr & 0x0001FE00) >> 9); // A9..A16
522 put_NAND(ROM, ((unsigned long)addr_ptr & 0x01FE0000) >> 17); // A17..A24
523 if (flash_dev_info->device_size > 0x02000000) {
524 put_NAND(ROM, ((unsigned long)addr_ptr & 0x06000000) >> 25); // A26..A27
526 CYGHWR_FLASH_TC58XXX_ALE(0);
530 // Caculate OOB data for page (ECC)
531 for (i = 0; i < 16; i++) {
534 // Calculate ECC for page
535 _nand_page_ECC((unsigned char *)&data_ptr[0], &oob[0], &oob[1], &oob[2]);
536 _nand_page_ECC((unsigned char *)&data_ptr[256], &oob[3], &oob[6], &oob[7]);
537 // Move one page of data to buffer
538 for (i = 0; i < 512; i++) {
539 put_NAND(ROM, *data_ptr++);
541 if ((i % 16) == 15) diag_printf("\n");
545 for (i = 0; i < 16; i++) {
546 put_NAND(ROM, oob[i]);
548 if ((i % 16) == 15) diag_printf("\n");
554 CYGHWR_FLASH_TC58XXX_CLE(1);
555 put_NAND(ROM, FLASH_Program);
556 CYGHWR_FLASH_TC58XXX_CLE(0);
557 CYGACC_CALL_IF_DELAY_US(1); // Actually 200ns
559 CYGACC_CALL_IF_DELAY_US(10);
560 while (!CYGHWR_FLASH_TC58XXX_RDY()) cnt++; // Wait for page data to be ready
561 CYGHWR_FLASH_TC58XXX_CLE(1);
562 put_NAND(ROM, FLASH_Status);
563 CYGHWR_FLASH_TC58XXX_CLE(0);
568 CYGHWR_FLASH_TC58XXX_CE(0);
570 diag_printf("program at %x, stat: %x, count = %d\n", addr_ptr, stat, cnt);
572 addr_ptr += 512; len -= 512;
574 diag_printf("Status after write: %x\n", stat);
575 if ((stat & 0x80) == 0x00) {
576 res = FLASH_ERR_PROTECT;
578 res = FLASH_ERR_PROGRAM;
585 //----------------------------------------------------------------------------
586 // Read data into buffer
588 flash_read_buf(void* addr, void* data, int len)
590 volatile flash_data_t* ROM;
591 volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr;
592 volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
594 int res = FLASH_ERR_OK;
597 unsigned char oob[16], dev_oob[16];
599 ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
603 CYGHWR_FLASH_TC58XXX_CE(1);
604 CYGHWR_FLASH_TC58XXX_CLE(1);
605 if (((unsigned long)addr & 0x100) == 0) {
606 // Mode 1 - reads from start of line
607 put_NAND(ROM, FLASH_Read_Mode1);
609 // Mode 2 - reads from second half of line
610 put_NAND(ROM, FLASH_Read_Mode2);
612 CYGHWR_FLASH_TC58XXX_CLE(0);
613 CYGHWR_FLASH_TC58XXX_ALE(1);
614 put_NAND(ROM, ((unsigned long)addr_ptr & 0x000000FF) >> 0); // A0..A7
615 put_NAND(ROM, ((unsigned long)addr_ptr & 0x0001FE00) >> 9); // A9..A16
616 put_NAND(ROM, ((unsigned long)addr_ptr & 0x01FE0000) >> 17); // A17..A24
617 if (flash_dev_info->device_size > 0x02000000) {
618 put_NAND(ROM, ((unsigned long)addr_ptr & 0x06000000) >> 25); // A26..A27
620 CYGHWR_FLASH_TC58XXX_ALE(0);
625 CYGACC_CALL_IF_DELAY_US(10);
626 while (!CYGHWR_FLASH_TC58XXX_RDY()) cnt++; // Wait for page data to be ready
628 diag_printf("Read data starting at %p, count = %d\n", data_ptr, cnt);
631 page = (unsigned char *)data_ptr;
634 if (++offset == 0x200) {
635 // Data page has been read, fetch ECC/OOB data
636 for (i = 0; i < 16; i++) {
639 // Calculate actual ECC on page
640 _nand_page_ECC(&page[0], &oob[0], &oob[1], &oob[2]);
641 _nand_page_ECC(&page[256], &oob[3], &oob[6], &oob[7]);
642 // Check & repair if possible
643 if ((oob[0] != dev_oob[0]) || (oob[1] != dev_oob[1]) || (oob[2] != dev_oob[2]) ||
644 (oob[3] != dev_oob[3]) || (oob[6] != dev_oob[6]) || (oob[7] != dev_oob[7])) {
645 unsigned char read_ecc[3], calc_ecc[3];
648 read_ecc[0] = dev_oob[0]; calc_ecc[0] = oob[0];
649 read_ecc[1] = dev_oob[1]; calc_ecc[1] = oob[1];
650 read_ecc[2] = dev_oob[2]; calc_ecc[2] = oob[2];
651 res = _nand_correct_data(&page[0], read_ecc, calc_ecc);
652 if ((res != 0) && (res != 1)) {
653 diag_printf("ECC failed\n");
657 read_ecc[0] = dev_oob[3]; calc_ecc[0] = oob[3];
658 read_ecc[1] = dev_oob[6]; calc_ecc[1] = oob[6];
659 read_ecc[2] = dev_oob[7]; calc_ecc[2] = oob[7];
660 res = _nand_correct_data(&page[256], read_ecc, calc_ecc);
661 if ((res != 0) && (res != 1)) {
662 diag_printf("ECC failed\n");
668 CYGACC_CALL_IF_DELAY_US(10);
669 while (!CYGHWR_FLASH_TC58XXX_RDY()) cnt++; // Wait for page data to be ready
671 diag_printf("Read data starting at %p, count = %d\n", data_ptr, cnt);
674 page = (unsigned char *)data_ptr;
677 CYGHWR_FLASH_TC58XXX_CLE(1);
678 put_NAND(ROM, FLASH_Status);
679 CYGHWR_FLASH_TC58XXX_CLE(0);
681 CYGHWR_FLASH_TC58XXX_CE(0);
683 diag_printf("Status after read: %x\n", stat);
689 #endif // CYGONCE_DEVS_FLASH_TOSHIBA_TC58XXX_INL
691 // EOF flash_tc58xxx.inl