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

📄 nandflash.c

📁 WINCE4.25.0下的NANDFLASH驱动2k大页面
💻 C
📖 第 1 页 / 共 2 页
字号:
   	    Block_Address = set_block_address(Block_Address,block_count);    //获取模块首地址
   		block_count = 64;
   	    if(check_is_invalid_block(Block_Address) && check_is_invalid_block(Block_Address+1))
			{	
	    		if(bad_block_count == 0)
					{
			    		bad_blocks.value.bad_block = Block_Address;		//添加无效模块表
			    		bad_block_count++;
			    		printf("BAD_BLOCK = %d ,num = %d \n",Block_Address/64,bad_block_count);
					}
				else
					{
			    		struct Invalid_Block * p;
						p = (struct Invalid_Block *)malloc(sizeof(struct Invalid_Block));
						list_table = p;
						list_table->bad_block = Block_Address;
						list_table = p->next;
						bad_block_count++;
						printf("BAD_BLOCK = %d ,num = %d \n",Block_Address/64,bad_block_count);
					}				
			}	
   	}		
	
}

bool check_is_invalid_block(unsigned int Block_Address)
{
    
	int NAND_Addr;
	unsigned char pdes;
	unsigned short Page_Address = 0x07FF; //2048列
	NAND_Addr = (Block_Address << 12) | Page_Address;

	pdes = check_block_read(NAND_Addr);
	
    if((pdes) == 0xFF || (pdes) == 0xFFFF)                    //比较地址后标志。
		{
			return false;
		}
	else						
		return true;
	
}

unsigned int set_block_address(unsigned int Block_Address ,int block_count)
{
    	Block_Address += block_count;
    	return Block_Address;
}



void write_command(unsigned char command)
{	
    data_in_enable(setdata0);
    data_thran_dir(set_dir_out);
    *pNAND_COMMAND_REG = 0x0;
    
    nandflash_ale_off();
    delay(5);
    nandflash_re_off();
    delay(5);
    nandflash_ce_on();
    delay(5);
    nandflash_cle_on();
    delay(5);
    nandflash_we_on();
    delay(5);
    
    write_flash_command(command);
    nandflash_ce_off();
    delay(5);
    nandflash_we_off();
    delay(5);
    nandflash_cle_off();
	delay(5);
}

void write_flash_command(unsigned char write_data)
{
	*pNAND_COMMAND_REG = write_data;
	delay(100);//延迟>30ns
}


void write_addr(int nand_addr)
{
	unsigned char addr1,addr2,addr3,addr4,addr5;
	data_in_enable(setdata0);
	data_thran_dir(set_dir_out);
	*pNAND_ADDRESS_REG = 0x0;
	addr1 = (unsigned char)(nand_addr & 0x000000FF);  //NAND_Address_A0_A7
	addr2 = (unsigned char)((nand_addr >> 8) & 0x0000000F);//NAND_Address_A8_A11
	addr3 = (unsigned char)((nand_addr >> 12) & 0x000000FF);//NAND_Address_A12_A19
	addr4 = (unsigned char)((nand_addr >> 20) & 0x000000FF);//NAND_Address_A20_A27
	addr5 = (unsigned char)((nand_addr >> 28) & 0x00000001);//NAND_Address_A28
	
	nandflash_cle_off();
	delay(5);
	nandflash_re_off();
	delay(5);
	nandflash_ce_on();
	delay(5);
	nandflash_ale_on();
	delay(5);
	nandflash_we_on();

	delay(5);
	write_flash_addr(addr1);
	write_flash_addr(addr2);
	write_flash_addr(addr3);
	write_flash_addr(addr4);
	write_flash_addr(addr5);
	
	nandflash_ce_off();
	delay(5);
	nandflash_we_off();
	delay(5);
	nandflash_ale_off();	
	delay(5);	
}
void write_flash_addr(unsigned char addr)
{
   	*pNAND_ADDRESS_REG = addr;
	delay(100);//延迟>30ns	
}


bool Page_data_read(unsigned int Block_Address,unsigned short Page_Address,unsigned char *pdes)
{
	int i;
	int NAND_Addr;
	NAND_Addr = (Block_Address << 12) | Page_Address;
	int DATA_NUM = 2048 - Page_Address;
	//int DATA_NUM = 5;	
	
  	write_command(0x00);
	write_addr(NAND_Addr);//修改
	write_command(0x30);															

	nandflash_cle_off();
	delay(5);
	nandflash_ale_off();
	delay(5);
	nandflash_we_off();
	delay(5);
	nandflash_ce_on();
	delay(5);
	Wait_NAND_RADY(rb);
	for(i = 0;i<DATA_NUM;i++)
	{
	*(pdes+i) = ReadByte();
	}
	nandflash_ce_off();
	delay(5);
	data_in_enable(setdata0);
	data_thran_dir(set_dir_out);
	return true;

}

bool Page_data_write(unsigned int Block_Address,unsigned short Page_Address,unsigned char *psrc)
{
	int i;
	unsigned char NAND_Data;
	int NAND_Addr;
	int DATA_NUM = strlen(psrc);
	data_in_enable(setdata0);
	data_thran_dir(set_dir_out);

	NAND_Addr = (Block_Address << 12) | Page_Address;
													//	Table.current.value = NAND_Addr;
	write_command(0x80);
	write_addr(NAND_Addr);
	
	delay(50);   //写数据之前均要延迟>100ns
    *pNAND_DATA_REG = 0x0;
    nandflash_ce_on();
    delay(5);
    nandflash_cle_off();
    delay(5);
    nandflash_ale_off();
    delay(5);
    nandflash_re_off();
	delay(5);
    for(i = 0;i<DATA_NUM;i++)
		{
		    delay(100);//写周期>30ns ,max program time= 700 us
		    nandflash_we_on();
		    delay(5);
			*pNAND_DATA_REG = *(psrc+i);
			nandflash_we_off();
			delay(5);
//		    printf("commit data = %x\n",*(psrc+i));
		}
		
	write_command(0x10);
	
	//Wait_NAND_RADY(rb);//页寄存器内部写结束 进入状态读写
	
	NAND_Data = statue_read();

	if(!(NAND_Data & (0x1 << 6)))
    {
        Wait_NAND_RADY(rb);
     }
	if(NAND_Data & (0x1))//0xc0
	   {
	    printf("get write false!\n");
		return false;
	   }
	else 
		return true;
}


bool nd_block_erase(unsigned int Block_Address)
{
	unsigned char NAND_Data = 0;
	unsigned int address;
	address = Block_Address << 12;
	
	write_command(0x60);
	write_addr(address);
	write_command(0xd0);

	delay(500000);//擦除模块延迟<3ms
	
	//前面为擦除执行
	NAND_Data = statue_read();

	if(!(NAND_Data & (0x1 << 6)))
    {
        Wait_NAND_RADY(rb);
     }
	if(NAND_Data & (0x1))//0xc0
	   {
	    printf("get write false!\n");
		return false;
	   }
	else 
		return true;
}

bool Wait_NAND_RADY(int pf)
{
	volatile unsigned short int *tempregister;
    tempregister = FIO1_FLAG_D;
    pf -= 16;
    while(!(*tempregister & (0x1<<pf))) //ready
		{;}
	return true;
}
bool NAND_Finish(int pf)
{
	volatile unsigned short int *tempregister;
    tempregister = FIO1_FLAG_D;
    pf -= 16;
    while(*tempregister & (0x1<<pf))//busy
    	{;}
    return true;
}


unsigned char check_block_read(int NAND_Addr)
{
    unsigned char rdata;
	write_command(0x00);
	write_addr(NAND_Addr);//修改
	write_command(0x30);

	nandflash_cle_off();
	delay(5);
	nandflash_ale_off();
	delay(5);
	nandflash_we_off();
  	delay(5);
	nandflash_ce_on();
	delay(5);
	Wait_NAND_RADY(rb);
	
	rdata = ReadByte();
    nandflash_ce_off();
 	delay(5);
    data_in_enable(setdata0);
	data_thran_dir(set_dir_out);
	return rdata;
}

unsigned char statue_read(void)
{	
    unsigned char rdata;
	write_command(0x70);
	delay(50); //状态寄存器写入延迟
	*pNAND_DATA_REG = 0x0; //清零

	nandflash_cle_off();
	delay(5);
	nandflash_ale_off();
	delay(5);
	nandflash_we_off();
    delay(5);
	nandflash_ce_on();
	delay(5);
	Wait_NAND_RADY(rb);
	
	rdata = ReadByte();
    nandflash_ce_off();
	delay(5);
    data_in_enable(setdata0);
	data_thran_dir(set_dir_out);
	return rdata;	
	
}

unsigned char ReadByte(void)
{
	unsigned char Rdata;

	data_in_enable(setdata1);
	data_thran_dir(set_dir_in);
	

	nandflash_re_on();
	delay(5);
	Rdata = *pNAND_DATA_REG;
	delay(50);//读周期延迟>30ns delay(50) = 1.2us
	nandflash_re_off();
    delay(5);

//	printf("Rdata = %c\n",Rdata);
	return Rdata;
}

bool nandflash_exit()
{
	if(nandflash_ce_off())
		return true;
	else
		return false;
}

⌨️ 快捷键说明

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