📄 flflash.c
字号:
FlashPTR flashPtr = (FlashPTR) flMap(vol.socket,idOffset);
unsigned char firstByte = 0;
unsigned char resetCmd = amdCmdRoutine ? AMD_READ_ARRAY : INTEL_READ_ARRAY;
for (inlv = 0; inlv < 15; inlv++) { /* Increase interleaving until failure */
flashPtr[inlv] = resetCmd; /* Reset the chip */
flashPtr[inlv] = resetCmd; /* Once again for luck */
if (inlv == 0)
firstByte = flashPtr[0]; /* Remember byte on 1st chip */
if (amdCmdRoutine) /* AMD: use unlock sequence */
amdCmdRoutine(&vol,idOffset + inlv, READ_ID, flashPtr);
else
flashPtr[inlv] = READ_ID; /* Read chip id */
if (inlv == 0)
vendorId = flashPtr[0]; /* Assume first chip responded */
else if (flashPtr[inlv] != vendorId || firstByte != flashPtr[0]) {
/* All chips should respond in the same way. We know interleaving = n */
/* when writing to chip n affects chip 0. */
/* Get full JEDEC id signature */
vol.type = (FlashType) ((vendorId << 8) | flashPtr[inlv]);
flashPtr[inlv] = resetCmd;
break;
}
flashPtr[inlv] = resetCmd;
}
if (inlv & (inlv - 1))
vol.type = NOT_FLASH; /* not a power of 2, no way ! */
else
vol.interleaving = (word)inlv;
}
/*----------------------------------------------------------------------*/
/* i n t e l S i z e */
/* */
/* Identify the card size for Intel-style Flash. */
/* Sets the value of vol.noOfChips. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* amdCmdRoutine : Routine to read-id AMD/Fujitsu style at */
/* a specific location. If null, Intel procedure */
/* is used. */
/* idOffset : Chip offset to use for identification */
/* */
/* Returns: */
/* FLStatus : 0 = OK, otherwise failed (invalid Flash array)*/
/*----------------------------------------------------------------------*/
FLStatus flIntelSize(FLFlash vol,
void (*amdCmdRoutine)(FLFlash vol, CardAddress,
unsigned char, FlashPTR),
CardAddress idOffset)
{
unsigned char resetCmd = amdCmdRoutine ? AMD_READ_ARRAY : INTEL_READ_ARRAY;
FlashPTR flashPtr = (FlashPTR) vol.map(&vol,idOffset,0);
if (amdCmdRoutine) /* AMD: use unlock sequence */
amdCmdRoutine(&vol,0,READ_ID, flashPtr);
else
flashPtr[0] = READ_ID;
/* We leave the first chip in Read ID mode, so that we can */
/* discover an address wraparound. */
for (vol.noOfChips = 0; /* Scan the chips */
vol.noOfChips < 2000; /* Big enough ? */
vol.noOfChips += vol.interleaving) {
int i;
flashPtr = (FlashPTR) vol.map(&vol,vol.noOfChips * vol.chipSize + idOffset,0);
/* Check for address wraparound to the first chip */
if (vol.noOfChips > 0 &&
(FlashType) ((flashPtr[0] << 8) | flashPtr[vol.interleaving]) == vol.type)
goto noMoreChips; /* wraparound */
/* Check if chip displays the same JEDEC id and interleaving */
for (i = (vol.noOfChips ? 0 : 1); i < vol.interleaving; i++) {
if (amdCmdRoutine) /* AMD: use unlock sequence */
amdCmdRoutine(&vol,vol.noOfChips * vol.chipSize + idOffset + i,
READ_ID, flashPtr);
else
flashPtr[i] = READ_ID;
if ((FlashType) ((flashPtr[i] << 8) | flashPtr[i + vol.interleaving]) !=
vol.type)
goto noMoreChips; /* This "chip" doesn't respond correctly, so we're done */
flashPtr[i] = resetCmd;
}
}
noMoreChips:
flashPtr = (FlashPTR) vol.map(&vol,idOffset,0);
flashPtr[0] = resetCmd; /* reset the original chip */
return (vol.noOfChips == 0) ? flUnknownMedia : flOK;
}
/*----------------------------------------------------------------------*/
/* i s R A M */
/* */
/* Checks if the card memory behaves like RAM */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* */
/* Returns: */
/* 0 = not RAM-like, other = memory is apparently RAM */
/*----------------------------------------------------------------------*/
static FLBoolean isRAM(FLFlash vol)
{
FlashPTR flashPtr = (FlashPTR) flMap(vol.socket,0);
unsigned char firstByte = flashPtr[0];
char writeChar = (firstByte != 0) ? 0 : 0xff;
volatile int zero=0;
flashPtr[zero] = writeChar; /* Write something different */
if (flashPtr[zero] == writeChar) { /* Was it written ? */
flashPtr[zero] = firstByte; /* must be RAM, undo the damage */
DEBUG_PRINT(("Debug: error, socket window looks like RAM.\r\n"));
return TRUE;
}
return FALSE;
}
/*----------------------------------------------------------------------*/
/* f l I d e n t i f y F l a s h */
/* */
/* Identify the current Flash medium and select an MTD for it */
/* */
/* Parameters: */
/* socket : Socket of flash */
/* vol : New volume pointer */
/* */
/* Returns: */
/* FLStatus : 0 = Flash was identified */
/* other = identification failed */
/*----------------------------------------------------------------------*/
FLStatus flIdentifyFlash(FLSocket *socket, FLFlash vol)
{
FLStatus status = flUnknownMedia;
int iMTD;
dword blockSize;
vol.socket = socket;
#ifndef FIXED_MEDIA
/* Check that we have a media */
flResetCardChanged(vol.socket); /* we're mounting anyway */
checkStatus(flMediaCheck(vol.socket));
#endif
#ifdef ENVIRONMENT_VARS
if(flUseisRAM==1)
{
#endif
if ( isRAM(&vol))
return flUnknownMedia; /* if it looks like RAM, leave immediately */
#ifdef ENVIRONMENT_VARS
}
#endif
/* Install default methods */
vol.type = NOT_FLASH;
vol.mediaType = NOT_DOC_TYPE;
vol.pageSize = 0;
vol.flags = 0;
vol.map = flashMap;
vol.read = flashRead;
vol.setPowerOnCallback = setNoCallback;
vol.erase = flashNoErase;
vol.write = flashNoWrite;
vol.readBBT = NULL;
vol.writeIPL = NULL;
vol.readIPL = NULL;
#ifdef HW_OTP
vol.otpSize = NULL;
vol.readOTP = NULL;
vol.writeOTP = NULL;
vol.getUniqueId = NULL;
#endif /* HW_OTP */
#ifdef HW_PROTECTION
vol.protectionBoundries = NULL;
vol.protectionKeyInsert = NULL;
vol.protectionKeyRemove = NULL;
vol.protectionType = NULL;
vol.protectionSet = NULL;
#endif /* HW_PROTECTION */
vol.download = NULL;
vol.enterDeepPowerDownMode = NULL;
#ifndef FL_NO_USE_FUNC
if(flBusConfig[flSocketNoOf(socket)] != FL_ACCESS_USER_DEFINED)
{
vol.memRead = NULL;
vol.memWrite = NULL;
vol.memSet = NULL;
vol.memRead8bit = NULL;
vol.memWrite8bit = NULL;
vol.memRead16bit = NULL;
vol.memWrite16bit = NULL;
vol.memWindowSize = NULL;
vol.memSetGetMode = NULL;
}
#endif /* FL_NO_USE_FUNC */
/* Setup arbitrary parameters for read-only mount */
vol.chipSize = 0x100000L;
vol.erasableBlockSize = 0x1000L;
vol.noOfChips = 1;
vol.interleaving = 1;
vol.noOfFloors = 1;
vol.totalProtectedAreas = 0;
vol.changeableProtectedAreas = 0;
vol.ppp = 5;
vol.firstUsableBlock = 0;
vol.maxEraseCycles = 100000L; /* Defaul for NOR */
/* Attempt all MTD's */
for (iMTD = 0; (iMTD < doc_noOfMTDs) && (status != flOK) &&
(status != flBadDownload); iMTD++)
status = doc_mtdTable[iMTD](&vol);
if (status == flBadDownload)
{
DEBUG_PRINT(("Debug: Flash media reported bad download error.\r\n"));
return flBadDownload;
}
if (status != flOK) /* No MTD recognition */
{
DEBUG_PRINT(("Debug: did not identify flash media.\r\n"));
return flUnknownMedia;
}
/* Calculate erasable Block Size Bits */
for(blockSize = vol.erasableBlockSize>>1,vol.erasableBlockSizeBits = 0;
blockSize>0; vol.erasableBlockSizeBits++,blockSize = blockSize >> 1);
return flOK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -