⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i28f016.c

📁 vxworks tffs for x86
💻 C
字号:
/* * $Log:   P:/user/amir/lite/vcs/i28f016.c_v  $ *  *    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 "flflash.h"#include "backgrnd.h"/* JEDEC ids for this MTD */#define I28F016_FLASH	0x89a0#define SETUP_ERASE	0x2020#define SETUP_WRITE	0x4040#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))/*----------------------------------------------------------------------*//*                    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] == 0x66a0)      break;	  /* We've wrapped around to the first chip ! */    flashPtr[0] = READ_ID;    if (!(flashPtr[0] == 0x0089 && flashPtr[1] == 0x66a0))      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 = flOK;  FlashWPTR flashPtr;  int maxLength, i, from;  if (flWriteProtected(vol.socket))    return flWriteProtect;  if ((length & 1) || (address & 1))	/* Only write words on word-boundary */    return flBadParameter;#ifdef SOCKET_12_VOLTS  checkStatus(flNeedVpp(vol.socket));#endif  maxLength = 256 * vol.interleaving;  for (from = 0; from < length && status == flOK; from += maxLength) {    FlashWPTR currPtr;    unsigned lengthWord;    int tailBytes;    int thisLength = length - from;    if (thisLength > maxLength)      thisLength = maxLength;    lengthWord = (thisLength + vol.interleaving - 1) /		 (vol.interleaving == 1 ? 2 : vol.interleaving) - 1;    if (vol.interleaving != 1)      lengthWord |= (lengthWord << 8);    flashPtr = (FlashWPTR) flMap(vol.socket,address + from);    tailBytes = ((thisLength - 1) & (vol.interleaving - 1)) + 1;    for (i = 0, currPtr = flashPtr;	 i < vol.interleaving && i < thisLength;	 i += 2, currPtr++) {      *currPtr = LOAD_PAGE_BUFFER;      *currPtr = i < tailBytes ? lengthWord : lengthWord - 1;      *currPtr = 0;    }    tffscpyWords((unsigned long FAR0 *) flashPtr,	    (const char FAR1 *) buffer + from,	    thisLength);    for (i = 0, currPtr = flashPtr;	 i < vol.interleaving && i < thisLength;	 i += 2, currPtr++) {      *currPtr = WRITE_PAGE_BUFFER;      if (!((address + from + i) & vol.interleaving)) {	/* Even address */	*currPtr = lengthWord;	*currPtr = 0;      }      else {	/* Odd address */	*currPtr = 0;	*currPtr = lengthWord;      }    }    /* map to the GSR & BSR */    flashPtr = (FlashWPTR) flMap(vol.socket,			       ((address + from) & -vol.erasableBlockSize) +			       4 * vol.interleaving);    for (i = 0, currPtr = flashPtr;	 i < vol.interleaving && i < thisLength;	 i += 2, currPtr++) {      *currPtr = READ_EXTENDED_REGS;      while (!(both(*currPtr) & WSM_READY) && flMsecCounter < writeTimeout)	;      if ((any(*currPtr) & GSR_ERROR) || !(both(*currPtr) & WSM_READY)) {      #ifdef DEBUG_PRINT	DEBUG_PRINT("Debug: write failed for 16-bit Intel media.\n");      #endif	status = flWriteFault;	*currPtr = CLEAR_STATUS;      }      *currPtr = READ_ARRAY;    }  }#ifdef SOCKET_12_VOLTS  flDontNeedVpp(vol.socket);#endif  flashPtr = (FlashWPTR) flMap(vol.socket, address);  /* verify the data */  if (status == flOK && tffscmpWords((void FAR0 *) flashPtr, (void FAR1 *) buffer,length)) {  #ifdef DEBUG_PRINT    DEBUG_PRINT("Debug: write failed for 16-bit Intel media in verification.\n");  #endif    status = flWriteFault;  }  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;  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  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;#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] == 0x66a0) {    /* 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 = 0x200000L;    vol.erasableBlockSize = 0x10000L * 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    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 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -