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

mini2440硬件篇之Nor Flash

发布时间:2020-12-15 17:22:39 所属栏目:百科 来源:网络整理
导读:1. ? 硬件原理 1.1. ? Nor?Flash 简介 NOR?Flash是Intel在1988年推出的一款商业性闪存芯片,它需要很长的时间进行抹写,大半生它能够提供完整的寻址与数据总线,并允许随机存取存储器上的任何区域,而且它可以忍受一万次到一百万次擦写,是早期的闪存媒体的

1.?硬件原理

1.1.?Nor?Flash简介

NOR?Flash是Intel在1988年推出的一款商业性闪存芯片,它需要很长的时间进行抹写,大半生它能够提供完整的寻址与数据总线,并允许随机存取存储器上的任何区域,而且它可以忍受一万次到一百万次擦写,是早期的闪存媒体的基础。

1.2.?处理器连接

从处理器的角度来看,每个地址对应的是一个BYTE的数据单元。而Nor?Flash的每个地址有可能对应的是一个BYTE的数据单元也有可能对应的是一个HALF-WORD的数据单元。所以在硬件设计中,连接ARM处理器和NFlash时,必须根据实际情况对地址信号做特别的处理。如果ARM处理器外部扩展的是8-BIT的NOR?Flash,数据线和地址线的连接应该如图1所示。从图中我们可以看到,处理器的数据信号D0-D7和Flash的数据信号D0-D7是一一对应连接的,处理器的地址信号A0-An和NOR?Flash的地址信号A0-An也是一一对应连接的。

如果ARM处理器外部扩展的是16-BIT的NFlash,数据线必须要错位连接。图2给了一个ARM处理器和16-BIT?NORFlash的连接示意图。如图2所示,ARM处理器的数据信号D0-D15和Flash的数据信号D0-D15是一一对应的。而ARM处理器的地址信号和NFlash的地址信号是错位连接的,ARM的A0悬空,ARM的A1连接Flash的A0,ARM的A2连接Flash的A1,依次类推。需要错位连接的原因是:ARM处理器的每个地址对应的是一个BYTE的数据单元,而16-BIT的Flash的每个地址对应的是一个HALF-WORD(16-BIT)的数据单元。为了保持匹配,所以必须错位连接。这样,从ARM处理器发送出来的地址信号的最低位A0对16-BITFlash来说就被屏蔽掉了。

补充说明:1、一般来说,ARM处理器内部要设置相应的寄存器,告诉处理器外部扩展的Flash的位宽(8-BIT/16-BIT/32-BIT)。这样,处理器才知道在访问的时候如何从Flash正确的读取数据。2、有些ARM处理器内部可以设置地址的错位。对于支持软件选择地址错位的处理器,在连接16-BITFlash的时候,硬件上可以不需要把地址线错位。3、如果处理器支持内部设置地址错位,在实际访问的时候,送出的地址实际上是在MCU内部做了错位处理,其作用是等效于硬件连接上的错位的。

2.?芯片手册

2.1.?特性

容量2MB扇区分布一个16K,两个8K,一个32K3164K(Boottom?Boot?Device

2.2.?引脚描述

?

2.3.?逻辑图

?

2.4.?设备总线操作

字节还是半字选择,BYET#引脚高,半字;低,字节。开机或复位自动进入读状态写命令序列,绕过解锁模式Unlock?Bypass只需要2个周期,而不是4个周期编程和擦除需要轮询状态位。自动选择模式:读ID,扇区组保护,硅扇区。两种方法进入自动选择模式,编程器电压方式,写命令方式。

2.5.?CFI

2.6.?指令集

见数据手册

2.7.?读

Nor?Flash上电后处于数据读取状态(Reading?Array?Data)。此状态可以进行正常的读,这和读取SDRAM/SRAM/ROM一样。(要是不一样的话,芯片上电后如何从Nor?Flash中读取启动代码)

2.8.?读ID

一般再对Flash进行操作前都要读取芯片信息比如设备号。这样做的主要目的是为了判断自己写的程序是否支持该设备。支持种方式获取号:一种是编程器所用的方法需要高电压(8.5V-12.5V);另一种方法就是所谓的in-system方法,就是在系统中通过的命令寄存器来完成。本文中只对方法进行说明,此时需要切换到自动选择(AutoselectCommand),这要通过发送命令来完成。注意:进入自动选择模式后需要发送复位命令才能回到数据读取状态(ReadingArrayData)

2.9.?擦除

在完成信息获取后一般就要擦除数据。支持扇区擦除(SectorErase)和整片擦除(Chip,这种模式都有对应的命令序列,在完成擦除命令后会自动返回到数据读取状态,在返回前可查询编程的状态。

2.10.?编程

完成擦除后就需要对芯片进行写入操作也就是编程,这就需要进入编程(Program)状态。在完成编程命令后会自动返回到数据读取状态,在返回前可查询编程的状态,注意:编程前一定要先擦除.因为编程只能将'1'改写为'0',通过擦写可以将数据全部擦写为

2.11.?等待操作

Nor?Flash提供几个数据位来确定一个写操作的状态它们分别是:DQ2、DQ3、DQ5、DQ6、DQ7、andRY/BY#。如上图所示其中DQ7,RY/BY#引脚DQ6中的每一个都提供了一种方法来判断一个编程或者擦除操作是否已经完成或正在进行中实际编程中只需要使用其中的一种。
??DQ7:Data#Pollingbit,DQ7在编程时的状态变化。在编程过程中从正在编程的地址中读出的数据的DQ7为要写入数据的补码比如写入的数据为0x0000,及输入的'0',则在编程中读出的数据为'1';当编程完成时读出的数据又变回输入的数据即'0'。在擦除过程中输出为'0';擦除完成后输出为注意读取的地址必须是擦除范围内的地址。RY/BY#:高电平表示'就绪',低电平表示??DQ6:轮转位1(ToggleBit1)。在编程和擦除期间读任意地址都会导致的轮转(0,1间相互变换当操作完成后,停止转换。??DQ2:轮转位2(Toggle2)当某个扇区被选中擦除时读有效地址地址都在擦除的扇区范围内会导致DQ2注意:只能判断一个特定的扇区是否被选中擦除但不能区分这个快是否正在擦除中或者正处于擦除暂停状态相比之下可以区分是否处于擦除中或者擦除状态但不能区分哪个快被选中擦除因此需要这个位来确定扇区和模式状态信息??DQ5超时位(ExceededTimingLimits)当编程或擦除操作超过了一个特定内部脉冲计数是DQ5=1这表明操作失败当编程时把改为就会导致因为只有擦除擦做才能把当错误发生后需要执行复位命令见图1-1)才能返回到读数据状态DQ3:(扇区擦除计时位)SectorEraseTimer只在扇区擦除指令时起作用当擦除指令真正开始工作是DQ3=1此时输入的命令除擦除暂停命令外都被忽略DQ3=0是可以添加附加的扇区用于多扇区擦除以上讲了这些状态为,实际只需要使用几个就行比较简单的就是选择DQ5DQ6/DQ2

?

3.?mini2440电路图

4.?S3C2440寄存器

nor.h

/*******************************************************************
 * Copyright (C),2011-2012, XXX.
 * FileName: nand.h 
 * Author:HuangYinqing
 * Version:1.0
 * Date::2012-04-22
 * Description:nor flash驱动.
 * Function List:
 * History:
 ******************************************************************/

#ifndef __NOR_H__
#define __NOR_H__

/*nor flash调试等级*/
#define DBG_NOR_LEVEL	  	1

#define NOR_TYPE_S29AL016J		0x00012249

/*nor flash信息*/
#define NOR_MAIN_SECT_SIZE		(64*1024)	//==1页2k
#define NOR_SIZE			(2*1024*1024)				//==容量256M
#define NOR_FLASH_BASE	0x00000000								//==nor基地址0

/*命令地址*/
#define NOR_CMD_ADDR1		(*(volatile unsigned short *)(NOR_FLASH_BASE + (0x00000555 << 1)))
#define NOR_CMD_ADDR2		(*(volatile unsigned short *)(NOR_FLASH_BASE + (0x000002AA << 1)))

/*操作命令*/
#define NOR_CMD_UNLOCK1		0x000000AA
#define NOR_CMD_UNLOCK2		0x00000055

#define NOR_CMD_RESET						0xF0
#define NOR_CMD_AUTOSELECT			0x90
#define NOR_CMD_PROGRAM				0xA0
#define NOR_CMD_ERASE_SETUP		0x80
#define NOR_CMD_CHIP_ERASE			0x30
#define NOR_CMD_SECTOR_ERASE	0x10

/*函数*/
void NorTest(void);
void NorInit(void);

#endif 

nor.c
/*******************************************************************
 * Copyright (C),2011-2012, XXX.
 * FileName: nor.h 
 * Author:HuangYinqing
 * Version:1.0
 * Date::2012-04-22
 * Description:nor flashS29AL160J-70TFI02驱动.
 * Function List:
 * History:
 ******************************************************************/
#include "common.h"
#include "core.h"
#include "nor.h"


/********************************************************************
函数功能:nor flash复位。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/ 
void NorReset(void)
{
	*( (volatile U16*)0x0 ) = NOR_CMD_RESET;
}


/********************************************************************
函数功能:nor flash读ID。
入口参数:无。
返    回:设备ID。
备    注:无。
********************************************************************/ 
unsigned long NorReadID(unsigned long *pucIDBuffer)
{
	U32 ulFlashID = 0x0;

	NOR_CMD_ADDR1 = NOR_CMD_UNLOCK1;
	NOR_CMD_ADDR2 = NOR_CMD_UNLOCK2;
	NOR_CMD_ADDR1 = NOR_CMD_AUTOSELECT;
	ulFlashID = (*(volatile unsigned short *)(NOR_FLASH_BASE+ (0x100<<1))) << 16;

	NOR_CMD_ADDR1 = NOR_CMD_UNLOCK1;
	NOR_CMD_ADDR2 = NOR_CMD_UNLOCK2;
	NOR_CMD_ADDR1 = NOR_CMD_AUTOSELECT;	
	ulFlashID |=  (*(volatile unsigned short *)(NOR_FLASH_BASE+ (0x101<<1)));

	*pucIDBuffer = ulFlashID;
//	*pucIDBuffer = (*(volatile unsigned short *)(NOR_FLASH_BASE+ (0x0<<1))) << 16;
//	*pucIDBuffer |=  (*(volatile unsigned short *)(NOR_FLASH_BASE+ (0x1<<1)));

	return ERR_SUCCESS;
}


/********************************************************************
函数功能:读2个字节。
入口参数:
	ulAddr:地址
	pucBuffer:缓冲区
返    回:成功:读取字节数
备    注:无。
********************************************************************/ 
U32 NorReadByte(U32 ulAddr,U16 *punData)
{
	*punData = *( (volatile U16*)(ulAddr) );
	return ERR_SUCCESS;
}

/********************************************************************
函数功能:写nor flash一页数据。(大页)
入口参数:
	ulPageNum:页索引
	pucBuffer:缓冲区
返    回:成功:读取字节数
备    注:无。
********************************************************************/ 
U32 NorWriteByte(U32 ulAddr,U16 unData )
{
	unsigned short unResult;

	NOR_CMD_ADDR1 = NOR_CMD_UNLOCK1;
	NOR_CMD_ADDR2 = NOR_CMD_UNLOCK2;
	NOR_CMD_ADDR1 = NOR_CMD_PROGRAM;
	*( (volatile U16*)(ulAddr) ) = unData;
	do
	{
		udelay(1);
		unResult = *(unsigned short *)ulAddr;
		if( (unResult & 0x80) == (unData & 0x80) )
		{
			break;	
		}
	}while (1);

	return ERR_SUCCESS;
}


/********************************************************************
函数功能:擦除扇区。
入口参数:
	ulBlock:块索引
返    回:成功:0;其他:出错。
备    注:无。
********************************************************************/ 
int NorEraseSector(U32 ulSectAddr)
{
	unsigned short unResult;

 	NOR_CMD_ADDR1 = NOR_CMD_UNLOCK1;
	NOR_CMD_ADDR2 = NOR_CMD_UNLOCK2;
	NOR_CMD_ADDR1 = NOR_CMD_ERASE_SETUP;

 	NOR_CMD_ADDR1 = NOR_CMD_UNLOCK1;
	NOR_CMD_ADDR2 = NOR_CMD_UNLOCK2;
	*( (volatile U16*)(ulSectAddr) ) =  NOR_CMD_SECTOR_ERASE;

	do
	{
		mdelay(5);
		unResult = *(unsigned short *)ulSectAddr;
		if( unResult & 0x80)
		{
			break;	
		}
	}while (1);

	return ERR_SUCCESS;
}


/********************************************************************
函数功能:擦除整块芯片。
入口参数:
	ulBlock:块索引
返    回:成功:0;其他:出错。
备    注:无。
********************************************************************/ 
int NorEraseChip(void)
{
	unsigned short unResult;

 	NOR_CMD_ADDR1 = NOR_CMD_UNLOCK1;
	NOR_CMD_ADDR2 = NOR_CMD_UNLOCK2;
	NOR_CMD_ADDR1 = NOR_CMD_ERASE_SETUP;

 	NOR_CMD_ADDR1 = NOR_CMD_UNLOCK1;
	NOR_CMD_ADDR2 = NOR_CMD_UNLOCK2;
	NOR_CMD_ADDR1 = NOR_CMD_CHIP_ERASE;

	do
	{
		mdelay(5);
		unResult = *( (volatile U16*)(0x0) );
		if( unResult & 0x80)
		{
			break;		 
		}
	}while (1);

	return ERR_SUCCESS;
}


/********************************************************************
函数功能:nor flash初始化。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/ 
void NorInit(void)
{
	unsigned long ulFlashID;
 	DbgPrintX( DBG_NOR_LEVEL,"rnor flash Initn");
	NorReadID( &ulFlashID );
	DbgPrintX( DBG_NOR_LEVEL,"rnor flash ID=%xn",ulFlashID);
	NorReset();
	udelay(100);
}
/********************************************************************
函数功能:测试nor flash。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/ 
void NorTest(void)
{
	int ret;
	unsigned char data[4][1024];

	memset(data,0x86,4*1024);
	NorEraseChip();
#if 0
	ret = NorErase(2);
	if(ret != ERR_SUCCESS)
	{
	 	DbgPrintX( DBG_NAND_LEVEL,"rnor erase err=%2xn",ret);
		return;
	}

	ret = NorWrite( 0x50000,4*1024,(unsigned char *)data );
	if(ret != ERR_SUCCESS)
	{
	 	DbgPrintX( DBG_NAND_LEVEL,"rnor write err=%2xn",ret);
		return;
	}

	ret = NorRead(0x50000,(unsigned char *)0x31000000);
	if(ret != ERR_SUCCESS)
	{
	 	DbgPrintX( DBG_NAND_LEVEL,"rnor read err=%2xn",ret);
		return;
	}
#endif
}


??

(编辑:李大同)

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

    推荐文章
      热点阅读