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

📄 i28f016.c

📁 powerPC866 系列平台BSP移植开发的参考代码
💻 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 + -