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

📄 i28f128.c

📁 intel 28f128 flash驱动程序
💻 C
字号:
#include "../../h/tffs/flflash.h"
#include "../../h/tffs/backgrnd.h"
#include "ads860.h"
#include "stdio.h"

#define PROGRAM_TIMEOUT		1000000L
#define TMPL_BUFFER_SIZE          0x20         /* bytes */ 
#define TMPL_WRITE_TO_BUFFER      0x00E8
#define TMPL_SET_READ_CONFIG      0x0003
#define BIG_ENDIAN_ARCHITECTURE		1
#define TMPL_BLOCK_MASK		(0x20000-1)
 #define TMPL_CONFIRM               0x00D0
 #define TMPL_READ_ARRAY            0x00ff 
 
#define I28F128_FLASH	0x8918
#define TMPL_STATUS_READY         0x0080

#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	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 mIsStatusReady(A) ( ( A & TMPL_STATUS_READY ) == TMPL_STATUS_READY )

static FLStatus i28f128WordSize(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] == 0x0018)
      break;	  /* We've wrapped around to the first chip ! */

    flashPtr[0] = READ_ID;
    if (!(flashPtr[0] == 0x0089 && flashPtr[1] == 0x0018))
      break;
    flashPtr[0] = CLEAR_STATUS;
    flashPtr[0] = READ_ARRAY;
  }

  flashPtr = (FlashWPTR) flMap(vol.socket,0);
  flashPtr[0] = READ_ARRAY;
printf("wordsize noofchips=%d,hubing\n",vol.noOfChips);
  return flOK;
}

UINT16 TMPL_ReadStatus ( void )
{
    UINT16 status;
    UINT16 *tmpPtr;
    tmpPtr = (UINT16 *)FLASH_BASE_ADRS;
    *tmpPtr = READ_STATUS;
    status = *tmpPtr;
    return( status );

}
UINT8 TMPL_WaitUntilReady ( UINT32 timeout )
{

   while( timeout )
   {

      if ( mIsStatusReady( TMPL_ReadStatus() ) )
	  {
	     return( TRUE );
	  }

      timeout--;
   }

   return( FALSE );

}
static FLStatus i28f128Write(FLFlash vol,
			   CardAddress address,
			   const void FAR1 *buffer,
			   int length,
			   FLBoolean overwrite)
{
  /* Set timeout ot 5 seconds from now */
  UINT16     writedata;
   UINT16         numitems; 
   UINT32         cmndaddress; 
   UINT32         numwritebytes;
   UINT32         byteswritten;
   UINT8 *buf1;
  FlashWPTR flashPtr;
 #ifdef HUBING_DEBUG 
  printf("enter flash write procedure,address is %d,length is %d,hubing\n",address,length);
#endif
  if (flWriteProtected(vol.socket))
    return flWriteProtect;

#ifdef HUBING_DEBUG   
printf("no protect,hubing\n");
#endif
   cmndaddress = address;
buf1 = (UINT8 *)buffer;

   if ( ( address + length ) > FLASH_SIZE )
   {
	return flBadLength;      
   }

   if ( cmndaddress & 0x01 )
   {
      cmndaddress --;
   }

   if ( !TMPL_WaitUntilReady( PROGRAM_TIMEOUT ) )
   {
	return flDriveNotReady;
   }
   else
   {

      /* if (start address is not TMPL_BUFFER_SIZE-byte aligned ) */

      if ( ( address % TMPL_BUFFER_SIZE ) != 0 )
      {
         /* if ( buffer size is > TMPL_BUFFER_SIZE ) or 
            ( buffer crosses block boundary ) */
         if ( ( length > TMPL_BUFFER_SIZE ) ||
		      ( ( address & 0x1 ) && ( length >= TMPL_BUFFER_SIZE ) ) ||
              ( ( address + length -1 ) > ( address | TMPL_BLOCK_MASK) ) 
            )
		 {
		    /* write partial buffer */
		    numwritebytes = ( TMPL_BUFFER_SIZE - ( address % TMPL_BUFFER_SIZE ) );
         }
		 else
		 {
		    /* write all remaining bytes */
		    numwritebytes = length;
		 }

         byteswritten = numwritebytes;

		 flashPtr = (FlashWPTR) flMap(vol.socket,cmndaddress);
		 *flashPtr = TMPL_WRITE_TO_BUFFER;
		 /*
		 TMPL_WriteF( cmndaddress, TMPL_WRITE_TO_BUFFER );
		*/	
		 numitems = numwritebytes / sizeof(UINT16);

		 if ( ( ( numwritebytes % sizeof(UINT16) ) != 0 ) ||
		        ( ( numwritebytes > 0x01 ) && ( address & 0x01 ) ) )
		 {
	        numitems++;
		 }
		flashPtr = (FlashWPTR) flMap(vol.socket,cmndaddress);
		 *flashPtr = numitems-1;	

		 
	
		 if ( numwritebytes > 0 ) /* while more data to write */ 
		 {
		    while ( numwritebytes > 0 ) /* if more bytes still to write */ 
			{
			   if ( ( address & 0x1 ) != 0 ) /* if destination address is odd */ 
			   {
                      address--;
#if (BIG_ENDIAN_ARCHITECTURE)
					  writedata = (UINT16) *buf1;
					  writedata |= 0xff00;
#else /* little endian */ 
					  writedata = *((UINT16 *)buf1);
					  writedata = ( writedata << 8 ) | 0x00ff;
#endif
					  numwritebytes--;
					  buf1++;
			   }
			   else /* destination address is even */ 
			   {
#if BIG_ENDIAN_ARCHITECTURE
				      /* grab first byte */	
					  writedata = (UINT16)( *buf1 );
					  writedata = ( ( writedata << 8 ) & 0xff00 );
					  /* grab second byte */	
					  writedata = writedata | ( (UINT16) *(buf1+1) );
#else /* little endian architecture */
					  /* grab 2 bytes */
					  writedata = *( (UINT16 *)buf1 ); 
#endif /* BIG_ENDIAN_ARCHITECTURE */ 

					  if ( numwritebytes == 1 ) 
					  {
#if BIG_ENDIAN_ARCHITECTURE
					     writedata |= 0x00ff;
#else
						 writedata |= 0xff00;
#endif
						 numwritebytes--;
					  }
					  else
					  {
					     numwritebytes -= sizeof(UINT16);
					  }

					  buf1 += sizeof(UINT16);
			   }

			   flashPtr = (FlashWPTR) flMap(vol.socket,address);
			   *flashPtr = writedata; 
			   address += sizeof(UINT16);
		    }
		 }
		flashPtr = (FlashWPTR) flMap(vol.socket,cmndaddress);
		 *flashPtr = TMPL_CONFIRM ;

         if ( !TMPL_WaitUntilReady( PROGRAM_TIMEOUT ) )
         {
            
            return flWriteFault;
         }

         length -= byteswritten;

      } /* end if  ( ( address % TMPL_BUFFER_SIZE )  != 0 ) ) */

      /* while bytes remain */
      while ( length != 0 )
	  {
         /* if TMPL_BUFFER_SIZE bytes remain */
         if ( length > TMPL_BUFFER_SIZE )
		 {
		    /* write full TMPL_BUFFER_SIZE-byte buffer */
		    numwritebytes = TMPL_BUFFER_SIZE;
		 }
		 /* else */
		 else
		 {
		    /* write partial buffer */
		    numwritebytes = length;
         }
         /* end if */

         byteswritten = numwritebytes;

         cmndaddress = address;

		 
		 flashPtr = (FlashWPTR) flMap(vol.socket,cmndaddress);
		 *flashPtr = TMPL_WRITE_TO_BUFFER ;
	
		 numitems = numwritebytes / sizeof(UINT16);

		 if ( ( numwritebytes % sizeof(UINT16) ) != 0 )
		 {
	        numitems++;
		 }

		 
		 flashPtr = (FlashWPTR) flMap(vol.socket,cmndaddress);
		 *flashPtr = numitems-1 ;
	
		 if ( numwritebytes > 0 ) /* while more data to write */ 
		 {
		    while ( numwritebytes > 0 ) /* if more bytes still to write */ 
			{ /* address is known even at this point */
#if BIG_ENDIAN_ARCHITECTURE
		       /* grab first byte */	
			   writedata = (UINT16)( *buf1 );
			   writedata = ( ( writedata << 8 ) & 0xff00 );
			   /* grab second byte */	
			   writedata = writedata | ( (UINT16) *(buf1+1) );
#else /* little endian architecture */
			   /* grab 2 bytes */
			   writedata = *( (UINT16 *)buf1 ); 
#endif /* BIG_ENDIAN_ARCHITECTURE */ 

			   if ( numwritebytes == 1 ) 
			   {
#if BIG_ENDIAN_ARCHITECTURE
			      writedata |= 0x00ff;
#else
				  writedata |= 0xff00;
#endif
				  numwritebytes--;
			   }
			   else
			   {
			      numwritebytes -= sizeof(UINT16);
			   }

			   buf1 += sizeof(UINT16);
			   
			   

			   flashPtr = (FlashWPTR) flMap(vol.socket,address);
			   *flashPtr = writedata; 
			   address += sizeof(UINT16);
		    }
		 }

		 flashPtr = (FlashWPTR) flMap(vol.socket,cmndaddress);
		 *flashPtr = TMPL_CONFIRM ;
		

         if ( !TMPL_WaitUntilReady( PROGRAM_TIMEOUT ) )
         {
            
            return flWriteFault;
         }

         length -= byteswritten;

      } /* end while length != 0 ) */

   }/* end if ( !TMPL_WaitUntilReady( PROGRAM_TIMEOUT ) ) */

   
   /* return device to read array mode */
 
	flashPtr = (FlashWPTR) flMap(vol.socket,FLASH_BASE_ADRS);
	*flashPtr = TMPL_READ_ARRAY ;

   return flOK;
  
}
static FLStatus i28f128Erase(FLFlash vol,
			   int firstErasableBlock,
			   int numOfErasableBlocks)
{
  FLStatus status = flOK;	/* unless proven otherwise */
  int iBlock;
#ifdef HUBING_DEBUG
printf("now is erasing,hubing\n");
printf("erase first block=%x,num of block is %x\n",firstErasableBlock,numOfErasableBlocks);
#endif
  if (flWriteProtected(vol.socket))
    return flWriteProtect;


  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 {
      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) {
	    status = (any(*currPtr) & WSM_VPP_ERROR) ? flVppFailure : flWriteFault;
	    *currPtr = CLEAR_STATUS;
	  }
	  *currPtr = READ_ARRAY;
	}
      }
    } while (!finished);
  }


  return status;
}
FLStatus UnLockAllBlocks()
{
	UINT16 *ptr;
	ptr = (UINT16 *)FLASH_BASE_ADRS;
	*ptr = 0x6060;
	*ptr = 0xD0D0;
	if ( !TMPL_WaitUntilReady( PROGRAM_TIMEOUT ) )
   	{
   		printf("unlock err");
		return flDriveNotReady;
   	}
   	printf("unlock all blocks,hubing\n");
   	*ptr = 0xffff;
   	return flOK;
}

static FLStatus i28f128Read(FLFlash vol,CardAddress address,const void FAR1 *buffer,int length,int a)
{
	UINT8 *flashPtr;
	UINT16 worddata;
	int num;
	UINT8 * ramptr;
	flashPtr = (UINT8 *)flMap(vol.socket,address);
	
	ramptr = (UINT8 *)buffer;
	num = 0;
	
	if(length==0)
		return flOK;
	if( ((UINT32)flashPtr)&1 )
	{
		flashPtr--;
		worddata = *((UINT16 *)flashPtr);
		*ramptr++ = (UINT8)(worddata&0xff);
		flashPtr+=2;
		num++;
	}
	for(;num<length-1;num+=2)
	{
		worddata = *((UINT16 *)flashPtr);
		*ramptr++ = (UINT8)((worddata>>8)&0xff);
		*ramptr++ = (UINT8)(worddata&0xff);
		flashPtr += 2;
	}
	if(num != length)
	{
		worddata = *((UINT16 *)flashPtr);
		*ramptr = (UINT8)((worddata>>8)&0xff);
	}
}

FLStatus i28f128Identify(FLFlash vol)
{
  FlashWPTR flashPtr;


	if(UnLockAllBlocks())
	{
		printf("unlock wrong\n");
		return flWriteProtect;
	}
printf("now to identify\n");
  flSetWindowBusWidth(vol.socket,16);/* use 16-bits */
  flSetWindowSpeed(vol.socket,150);  /* 120 nsec. */
  flSetWindowSize(vol.socket,2);	/* 8 KBytes */

  flashPtr = (FlashWPTR) flMap(vol.socket,0);
  printf("the flash base address is %x,hubing\n",flashPtr);

  vol.noOfChips = 1;
  flashPtr[0] = READ_ID;
  if (flashPtr[0] == 0x0089&& flashPtr[1] == 0x0018) {
    /* Word mode */
    vol.type = I28F128_FLASH;
    vol.interleaving = 1;
    flashPtr[0] = READ_ARRAY;
    printf("get the correct flash id\n");
  }
  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 */
      printf("kao,enter other flash config\n");
  }

  if (vol.type == I28F128_FLASH) {
    vol.chipSize = 0x1000000L;
    vol.erasableBlockSize = 0x20000L * vol.interleaving;
/*    checkStatus(vol.interleaving == 1 ?
		i28f128WordSize(&vol) :
		flIntelSize(&vol, NULL,0));*/

    /* Register our flash handlers */
    vol.write = i28f128Write;
    vol.erase = i28f128Erase;
    vol.read = i28f128Read;
printf("flash function assigned\n");
    return flOK;
  }
  else {
    return flUnknownMedia; 	/* not ours */
  }
}

⌨️ 快捷键说明

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