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

nor flash 驱动

发布时间:2020-12-15 17:54:51 所属栏目:百科 来源:网络整理
导读:nor flash 驱动 转自:http://www.cnblogs.com/yytblog/archive/2009/09/02/1558943.html Nor Flash 与 Nand flash 的不同之处在于 Nor Flash 的地址和数据线是不共用的,所以 Nor Flash 比较象 ROM, 是可以按地址自由读的,这样就非常适合存储代码,在开机

nor flash 驱动

转自:http://www.cnblogs.com/yytblog/archive/2009/09/02/1558943.html

Nor FlashNand flash的不同之处在于Nor Flash的地址和数据线是不共用的,所以Nor Flash比较象ROM,是可以按地址自由读的,这样就非常适合存储代码,在开机时从Nor Flash中取代码来执行。在我的板子上有16MIntelNor Flash E28F128J3A150,以此为例来研究一下Nor Flash的一些常用操作。E28F128J3A150每个sector128k,擦除是按扇区操作了。

首先来看下E28F128J3A150s3c2410的接口吧。

一般情况下ROMs3c2410的接口我们可以在s3c2410的手册上看到,如下图所示

仔细看下16位和8位数据接口在地址线连接上的区别吧,16位的地址线是要移位的,A1接到A0上,这当然是比较容易理解的,位宽大了一倍,地址就少了一条。对于E28F128J3A150其实也是这样,不过又有点不一样,仔细看看E28F128J3A150的手册吧。下面给出接线图。

?

不同之处E28F128J3A150貌似并没有移位,其实只是因为E28F128J3A150A1就相对于别的16ROMA0,其A0就相当于他们的A(-1)是用来指示8位地址的,所以还是一样的。

来看看Flash操作的命令集吧

以几个比较重要的操作来说明比较容易懂

首先就是Read Identifier Codes

先给定我们的flash开始的地址吧,flash_addr=ioremap(0x0,0x1000000);

物理地址从0x0开始的0x100000016M)地址空间,这样得到了可访问的虚拟地址flash_addr

很简单,看命令表,先写一个命令????? writew(0x90,flash_addr);

然后把Manufacture Code读回来????????????? readw(flash_addr)

接着再读Device Code????????????????????? readw(flash_addr+2);

细节部分还是参考手册吧

其实内核已经MTD驱动完全支持Nor Flash的操作,所以不必要自己再写了。

不过在JTAG烧写flash的程序中可以加入对我们自己的flash的支持。

来看看其中对E28F128J3A150的烧写代码,分析一下。

int Strata_CheckID(int targetAddr) ??????????? //返回Manufacture Code

{

??? _WR(targetAddr,0x0090);???

??? return _RD(targetAddr);????????????????????? //_WR_RD都是半字操作

}

int Strata_CheckDevice(int targetAddr) ????? //返回Device Code

{

??? _WR(targetAddr,0x0090);

??? return _RD(targetAddr+0x2);

}

看着Block Erase Flowchart再对照着Block Erase的函数看就比较能完全看懂了

void Strata_EraseSector(int targetAddress)

{

?? ?unsigned long ReadStatus;

??? unsigned long bSR5;

??? unsigned long bSR7;

??? _WR(targetAddress,0x0020);????? //擦除命令first cycle

??? _WR(targetAddress,0x00d0);??? //擦除命令second cycle

??? _WR(targetAddress,0x0070);????? //读状态寄存器命令

??? ReadStatus=_RD(targetAddress); ?//读状态寄存器

bSR7=ReadStatus & (1<<7);

while(!bSR7 ) ????? //需要判断状态寄存器的第7位

??? {

??????? _WR(targetAddress,0x0070);

??????? ReadStatus=_RD(targetAddress);

??????? bSR7=ReadStatus & (1<<7);

??? }

??? _WR(targetAddress,0x0070);

??? ReadStatus=_RD(targetAddress);?

bSR5=ReadStatus & (1<<5);??????????

if (bSR5==0)

??? {

??????? printf("Block @%xh Erase O.K. "n",targetAddress);

??? }

??? else

??? {

??????? _WR(targetAddress,0x0050);????? //// Clear Status Register

??????? error_erase=1;??

??? }

_RESET();?//就相当于_WR(targetAddress,0x00ff),回到Read Array的状态。

}

很清晰的流程吧。

Byte/Word Program Flowchart

?

共两种Program方式可以把数据写到Flash中,一般也只用到这种就可以了

int Strata_ProgFlash(U32 realAddr,U16 data)

{

??? unsigned long ReadStatus;

??? unsigned long bSR4;?

??? unsigned long bSR7;???

??? _WR(realAddr,0x0040);

??? _WR(realAddr,data);

??? _WR(realAddr,0x0070);

??? ReadStatus=_RD(realAddr);

??? bSR7=ReadStatus & (1<<7);

??? while(!bSR7)

??? {

??????? _WR(realAddr,0x0070);

??????? ReadStatus=_RD(realAddr);

??????? bSR7=ReadStatus & (1<<7);

??? }

??? _WR(realAddr,0x0070);

??? ReadStatus=_RD(realAddr);

??? bSR4=ReadStatus & (1<<4);

??? if (bSR4==0)

??? {

??????? //printf("Successful Program!!"n");

??? }

??? else

??? {

??????? _WR(realAddr,0x0050);????? // Clear Status Register

??????? error_program=1;????????

??? }

??? _RESET();

??? return 0;

}

以上这种写会很慢,以致于JTAG烧写相当得慢。

?

int Strata_unprotect_sector(int targetAddr) ??????? //去除sector的写保护
{
? ?int SR7,SR3,SR4,SR5,ReadStatus;
? ?int res=0;
? ?_WR(targetAddr,0x0050); //Clear Status Register
? ?_WR(targetAddr,0x0060); //First bus cycle
? ?_WR(targetAddr,0x00D0); //Second bus cycle
? ?_WR(targetAddr,0x0070);
? ?ReadStatus=_RD(targetAddr);
? ?SR7=ReadStatus & (1<<7);
? ?while(!SR7)
? ?{
? ? ?_WR(targetAddr,0x0070);
? ? ?ReadStatus=_RD(targetAddr);
? ? ?SR7=ReadStatus & (1<<7);
? ?}?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ?_WR(targetAddr,0x0070);
? ? ?ReadStatus=_RD(targetAddr);
? ? ?SR3=ReadStatus & (1<<3);
? ? ?SR4=ReadStatus & (1<<4);
? ? ?SR5=ReadStatus & (1<<5);
? ? ?if(SR3) {printf("Voltage Range Error"); res=-1;}
? ? ?if(SR4 && SR5) {printf("Command Sequence Error"); res=-2;}
? ? ?if(SR5) {printf("Clear Block Lock-Bits Error"); res=-3;}
? ? ?_RESET();
? ? ?return res;
}

另外按照write to buffer的流程自己写了一个函数,没有test,不想再去烧写了,太烦了,就这样好了。

void Strata_buffer_program(int blockAddress,int tagetAddress,U16* buf)

{

??? unsigned long ReadStatus;

??? unsigned long bSR4;????

??? unsigned long bSR7;

??? int i;

?????? do {

????????????? _WR(blockAddress,0x00E8);

??? ????_WR(blockAddress,0x0070);

??????? ReadStatus=_RD(blockAddress);

??????? bSR7=ReadStatus & (1<<7);

?????? } while(!bSR7);

??? _WR(blockAddress,0x001F);

?????? for(i=0;i<=0x1F;i++)

????????????? _WR(targetAddress+2*i,*(buf+i));

?????? _WR(blockAddress,0x00D0);

?????? do {

??????? _WR(blockAddress,0x0070);

??? ReadStatus=_RD(blockAddress);?

??? bSR4=ReadStatus & (1<<4);?

??? if (bSR4==0)

??? {

??????? //printf("Successful Program!!"n");

??? }

??? else

??? {

??????? _WR(blockAddress,0x0050);

??????? error_program=1;

??? }

??? _RESET();?

}

(编辑:李大同)

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

    推荐文章
      热点阅读