allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / cfe / cfe / arch / mips / board / bcm9635x / src / flash.c
blob50a514612c8364eebf0d101021867714dc3af7b3
1 /*
2 <:copyright-broadcom
4 Copyright (c) 2002 Broadcom Corporation
5 All Rights Reserved
6 No portions of this material may be reproduced in any form without the
7 written permission of:
8 Broadcom Corporation
9 16215 Alton Parkway
10 Irvine, California 92619
11 All information contained in this document is Broadcom Corporation
12 company private, proprietary, and trade secret.
16 //**************************************************************************
17 // Filename: flash.c
18 // Author: Dannie Gay
19 // Creation Date: 2-mar-97
21 //**************************************************************************
22 // Description:
24 // CM MAC FLASH Memory access routines.
25 //
26 //**************************************************************************
27 // Revision History:
28 // 0.1 initial revision
29 // 0.2 support for 28016 Flash
30 // 0.3 BCM3300I MIPS port
31 // 0.4 add support for AMD flash. 10-15-99 ytl
33 //**************************************************************************
35 /* Includes. */
36 #include "lib_types.h"
37 #include "lib_string.h"
38 #include "lib_printf.h"
39 #include "cfe_timer.h"
40 #include "sbmips.h"
41 #include "flash.h"
43 extern void udelay(long us);
45 /* Globals. */
46 // Pointer to base (word) of Flash Memory
47 unsigned short * flashBasePtr = (unsigned short *)FLASH_BASE_ADDR_REG;
49 static unsigned char s3s5Device=FALSE; // flag indicating new flash device
50 static unsigned short flashId=FALSE; // flashId read from device
51 static unsigned short TRead_Array_Cmd=FALSE; // runtime cmd for function Set_Read_Array
53 int nTOTAL_FLASH_BLOCKS;
55 // storage to hold flash information
56 static FLASH_INFO flashinfo;
58 //local function pointer that assigned dynamically to flash routines during startup
59 static int (*TEraseFlashAddressBlock)(unsigned short *, unsigned short * ) = 0;
60 static unsigned short (*TEraseAllUnlockFlashBlocks)(unsigned short * , long * ) = 0;
61 static unsigned short (*TSuspendEraseToReadArray)(unsigned short *, unsigned short *) = 0;
62 static int (*TFlashWordWrite)(unsigned short *, unsigned short *, unsigned long, unsigned short *) = 0;
63 static unsigned short (*TReadFlashIdCodes)(void) = 0;
65 int IntelEraseFlashAddressBlock(unsigned short * dest, unsigned short * esr);
66 int AMDEraseFlashAddressBlock(unsigned short * dest, unsigned short * esr);
67 unsigned short EraseAllUnlockFlashBlocks(unsigned short * basePtr, long * failureList);
68 unsigned short IntelEraseAllUnlockFlashBlocks( unsigned short * basePtr, long * failureList);
69 unsigned short AMDEraseAllUnlockFlashBlocks(unsigned short * basePtr, long * failureList);
70 int IntelFlashWordWrite(unsigned short * dest, unsigned short * src, unsigned long count, unsigned short * esr);
71 int AMDFlashWordWrite(unsigned short * dest, unsigned short * src, unsigned long count, unsigned short * esr);
72 unsigned short IntelSuspendEraseToReadArray(unsigned short * dataPtr, unsigned short * result);
73 unsigned short AMDSuspendEraseToReadArray(unsigned short * dataPtr, unsigned short * result);
74 unsigned short ReadIntelFlashIdCodes(void);
75 unsigned short ReadAMDFlashIdCodes(void);
76 void AutoDetectFlash(unsigned char debugMsg);
77 void DetectFlashInfo(FLASH_INFO * autoflashinfo);
81 /************************************************************************
82 Base
84 Description: Given a word address in the Flash - return a
85 word pointer to the base of the corresponding
86 32K (word) block.
87 (note: Base of flash resides on a 1Meg boundary)
89 Paramters:
91 unsigned short * dataPtr - pointer to a word within a 32K block
93 Return:
94 unsigned short * - blkBasePtr - pointer to block base
96 ************************************************************************/
97 unsigned short *
98 Base(unsigned short * dataPtr)
100 if( flashId == FLASH_28F320C3_DEV_CODE )
102 if (((unsigned long)dataPtr - FLASH_BASE) < 0x10000)
103 return (unsigned short *)((unsigned long)dataPtr & 0xffffe000);
104 else
105 return (unsigned short *)((unsigned long)dataPtr & flashinfo.flash_block_mask);
107 else
108 return (unsigned short *)((unsigned long)dataPtr & flashinfo.flash_block_mask);
111 /************************************************************************
113 WriteProtect
115 Description: Turn on/off write protection to Flash
117 Paramters:
119 int 1 turns write protect on,
120 0 turns write protect off.
122 Return:
124 int - NULL = success, otherwise error.
126 ************************************************************************/
127 int
128 BlkWriteProtect(unsigned short blk, int on)
130 unsigned long blkBasePtr;
131 volatile unsigned short * blockBase;
132 unsigned short * dest;
134 if (s3s5Device)
136 if( flashId == FLASH_28F320C3_DEV_CODE )
138 const unsigned short FLASH_64K_BLKS_TOTAL = 63;
139 const unsigned short FLASH_8K_BLKS_TOTAL = 8;
140 /* max block = FLASH_64K_BLKS_TOTAL * 64K + 8 blks * 8K */
141 if (blk >= (FLASH_64K_BLKS_TOTAL + FLASH_8K_BLKS_TOTAL))
142 return -1;
144 if (blk < 8)
145 blkBasePtr = flashinfo.flash_base + (blk * 0x2000);
146 else
147 blkBasePtr = flashinfo.flash_base + ((blk - 7) * 0x10000);
149 else
151 if (blk >= flashinfo.flash_block_total)
152 return -1;
154 blkBasePtr = (unsigned long)flashinfo.flash_base +
155 (unsigned long)(blk * flashinfo.flash_block_size);
158 //------------------------------------------------------------------
159 // Convert block number to block base address and issue erase
160 //------------------------------------------------------------------
161 dest = (unsigned short *)blkBasePtr;
162 blockBase = Base(dest);
164 return (FlashBlockLock(blockBase, on));
167 return 0;
170 int
171 AddrWriteProtect(unsigned short * dest, int on)
173 volatile unsigned short * blockBase;
175 if (s3s5Device)
177 if( flashId == FLASH_28F320C3_DEV_CODE )
179 if (dest >= (unsigned short *)(FLASH_BASE +
180 (flashinfo.flash_block_total * flashinfo.flash_block_size)))
182 return -1;
185 else
187 if (dest >= (unsigned short *)(FLASH_BASE +
188 (flashinfo.flash_block_total * flashinfo.flash_block_size)))
190 return -1;
194 blockBase = Base(dest);
196 return (FlashBlockLock(blockBase, on));
198 return 0;
201 int FlashBlockLock(volatile unsigned short * blockBase, int on)
203 unsigned short cmd;
204 volatile unsigned short esr;
205 int j;
207 if (on)
208 { // set block lock bit
209 cmd = BLOCK_LOCK_CMD;
211 else
212 { // clear block lock bit
213 cmd = BLOCK_UNLOCK_CMD;
215 //------------------------------------------------------------------
216 // Issue Single Block lock at block address
217 //------------------------------------------------------------------
218 *blockBase = CFG_SETUP_CMD;
219 *blockBase = cmd;
221 //------------------------------------------------------------------
222 // Poll SR.7 until block ready
223 // Clear Status Register, reset device to read array mode
224 //------------------------------------------------------------------
226 /* according to the spec, this should take max of 0.7 second;
227 typically, it takes about 0.5 sec. So, let's poll this
228 every 0.5 sec; allow max of 3 times. */
229 for (j = 0; j < 3; j++)
231 cfe_sleep(CFE_HZ/2);
232 if (BIT_7 & *(blockBase+1))
233 break;
236 if (j == 3)
238 printf("FlashBlockLock(): SR.7 is not set after about 1.5 second. Timeout!\n");
239 return -1;
242 esr = *(blockBase+1);
244 *blockBase = CLR_STATUS_REGS_CMD;
245 *blockBase = READ_ARRAY_CMD;
247 //------------------------------------------------------------------
248 // Check for any errors
249 //------------------------------------------------------------------
250 if (esr & OPERATION_STATUS_ERR_2)
252 *blockBase = READ_ARRAY_CMD;
253 return -1;
255 else
257 *blockBase = READ_ARRAY_CMD;
258 return 0;
262 /************************************************************************
264 IsBlockProtected
266 Description: Read block lock status
268 Paramters:
270 unsigned short blk - block number
272 Return:
274 int 1 block protect on,
275 0 block protect off.
277 ************************************************************************/
278 int IsBlockProtected(unsigned short blk)
280 unsigned long blkBasePtr;
281 volatile unsigned short * blockBase;
282 unsigned short * dest;
283 volatile unsigned short LockStatus = 0;
285 if (s3s5Device)
288 if( flashId == FLASH_28F320C3_DEV_CODE )
290 if (blk < 8)
291 blkBasePtr = flashinfo.flash_base + (blk * 0x2000);
292 else
293 blkBasePtr = flashinfo.flash_base + ((blk - 7) * 0x10000);
295 else
297 blkBasePtr = (unsigned long) flashinfo.flash_base + (unsigned long)
298 (blk * flashinfo.flash_block_size);
301 //------------------------------------------------------------------
302 // Convert block number to block base address and issue erase
303 //------------------------------------------------------------------
304 dest = (unsigned short *)blkBasePtr;
305 blockBase = Base(dest);
307 //------------------------------------------------------------------
308 *blockBase = READ_ID_CODES_CMD;
309 LockStatus = *(blockBase+2);
311 *blockBase = READ_ARRAY_CMD;
315 return LockStatus;
318 /************************************************************************
320 EraseFlashAddressBlock
322 Description: Erase Flash Block. The Flash is partitioned into
323 32 Blocks of 32K words each
325 Paramters:
327 unsigned short * dest - pointer to flash destination address of
328 block to erase
329 unsigned short * esr - pointer for returned esr status
330 (Upper byte=GSR, Lower byte=BSR)
331 Return:
333 int - NULL = success, otherwise error.
335 ************************************************************************/
336 int EraseFlashAddressBlock(unsigned short * dest, unsigned short * esr)
338 BDGPrint(("EraseFlashAddressBlock %08x\n", (unsigned long)dest));
340 return TEraseFlashAddressBlock(dest, esr);
343 //------------------------------------------------------------------
344 // Intel flash specific
345 //------------------------------------------------------------------
346 int IntelEraseFlashAddressBlock(unsigned short * dest, unsigned short * esr)
348 int j;
349 volatile unsigned short * blockBase = Base(dest);
350 volatile unsigned short *tempdest = dest;
351 volatile unsigned short *volesr = esr;
353 //------------------------------------------------------------------
354 // support both 28016SV/SA and 28160S3/S5 flash
355 //------------------------------------------------------------------
356 if (s3s5Device)
358 //------------------------------------------------------------------
359 // Issue Single Block Erase at block address
360 //------------------------------------------------------------------
361 *tempdest = SINGLE_BLOCK_ERASE_CMD;
362 *tempdest = CONFIRM_RESUME_CMD;
364 //------------------------------------------------------------------
365 // Poll SR.7 until block ready
366 // Clear Status Register, reset device to read array mode
367 //------------------------------------------------------------------
369 /* according to the spec, it would take max of 5 sec,
370 typically 1 second. So we are giving polling once every second
371 for 7 sec */
373 for (j = 0; j < 7; j++)
375 cfe_sleep(CFE_HZ);
376 if (BIT_7 & *(blockBase+1))
377 break;
380 if (j == 7)
382 printf("IntelEraseFlashAddressBlock(): SR.7 is not set after about 7 seconds. Timeout!\n");
383 return -1;
386 *volesr = *(blockBase+1);
388 *tempdest = CLR_STATUS_REGS_CMD;
389 *tempdest = READ_ARRAY_CMD;
391 //------------------------------------------------------------------
392 // Check for any errors
393 //------------------------------------------------------------------
394 if (*volesr & OPERATION_STATUS_ERR_2)
396 *tempdest = READ_ARRAY_CMD;
397 return -1;
399 else
401 *tempdest = READ_ARRAY_CMD;
402 return ((int)NULL);
405 else
407 //------------------------------------------------------------------
408 // Read Extended Status Registers - Poll BSR until BSR.3 of dest
409 // address=0 (queue available).
410 // (note: BSR is 1 word above base of target block in status reg space)
411 //------------------------------------------------------------------
412 *tempdest = ESR_READ_CMD;
414 for (j = 0; j < 500; j++)
416 udelay(10);
417 if (!(BIT_3 & *(blockBase+1)))
418 break;
421 if (j == 500)
423 printf("IntelEraseFlashAddressBlock(): SR.3 is clear after about 5 msec. Timeout!\n");
424 return -1;
427 *tempdest = SINGLE_BLOCK_ERASE_CMD;
428 *tempdest = CONFIRM_RESUME_CMD;
429 // issue Confirm/Resume again per latest spec errata update
430 *tempdest = CONFIRM_RESUME_CMD;
431 *tempdest = ESR_READ_CMD;
433 //------------------------------------------------------------------
434 // Poll BSR.7 until block ready
435 // Clear Status Register, reset device to read array mode
436 //------------------------------------------------------------------
437 for (j = 0; j < 7; j++)
439 cfe_sleep(CFE_HZ);
440 if ((BIT_7 & *(blockBase+1)))
441 break;
444 if (j == 7)
446 printf("IntelEraseFlashAddressBlock(): SR.7 is not set after about 7 seconds. Timeout!\n");
447 return -1;
450 *volesr = (*(blockBase+2) << 8) + (*(blockBase+1) & LOW_BYTE);
452 *tempdest = CLR_STATUS_REGS_CMD;
453 *tempdest = READ_ARRAY_CMD;
455 //------------------------------------------------------------------
456 // Check for any errors
457 //------------------------------------------------------------------
458 if (*volesr & OPERATION_STATUS_ERR)
460 *tempdest = READ_ARRAY_CMD;
461 return -1;
463 else
465 *tempdest = READ_ARRAY_CMD;
466 return ((int)NULL);
471 //------------------------------------------------------------------
472 // AMD flash specific
473 //------------------------------------------------------------------
474 int AMDEraseFlashAddressBlock(unsigned short * dest, unsigned short * esr)
476 unsigned long timeout;
477 volatile unsigned short * blockBase;
479 //esr not applicable to AMD flash, just set ot all F's for now
480 *esr = -1;
482 /* AMD erase sector command sequence ... */
483 AMDFLASH_WRITE_RAW(0xaaaa, 0x555 );
484 AMDFLASH_WRITE_RAW(0x5555, 0x2aa );
485 AMDFLASH_WRITE_RAW(AMD_ERASE_CMD, 0x555 );
486 AMDFLASH_WRITE_RAW(0xaaaa, 0x555 );
487 AMDFLASH_WRITE_RAW(0x5555, 0x2aa );
488 /* now the sector to erase */
489 blockBase = dest ;
490 *blockBase = AMD_SECTOR_ERASE_CMD;
492 /* loop and wait for erase to complete. Set a timeout of 5 seconds */
493 /* so it doesn't get stuck here ... device spec says typical 0.7s */
494 for (timeout=0; timeout<50; timeout++)
496 unsigned short data = *blockBase ;
498 /* device hasn't done yet, wait a while */
499 cfe_sleep(1); /* Delayms(100); */
501 /* if done bit (D7) is 1, erase is complete */
502 if ((data & DQ7) == DQ7 )
504 BDGPrint(("AMD sector (0x%08x) erase success (Ntime=%d)!\n", (unsigned long)blockBase, timeout));
505 return 0;
508 /* check for timeout condition */
509 else if ( (data & DQ5) == DQ5 ) //DQ5 == 1
511 data = *blockBase;
512 if ( (data & DQ7) == DQ7 )
514 BDGPrint(("AMD sector (0x%08x) erase success (Stime=%d)!\n", (unsigned long)blockBase, timeout));
515 return 0;
517 else
519 BDGPrint(("AMD sector (0x%08x) erase bit5 timeout!\n", (unsigned long)blockBase));
520 *blockBase = AMD_RESET_CMD ; //reset to return to read mode
521 return -1;
525 } /* for */
527 *blockBase = AMD_RESET_CMD ; //reset to return to read mode
528 BDGPrint(("Loop timeout! AMD sector (0x%08x) erase fail!\n", (unsigned long)blockBase));
530 return -1;
533 /************************************************************************
535 EraseFlashBlock
537 Description: Erase Flash Block. The Flash is partitioned into
538 32 Blocks of 32K words each
540 Paramters:
542 unsigned short blk - block number
544 Return:
546 int - NULL = success, otherwise error (esr status).
548 ************************************************************************/
549 int EraseFlashBlock(unsigned short blk)
551 unsigned short esr = -1;
552 unsigned long blkBasePtr;
554 BDGPrint(("EraseFlashBlock # %d\n", blk));
556 if( (flashId==FLASH_AMD29LV160BB_ID) && !blk ) //AMD flash blk 0 needs to be handled differently
558 //For transperancy to the users, the first 64K byte block of the AMD flash
559 //needs to be handled differently inorder to looks the same as the Intel flash
560 //There are 4 sectors in the first 64K byte; 16K, 8K, 8K, 32K
561 unsigned short i, amdsa[4] = {0,16,24,32};
562 for( i=0; i<4; i++ )
564 blkBasePtr = (unsigned long)(flashinfo.flash_base)+(unsigned long)(amdsa[i] * 1024); //offset to the beginning of a block
565 if (EraseFlashAddressBlock((unsigned short *)blkBasePtr, &esr) == -1)
566 return esr;
567 } //end for
568 } //end if
569 else
571 //------------------------------------------------------------------
572 // Convert block number to block base address and issue erase
573 //------------------------------------------------------------------
574 if( flashId == FLASH_28F320C3_DEV_CODE )
576 if (blk < 8)
577 blkBasePtr = flashinfo.flash_base + (blk * 0x2000);
578 else
579 blkBasePtr = flashinfo.flash_base + ((blk - 7) * 0x10000);
581 else
582 blkBasePtr = (unsigned long)flashinfo.flash_base +(unsigned long)(blk * flashinfo.flash_block_size);
584 if (EraseFlashAddressBlock((unsigned short *)blkBasePtr, &esr) == -1)
587 printf("failed on erase on blkBasePtr 0x%x, with esr %d\n", blkBasePtr, esr);
588 return esr;
590 } //end else
592 return ((int)NULL); //return success
595 /************************************************************************
597 EraseAllUnlockFlashBlocks
599 Description: Erase All Unlocked Flash Blocks. The Flash is
600 partitioned into 32 Blocks of 32K words each.
602 Paramters:
604 unsigned short * basePtr - pointer to base of flash.
605 long * failureList - map of block failures (bit position=1 for
606 block failure)
607 Return:
609 unsigned short - GSR, Global Status Register
611 ************************************************************************/
612 unsigned short EraseAllUnlockFlashBlocks(unsigned short * basePtr, long * failureList)
614 BDGPrint(("EraseAllUnlockFlashBlocks(chip erase)\n"));
616 return TEraseAllUnlockFlashBlocks(basePtr, failureList);
619 //------------------------------------------------------------------
620 // Intel flash specific
621 //------------------------------------------------------------------
622 unsigned short IntelEraseAllUnlockFlashBlocks( unsigned short * basePtr, long * failureList)
624 int j;
625 unsigned short gsr, block;
626 long power=1;
627 volatile unsigned short *volbasePtr = basePtr;
629 //------------------------------------------------------------------
630 // command not supported on 28160S3/S5 flash
631 //------------------------------------------------------------------
632 if (s3s5Device)
633 return 0;
635 //------------------------------------------------------------------
636 // Return value will contain GSR in both upper and lower bytes.
637 // 32 bit long word pointed to by failureList is used to return
638 // map of block failures, each bit representing one block's status.
639 // basePtr points to base address of Flash.
640 //------------------------------------------------------------------
641 *failureList = 0;
642 *volbasePtr = ESR_READ_CMD;
644 //------------------------------------------------------------------
645 // Poll BSR.3 until queue available, then issue full chip erase cmd
646 //------------------------------------------------------------------
647 for (j = 0; j < 500; j++)
649 udelay(10);
650 if (!(BIT_3 & *(volbasePtr+1)))
651 break;
654 if (j == 500)
656 printf("(IntelEraseAllUnlockFlashBlocks): BSR.3 is not clear after about 5 msec. Timeout!\n");
657 return -1;
660 *volbasePtr = ERASE_ALL_UNLCK_BLKS_CMD;
661 *volbasePtr = CONFIRM_RESUME_CMD;
662 *volbasePtr = ESR_READ_CMD;
664 //------------------------------------------------------------------
665 // Poll GSR.7 until WSM ready, then go through all blocks and test
666 // BSR.5 for operation failure - set failureList accordingly.
667 //------------------------------------------------------------------
668 for (j = 0; j < 7; j++)
670 cfe_sleep(CFE_HZ);
671 if (BIT_7 & *(volbasePtr+2))
672 break;
675 if (j == 7)
677 printf("(IntelEraseAllUnlockFlashBlocks): SR.7 is not clear after about 7 sec. Timeout!\n");
678 return -1;
681 for (block=0; block < 0x0020; block++)
683 if (BIT_5 & *(volbasePtr + block * flashinfo.flash_block_size + 1))
684 *failureList += power;
685 power = power << 1;
688 gsr = *(volbasePtr+2);
689 *basePtr = CLR_STATUS_REGS_CMD;
690 *basePtr = READ_ARRAY_CMD;
692 return gsr;
695 //------------------------------------------------------------------
696 // AMD flash specific
697 //------------------------------------------------------------------
698 unsigned short AMDEraseAllUnlockFlashBlocks(unsigned short * basePtr, long * failureList)
700 unsigned long timeout;
701 unsigned short data1, data2 ;
702 volatile unsigned short *volbasePtr = basePtr;
704 *failureList = -1;
706 /* AMD erase chip command sequence ... */
707 AMDFLASH_WRITE_RAW(0xaaaa, 0x555 );
708 AMDFLASH_WRITE_RAW(0x5555, 0x2aa );
709 AMDFLASH_WRITE_RAW(AMD_ERASE_CMD, 0x555 );
710 AMDFLASH_WRITE_RAW(0xaaaa, 0x555 );
711 AMDFLASH_WRITE_RAW(0x5555, 0x2aa );
712 AMDFLASH_WRITE_RAW(AMD_CHIP_ERASE_CMD, 0x555 );
714 /* loop and wait for erase to complete. Set a timeout of 40 seconds */
715 /* so it doesn't get stuck here ... device spec says up to 30s ??? */
716 for (timeout=0; timeout<400; timeout++)
718 data1 = *volbasePtr;
719 data2 = *volbasePtr;
721 //check if DQ6 & DQ2 toggling
722 if( (data1 & B6B2TOGGLE) == (data2 & B6B2TOGGLE) ) //toggling?
724 data2 = *volbasePtr;
725 if( data2 == 0xFFFF )
727 BDGPrint(("AMD chip erase success (Ntime=%d)!\n", timeout));
728 *failureList = 0;
729 return 0;
733 /* check for timeout condition */
734 else if ((data2 & DQ5) == DQ5 ) //check if DQ5 == 1
736 data1 = *volbasePtr;
737 if ((data1 & DQ7) == DQ7 )
739 BDGPrint(("AMD chip erase success (Stime=%d)!\n", timeout));
740 *failureList = 0;
741 return 0;
743 else
745 BDGPrint("AMD chip erase bit5 timeout!\n");
746 AMDFLASH_WRITE_RAW(AMD_RESET_CMD, 0x000); //reset command
747 return -1;
751 /* device hasn't done yet, wait a while */
752 cfe_sleep(1); /* Delayms(100); */
753 } /* end for */
755 AMDFLASH_WRITE_RAW(AMD_RESET_CMD, 0x000); //reset command
756 BDGPrint(("AMD chip erase fail timeout, data1=%04x data2=%04x!\n", data1, data2));
757 return -1;
761 /************************************************************************
763 FlashWordWrite
765 Description: Writes words to the Flash
767 Paramters:
769 unsigned short * dest - word pointer to Flash write destination
770 unsigned short * src - word pointer to source data
771 unsigned short count - number of words to write
772 unsigned short * esr - pointer for returned esr status
773 (Upper byte=GSR, Lower byte=BSR)
774 Return:
776 int - NULL = success, otherwise error.
778 ************************************************************************/
779 int FlashWordWrite(unsigned short * dest, unsigned short * src, unsigned long count, unsigned short * esr)
781 BDGPrint(("Block FlashWordWrite %d swords from %08x to %08x\n", count, src, dest));
783 return TFlashWordWrite(dest, src, count, esr);
786 //------------------------------------------------------------------
787 // Intel flash specific
788 //------------------------------------------------------------------
789 int IntelFlashWordWrite(unsigned short * dest, unsigned short * src, unsigned long count, unsigned short * esr)
791 int i;
792 volatile unsigned short *blockBase = Base(dest);
793 int j;
795 //------------------------------------------------------------------
796 // support both 28016SV/SA and 28160S3/S5 flash
797 //------------------------------------------------------------------
798 if (s3s5Device)
800 //------------------------------------------------------------------
801 // Write actual data to flash, Read SR, polling until SR.7=1
802 // (note: BSR is 1 word above base of target block in status reg space)
803 //------------------------------------------------------------------
804 for (i=0; i < count; i++)
806 *dest = ALT_WORD_WRITE_CMD;
807 *dest++ = *src++;
809 /* this shouldn't take too long */
810 for (j = 0; j < 2000; j++)
812 if (BIT_7 & *(blockBase+1))
813 break;
816 if (j == 2000)
818 /* one last chance; give it another tick */
819 cfe_sleep(1);
820 if (!(BIT_7 & *(blockBase+1)))
822 printf("IntelFlashWordWrite(): SR.7 is not set after more than 13 usec. Timeout!\n");
823 return -1;
827 if( (i & 0x3fff) == 0 )
828 printf( "-" );
831 //------------------------------------------------------------------
832 // Check for any errors
833 //------------------------------------------------------------------
834 *esr = *(blockBase+1);
835 if (*esr & OPERATION_STATUS_ERR_2)
837 *blockBase = CLR_STATUS_REGS_CMD;
838 *blockBase = READ_ARRAY_CMD;
839 return -1;
842 *blockBase = CLR_STATUS_REGS_CMD;
843 *blockBase = READ_ARRAY_CMD;
845 return ((int)NULL);
847 else
849 //------------------------------------------------------------------
850 // Write actual data to flash, Read ESR, polling until BSR.3=0
851 // (queue available) then issue write word.
852 // (note: BSR is 1 word above base of target block in status reg space)
853 //------------------------------------------------------------------
854 for (i=0; i < count; i++)
856 *dest = ESR_READ_CMD;
858 for (j = 0; j < 500; j++)
860 udelay(10);
861 if (BIT_3 & *(blockBase+1))
862 break;
865 if (j == 500)
867 printf("IntelFlashWordWrite(): BSR.3 is not set after about 5msec. Timeout!\n");
868 return -1;
871 *dest = ALT_WORD_WRITE_CMD;
872 *dest++ = *src++;
874 if( (i & 0x3fff) == 0 )
875 printf( "-" );
878 //------------------------------------------------------------------
879 // Get status of operation and return in esr
880 // Poll BSR until BSR.7 of target address=1 (block ready)
881 // Put GSR in upper byte and BSR in lower byte of esr.
882 //------------------------------------------------------------------
884 *dest = ESR_READ_CMD;
885 /* according to the spec, this should typically take 210 usec and max
886 of 630 usec. So, let's poll this every 210 usec and 8 times */
887 for (j = 0; j < 170; j++)
889 udelay(10);
890 if (BIT_7 & *(blockBase+1))
891 break;
894 if (j == 170)
896 printf("IntelFlashWordWrite(): SR.7 is not set after about 1.7 msec. Timeout!\n");
897 return -1;
900 *esr = (*(blockBase+2) << 8) + (*(blockBase+1) & LOW_BYTE);
901 *dest = CLR_STATUS_REGS_CMD;
902 *dest = READ_ARRAY_CMD;
904 //------------------------------------------------------------------
905 // Check for any errors
906 //------------------------------------------------------------------
907 if (*esr & OPERATION_STATUS_ERR)
908 return -1;
909 else
910 return ((int)NULL);
914 //------------------------------------------------------------------
915 // AMD flash specific
916 //------------------------------------------------------------------
917 #define USE_BLOCK_WRITE
918 int AMDFlashWordWrite(unsigned short * dest, unsigned short * src, unsigned long count, unsigned short * esr)
920 unsigned short timeout, value;
921 int ret_val = (int)NULL; //assume no error
923 *esr = (int)NULL; //esr not supported in AMD flash, set it to 0 for now
925 #ifdef USE_BLOCK_WRITE
926 /* AMD unlock bypass mode command sequence ...(faster for block write) */
927 AMDFLASH_WRITE_RAW(0xaaaa, 0x555 );
928 AMDFLASH_WRITE_RAW(0x5555, 0x2aa );
929 AMDFLASH_WRITE_RAW(AMD_ULBYPASS_MOD_CMD, 0x555 );
930 #endif
932 while( count-- )
934 #ifdef USE_BLOCK_WRITE
935 /* AMD unlock bypass program command... */
936 AMDFLASH_WRITE_RAW(AMD_ULBYPASS_PGM_CMD, 0x000 );
937 #else
938 /* AMD single write command sequence ... */
939 AMDFLASH_WRITE_RAW(0xaaaa, 0x555 );
940 AMDFLASH_WRITE_RAW(0x5555, 0x2aa );
941 AMDFLASH_WRITE_RAW(AMD_PROGRAM_CMD, 0x555 );
942 #endif
944 /* write the sword */
945 value = *src;
946 *dest = value;
948 /* loop round waiting for program to complete or time out ... */
949 for (timeout=200; timeout; timeout--)
951 if ( *dest == value ) //wait for complete
952 break;
955 if( !timeout ) //timeout?
957 ret_val = -1;
958 *esr = -1;
959 BDGPrint(("AMD program sword @(0x%08x) timeout!\n", dest));
962 //next location
963 src++;
964 dest++;
966 } //end while
968 #ifdef USE_BLOCK_WRITE
969 /* AMD unlock bypass reset command... */
970 AMDFLASH_WRITE_RAW(AMD_ULBYPASS_RST_CMD, 0x000 );
971 AMDFLASH_WRITE_RAW(0x0000, 0x000 );
972 #endif
974 AMDFLASH_WRITE_RAW(AMD_RESET_CMD, 0x000); //reset command
975 return ret_val;
978 /************************************************************************
980 SuspendEraseToReadArray
982 Description: Suspend an Erase Cycle.
984 Paramters:
986 unsigned short * dataPtr - pointer value to be read
987 unsigned short * result - holds value read until procedure complete
989 Return:
991 unsigned short ESR - GSR in upper byte, BSR in lower byte
993 ************************************************************************/
994 unsigned short SuspendEraseToReadArray(unsigned short * dataPtr, unsigned short * result)
996 BDGPrint(("SuspendEraseToReadArray @ address %08x\n", dataPtr));
998 return TSuspendEraseToReadArray(dataPtr, result);
1001 //------------------------------------------------------------------
1002 // Intel flash specific
1003 //------------------------------------------------------------------
1004 unsigned short IntelSuspendEraseToReadArray(unsigned short * dataPtr, unsigned short * result)
1006 unsigned short esr;
1007 volatile unsigned short * blockBase=Base(dataPtr);
1008 int j;
1010 //------------------------------------------------------------------
1011 // support both 28016SV/SA and 28160S3/S5 flash
1012 //------------------------------------------------------------------
1013 if (s3s5Device)
1015 //------------------------------------------------------------------
1016 // issue suspend
1017 //------------------------------------------------------------------
1018 *dataPtr = ERASE_SUSPEND_CMD;
1019 *dataPtr = ESR_READ_CMD;
1020 // wait until operation complete
1022 /* according to the spec, this should typically take 36 us and max about
1023 40 us; so we are polling once every 36 us for 3 times */
1024 for (j = 0; j < 10; j++)
1026 udelay(10);
1027 if (BIT_7 & *(blockBase+1))
1028 break;
1031 if (j == 10)
1033 printf("IntelSuspendEraseToReadArray(): SR.7 is not set after 108 usec. Timeout!\n");
1034 return -1;
1037 // attempt to suspend erase
1038 if (BIT_6 & *(blockBase+1))
1040 *dataPtr = READ_ARRAY_CMD;
1041 *result = *dataPtr;
1042 *dataPtr = CONFIRM_RESUME_CMD;
1043 *dataPtr = CLR_STATUS_REGS_CMD;
1045 else
1046 { // erase already complete
1047 *dataPtr = CLR_STATUS_REGS_CMD;
1048 *dataPtr = READ_ARRAY_CMD;
1049 return 0;
1051 esr = *(blockBase+2);
1053 else
1055 //------------------------------------------------------------------
1056 // Get status then wait until Block Ready, issue suspend
1057 //------------------------------------------------------------------
1058 *dataPtr = ESR_READ_CMD;
1059 for (j = 0; j < 10; j++)
1061 udelay(10);
1062 if (BIT_7 & *(blockBase+1))
1063 break;
1066 if (j == 10)
1068 printf("IntelSuspendEraseToReadArray(): SR.7 is not set after 108 usec. Timeout!\n");
1069 return -1;
1072 *dataPtr = ERASE_SUSPEND_CMD;
1073 *dataPtr = ESR_READ_CMD;
1075 //------------------------------------------------------------------
1076 // Wait until WSM ready, check result, read data
1077 //------------------------------------------------------------------
1079 /* according to the spec, this should typically take 36 us and max about
1080 40 us; so we are polling once every 36 us for 3 times */
1081 for (j = 0; j < 10; j++)
1083 udelay(10);
1084 if (BIT_7 & *(blockBase+2))
1085 break;
1088 if (j == 10)
1090 printf("IntelSuspendEraseToReadArray(): SR.7 is not set after 108 usec. Timeout!\n");
1091 return -1;
1094 if (BIT_6 & *(blockBase+2))
1096 *dataPtr = READ_ARRAY_CMD;
1097 *result = *dataPtr;
1098 *dataPtr = CONFIRM_RESUME_CMD;
1100 else
1102 *dataPtr = READ_ARRAY_CMD;
1103 *result = *dataPtr;
1106 *dataPtr = ESR_READ_CMD;
1107 esr = (*(blockBase+2) << 8) + (*(blockBase+1) & LOW_BYTE);
1108 *dataPtr = CLR_STATUS_REGS_CMD;
1110 return esr;
1113 //------------------------------------------------------------------
1114 // AMD flash specific
1115 //------------------------------------------------------------------
1116 unsigned short AMDSuspendEraseToReadArray(unsigned short * dataPtr, unsigned short * result)
1118 //For AMD, Suspend erase is only valid during sector erase which typically took 0.7 sec
1119 //This function is supposed to be called IN the AMDEraseFlashAddressBlock() routine, otherwise
1120 //it would be just the same as reading routine
1122 /* AMD Enter erase suspend ... */
1123 AMDFLASH_WRITE_RAW(AMD_ERASE_SUSPEND_CMD, 0x000 ); //valid only during a sector erase operation
1125 // read the data
1126 *result = *dataPtr;
1128 /* AMD resume erase ... */
1129 AMDFLASH_WRITE_RAW(AMD_ERASE_RESUME_CMD, 0x000 ); //valid only during a sector erase operation
1131 return 0;
1134 /************************************************************************
1136 ReadFlashCsrStatus
1138 Description: Returns the contents of the Flash CSR status register
1140 Paramters:
1142 none
1144 Return:
1146 unsigned char - CSR register (SR for 28160S3/S5)
1148 ************************************************************************/
1149 unsigned char
1150 ReadFlashCsrStatus(void)
1152 unsigned short csr;
1154 BDGPrint(("In ReadFlashCsrStatus\n"));
1156 //------------------------------------------------------------------
1157 // not supported in AMD flash
1158 //------------------------------------------------------------------
1159 if( flashId == FLASH_AMD29LV160BB_ID )
1160 return 0;
1162 //------------------------------------------------------------------
1163 // support both 28016SV/SA and 28160S3/S5 flash
1164 //------------------------------------------------------------------
1165 if (s3s5Device)
1167 *((unsigned short *)flashinfo.flash_base) = READ_SR_CMD;
1168 csr = *((unsigned short *)flashinfo.flash_base);
1169 *((unsigned short *)flashinfo.flash_base) = READ_ARRAY_CMD;
1171 else
1173 *((unsigned short *)flashinfo.flash_base) = READ_CSR_CMD;
1174 csr = *((unsigned short *)flashinfo.flash_base);
1175 *((unsigned short *)flashinfo.flash_base) = READ_ARRAY_CMD;
1178 return (unsigned char)csr;
1181 /************************************************************************
1183 ReadDeviceInformation
1185 Description: Reads the Flash Device Information
1187 Paramters:
1189 none
1191 Return:
1193 unsigned short - device revision status
1195 ************************************************************************/
1196 unsigned short
1197 ReadDeviceInformation(void)
1199 unsigned short drc;
1200 volatile unsigned short * blockBase = (unsigned short *) (flashinfo.flash_base);
1202 BDGPrint(("In ReadDeviceInformation\n"));
1204 //------------------------------------------------------------------
1205 // not supported in AMD flash
1206 //------------------------------------------------------------------
1207 if( flashId == FLASH_AMD29LV160BB_ID )
1208 return 0;
1210 //------------------------------------------------------------------
1211 // not supported in 28160S3/S5 flash
1212 //------------------------------------------------------------------
1213 if (s3s5Device)
1214 return 0;
1216 *blockBase = ESR_READ_CMD;
1218 while((BIT_3 & *(blockBase+2)) && (!(BIT_7 & *(blockBase+2))))
1221 *blockBase = UPLOAD_DEV_INFO_CMD;
1222 *blockBase = CONFIRM_RESUME_CMD;
1223 *blockBase = ESR_READ_CMD;
1225 while(!(BIT_7 & *(blockBase+2)))
1228 if (BIT_5 & *(blockBase+2))
1229 return ((*(blockBase+2) & HIGH_BYTE) << 8);
1231 *blockBase = PAGE_BUF_SWAP_CMD;
1232 *blockBase = READ_PAGE_BUF_CMD;
1234 drc = (*(blockBase+2) & 0xff00 << 8) + (*(blockBase+3) & LOW_BYTE);
1236 *blockBase = CLR_STATUS_REGS_CMD;
1237 *blockBase = READ_ARRAY_CMD;
1239 return drc;
1242 /************************************************************************
1244 ReadFlashIdCodes
1246 Description: Reads the Flash manufacturer and device IDs
1248 Paramters:
1250 none
1252 Return:
1254 unsigned short - device Manufacturer (HI-byte) | Device ID code (LO-byte)
1256 ************************************************************************/
1257 unsigned short ReadFlashIdCodes(void)
1259 return TReadFlashIdCodes();
1262 //------------------------------------------------------------------
1263 // Intel flash specific
1264 //------------------------------------------------------------------
1265 unsigned short ReadIntelFlashIdCodes(void)
1267 volatile unsigned short *blockBase = flashBasePtr;
1268 unsigned short manCode;
1269 unsigned short devCode;
1271 *blockBase = READ_ID_CODES_CMD;
1272 manCode = *blockBase;
1273 devCode = *(blockBase+1);
1275 *blockBase = CLR_STATUS_REGS_CMD;
1276 *blockBase = READ_ARRAY_CMD;
1278 return ((manCode << 8) | devCode);
1281 //------------------------------------------------------------------
1282 // AMD flash specific
1283 //------------------------------------------------------------------
1284 unsigned short ReadAMDFlashIdCodes(void)
1286 unsigned short manCode;
1287 unsigned short devCode;
1289 /* AMD write command sequence ... */
1290 AMDFLASH_WRITE_RAW(0xaaaa, 0x555 );
1291 AMDFLASH_WRITE_RAW(0x5555, 0x2aa );
1292 AMDFLASH_WRITE_RAW(AMD_AUTOSELECT_CMD, 0x555 );
1294 manCode = AMDFLASH_READ_RAW(AMD_MAN_ID_ADDR) & 0x00ff; //only interested in the lower byte
1295 devCode = AMDFLASH_READ_RAW(AMD_DEV_ID_ADDR) & 0x00ff; //only interested in the lower byte
1297 AMDFLASH_WRITE_RAW(AMD_RESET_CMD, 0x000); //reset to return to read mode
1299 return ((manCode << 8) | devCode);
1303 /************************************************************************
1305 AutoDectectFlash
1307 Description:
1309 Paramters:
1311 debugMsg - whether to show debug message or not
1312 auto_info - a pointer to flash information
1314 Return:
1318 ************************************************************************/
1319 void
1320 AutoDetectFlash(unsigned char debugMsg)
1322 static int firsttime = FALSE;
1324 BDGPrint(("\nIn AutoDetectFlash\n" ));
1326 if( !firsttime )
1328 BDGPrint(("\n[[***OneTime assigning flash routines pointer..." ));
1329 flashId = ReadAMDFlashIdCodes();
1330 if( flashId == FLASH_AMD29LV160BB_ID )
1332 // fill in AMD flash information
1333 flashinfo.flash_base = FLASH_BASE_ADDR_REG; // flash base
1334 flashinfo.flash_block_total = TOTAL64K_FLASH_BLOCKS; // 64 blocks
1335 flashinfo.flash_block_size = FLASH64K_BLOCK_SIZE; // 64kb
1336 flashinfo.flash_block_mask = FLASH64K_BLOCK_SIZE_MASK; // mask used
1338 BDGPrint(("AMD flash detected***]]\n\n" ));
1339 firsttime = TRUE;
1340 TSuspendEraseToReadArray = AMDSuspendEraseToReadArray ;
1341 TFlashWordWrite = AMDFlashWordWrite ;
1342 TReadFlashIdCodes = ReadAMDFlashIdCodes ;
1343 TEraseFlashAddressBlock = AMDEraseFlashAddressBlock;
1344 TEraseAllUnlockFlashBlocks = AMDEraseAllUnlockFlashBlocks;
1345 TRead_Array_Cmd = AMD_RESET_CMD ;
1348 else if( (ReadIntelFlashIdCodes() & 0xff) == STRATA_FLASH32_DEV_CODE)
1350 // fill in Intel flash information
1351 flashinfo.flash_base = STRATA32_FLASH_BASE;
1352 flashinfo.flash_block_total = STRATA_FLASH32_TOTAL_FLASH_BLOCKS;
1353 flashinfo.flash_block_size = STRATA_FLASH_BLOCK_SIZE;
1354 flashinfo.flash_block_mask = STRATA_FLASH_BLOCK_SIZE_MASK;
1356 BDGPrint(("Intel Strata flash detected***]]\n\n" ));
1357 firsttime = TRUE;
1358 TSuspendEraseToReadArray = IntelSuspendEraseToReadArray ;
1359 TFlashWordWrite = IntelFlashWordWrite ;
1360 TReadFlashIdCodes = ReadIntelFlashIdCodes ;
1361 TEraseFlashAddressBlock = IntelEraseFlashAddressBlock;
1362 TEraseAllUnlockFlashBlocks = IntelEraseAllUnlockFlashBlocks;
1363 TRead_Array_Cmd = READ_ARRAY_CMD;
1365 else if( (ReadIntelFlashIdCodes() & 0xff) == STRATA_FLASH64_DEV_CODE)
1367 // fill in Intel flash information
1368 flashinfo.flash_base = STRATA64_FLASH_BASE;
1369 flashinfo.flash_block_total = STRATA_FLASH32_TOTAL_FLASH_BLOCKS;
1370 flashinfo.flash_block_size = STRATA_FLASH_BLOCK_SIZE;
1371 flashinfo.flash_block_mask = STRATA_FLASH_BLOCK_SIZE_MASK;
1373 BDGPrint(("Intel Strata flash detected***]]\n\n" ));
1374 firsttime = TRUE;
1375 TSuspendEraseToReadArray = IntelSuspendEraseToReadArray ;
1376 TFlashWordWrite = IntelFlashWordWrite ;
1377 TReadFlashIdCodes = ReadIntelFlashIdCodes ;
1378 TEraseFlashAddressBlock = IntelEraseFlashAddressBlock;
1379 TEraseAllUnlockFlashBlocks = IntelEraseAllUnlockFlashBlocks;
1380 TRead_Array_Cmd = READ_ARRAY_CMD;
1382 else //assume Intel flash
1384 // fill in Intel flash information
1385 flashinfo.flash_base = FLASH_BASE_ADDR_REG; // flash base
1386 flashinfo.flash_block_total = TOTAL64K_FLASH_BLOCKS; // 64 blocks
1387 flashinfo.flash_block_size = FLASH64K_BLOCK_SIZE; // 64kb
1388 flashinfo.flash_block_mask = FLASH64K_BLOCK_SIZE_MASK; // mask used
1390 BDGPrint(("Intel flash detected***]]\n\n" ));
1391 firsttime = TRUE;
1392 TSuspendEraseToReadArray = IntelSuspendEraseToReadArray ;
1393 TFlashWordWrite = IntelFlashWordWrite ;
1394 TReadFlashIdCodes = ReadIntelFlashIdCodes ;
1395 TEraseFlashAddressBlock = IntelEraseFlashAddressBlock;
1396 TEraseAllUnlockFlashBlocks = IntelEraseAllUnlockFlashBlocks;
1397 TRead_Array_Cmd = READ_ARRAY_CMD;
1399 } //end if firsttime
1401 flashId = ReadFlashIdCodes() & 0x00ff; // mask off man code
1402 flashinfo.flashId = flashId;
1404 if (flashId == STRATA_FLASH32_DEV_CODE)
1406 s3s5Device = TRUE;
1407 nTOTAL_FLASH_BLOCKS = STRATA_FLASH32_TOTAL_FLASH_BLOCKS;
1408 if (debugMsg)
1409 BDGPrint("28F320J3A Strata Flash Detected\n");
1411 else if (flashId == STRATA_FLASH64_DEV_CODE)
1413 s3s5Device = TRUE;
1414 nTOTAL_FLASH_BLOCKS = STRATA_FLASH64_TOTAL_FLASH_BLOCKS;
1415 if (debugMsg)
1416 BDGPrint("28F640J3A Strata Flash Detected\n");
1418 else if (flashId == FLASH_160_DEV_CODE)
1420 s3s5Device = TRUE;
1421 nTOTAL_FLASH_BLOCKS = 32;
1422 if (debugMsg)
1423 BDGPrint("28F160 flash detected\n");
1425 else if (flashId == FLASH_320_DEV_CODE)
1427 s3s5Device = TRUE;
1428 nTOTAL_FLASH_BLOCKS = 64;
1429 if (debugMsg)
1430 BDGPrint("28F320 flash detected\n");
1432 else if (flashId == FLASH_016_DEV_CODE)
1434 s3s5Device = FALSE;
1435 nTOTAL_FLASH_BLOCKS = 32;
1436 if (debugMsg)
1437 BDGPrint("28F016 flash detected\n");
1439 else if( flashId == FLASH_28F320C3_DEV_CODE )
1441 s3s5Device = TRUE;
1442 nTOTAL_FLASH_BLOCKS = 64;
1443 if (debugMsg)
1444 BDGPrint("Intel 28F320C3 flash detected\n");
1446 else if( flashId == FLASH_AMD29LV160BB_DEV_CODE )
1448 if (debugMsg)
1449 BDGPrint("AM29LV160 flash detected\n");
1453 /************************************************************************
1455 Set_Read_Array
1457 Description: Put flash back to reading mode
1459 Paramters:
1461 none
1463 Return:
1464 none
1467 ************************************************************************/
1468 void Set_Read_Array(void)
1470 *((unsigned short *)FLASH_BASE_ADDR_REG) = TRead_Array_Cmd;
1473 /************************************************************************
1475 DetectFlashInfo
1477 Description: Copy flash information into passed parameter
1479 Paramters:
1481 autoflashinfo - where the flash data is to be stored
1483 Return:
1484 none
1487 ************************************************************************/
1488 void DetectFlashInfo(FLASH_INFO * autoflashinfo)
1490 AutoDetectFlash(0);
1492 // copy the flash information
1493 memcpy(autoflashinfo, &flashinfo, sizeof(flashinfo));
1497 /***********************************************************************
1498 * Function Name: flash_init
1499 * Description : Initialize flash driver.
1500 * Returns : 0.
1501 ***********************************************************************/
1502 unsigned char flash_init(void)
1504 AutoDetectFlash(0);
1505 return( 0 );
1506 } /* flash_sector_erase_int */
1509 /***********************************************************************
1510 * Function Name: flash_reset
1511 * Description : Called after a flash operation.
1512 * Returns : 1
1513 ***********************************************************************/
1514 unsigned char flash_reset(void)
1516 cfe_sleep(1);
1517 Set_Read_Array();
1518 return( 1 );
1519 } /* flash_reset */
1522 /***********************************************************************
1523 * Function Name: flash_sector_erase_int
1524 * Description : Erase a flash block.
1525 * Returns : 1
1526 ***********************************************************************/
1527 unsigned char flash_sector_erase_int(unsigned char sector)
1529 EraseFlashBlock(sector);
1530 return( 1 );
1531 } /* flash_sector_erase_int */
1534 /***********************************************************************
1535 * Function Name: flash_get_numsectors
1536 * Description : Returns the total number of flash blocks.
1537 * Returns : 1
1538 ***********************************************************************/
1539 int flash_get_numsectors(void)
1541 return( (int) flashinfo.flash_block_total );
1542 } /* flash_get_numsectors */
1545 /***********************************************************************
1546 * Function Name: flash_get_sector_size
1547 * Description : Returns the size of a flash block.
1548 * Returns : 1
1549 ***********************************************************************/
1550 int flash_get_sector_size( unsigned char sector )
1552 return( (int) flashinfo.flash_block_size );
1553 } /* flash_get_sector_size */
1556 /***********************************************************************
1557 * Function Name: flash_get_memptr
1558 * Description : Returns the starting address for a flash block.
1559 * Returns : 1
1560 ***********************************************************************/
1561 unsigned char *flash_get_memptr( unsigned char sector )
1563 return( (unsigned char *) (FLASH_BASE_ADDR_REG +
1564 flashinfo.flash_block_size * (unsigned long) sector) );
1565 } /* flash_get_memptr */
1568 /***********************************************************************
1569 * Function Name: flash_get_blk
1570 * Description : Returns the starting address for a flash block.
1571 * Returns : 1
1572 ***********************************************************************/
1573 int flash_get_blk( int addr )
1575 int blk_start, i;
1576 int last_blk = flash_get_numsectors();
1577 int relative_addr = addr - (int) FLASH_BASE_ADDR_REG;
1579 for(blk_start=0, i=0; i < relative_addr && blk_start < last_blk; blk_start++)
1580 i += flash_get_sector_size(blk_start);
1582 if( i > relative_addr )
1584 blk_start--; // last blk, dec by 1
1586 else
1587 if( blk_start == last_blk )
1589 printf("Address is too big.\n");
1590 blk_start = -1;
1593 return( blk_start );
1594 } /* flash_get_blk */
1597 /************************************************************************/
1598 /* The purpose of flash_get_total_size() is to return the total size of */
1599 /* the flash */
1600 /************************************************************************/
1602 int flash_get_total_size()
1604 return flashinfo.flash_block_size * flashinfo.flash_block_total;