📄 flflash.c
字号:
/* * $Log: P:/user/amir/lite/vcs/flflash.c_v $ * * Rev 1.14 08 Aug 2000 11:22:00 chackney * Changed second arameter for ISRAM_WRITE to &flashPtr[0] * * Rev 1.13 03 Nov 1997 16:11:32 danig * amdCmdRoutine receives FlashPTR * * Rev 1.12 10 Sep 1997 16:28:48 danig * Got rid of generic names * * Rev 1.11 04 Sep 1997 18:36:24 danig * Debug messages * * Rev 1.10 18 Aug 1997 11:46:26 danig * MTDidentifyRoutine already defined in header file * * Rev 1.9 28 Jul 1997 14:43:30 danig * setPowerOnCallback * * Rev 1.8 24 Jul 1997 17:54:28 amirban * FAR to FAR0 * * Rev 1.7 07 Jul 1997 15:21:38 amirban * Ver 2.0 * * Rev 1.6 08 Jun 1997 17:03:28 amirban * power on callback * * Rev 1.5 20 May 1997 13:53:34 danig * Defined write/read mode * * Rev 1.4 18 Aug 1996 13:47:24 amirban * Comments * * Rev 1.3 31 Jul 1996 14:30:36 amirban * New flash.erase definition * * Rev 1.2 04 Jul 1996 18:20:02 amirban * New flag field * * Rev 1.1 16 Jun 1996 14:02:20 amirban * Corrected reset method in intelIdentify * * Rev 1.0 20 Mar 1996 13:33:08 amirban * Initial revision. *//************************************************************************//* *//* FAT-FTL Lite Software Development Kit *//* Copyright (C) M-Systems Ltd. 1995-1996 *//* *//************************************************************************/#include "tffs/flflash.h"#define READ_ID 0x90#define INTEL_READ_ARRAY 0xff#define AMD_READ_ARRAY 0xf0#if FALSE/* MTD registration information */extern int noOfMTDs;extern MTDidentifyRoutine mtdTable[];#endif /* FALSE *//*----------------------------------------------------------------------*//* f l a s h M a p *//* *//* Default flash map method: Map through socket window. *//* This method is applicable for all NOR Flash *//* *//* Parameters: *//* vol : Pointer identifying drive *//* address : Card address to map *//* length : Length to map (irrelevant here) *//* *//* Returns: *//* Pointer to required card address *//*----------------------------------------------------------------------*/static void FAR0 *flashMap(FLFlash vol, CardAddress address, int length){ return flMap(vol.socket,address);}/*----------------------------------------------------------------------*//* f l a s h R e a d *//* *//* Default flash read method: Read by copying from mapped address *//* *//* Parameters: *//* vol : Pointer identifying drive *//* address : Card address to read *//* buffer : Area to read into *//* length : Length to read *//* *//*----------------------------------------------------------------------*/static FLStatus flashRead(FLFlash vol, CardAddress address, void FAR1 *buffer, int length, int mode){ tffscpy(buffer,vol.map(&vol,address,length),length); return flOK;}/*----------------------------------------------------------------------*//* f l a s h N o W r i t e *//* *//* Default flash write method: Write not allowed (read-only mode) *//* *//* Parameters: *//* vol : Pointer identifying drive *//* address : Card address to write *//* buffer : Area to write from *//* length : Length to write *//* *//* Returns: *//* Write-protect error *//*----------------------------------------------------------------------*/static FLStatus flashNoWrite(FLFlash vol, CardAddress address, const void FAR1 *from, int length, int mode){ return flWriteProtect;}/*----------------------------------------------------------------------*//* f l a s h N o E r a s e *//* *//* Default flash erase method: Erase not allowed (read-only mode) *//* *//* Parameters: *//* vol : Pointer identifying drive *//* firstBlock : No. of first erase block *//* noOfBlocks : No. of contiguous blocks to erase *//* *//* Returns: *//* Write-protect error *//*----------------------------------------------------------------------*/static FLStatus flashNoErase(FLFlash vol, int firstBlock, int noOfBlocks){ return flWriteProtect;}/*----------------------------------------------------------------------*//* s e t N o C a l l b a c k *//* *//* Register power on callback routine. Default: no routine is *//* registered. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//*----------------------------------------------------------------------*/static void setNoCallback(FLFlash vol){ flSetPowerOnCallback(vol.socket,NULL,NULL);}/*----------------------------------------------------------------------*//* f l I n t e l I d e n t i f y *//* *//* Identify the Flash type and interleaving for Intel-style Flash. *//* Sets the value of vol.type (JEDEC id) & vol.interleaving. *//* *//* 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)*//*----------------------------------------------------------------------*/void flIntelIdentify(FLFlash vol, void (*amdCmdRoutine)(FLFlash vol, CardAddress, unsigned char, FlashPTR), CardAddress idOffset){ int inlv; FlashPTR flashPtr; unsigned char vendorId = 0; unsigned char firstByte = 0; unsigned char resetCmd = amdCmdRoutine ? AMD_READ_ARRAY : INTEL_READ_ARRAY; flNeedVpp (vol.socket); /* ADDED, first thing to do */ flashPtr = (FlashPTR) flMap(vol.socket,idOffset); 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 */ flDelayLoop(2); /* HOOK for VME-177 */ 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 = inlv; flDontNeedVpp (vol.socket); /* ADDED, last thing to do */}/*----------------------------------------------------------------------*//* 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; flNeedVpp (vol.socket); /* ADDED, first thing to do */ 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 */ flDontNeedVpp (vol.socket); /* ADDED, last thing to do */ 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){ volatile unsigned int FAR0 * flashIPtr; unsigned int firstInt; unsigned int writeInt; flNeedVpp (vol.socket); /* ADDED, first thing to do */ flashIPtr = (volatile unsigned int FAR0 *) flMap(vol.socket,0); firstInt = flashIPtr[0]; writeInt = (firstInt != 0x0) ? 0x0 : (unsigned int) -1; ISRAM_WRITE(writeInt, &flashIPtr[0]); /* write something else safe */ flDelayLoop(2); /* HOOK for VME-177 */ if (flashIPtr[0] == writeInt) { /* Was it written ? */ flashIPtr[0] = firstInt; /* must be RAM, undo the damage */ flDontNeedVpp (vol.socket); /* ADDED, last thing to do */#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: error, socket window looks like RAM.\n");#endif return TRUE; } flDontNeedVpp (vol.socket); /* ADDED, last thing to do */ 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; vol.socket = socket;#ifndef FIXED_MEDIA /* Check that we have a media */ flResetCardChanged(vol.socket); /* we're mounting anyway */ checkStatus(flMediaCheck(vol.socket));#endif/*2007-4-12 19:40*/ //if (isRAM(&vol)) // return flUnknownMedia; /* if it looks like RAM, leave immediately *//*2007-4-12 19:40*/ /* Install default methods */ /* Install default methods */ vol.type = NOT_FLASH; vol.flags = 0; vol.map = flashMap; vol.read = flashRead; vol.write = flashNoWrite; vol.erase = flashNoErase; vol.setPowerOnCallback = setNoCallback; /* Attempt all MTD's */ for (iMTD = 0; iMTD < noOfMTDs && status != flOK; iMTD++) status = mtdTable[iMTD](&vol); if (status != flOK) { /* No MTD recognition */ /* Setup arbitrary parameters for read-only mount */ vol.chipSize = 0x100000L; vol.erasableBlockSize = 0x1000; vol.noOfChips = 1; vol.interleaving = 1; #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: did not identify flash media.\n"); #endif return flUnknownMedia; } return flOK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -