tffmtd.c

来自「vxWorks Mtd,issued version.」· C语言 代码 · 共 399 行

C
399
字号
*************************************************************************************************************************************************/ #ifdef	__cplusplusextern "C"{#endif#include "tffs/flflash.h"#include "tffs/backgrnd.h"#include "stdio.h"#include "taskLib.h"#define TIME_OUT 				(2000000*100)#define AM29LV320_START_ADDR 	0x51000000 /*flash base addr*//* Addresses */#define ADDR_MANUFACTURER_ID	0x0000#define ADDR_DEVICE_ID			0x0001#define ADDR_SECTOR_LOCK		0x0002#define ADDR_HANDSHAKE			0x0003#define ADDR_UNLOCK_1			0x0555#define ADDR_UNLOCK_2			0x02AA/* Commands */#define CMD_UNLOCK_DATA_1		0xAAAA#define CMD_UNLOCK_DATA_2		0x5555#define CMD_MANUFACTURER_UNLOCK_DATA	0x9090#define CMD_UNLOCK_BYPASS_MODE		0x2020#define CMD_PROGRAM_UNLOCK_DATA		0xA0A0#define CMD_RESET_DATA			0xF0F0#define CMD_SECTOR_ERASE_UNLOCK_DATA	0x8080#define CMD_SECTOR_ERASE_UNLOCK_DATA_2	0x3030#define CMD_CHIP_ERASE_UNLOCK_DATA_2	0x1010#define CMD_AUTOSELECT             0x9090#define AMD_READ_ARRAY		0xf0#define MANUFACTURER_ID 0x0001#define AM29LV320DB_ID	0x22F9#define AM29LV320MB_ID	0x227E/* Return codes from flash_status */#define STATUS_READY    0       /* ready for action */#define STATUS_BUSY     1       /* operation in progress */#define STATUS_ERSUSP   2       /* erase suspended */#define STATUS_TIMEOUT  3       /* operation timed out */#define STATUS_ERROR    4       /* unclassified but unhappy status */#undef MY_TFFS_DEBUG#ifdef MY_TFFS_DEBUG#define DEBUG_PRINT	printf#endif/*var*//*function declare*/LOCAL UINT8 AFlashStatus(UINT16 *flashptr);/******************************************************************** Function Name : static void FAR0 * am29lv320MTDMap()* Description : A pointer to the flash memory map function,maps flash 				into an area of memory * Input : * Output : none* Returns : the only thing the map routine needs to do is to return 			a pointer to the specified address in flash memory* Options : none*******************************************************************/static void FAR0 * am29lv320MTDMap(FLFlash vol, CardAddress addr, int inter){    UINT32 ret;    ret = AM29LV320_START_ADDR + addr;#ifdef MY_TFFS_DEBUG  DEBUG_PRINT("Debug: in i28f320MTDMap ret=0x%x\n",ret);#endif    vol.socket->remapped = TRUE;    return (void FAR0 *)ret;}/******************************************************************** Function Name :LOCAL UINT8 AFlashStatus(UINT16 *flashptr)* Description :  Flash_status utilizes the DQ6, DQ5, and DQ3 polling algorithms described *                in the flash data book.  It can quickly ascertain the  operational status*                of the flash device, and return an appropriate status code                    * Input : toggle address* Output :none* Returns :toggle satatus* Options : none*******************************************************************/ LOCAL UINT8 AFlashStatus(UINT16 *flashptr){	UINT16 data,temp;	ULONG retry =0;		taskDelay(0);		while(retry++<TIME_OUT)	{	 data = *flashptr;        /* read data */	 temp = data ^ *flashptr;    /* read it again and see what toggled */	 taskDelay(0);	 	 if (temp == 0)	  {           /* no toggles, nothing's happening */		return STATUS_READY;	  }	 else if (temp == 0x04)	  { /* erase-suspend */	   if(retry==TIME_OUT)		return STATUS_ERSUSP;	  }	 else if (temp & 0x40)	  {		if (data & 0x20)		 {     /* timeout */		  if(retry==TIME_OUT)		   return STATUS_TIMEOUT;		 }	    else	  	 {	  	  if(retry==TIME_OUT)	       return STATUS_BUSY;	     }	  }	}     /*cann't run here*/   return STATUS_ERROR;}/******************************************************************** Function Name : static FLStatus am29lv320Write(FLFlash vol,CardAddress address,			   const void FAR1 *buffer,int length,FLBoolean overwrite)* Description : Write a block of bytes to Flash* Input : 	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	* Output : none* Returns : 0 on success, failed otherwise* Options : none*******************************************************************/static FLStatus am29lv320Write(FLFlash vol,			   CardAddress address,			   const void FAR1 *buffer,			   int length,			   FLBoolean overwrite){  int cLength;  FLStatus status = flOK;  FlashWPTR flashPtr,flashTmp;  volatile UINT16 *gBuffer;   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 	flashTmp = flashPtr = (FlashWPTR) vol.map(&vol, address, vol.interleaving);  	#ifdef MY_TFFS_DEBUG  DEBUG_PRINT("Debug: entering i28f320Write,flashPtr=0x%x address=0x%x\n",(UINT32)flashPtr,(unsigned int)address);#endif    cLength = length/2;    gBuffer = (UINT16 *)buffer;          while (cLength > 0) 	{   		*((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_UNLOCK_DATA_1;          /*解锁.*/		*((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_2) = CMD_UNLOCK_DATA_2;            	*((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_PROGRAM_UNLOCK_DATA;		*flashPtr = *gBuffer;                                                    /*写入数据.*/				if(AFlashStatus((UINT16 *)flashPtr)!=STATUS_READY)             /*检测写入是否成功.*/		{		 printf("failed: write flash may failed at:0x%x.\n", (int)flashPtr);		 return(ERROR);		}		cLength--;		flashPtr++;		gBuffer++;	}		#ifdef SOCKET_12_VOLTS  flDontNeedVpp(vol.socket);#endif   /* verify the data */  if (status == flOK && tffscmpWords((void FAR0 *) flashTmp, (void FAR1 *) buffer,length)) {  #ifdef MY_TFFS_DEBUG    DEBUG_PRINT("Debug: write failed for 16-bit am29lv320 media in verification.\n");  #endif    status = flWriteFault;  }  return status;}/******************************************************************** Function Name : static FLStatus am29lv320Erase(FLFlash vol,			   int firstErasableBlock,int numOfErasableBlocks)* Description : Erase one or more contiguous Flash erasable blocks* Input : 	vol		: 			 Pointer identifying drive			*      		firstErasableBlock : Number of first block to erase		*			numOfErasableBlocks: Number of blocks to erase		* Output : none* Returns : FLStatus	: 0 on success, failed otherwise* Options : This routine will be registered as the MTD vol.erase routine*******************************************************************/static FLStatus am29lv320Erase(FLFlash vol,			   int firstErasableBlock,			   int numOfErasableBlocks){  FLStatus status = flOK;	/* unless proven otherwise */  FlashWPTR flashPtr;  UINT32 addr;  int i,flag;    if (flWriteProtected(vol.socket))    return flWriteProtect;    #ifdef SOCKET_12_VOLTS  checkStatus(flNeedVpp(vol.socket));#endif  /*flashPtr = (FlashWPTR) flMap(vol.socket,(firstErasableBlock) * vol.erasableBlockSize);*/  flashPtr = (FlashWPTR) vol.map (&vol,(firstErasableBlock) * vol.erasableBlockSize,vol.interleaving);#ifdef MY_TFFS_DEBUG  DEBUG_PRINT("Debug: entering i28f320Erase,flashPtr=0x%x firstErasableBlock=0x%x numOfErasableBlocks=0x%x\n",(UINT32)flashPtr,               firstErasableBlock,numOfErasableBlocks);#endif  	  for(i=0;i<numOfErasableBlocks;i++)   {	addr = (UINT32)flashPtr + (UINT32)(i * vol.erasableBlockSize);    *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_UNLOCK_DATA_1;			/*连续解锁.*/	*((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_2) = CMD_UNLOCK_DATA_2;	*((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_SECTOR_ERASE_UNLOCK_DATA;	*((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_UNLOCK_DATA_1;	*((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_2) = CMD_UNLOCK_DATA_2;		flag=AFlashStatus((UINT16 *)flashPtr);		*(volatile UINT16 *)flashPtr = CMD_SECTOR_ERASE_UNLOCK_DATA_2;			/*写入擦除命令.*/	if((flag=AFlashStatus((UINT16 *)flashPtr))!=STATUS_READY)	 {	  if(flag==STATUS_TIMEOUT)	  {	   printf("warning: Chip Erase time out!\n");		   return ERROR;	  }	  else if(flag==STATUS_BUSY)	  {		   printf("warning: Chip Erase busy!\n");		   return ERROR;	  }	  else if(flag==STATUS_ERSUSP)	  {	   printf("warning: Chip Erase suspended!\n");	   return ERROR;	  }	  else	  {	   ;	  }	 }   }#ifdef SOCKET_12_VOLTS  flDontNeedVpp(vol.socket);#endif  return status;}/******************************************************************** Function Name : FLStatus am29lv320Identify(FLFlash vol)* Description : Identifies media based on am29lv320Identify and registers as an MTD * Input : 	vol	: Pointer identifying drive	* Output : none* Returns : FLStatus	: 0 on positive identificaion, failed otherwise* Options : This routine will be placed on the MTD list in custom.h. It must be	*			an extern routine.*******************************************************************/FLStatus am29lv320Identify(FLFlash vol){  FlashWPTR flashPtr;  UINT16 manCode=0;  UINT16 devCode=0;#ifdef MY_TFFS_DEBUG  DEBUG_PRINT("Debug: entering 16-bit am29lv320 media identification routine.\n");#endif  flSetWindowBusWidth(vol.socket,16);/* use 16-bits */  flSetWindowSpeed(vol.socket,120);  /* 120 nsec. */  flSetWindowSize(vol.socket,2);	/*  KBytes */   /* flashPtr = (FlashWPTR) flMap(vol.socket,(CardAddress)0);*/  flashPtr = (FlashWPTR)vol.map (&vol, (CardAddress)0, vol.interleaving);     *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_UNLOCK_DATA_1;         /*解锁.*/  *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_2) = CMD_UNLOCK_DATA_2;#ifdef MY_TFFS_DEBUG  DEBUG_PRINT("Debug: in am29lv320Identify flashPtr=0x%x\n",(UINT32)flashPtr);#endif  vol.noOfChips = 0;  *((volatile UINT16 *)AM29LV320_START_ADDR + ADDR_UNLOCK_1) = CMD_AUTOSELECT;  manCode=*((volatile UINT16*)(flashPtr+ADDR_MANUFACTURER_ID));  devCode=*((volatile UINT16*)(flashPtr+ADDR_DEVICE_ID));  #ifdef MY_TFFS_DEBUG  DEBUG_PRINT("Debug: man_ID=0x%x device_ID=0x%x\n",manCode,devCode);#endif    if (manCode == MANUFACTURER_ID && (devCode==AM29LV320DB_ID || devCode==AM29LV320MB_ID))   {    /* Word mode */    vol.type = MANUFACTURER_ID;    vol.interleaving = 1;    flashPtr[0] = AMD_READ_ARRAY;   }  else   {    if (vol.interleaving == 1)      vol.type = NOT_FLASH;	/* We cannot handle byte-mode interleaving-1 */   }  if (vol.type == MANUFACTURER_ID)   {    vol.chipSize = 0x400000L;    vol.erasableBlockSize = 0x10000L * vol.interleaving;      vol.noOfChips =0x1;	                                              /*one chip.*/        vol.write = am29lv320Write;    vol.erase = am29lv320Erase;    vol.map   = am29lv320MTDMap;    flashPtr[0] = AMD_READ_ARRAY;  #ifdef MY_TFFS_DEBUG    DEBUG_PRINT("Debug: identified 16-bit am29lv320 media.\n");  #endif    return flOK;   }  else   {  #ifdef MY_TFFS_DEBUG    DEBUG_PRINT("Debug: failed to identify 16-bit am29lv320 media.\n");  #endif    return flUnknownMedia; 	/* not ours */   }}#if	1/*----------------------------------------------------------------------*//*                   f l R e g i s t e r 28f320			*//*									*//* Registers this MTD for use						*//*									*//* Parameters:                                                          *//*	None								*//*                                                                      *//* Returns:								*//*	FLStatus	: 0 on success, otherwise failure		*//*----------------------------------------------------------------------*/FLStatus flRegisterAm29lv320(void){  if (noOfMTDs >= MTDS)    return flTooManyComponents;  mtdTable[noOfMTDs++] = am29lv320Identify;  return flOK;}#endif	/* FALSE */#ifdef	__cplusplus}#endif	/* end of __cplusplus */

⌨️ 快捷键说明

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