📄 i28f016.c
字号:
/*
* $Log: i28f016.c,v $
* Revision 1.2 2006/09/08 06:24:39 jin
* 为提高flash写入效率,去掉了write函数中的数据校验
*
* Revision 1.1.1.1 2006/08/29 09:58:35 jin
* no message
*
*
* Rev 1.10 06 Oct 1997 9:45:48 danig
* VPP functions under #ifdef
*
* Rev 1.9 10 Sep 1997 16:48:24 danig
* Debug messages & got rid of generic names
*
* Rev 1.8 31 Aug 1997 15:09:20 danig
* Registration routine return status
*
* Rev 1.7 24 Jul 1997 17:52:58 amirban
* FAR to FAR0
*
* Rev 1.6 20 Jul 1997 17:17:06 amirban
* No watchDogTimer
*
* Rev 1.5 07 Jul 1997 15:22:08 amirban
* Ver 2.0
*
* Rev 1.4 04 Mar 1997 16:44:22 amirban
* Page buffer bug fix
*
* Rev 1.3 18 Aug 1996 13:48:24 amirban
* Comments
*
* Rev 1.2 12 Aug 1996 15:49:04 amirban
* Added suspend/resume
*
* Rev 1.1 31 Jul 1996 14:30:50 amirban
* Background stuff
*
* Rev 1.0 18 Jun 1996 16:34:30 amirban
* Initial revision.
*/
/************************************************************************/
/* */
/* FAT-FTL Lite Software Development Kit */
/* Copyright (C) M-Systems Ltd. 1995-1996 */
/* */
/************************************************************************/
/*----------------------------------------------------------------------*/
/* */
/* This MTD supports the following Flash technologies: */
/* */
/* - Intel 28F016SA/28016SV/Cobra 16-mbit devices */
/* */
/* And (among else), the following Flash media and cards: */
/* */
/* - Intel Series-2+ PCMCIA cards */
/* */
/*----------------------------------------------------------------------*/
#include "tffs\flflash.h"
#include "tffs\backgrnd.h"
/* JEDEC ids for this MTD */
#define I28F016_FLASH 0x8917
#define SETUP_ERASE 0x2020
#define SETUP_WRITE 0x4040
#define SETUP_BYTE_WRITE 0x1010
#define CLEAR_STATUS 0x5050
#define READ_STATUS 0x7070
#define READ_ID 0x9090
#define SUSPEND_ERASE 0xb0b0
#define CONFIRM_ERASE 0xd0d0
#define RESUME_ERASE 0xd0d0
#define READ_ARRAY 0xffff
#define LOAD_PAGE_BUFFER 0xe0e0
#define WRITE_PAGE_BUFFER 0x0c0c
#define READ_EXTENDED_REGS 0x7171
#define WSM_VPP_ERROR 0x08
#define WSM_ERROR 0x38
#define WSM_SUSPENDED 0x40
#define WSM_READY 0x80
#define GSR_ERROR 0x20
#define both(word) (vol.interleaving == 1 ? (word) : (word) & ((word) >> 8))
#define any(word) ((word) | ((word) >> 8))
#define NO_12VOLTS 0x100 /* Card does not need 12 Volts Vpp */
/*yuhm*/
FLFlash *testPtr = NULL;
void FAR1 *testWritePtr=NULL;
/*----------------------------------------------------------------------*/
/* i 2 8 f 0 1 6 W o r d S i z e */
/* */
/* Identify the card size for an Intel 28F016 word-mode Flash array. */
/* Sets the value of vol.noOfChips. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/* Returns: */
/* FLStatus : 0 = OK, otherwise failed (invalid Flash array)*/
/*----------------------------------------------------------------------*/
static FLStatus i28f016WordSize(FLFlash vol)
{
FlashWPTR flashPtr = (FlashWPTR) flMap(vol.socket,0);
flashPtr[0] = CLEAR_STATUS;
flashPtr[0] = READ_ID;
/* We leave the first chip in Read ID mode, so that we can */
/* discover an address wraparound. */
for (vol.noOfChips = 1; /* Scan the chips */
vol.noOfChips < 2000; /* Big enough ? */
vol.noOfChips++) {
flashPtr = (FlashWPTR) flMap(vol.socket,vol.noOfChips * vol.chipSize);
if (flashPtr[0] == 0x0089 && flashPtr[1] == 0x0017)
break; /* We've wrapped around to the first chip ! */
flashPtr[0] = READ_ID;
if (!(flashPtr[0] == 0x0089 && flashPtr[1] == 0x0017))
break;
flashPtr[0] = CLEAR_STATUS;
flashPtr[0] = READ_ARRAY;
}
flashPtr = (FlashWPTR) flMap(vol.socket,0);
flashPtr[0] = READ_ARRAY;
return flOK;
}
/*----------------------------------------------------------------------*/
/* i 2 8 f 0 1 6 W r i t e */
/* */
/* Write a block of bytes to Flash */
/* */
/* This routine will be registered as the MTD flash.write routine */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* address : Card address to write to */
/* buffer : Address of data to write */
/* length : Number of bytes to write */
/* overwrite : TRUE if overwriting old Flash contents */
/* FALSE if old contents are known to be erased */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus i28f016Write(FLFlash vol,
CardAddress address,
const void FAR1 *buffer,
int length,
FLBoolean overwrite)
{
/* Set timeout ot 5 seconds from now */
unsigned long writeTimeout = flMsecCounter + 5000;
FLStatus status;
int i;
FlashWPTR flashWPtr;
int wLength;
/*
printf("Address=%x\n",address);
*/
if (flWriteProtected(vol.socket))
return flWriteProtect;
#ifdef SOCKET_12_VOLTS
if (!(vol.flags & NO_12VOLTS))
checkStatus(flNeedVpp(vol.socket));
#endif
flashWPtr = (FlashWPTR) vol.map(&vol, address,length);
wLength = length>>1;
while (wLength >= 1) {
*flashWPtr = SETUP_WRITE;
*flashWPtr = *(const unsigned short FAR1 *)buffer;
wLength--;
buffer = (const unsigned short FAR1 *) buffer + 1; /* bBuffer++; */
flashWPtr++;
while (!(flashWPtr[-1] & WSM_READY) && flMsecCounter < writeTimeout);
}
flashWPtr -= wLength;
buffer = (unsigned short *)buffer - wLength; /* bBuffer -= length */
status = flOK;
for (i = 0; i < vol.interleaving && i < length; i++) {
if (flashWPtr[i] & WSM_ERROR) {
printf("Debug: write failed for 16-bit Intel media.\n");
status = WSM_ERROR;
flashWPtr[i] = CLEAR_STATUS;
}
flashWPtr[i] = READ_ARRAY;
}
#ifdef SOCKET_12_VOLTS
if (!(vol.flags & NO_12VOLTS))
flDontNeedVpp(vol.socket);
#endif
/* we need this to switch to the read window */
flashWPtr = (FlashWPTR) vol.map(&vol, address,length); /* ADDED */
/* verify the data */
/*
for(i = 0; i < wLength; i++)
{
if (status == flOK && flashWPtr[i] != *((unsigned short *)buffer+i) )
{
printf("Debug: write failed for 16-bit Intel media in verification.\n");
printf("%x,%x", flashWPtr[i], *((unsigned short *)buffer+i) );
status = flWriteFault;
break;
}
}
printf("status:%x\n",status );
*/
return status;
}
/*----------------------------------------------------------------------*/
/* i 2 8 f 0 1 6 E r a s e */
/* */
/* Erase one or more contiguous Flash erasable blocks */
/* */
/* This routine will be registered as the MTD vol.erase routine */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* firstErasableBlock : Number of first block to erase */
/* numOfErasableBlocks: Number of blocks to erase */
/* */
/* Returns: */
/* FLStatus : 0 on success, failed otherwise */
/*----------------------------------------------------------------------*/
static FLStatus i28f016Erase(FLFlash vol,
int firstErasableBlock,
int numOfErasableBlocks)
{
FLStatus status = flOK; /* unless proven otherwise */
int iBlock;
/*
printf("firstErasableBlock=%x\n",firstErasableBlock);
printf("numOfErasableBlocks=%x\n",numOfErasableBlocks);
*/
if (flWriteProtected(vol.socket))
return flWriteProtect;
#ifdef SOCKET_12_VOLTS
checkStatus(flNeedVpp(vol.socket));
#endif
for (iBlock = 0; iBlock < numOfErasableBlocks && status == flOK; iBlock++) {
FlashWPTR currPtr;
int i;
FLBoolean finished;
FlashWPTR flashPtr = (FlashWPTR)
flMap(vol.socket,(firstErasableBlock + iBlock) * vol.erasableBlockSize);
for (i = 0, currPtr = flashPtr;
i < vol.interleaving;
i += 2, currPtr++) {
*currPtr = SETUP_ERASE;
*currPtr = CONFIRM_ERASE;
}
do {
#ifdef BACKGROUND
while (flForeground(1) == BG_SUSPEND) { /* suspend */
for (i = 0, currPtr = flashPtr;
i < vol.interleaving;
i += 2, currPtr++) {
*currPtr = READ_STATUS;
if (!(both(*currPtr) & WSM_READY)) {
*currPtr = SUSPEND_ERASE;
*currPtr = READ_STATUS;
while (!(both(*currPtr) & WSM_READY))
;
}
*currPtr = READ_ARRAY;
}
}
#endif
finished = TRUE;
for (i = 0, currPtr = flashPtr;
i < vol.interleaving;
i += 2, currPtr++) {
*currPtr = READ_STATUS;
if (any(*currPtr) & WSM_SUSPENDED) {
*currPtr = RESUME_ERASE;
finished = FALSE;
}
else if (!(both(*currPtr) & WSM_READY))
finished = FALSE;
else {
if (any(*currPtr) & WSM_ERROR) {
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: erase failed for 16-bit Intel media.\n");
#endif
status = (any(*currPtr) & WSM_VPP_ERROR) ? flVppFailure : flWriteFault;
*currPtr = CLEAR_STATUS;
}
*currPtr = READ_ARRAY;
}
}
} while (!finished);
}
#ifdef SOCKET_12_VOLTS
flDontNeedVpp(vol.socket);
#endif
/*
printf("erase status =%d\n\n",status );
*/
return status;
}
/*----------------------------------------------------------------------*/
/* i 2 8 f 0 1 6 I d e n t i f y */
/* */
/* Identifies media based on Intel 28F016 and registers as an MTD for */
/* such. */
/* */
/* This routine will be placed on the MTD list in custom.h. It must be */
/* an extern routine. */
/* */
/* On successful identification, the Flash structure is filled out and */
/* the write and erase routines registered. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/* Returns: */
/* FLStatus : 0 on positive identificaion, failed otherwise */
/*----------------------------------------------------------------------*/
FLStatus i28f016Identify(FLFlash vol)
{
FlashWPTR flashPtr;
testPtr = &vol;
/*printf("start Identify\n");*/
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: entering 16-bit Intel media identification routine.\n");
#endif
flSetWindowBusWidth(vol.socket,16);/* use 16-bits */
flSetWindowSpeed(vol.socket,120); /* 120 nsec. */
flSetWindowSize(vol.socket,2); /* 8 KBytes */
flashPtr = (FlashWPTR) flMap(vol.socket,0);
vol.noOfChips = 0;
flashPtr[0] = READ_ID;
if (flashPtr[0] == 0x0089 && flashPtr[1] == 0x0017) {
/* Word mode */
vol.type = I28F016_FLASH;
vol.interleaving = 1;
flashPtr[0] = READ_ARRAY;
}
else {
/* Use standard identification routine to detect byte-mode */
flIntelIdentify(&vol, NULL,0);
if (vol.interleaving == 1)
vol.type = NOT_FLASH; /* We cannot handle byte-mode interleaving-1 */
}
if (vol.type == I28F016_FLASH) {
vol.chipSize = 0x00400000L;
vol.erasableBlockSize = 0x20000L * vol.interleaving;
checkStatus(vol.interleaving == 1 ?
i28f016WordSize(&vol) :
flIntelSize(&vol, NULL,0));
/* Register our flash handlers */
vol.write = i28f016Write;
vol.erase = i28f016Erase;
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: identified 16-bit Intel media.\n");
#endif
/*
printf("Identify OK\n");
*/
return flOK;
}
else {
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: failed to identify 16-bit Intel media.\n");
#endif
return flUnknownMedia; /* not ours */
}
}
#if FALSE
/*----------------------------------------------------------------------*/
/* f l R e g i s t e r I 2 8 F 0 1 6 */
/* */
/* Registers this MTD for use */
/* */
/* Parameters: */
/* None */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failure */
/*----------------------------------------------------------------------*/
FLStatus flRegisterI28F016(void)
{
if (noOfMTDs >= MTDS)
return flTooManyComponents;
mtdTable[noOfMTDs++] = i28f016Identify;
return flOK;
}
#endif /* FALSE */
#if 0
void mytest()
{
if(testPtr==NULL)
{
printf("testPtr=NULL\n");
return;
}
printf("type=%x\n",testPtr->type);
printf("chipSize=%x\n",testPtr->chipSize);
printf("interleaving=%x\n",testPtr->interleaving);
}
void myerase(unsigned char blockoffset)
{
tffsShow();
mytest();
i28f016Erase(testPtr,blockoffset,1);
}
void mywrite(unsigned int offset)
{
unsigned short FAR1 buf[5]={0x1111,0x2222,0x3333,0x4444,0x5555};
i28f016Write(testPtr,offset,(const void FAR1 *)buf,5,0);
}
void erasexM(int x)
{
int i;
if(x == 0)
{
x = 1;
}
tffsShow();
mytest();
for(i =0; i< 16*x; i++ )
{
i28f016Erase(testPtr,i,1);
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -