📄 nandflash.c
字号:
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 + -