mini2440硬件篇之Nor Flash
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,一个32K31个64K(Boottom?Boot?Device 2.2.?引脚描述? 2.3.?逻辑图? 2.4.?设备总线操作字节还是半字选择,BYET#引脚高,半字;低,字节。开机或复位自动进入读状态。写命令序列,绕过解锁模式Unlock?Bypass只需要2个周期,而不是4个周期编程和擦除需要轮询状态位。自动选择模式:读ID,扇区组保护,硅扇区。两种方法进入自动选择模式,编程器电压方式,写命令方式。 2.5.?CFI2.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中的每一个都提供了一种方法来判断一个编程或者擦除操作是否已经完成或正在进行中实际编程中只需要使用其中的一种。 ? 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 }
??
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |