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

📄 nandmtd.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	   void                                      			*/
/*									*/
/* Returns:								*/
/*	   TRUE if device is ready                          		*/
/*                                                                      */
/*----------------------------------------------------------------------*/
FLBoolean waitForReady (void)
{
	int val;
	int n=0;

	do
	{
		n++;
		val = readStatus();
		val &= 0x40;    /* R/B 接 I/O(6) 读R/B状态判断设备状态 */ 
		if(n>10000)
		{
			printf("nand_erase_block time out!\n");
			break;
		}

	} while(val == 0);

	return TRUE; 
}

/*----------------------------------------------------------------------*/
/*		          m a k e C o m m a n d				*/
/*									*/
/* Set Page Pointer to Area A, B or C in page.				*/
/*                                                                      */
/* Author: kuangyaowen            Date:2007-11-21                            */
/*                                                                      */
/* Parameters:                                                          */
/*	vol     : Pointer identifying drive			        */
/*	cmd	: receives command relevant to area			*/
/*	addr	: receives the address to the right area.		*/
/*	modes	: mode of operation (EXTRA ...)				*/
/*                                                                      */
/*----------------------------------------------------------------------*/

static void makeCommand (PointerOp *cmd, CardAddress address, int modes)
{
	int bit8;

	if (modes & EXTRA)
	{
		*cmd = AREA_C;
	}
	else
	{ 
		bit8 = (unsigned short)address & 0x100;
		if(bit8 == 0)
		{
			*cmd = AREA_A;
		}
		else
		{
			*cmd = AREA_B;
		}
	}
}


/*----------------------------------------------------------------------*/
/*		          s e t A d d r e s s				*/
/*									*/
/* Latch address to selected flash device.				*/
/*									*/
/* Parameters:                                                          */
/*	address		: address to set.				*/
/*                                                                      */
/*----------------------------------------------------------------------*/

static void setAddress(CardAddress address )
{
	nand_ale_high();
	nand_write_address((unsigned char)address&0xff);
	nand_write_address((unsigned char)(address>>9)&0xff);
	nand_write_address((unsigned char)(address>>17)&0xff);
	nand_write_address((unsigned char)(address>>25)&0x01);
	nand_ale_low();
}


/*----------------------------------------------------------------------*/
/*		          r e a d C o m m a n d				*/
/*									*/
/* Issue read command.							*/
/*									*/
/* Parametes:                                                          	*/
/*      cmd		: Command to issue (according to area). 	*/
/*	address		: address to read from.				*/
/*									*/
/*----------------------------------------------------------------------*/

static void readCommand (PointerOp  cmd, CardAddress address)
{
	nand_write_command (cmd);       /* move flash pointer to respective area of the page*/
	setAddress (address);
	taskDelay(1);
}


/*----------------------------------------------------------------------*/
/*		          w r i t e C o m m a n d			*/
/*									*/
/* Issue write command.							*/
/*									*/
/* Parametes:                                                          	*/
/*      cmd		: Command to issue (according to area). 	*/
/*	address		: address to write to.				*/
/*									*/
/*----------------------------------------------------------------------*/

static void writeCommand (PointerOp  cmd, CardAddress address)
{
	nand_write_command(cmd);       /* move flash pointer to respective area of the page  */
	nand_write_command(SERIAL_DATA_INPUT);       /* start data loading for write  */
	setAddress (address);
}


/*----------------------------------------------------------------------*/
/*		          r e a d S t a t u s				*/
/*									*/
/* Read status of selected flash device.				*/
/*									*/
/* Parameters:								*/
/*									*/
/* Returns:                                                          	*/
/*      Chip status.							*/
/*									*/
/*----------------------------------------------------------------------*/

unsigned char readStatus(void)
{
	unsigned char chipStatus ;

	nand_write_command(READ_STATUS);
	chipStatus = nand_read_data();

	return chipStatus;
}


/*----------------------------------------------------------------------*/
/*		          w r i t e E x e c u t e			*/
/*									*/
/* Execute write.							*/
/*									*/
/* Parametes:								*/
/* Returns:                                                          	*/
/*	FLStatus	: 0 on success, otherwise failed.		*/
/*									*/
/*----------------------------------------------------------------------*/

static FLStatus writeExecute (void)
{
	nand_write_command(SETUP_WRITE);             /* execute page program*/
	waitForReady();

	if(readStatus() & FAIL)
	{
		return flWriteFault ;
	}

	return flOK ;
}



/*----------------------------------------------------------------------*/
/*		          r e a d O n e S e c t o r			*/
/*									*/
/* Read up to one 512-byte block from flash.				*/
/*									*/
/* Parameters:								*/
/*	vol		: Pointer identifying drive			*/
/* 	address	: Address to read from.					*/
/*	buffer	: buffer to read to.					*/
/*	length	: number of bytes to read (up to sector size).		*/
/*	modes	: EDC flag etc.						*/
/*									*/
/* Returns:                                                          	*/
/*	FLStatus: 0 on success, otherwise failed.			*/
/*									*/
/*----------------------------------------------------------------------*/

static FLStatus readOnePage (FLFlash vol,
			     CardAddress address,  /* starting flash address*/
			     char FAR1 *buffer,     /* target buffer */
			     int length,           /* bytes to read */
			     int modes)            /* EDC flag etc.*/
{
	FLStatus  status = flOK;
	PointerOp   cmd;

	int bit8;
	int i=0;
	int j=0;
	int x=0,y=0;

	nand_ce_low();           /*片选有效*/

	/* move flash pointer to areas A,B or C of page*/
	if (modes & EXTRA)
	{
		cmd = AREA_C;
	}
	else
	{ 
		bit8 = (unsigned short)address & 0x100;
		
		if(bit8 == 0)
		{
			cmd = AREA_A;
		}
		else
		{
			cmd = AREA_B;
		}
	}
	
	nand_write_command(cmd);       /* move flash pointer to respective area of the page  */

	nand_ale_high();
	nand_write_address((unsigned char)(address&0xff)); /* A0 ~ A7 */
	nand_write_address((unsigned char)(address>>9)&0xff); /* A9 ~ A16 */
	nand_write_address((unsigned char)(address>>17)&0xff); /* A17 ~ A24 */
	nand_write_address((unsigned char)(address>>25)&0x01); /* A25*/
	nand_ale_low();

	taskDelay(1);
	/*for(i=0;i<10000;i++)
		{
		j=j+1;
		}*/
	
	for(i=0;i<length;i++)
	{
		buffer[i]=nand_read_data(); /*读取数据*/
		/*printf("read:buffer[%d]=0x%x,address=0x%x\n",i,buffer[i],address);*/
	}

	nand_ce_high(); /*片选取消*/

#ifdef DEBUG_PRINT
	printf("READ: address = 0x%x, length = 0x%x,modes = 0x%x\n", address, length,modes);
#endif

	return status;
}

/*----------------------------------------------------------------------*/
/*		          w r i t e O n e S e c t o r			*/
/*									*/
/* Write data in one 512-byte block to flash.				*/
/* Assuming that EDC mode never requested on partial block writes.    	*/
/*                                                                      */
/* Author: kuangyaowen           Date:2007-11-21                            */
/*									*/
/* Parameters:								*/
/*	vol	: Pointer identifying drive			*/
/* 	address	: Address of sector to write to.			*/
/*	buffer	: buffer to write from.					*/
/*	length	: number of bytes to write (up to sector size).		*/
/*	modes	: OVERWRITE, EDC flags etc.				*/
/*									*/
/* Returns:                                                          	*/
/*	FLStatus: 0 on success, otherwise failed.			*/
/*									*/
/*----------------------------------------------------------------------*/
static FLStatus writeOnePage(FLFlash vol,
			     CardAddress address,    /* target flash addres  */
			     const char FAR1 *buffer, /* source RAM buffer   */
			     int length,             /* bytes to write (up to BLOCK) */
			     int modes)              /* OVERWRITE, EDC flags etc.  */
{
	FLStatus    status;
	PointerOp cmd;
	int bit8;
	int i=0;
	int x=0,y=0;


	nand_ce_low();           /*片选有效*/

	/* move flash pointer to areas A,B or C of page  */
	if (modes & EXTRA)
	{
		cmd = AREA_C;
	}
	else
	{ 
		bit8 = (unsigned short)address & 0x100;
		
		if(bit8 == 0)
		{
			cmd = AREA_A;
		}
		else
		{
			cmd = AREA_B;
		}
	}
	
	nand_write_command(cmd);       /* move flash pointer to respective area of the page  */

	nand_write_command(SERIAL_DATA_INPUT);       /* start data loading for write  */

	nand_ale_high();
	nand_write_address((unsigned char)(address&0xff)); /* A0 ~ A7 */
	nand_write_address((unsigned char)(address>>9)&0xff); /* A9 ~ A16 */
	nand_write_address((unsigned char)(address>>17)&0xff); /* A17 ~ A24 */
	nand_write_address((unsigned char)(address>>25)&0x01); /* A25*/
	nand_ale_low();

	/* load data and syndrom*/

	for(i=0;i<length;i++)	
	{
		nand_write_data(buffer[i]);
		/*printf("write:buffer[%d]=0x%x,address=0x%x\n",i,buffer[i],address);*/
	}	

	nand_write_command(SETUP_WRITE);     /* execute page program*/

	waitForReady();

	if(readStatus() & FAIL)
	{
		status = flWriteFault ;
	}
	else
	{
		status = flOK ;
	}


#ifdef DEBUG_PRINT
	printf("WRITE: address = 0x%x, length = 0x%x, mode = %d\n", address, length, modes);
#endif

	nand_ce_high(); /*片选取消*/

	return status;
}


    /* Core MTD methods - read, write and erase */

/*----------------------------------------------------------------------*/
/*		          n a n d  R e a d				*/
/*									*/
/* Read some data from the flash. This routine will be registered as 	*/
/* the read routine for this MTD.					*/
/*                                                                      */
/* Author: kuangyaowen         Date:2007-11-21                            */
/*									*/
/* Parameters:								*/
/*	vol		: Pointer identifying drive			*/
/* 	address	: Address to read from.					*/
/*	buffer	: buffer to read to.					*/
/*	length	: number of bytes to read (up to sector size).		*/
/*	modes	: EDC flag etc.						*/
/*									*/
/* Returns:                                                          	*/
/*	FLStatus: 0 on success, otherwise failed.			*/
/*									*/
/*----------------------------------------------------------------------*/
static FLStatus nandMTDRead(  FLFlash vol,
			 CardAddress address, /* target flash address */
			 void FAR1 *buffer,    /* source RAM buffer  */
			 int length,          /* bytes to write      */
			 int modes)           /* Overwrite, EDC flags etc. */
{
	char FAR1 *temp;
	int readNow;

	  /* read in sectors; first and last might be partial */

	int page = modes & EXTRA ? 16 : 512;
#if 0	  
	if(1==nand_is_bad_block((address&(~page))/32))/*坏块判断*/
	{
	address+=page;
	}
#endif
	readNow = page - ((unsigned short)address & (page - 1));
	temp = (char FAR1 *)buffer;

	for ( ; length > 0 ; )
	{
		if (readNow > length)   /* 如果要读的长度小于一个页面中偏移地址之后的空间大小 */
		{
			readNow = length;  /* 那要读的就是该长度 07-11-21 */
		}   

		/* turn off EDC on partial block read*/   /* 如果要读的长度大于一个页面的大小,就先读一个页面 */
		checkStatus( readOnePage(&vol, address, temp, readNow,
				(readNow != SECTOR_SIZE ? (modes & ~EDC) : modes)) );

		length -= readNow;
		address += readNow;
		temp += readNow;

		/* align at sector */
		readNow = page;
	}

	return flOK ;
}


/*----------------------------------------------------------------------*/
/*		          n a n d W r i t e				*/
/*									*/
/* Write some data to the flash. This routine will be registered as the	*/
/* write routine for this MTD.						*/
/*                                                                      */
/* Author: kuangyaowen             Date:2007-11-21                            */
/*									*/
/* Parameters:								*/
/*	vol	: Pointer identifying drive			*/

⌨️ 快捷键说明

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