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

📄 k9f1208.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	UINT32 blockpage;
	UINT32 i;
	UINT8 r_ecc0,r_ecc1,r_ecc2;

	blockpage=(block<<5)+page;
	
	/*NF_RSTECC();    */                 /*ECC使能*/
	nand_ce_low();           /*片选有效*/

	nand_write_command(CMD_READ0);   /*从0x00位置开始写一页*/

	nand_ale_high();
	nand_write_address(0x00);                   /*A7-A0为0x00*/
	nand_write_address(blockpage&0xff);   /*A9-A16*/
	nand_write_address((blockpage>>8)&0xff);/*A17-A24*/
	nand_write_address((blockpage>>16)&0x01);  /*A25*/
	nand_ale_low();

	taskDelay(1);
	
	for(i=0;i<512;i++)
	{
		buf_ret[i]=nand_read_data(); /*读取数据*/
		if(buf_ret[i] !=0xaa)
		{
			return -1;
		}
	}
	
	/*读取该页的3个字节ECC(写的时候的ECC)*/
    for(i=0;i<3;i++)
	{
		eccbufr[i]=nand_read_data();
	}
	
	/*printf("W_EEC0:0x%x,W_EEC1:0x%x,W_EEC2:0x%x\n",eccbuf[0],eccbuf[1],eccbuf[2]);
*/
	nand_ce_high(); /*片选取消*/

	if((eccbufr[0]!=eccbufw[0])&&(eccbufr[1]!=eccbufw[1])&&(eccbufr[2]!=eccbufw[2]))
	{
	return -2;
	}
	
	return 0;
	
#if 0	
	/*读出此时的ECC校验码(读出数据后产生的ECC)*/
	r_ecc0=rNF_ECC0;
	r_ecc1=rNF_ECC1;
	r_ecc2=rNF_ECC2;
	
	
	printf("R_ECC0:0x%x,R_EEC1:0x%x,R_EEC2:0x%x\n",r_ecc0,r_ecc1,r_ecc2);
	
	if( (r_ecc0==eccbuf[0]) && (r_ecc1==eccbuf[1]) && (r_ecc2==eccbuf[2]) )
	{
		printf("ECC check is ok\n");
		return TRUE;
	}	
	else 
	{
		printf("ECC check is error\n");
		return FALSE;
	}	
#endif

}

/*********************************************************************************************************
** Function name: nand_write_byte()
** Descriptions:  向某个块的某个页中的某个地址写入n个字节   
** Input: blcok		块地址   (0-4096)
**		  page		页地址   (0-31)
**		  addr      字节地址 (0-527)
**        num       写入字节的个数		
** Output:
** Created by:   
** Created Date: 2007-11-14 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int nand_write_byte(UINT32 block,UINT8 page,UINT32 addr,UINT32 num,UINT8 *buf)
{
	UINT32 blockpage;
	UINT32 i;
	UINT8 status;
	UINT32 n = 0;
	
	blockpage=(block<<5)+page;
	
	/*NF_RSTECC();  */                   /*ECC使能*/
	nand_ce_low();           /*片选有效*/
	
	if(addr>=512)
		nand_write_command(CMD_READOOB);  /*0x50(C区)*/
	else if(addr>=256)
		nand_write_command(CMD_READ1);    /*0x01(B区)*/
	else 
		nand_write_command(CMD_READ0);    /*0x00(A区)*/

	nand_write_command(CMD_SEQIN);		 /* 装载数据命令0x80*/

	nand_ale_high();
	nand_write_address(addr&0xff);    /* 发送地址A0-A7*/
	nand_write_address(blockpage&0xff);	            /* 发送地址A9--A16*/
	nand_write_address((blockpage>>8) & 0xff);	/*发送地址A17--A24*/
	nand_write_address((blockpage>>16) & 0x01);	/* 发送地址A25*/
	nand_ale_low();

	/*load data to nandflash*/
	for(i=0;i<num;i++)	
	{
		nand_write_data(buf[i]);
	}	

#if 0	
	eccbuf[0]=rNF_ECC0;
	eccbuf[1]=rNF_ECC1;
	eccbuf[2]=rNF_ECC2;         //两种方法都可以
	printf("W_EEC0:0x%x,W_EEC1:0x%x,W_EEC2:0x%x\n",eccbuf[0],eccbuf[1],eccbuf[2]);
#endif	
		
	nand_write_command(CMD_PAGEPROG); /*发送编程命令0x10*/

	nand_write_command(CMD_STATUS);	/* 发送读取状态命令0x70  */
	status = nand_read_data();

	/*等待操作完成*/
	while(!(status&0x40)) /* I/O(6) ==1 */
	{
		n++;
		nand_write_command(CMD_STATUS);
		status = nand_read_data();
		if(n>10000)
		{
			printf("nand_write_byte time out!\n");
			break;
		}
	}
		
	nand_ce_high(); /*片选取消*/

	/*printf("status = 0x%x\n",status);*/
	
	if(status&0x01)
	{
		return -1;
	}
	else
	{
		return 0;
	}

}

/*********************************************************************************************************
** Function name: nand_read_byte()
** Descriptions:    从某个块的某个页中的某个地址读出n个字节   
** Input: blcok		块地址   (0-4096)
**		  page		页地址   (0-31)
**		  addr      字节地址 (0-527)
**        num       写入字节的个数		
** Output:
** Created by:   
** Created Date: 2007-10-25 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int nand_read_byte(UINT32 block,UINT8 page,UINT32 addr,UINT32 num,UINT8 *buf_ret)
{
	UINT32 blockpage;
	UINT32 i;
	UINT8 r_ecc0,r_ecc1,r_ecc2;
	UINT8 status;

	int n = 0;
	
	blockpage=(block<<5)+page;

	/*NF_RSTECC();*/                     /*ECC使能*/
	nand_ce_low();           /*片选有效*/
		
	if(addr>=512)
		nand_write_command(CMD_READOOB);  /*0x50(C区)*/
	else if(addr>=256)
		nand_write_command(CMD_READ1);    /*0x01(B区)*/
	else 
		nand_write_command(CMD_READ0);    /*0x00(A区)*/

	nand_ale_high();
	nand_write_address(addr&0xff);                   /*A7-A0*/
	nand_write_address(blockpage&0xff);   /*A9-A16*/
	nand_write_address((blockpage>>8)&0xff);/*A17-A24*/
	nand_write_address((blockpage>>16)&0x01);  /*A25*/
	nand_ale_low();

	taskDelay(1);
	
	for(i=0;i<num;i++)
	{
		buf_ret[i]=nand_read_data(); /*读取数据*/
		printf("data=0x%x\n",buf_ret[i]);
	}
/*
	for(i=0;i<num;i++)
	{
		printf("buf_ret %d = 0x%x\n",i,buf[i]);
	}
*/
	
	nand_ce_high(); /*片选取消*/

	return 0;
#if 0	
	//读出此时的ECC校验码(读出数据后产生的ECC)
	r_ecc0=rNF_ECC0;
	r_ecc1=rNF_ECC1;
	r_ecc2=rNF_ECC2;
	
	
	printf("R_ECC0:0x%x,R_EEC1:0x%x,R_EEC2:0x%x\n",r_ecc0,r_ecc1,r_ecc2);
	
	if( (r_ecc0==eccbuf[0]) && (r_ecc1==eccbuf[1]) && (r_ecc2==eccbuf[2]) )
	{
		printf("ECC check is ok\n");
		return TRUE;
	}	
	else 
	{
		printf("ECC check is error\n");
		return FALSE;
	}	
#endif	

}

/*********************************************************************************************************
** Function name: nand_read_spare_data
** Descriptions:  读出block块中第page页的OOB区的第num个字节   
** Input: blcok		块地址
**		  page		页地址
**        num       第n个字节		
** Output:
** Created by: 
** Created Date:2007-11-14
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
UINT8  nand_read_spare_data(UINT32 block,UINT8 page, UINT8 num)
{
	UINT32 blockpage;
	UINT8 ret_data;
	
	blockpage=(block<<5)+page;

	/* 发送命令和地址*/
	nand_ce_low();           /*片选有效*/
	
	nand_write_command(CMD_READOOB);	 /* 读取空闲区数据*/

	nand_ale_high();
	nand_write_address(num&0x0f);   /* 发送地址地址的A3-A0,A7-A4无效*/
	nand_write_address(blockpage&0xff);	  /* 发送地址A9--A16*/
	nand_write_address((blockpage>>8)&0xff);	/* 发送地址A17--A24*/
	nand_write_address((blockpage>>16)&0x01);	/* 发送地址A25	*/
	nand_ale_low();
	
	taskDelay(1);
	
	ret_data=nand_read_data();  /* 读出一个字节的数据	*/
	
	nand_ce_high(); /*片选取消*/
	
	return ret_data;
}

/*********************************************************************************************************
;** 函数名称: 	nan_poll_bad_blocks
;** 功能描述: 	查询NAN 坏块并保存在缓存区里
;** 
;** 参    数: 	无
;**  
;** 返 回 值: 	无
;**         
;** 作   者: 	
;** 日   期: 	2007年11月14日
;**-------------------------------------------------------------------------------------------------------
;** 修 改 人: 
;** 日   期: 
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
void nan_poll_bad_blocks(void)
{
	UINT16	block_num = 0;
	UINT8	temp = 0;
	BOOL	block_valid = TRUE;
	UINT32	page_num = 0;

	for(block_num = 0; block_num < MAX_BLOCK_NUM; block_num++)
		nan_valid_block_bitmap[block_num] = 0;

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

	for(block_num = 0; block_num < MAX_BLOCK_NUM; block_num++)
	{		
		page_num 	= block_num * 32;
		block_valid 	= TRUE;

		for(temp = 0; temp < 2; temp++)
		{
			nand_write_command(0x50);
			
			nand_ale_high();
			nand_write_address(5);
			nand_write_address(page_num&0xff);
			nand_write_address((page_num>>8)&0xff);
			nand_write_address((page_num>>16)&0x01);
			nand_ale_low();

			page_num++;

			taskDelay(1);

			if(0xff != nand_read_data())
			{
				block_valid = -1;
				break;
			}
		}

		nan_valid_block_bitmap[block_num / 8] |=	block_valid << (block_num % 8);	
	
	}

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

}

/*判断当前块是否为坏块*/
int nand_is_bad_block(UINT32 block)
{
	/*读出每个块的1,2页的起始第517个字节*/
	if((nand_read_spare_data(block,PAGE0,5)!=0xff) 
		|| (nand_read_spare_data(block,PAGE1,5)!=0xff))  
	{
		return 1;
	}

	return 0;
}

/*********************************************************************************************************
** Function name: k9f1208_test
** Descriptions: 主函数,程序入口。            
** Input: 无
** Output: 系统返回值0
** Created by:
** Created Date: 2007-11-14 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int  k9f1208_test(void)
{	
	UINT32 id_code=0;
	UINT32 block_num;
	int page_num;
	UINT8 ret,w_buf[512],r_buf[512];
	UINT32 bad_block_num=0;      /*坏块计数器*/
	UINT32 i=0;
	
	printf("*********************nandflash test******************\n");
	nand_init();   /*nand 初始化*/
	id_code=nand_get_id();  /*读出芯片的ID信息*/
	printf("manufacture id:0x%x,device code:0x%x,",((id_code&0xff000000)>>24),((id_code&0x00ff0000)>>16));
	printf("id_code:0x%x\n",id_code);

	/*/////////////////////erase all block:4096////////////////////////////////////*/
#if 1
	printf("*********************erase all block******************\n");
	for(block_num=0;block_num<MAX_BLOCK_NUM;block_num++)
	{
	 	
	 	ret=nand_erase_block(block_num);
	 	if(-1 == ret)
	 		{
	 			printf("bad block num:%d\n",block_num);
	 		}
	}
	
	printf("erase all block is ok!\n");
	
	/****************************check bad block******************************************************/
	printf("*********************check bad block******************\n");
	for(block_num=0;block_num<MAX_BLOCK_NUM;block_num++)
	{
		if(1 == nand_is_bad_block(block_num))  /*读出每个块的1,2页的起始第517个字节*/
			{
				bad_block_num++;
				printf("block%d is bad\n",block_num);
			}
	}
	printf("total num of bad block is:%d\n",bad_block_num);   /*打印出总的坏块*/

	/*//////////////////////////////////////////////////////////////////////////////////////////////////*/
#endif	
	for(i=0;i<512;i++)
	{
		w_buf[i]=0xaa;              /*初始化写buf,注意uint8只能到0xf,所以后面的是256个字节又重复0-0xff  */
	}
	
	for(i=0;i<512;i++)
	{
		r_buf[i]=0;              /*初始化读buf*/
	}
#if 0	
	ret=nand_erase_block(0);      /*擦除第二块*/
	if(-1 == ret)
	 {
	 	printf("bad block\n");
	 }
	 	
	ret=nand_wite_page(0,0,w_buf);   /*向第2块的第1页写入512字节 */
	if(-1 == ret)
	 {
	 	printf("write page error \n");
	 }
	 	
	nand_read_page(0,0,r_buf);  /*从第2块的第1页读出512字节 */
	for(i=0;i<512;i++)
	{	
		printf("%d**",r_buf[i]);
	}
#endif	
	printf("*********************ECC all block******************\n");
	for(block_num=0;block_num<MAX_BLOCK_NUM;block_num++)
	{
		for(page_num=0;page_num<32;page_num++)
		{
		 	ret = nand_wite_page(block_num,page_num,w_buf);
			if(-1 == ret)
			 {
			 	printf("block_num=%d,page_num=%d :write error!\n",block_num,page_num);
			 }
		}
		for(page_num=0;page_num<32;page_num++)
		{
		 	ret = nand_read_page(block_num,page_num,r_buf);
			if(-1 == ret)
			 {
			 	printf("block_num=%d,page_num=%d :read error!\n",block_num,page_num);
			 }

			if(-2 == ret)
			 {
			 	printf("block_num=%d,page_num=%d :ECC error!\n",block_num,page_num);
			 }
		}

	}


   	return(0);
}

/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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