加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

nandflash驱动设计

发布时间:2020-12-15 17:37:37 所属栏目:百科 来源:网络整理
导读:一: Nandflash 驱动设计写的流程 1 ,?知道要读的东西??即:芯片选择为 nandflash? 方式: NFCOPNT- 》对应位使有效; 2?? 清除 RnB? 即:使其进入空闲状态?方式: NFCONF —》对应位是空闲(清除要写入 1 才能变 0 ) 3?? 发送页读指令周期 0x00? 方式:?

一:Nandflash驱动设计写的流程

1,?知道要读的东西??即:芯片选择为nandflash?方式:NFCOPNT-》对应位使有效;

2??清除RnB?即:使其进入空闲状态?方式:NFCONF—》对应位是空闲(清除要写入1才能变0

3??发送页读指令周期0x00?方式:?NFCMMD=0x00

4??发送列地址和行地址?方式:NFADDR=addr

????注:?行地址是页号,列地址是页内偏移,若是页读则列地址发送0x00就行

????????若是随机读取则需要定位列地址和行地址

5?发送页读命令周期0x30?方式:NFCMMD=0x30

6?等待RnB??;等待CPU将前面的工作完成之后使RnB进入忙?方式:检测NFSTAT??????中对应位是否为1,为1等待结束,为0等待继续

7?读取数据?方式:?将NFDATA中的数据传给制定缓冲?eg?buff[i]=NFDATA

8?取消nandflash芯片选择?方式:?NFCONT?使对应为无效

我理解的发送两次页读命令周期:第一次发送0x00?是进行读前的准备工作?即找读的地址?等???第二次发送0x30?是进行真正的将数据从nandflash中读取到缓冲中??同理到其他的周期命令中:一般第一次是准备工作,第二次是进行工作

?

二:?一切工作看似已经完成,其实还有,这个可能还是用与其他大部分的驱动程序。那就 是在使用一个设备时要先初始化这个设备,在次?我们要初始化的是nandflash

其实在之前初始化的东西很多,比如在用C编写的话要初始化堆栈。还有要初始化SDRAM????总之一句话那就是用到什么就要先初始化什么

?

1?初始化NFCONFF?其实是初始化NFCONF中的三个位即?TACLS?TWRPH0?TWRPH1

??因为他们三个基本决定了读取数据的一些重要时间:(具体大小需要按照不同类型的nandflash进行计算,但一般原则是它们的值大一点比较稳定)

2??初始化NFCONT?设置REG_nCE位为1?MOND位为1?即?使片选信号无效

并开启控制器

3?复位??

A?选中nandflash芯片?同上

B?清除RnB?同上

C?发送命令?0xffreset?命令周期)

D?等待?RnB?同上

E?取消选中nandflash

三:?在汇编语言中即程序入口处调用读取页的函数,并用相应的寄存器传参;

四:nandflash驱动的写和读差不多:

参考的芯片手册与文档:S3C2440文档;K9GAG08U0Dnandflash芯片文档)

6410210都差不多就是寄存器地址与相应的位需要变一下;

代码如下:

#define?NFCONF?(*(volatile?unsigned?long*)0x4E000000)

#define?NFCONT?(*(volatile?unsigned?long*)0x4E000004)

#define?NFSTAT?(*(volatile?unsigned?char*)0x4E000020)

#define?NFCMD??(*(volatile?unsigned?char*)0x4E000008)

#define?NFADDR?(*(volatile?unsigned?char*)0x4E00000C)

#define?NFDATA?(*(volatile?unsigned?char*)0x4E000010)

?

#define?TACLS?1

#define?TWRPH0?2

#define?TWRPH1?1

?

?

void?select_chip()

{

????NFCONT?&=?~(1<<1);

}

?

void?deselect_chip()

{

????NFCONT?|=?(1<<1);

}

?

void?clear_RnB()

{

???NFSTAT?|=?(1<<2);?

}

?

void?send_cmd(unsigned?cmd)

{

?????NFCMD?=?cmd;

}

?

void?send_addr(unsigned?addr)

{

?????NFADDR?=?addr;

}

?

void?wait_RnB()

{

???while?(!(NFSTAT&(1<<2)))

???{

???????;

???}

}

?

void?nand_reset()

{

????//选中flash

????select_chip();

????

????//清除RnB

????clear_RnB();

????

????

????//发送0xff命令

????send_cmd(0xff);

????

????

????//等待RnB

????wait_RnB();

????

????//取消选中flash

????deselect_chip();

}

?

void?nand_init()

{

????//初始化NFCONF

????NFCONF?=?(TACLS<<12)?|?(TWRPH0<<8)?|?(TWRPH1<<4);

????

????//初始化NFCONT

????NFCONT?=?(1<<0)?|?(1<<1);

????

????//复位

????nand_reset();

}

?

void?NF_PageRead(unsigned?long?addr,unsigned?char*?buff)

{

int?i;

//选中nandflash芯片

select_chip();

//清除RnB

clear_RnB();

//发送命令0x00

send_cmd(0x00);

//发送列地址

send_addr(0x00);

send_addr(0x00);

//发送行地址

send_addr(addr&0xff);

send_addr((addr>>8)&0xff);

send_addr((addr>>16)&0xff);

//发送命令0x30

send_cmd(0x30);

//等待RnB

wait_RnB();

//读取数据

for(i=0;i<2048;i++)

{

???buff[i]?=?NFDATA;??

}

//取消选中nandflash芯片

deselect_chip();

}

?

?

void?nand_to_ram(unsigned?long?start_addr,?unsigned?char*?sdram_addr,?int?size)

{

?????int?i;

?????

for(?i=(start_addr?>>11);?size>0;)

{

????NF_PageRead(i,sdram_addr);

????size?-=?2048;

????sdram_addr?+=?2048;

????i++;

}

}

?

void?NF_Erase(unsigned?long?addr)

{

int?ret;

????????//选中flash芯片

select_chip();

//清除RnB

clear_RnB();

//发送命令0x60

send_cmd(0x60);

//发送行地址

send_addr(addr&0xff);

send_addr((addr>>8)&0xff);

send_addr((addr>>16)&0xff);

//发送命令D0

send_cmd(0xD0);

//等待RnB

wait_RnB();

//发送命令0x70

send_cmd(0x70);

//读取擦除结果

ret?=?NFDATA;

//取消选中flash芯片

deselect_chip();

return?ret;

}

?

int?NF_WritePage(unsigned?long?addr,?unsigned?char*?buff)

{

int?ret;

int?i;

//选中flash芯片

select_chip();

//清除RnB

clear_RnB();

//发送命令0x80

send_cmd(0x80);

//发送列地址

send_addr(0x00);

send_addr(0x00);

//发送行地址

send_addr(addr&0xff);

send_addr((addr>>8)&0xff);

send_addr((addr>>16)&0xff);

//写入数据

for(i=0;i<2048;i++)

{

???NFDATA?=?buff[i];?

}

//发送命令0x10

send_cmd(0x10);

//等待RnB

wait_RnB();

//发送命令0x70

send_cmd(0x70);

//读取写入结果

ret?=?NFDATA;

//取消选中flash芯片

deselect_chip();

return?ret;

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读