一、擦除nand flash
k9f1208U0M是按块擦除nand flash 的,1 block = 32 page = 32 * 512 byte= 16KB
这里有注意的是擦除的地址绝对要是块对其的,即addr % block == 0
看看datasheet上面擦除block的时序
关于状态的读取
代码如下:
//擦除一个block块
int erase_one_block(int addr)
{
int statu;
addr = addr >> 9;
WRITE_CMD(0x60);//setup cmd
WRITE_ADDR(addr&0xff);//1st Cycle
WRITE_ADDR((addr >> 8)&0xff);//2st Cycle
WRITE_ADDR((addr >> 16)&0xff);//3rd Cycle
WRITE_CMD(0xd0);//erase cmd
while(!NFREADY());//wait ready
statu = read_statu();
if((statu & 0x1) != 0)
return -1;
return 0;
}
/*
* 对nand flash 的一个块进行擦除
* 1 page_size = 512 bye;
* 1 block_size = 32 * page_size = 32 * 512 / 1024 = 16bye;
*/
int nand_erase(int addr,int size)
{
int n = size / BLOCK_SIZE;
int i = 0;
//判断是否是块对齐的地址
if(addr % BLOCK_SIZE != 0)
{
uart0_printf("The addr is invalid,must addr %% 16byte == 0.\r\n");
return -1;
}
if(n < 1)
n = 1;
uart0_printf("Start %#x will %d blocks will be erased.\r\n",addr,n);
NFChipEn();
for(i = 1;i <= n;i ++)
{
if(erase_one_block(addr) < 0)
uart0_printf("Erase failed.\r\n");
uart0_printf("%d block is erased\r",i);
addr = addr + BLOCK_SIZE;
}
uart0_printf("\n");
NFChipDs();
return 0;
}
int read_statu()
{
int statu;
WRITE_CMD(0x70);
delay_mtime(1000);
statu = READ_DATA();
#ifdef _DEBUG_
uart0_printf("statu = %#x.\r\n",statu);
#endif
return statu;
}
二、写nand flash
k9f1208U0M是按页写nand flash 的,1 page = 512 byte
这里有注意的是擦除的地址绝对要是页对其的,即addr % page == 0
看看datasheet上面写一个页的时序
代码如下:
//发送命令和地址
int write_cmd_addr(int addr)
{
int column_addr,page_address;
column_addr = addr % PAGE_SIZE;
page_address = addr >> 9;
WRITE_CMD(0x80);
WRITE_ADDR(column_addr & 0xff);
WRITE_ADDR(page_address & 0xff);
WRITE_ADDR((page_address >> 8) & 0xff);
WRITE_ADDR((page_address >> 16) & 0xff);
return 0;
}
/*
*注意:不管你要写多少个字节,每次写占用的最少
*是一个页的大小。
*/
int write_nand_page(int addr,char str[])
{
int statu,new_addr = addr;
int i = 0,j = 0;
int nbyte = my_strlen(str),n;
uart0_printf("write %d pages.\n",nbyte/PAGE_SIZE);
if(addr % PAGE_SIZE != 0)
{
uart0_printf("The addr is invalid.\r\n");
return -1;
}
/*
*不够一页的按一页处理
*超过一页的按两页处理
*/
n = nbyte / PAGE_SIZE;
if(nbyte % PAGE_SIZE != 0) n ++;
if(n < 1) n = 1;
NFChipEn();
for(i = 0;i < n;i ++)
{
write_cmd_addr(new_addr);
for(j = 0;j < PAGE_SIZE && *str != '\0';j ++,str ++)
{
WRITE_DATA(*str);
}
WRITE_CMD(0x10);
while(!NFREADY());
statu = read_statu();
if((statu & 0x1) != 0)
{
uart0_printf("write error.\r\n");
return -1;
}
new_addr += PAGE_SIZE;
}
#ifdef _DEBUG_
uart0_printf("*str = %c n = %d nbyte = %d.\r\n",*str,n,nbyte);
#endif
uart0_printf("write %d bytes at addr : %#x.\r\n",nbyte,addr);
NFChipDs();
return ;
}