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

📄 k9f1208.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************Copyright (c)**************************************************
**                              evoc
**                                     
**                                 http://www.evoc.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: main.c
** Last modified Date: 
** Last Version: 
** Description: 
**
**------------------------------------------------------------------------------------------------------
** Created By: kuangyaowen 
** Created date: 2007.12.03
** Version: 
** Descriptions:nand flash 驱动程序
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#include  "config.h"

/*NAND操作定义*/
#define NAND_ADDRESS_BASE	     (0xffe00000)
#define NAND_ALE				(*(volatile unsigned char *)0xffc00002) /*bit 0*/
#define NAND_CLE				(*(volatile unsigned char *)0xffc00002)  /*bit 1*/
#define NAND_CE                              (*(volatile unsigned char *)0xffc00002) /*bit 2*/
#define NANF_CE_LOW()                    NAND_CE = NAND_CE & (~0x4)
#define NANF_CE_HIGH()                    NAND_CE = NAND_CE | 0x4 

/* NAND Flash控制器命令字定义*/
#define   CMD_READ0			0x00 
#define   CMD_READ1			0x01
#define   CMD_PAGEPROG		0x10
#define   CMD_READOOB		0x50
#define   CMD_ERASE1		0x60
#define   CMD_STATUS		0x70
#define   CMD_SEQIN			0x80
#define   CMD_READID		0x90
#define   CMD_ERASE2		0xD0
#define   CMD_RESET			0xFF


#define   MAX_BLOCK_NUM     4096
#define   PAGE0             0
#define   PAGE1             1

UINT8 eccbufw[3]={0xff,0xff,0xff};
UINT8 eccbufr[3]={0,0,0};

#define NAND_READ_DATA()		(*(volatile UINT8 *)NAND_ADDRESS_BASE)	

/*用于存放NAN FLASH 坏块信息*/
UINT8	nan_valid_block_bitmap[MAX_BLOCK_NUM] = {0};

void cle()
{
	int i;

	for(i=0;i<10;i++)
		{
	NAND_CLE =0x55;
	taskDelay(1);
	printf("cle %d= 0x%x\n",i,NAND_CLE);
		}
	
		for(i=0;i<10;i++)
		{
	NAND_CLE =0xaa;
	taskDelay(1);
	printf("cle %d= 0x%x\n",i,NAND_CLE);
		}

}

/*命令锁存(CLE) 取消*/
void nand_cle_low()
{
	int i;
	for(i=0;i<1000;i++)
	{
		NAND_CLE &=~0x2 ;
		
		if((NAND_CLE &0x2) == 0x00)
		{
			break;
		}
	}

	if(i==1000)
	{
		printf("CLE low time out ...\n");
	}
}

/*命令锁存(CLE) 置位*/
void nand_cle_high()
{
	int i;
	for(i=0;i<1000;i++)
	{
		NAND_CLE |=0x2 ;
              
		if((NAND_CLE &0x2) == 0x2)
		{
			break;
		}
	}

	if(i==1000)
	{
		printf("CLE high time out ...\n");
		return;
	}
}

/*地址锁存(ALE) 取消*/
void nand_ale_low()
{
	int i;
	for(i=0;i<1000;i++)
	{
		NAND_ALE &=~0x1 ;
		
		if((NAND_ALE&0x1) == 0x00)
		{
			break;
		}
	}

	if(i==1000)
	{
		printf("ALE low time out ...\n");
	}
}

/*地址锁存(ALE) 置位*/
void nand_ale_high()
{
	int i;
	for(i=0;i<1000;i++)
	{
		NAND_ALE |=0x1 ;
		
		if((NAND_ALE&0x1) == 0x1)
		{
			break;
		}
	}

	if(i==1000)
	{
		printf("ALE high time out ...\n");
		return;
	}
}

/*nand flash片选有效*/
void nand_ce_low()
{
	int i;
		
	for(i=0;i<1000;i++)
	{
		NAND_CE &=~0x4 ;
		
		if((NAND_CE&0x4) == 0x00)
		{
			break;
		}
	}

	if(i==1000)
	{
		printf("CE low time out ...\n");
	}
}

/*nand flash片选取消*/
void nand_ce_high()
{
	int i;
	
	for(i=0;i<1000;i++)
	{
		NAND_CE |=0x4 ;
		
		if((NAND_CE&0x4) == 0x4)
		{
			break;
		}
	}

	if(i==1000)
	{
		printf("CE high time out ...\n");
		return;
	}
}

/*发送nand flash操作命令*/
void nand_write_command(UINT8 command)
{
	nand_cle_high();

	*(volatile UINT8 *)NAND_ADDRESS_BASE = command;
	
	nand_cle_low();
}

/*发送地址*/
void nand_write_address(UINT8 address)
{	
	*(volatile UINT8 *)NAND_ADDRESS_BASE = address;
}

/*读取数据*/
UINT8 nand_read_data()
{
	return (*(volatile UINT8 *)NAND_ADDRESS_BASE);
}

/*发送数据*/
void nand_write_data(UINT8 data)
{
	*(volatile UINT8 *)NAND_ADDRESS_BASE = data;
}

/*复位nand flash芯片*/
void nand_reset()
{
	nand_ce_low();  /*片选有效*/
	nand_write_command(0xff);          /*发送复位命令*/
	taskDelay(2);
	nand_ce_high(); /*片选取消*/
}

/*nand flash操作初始化*/
void nand_init()
{
	sysPciConfigWrite(0,0,0,0xf6,2,0x1440); /*MCCR2 (mpc107)
                                                                bit28-25 :0b1010 (10 clocks) AS rise time
									bit24-21 :0b1010 (10 clocks) AS fall time*/

	nand_cle_low();
	nand_ale_low();
	nand_ce_high();
	
	nand_reset();
}


/*********************************************************************************************************
** Function name: nand_get_id
** Descriptions: 读取器件ID (ID Read1)
** Input: 无
** Output: 返回值即时读出的4字节ID信号 (先读出的数据放在最高字节处)
** Created by: 
** Created Date:2007-11-13 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int nand_get_id(void)
{
	int	id = 0;

	/*发送命令和地址*/
	nand_ce_low();           /*片选有效*/
	
	nand_write_command(CMD_READID);       /*发送读ID命令*/
	
	nand_ale_high();
	nand_write_address(0x00);      /*发送地址0*/
	nand_ale_low();

	taskDelay(1);
		
	/*读取ID信息*/
	id += nand_read_data(); /*manufacture ID*/
	id <<= 8;
	id += nand_read_data(); /*device code*/
	id <<= 8;
	id += nand_read_data(); /**/
	id <<= 8;
	id += nand_read_data(); /**/
	
	nand_ce_high(); /*片选取消*/
	
	return id;
}

/*********************************************************************************************************
** Function name: nand_erase_block
** Descriptions:  块擦除操作
** Input: block:  擦除某个块 (不算空闲区,即64MB的地址)
** Output: 擦除成功返回0,否则返回-1
** Created by:
** Created Date: 2007-11-13
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int nand_erase_block(UINT32 block)
{
	UINT32 blockpage;                  /*块地址*/
	UINT8 status;
	UINT32 n = 0;

	blockpage = block<<5;/*    block 00000 (A8 0000 0000:not send),所以左移5位  */

	/* 发送命令和地 址  */
	nand_ce_low();           /*片选有效*/
	
	nand_write_command(CMD_ERASE1);  /* 发送块擦除命令0x60*/
		
	/*注意只送了3个周期*/
	nand_ale_high();
	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();
	
	nand_write_command(CMD_ERASE2);	    /*0xd0*/

	taskDelay(1);
	
	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_erase_block time out!\n");
			break;
		}
	}
		
	nand_ce_high(); /*片选取消*/

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

}

/*********************************************************************************************************
** Function name: nand_wite_page
** Descriptions:  写一页数据
** Input: block:  块号
		  page    页号
** Output       :          
** Created by:
** Created Date: 2007-11-13 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int nand_wite_page(UINT32 block,UINT8 page,UINT8 *buf)
{
	UINT32 blockpage;
	UINT32 i;
	UINT8 status;
	UINT32 n=0;

	blockpage=(block<<5)+page;
	
	/*NF_RSTECC();*/                     /*ECC使能*/
	nand_ce_low();           /*片选有效*/
	
	nand_write_command(CMD_READ0);  /*从0x00位置开始写一页*/
	nand_write_command(CMD_SEQIN);  /*0x80*/

	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();

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

#if 0	
	/*写OOB区数据,只写前面的三个为了测试*/
	/*
	eccbuf[0]=rNF_ECC0;
	eccbuf[1]=rNF_ECC1;
	eccbuf[2]=rNF_ECC2;         /*两种方法都可以*/
	*/
	i=0x55;
	eccbuf[0]=i&0xff;
	eccbuf[1]=(i>>8)&0xff;
	eccbuf[2]=(i>>16)&0xff;
	printf("W_EEC0:0x%x,W_EEC1:0x%x,W_EEC2:0x%x\n",eccbuf[0],eccbuf[1],eccbuf[2]);
	for(i=0;i<3;i++)
	{
		nand_write_data(eccbuf[i]);
	}
#endif

	for(i=0;i<3;i++)
	{
		nand_write_data(eccbufw[i]);
	}

	nand_write_command(CMD_PAGEPROG); /*发送编程命令0x10*/

	/*taskDelay(1);*/
	
	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_wite_page 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_page
** Descriptions:  读一页数据
** Input: block:  块号 (0-4095)
		  page    页号(0-31)
** Output       :          
** Created by:
** Created Date: 2007-11-14
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int nand_read_page(UINT32 block,UINT8 page,UINT8 *buf_ret)
{

⌨️ 快捷键说明

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