啊,想死,第一次整体的看了一些芯片手册,发现还是挺简单的哈,不,只是看得代码为什么是这么写的了,简单我现在还不可以这么说,不过眼睛的看瞎了。tx板子真的垃圾!真的垃圾!真的垃圾。
我举一个NANDflash来说说吧!
NANDflash流程:首先把NANDflash前4k数据放到内部内存SRAM里面去,然后在SRAM(地址为0)里面初始化外部内存SDRAM(地址为0x30000000),然后把它的4k数据又拷贝到SDRAM里面。
顺便说下norflash:norflash启动直接在norflash(0地址)
大小:256M,数据宽度:8位,有专门的时序控制线,不占系统总线资源。成本低,擦除速度快。
非线性寻址,读操作,一次必须读一个扇区(512字节)。写操作,可按指定地址写入,写之前必须进行擦除操作。
不过我们只读4k到SDRAM上面去4k=4*1024=4096, SDRAM的首地址0x30000000.
主要用到有命令寄存器xxCMD,地址寄存器xxADDR,状态寄存器xxSTATUS,数据寄存器xxDATA等寄存器。
勒,这些都是寄存器,后面是他所对应的地址,地址是有S3C2440芯片手册上知道的。
来咱先看S3C2440,直接看NANFflash的寄存器这里
看吧地址相同吧!好了现在把地址配置好了,其实这些寄存器的目的,我现在认为是为了配置——初始化设备比如NANDFlash,因为NANDflash有很多种功能呀,我们只是配置我们需要的功能,好了,开始配置。
初始化NANDfalsh
static void InitNandCfg(void)
{
// for S3C2440
rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
// Nand_Reset();
}
这些什么意思呢,咱往下看
为什么只用到ACLS,TWRPH,TWRPH呢; 还有HCLK我知道是时钟频率NANDflash和主时钟一样是100hz,duration是什么呢,应该可以在nandflash芯片手册上可以找到,好像应该是什么持续时间的范围吧!我也不太清楚,反正我们只改我们要用的,其他的都是默认就好了,所以就不动他。所以配置寄存器就是配置他下面的东西,使用位运算,这些位是二进制表示的所以就用0/1移位。还有一个寄存器原理也是一样的。
咱们初始化好了,咱们就可以写命令和数据了,也是通过寄存器操作的,就是命令寄存器和数据寄存器,先说写命令。
#define NF_CMD(cmd) {rNFCMD=cmd;}
#define NF_ADDR(addr) {rNFADDR=addr;}
#define NF_RSTECC() {rNFCONT|=(1<<4);}
#define NF_RDDATA() (rNFDATA)
/* #define rNFCMD (*(volatile unsigned *)0x4E000008) //NAND Flash command */
/*********下面是命令指令********/nandflash芯片手册上面有
#define READCMD0 0 //Read0 model command == Page addr 0~127
#define READCMD1 1 //Read1 model command == Page addr 128~511
#define READCMD2 0x50 //Read2 model command == Page addr 512~527
#define READCMD3 0x30 //Read3 model for Large Page
#define ERASECMD0 0x60 //Block erase command 0
#define ERASECMD1 0xd0 //Block erase command 1
#define PROGCMD0 0x80 //page write command 0
#define PROGCMD1 0x10 //page write command 1
#define QUERYCMD 0x70 //query command 读状态命令
#define RdIDCMD 0x90 //read id command
#define RESETCMD 0xFF //reset command
#define NAND_SECTOR_SIZE_LP 2048 这个的意思是读多大的数据 2k
/* 选中芯片 */
nand_select_chip(); //先选中片选
for(i=start_addr; i < (start_addr + size);) {
write_cmd(0); //如果是大页就要有2个cycle,小页一个cycle就好了
write_addr(i); //先发1stcycle 然后发地址
write_cmd(0x30); //然后再发2stcycle
wait_idle(); //查询状态
for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++) { 可以读4k,这里我们只读2k数据
*buf = read_data(); //最后再读数据
buf++;
再分析一个
U32 ReadChipId(void)
{
U32 id;
NF_ChipEn();
NF_CMD(RdIDCMD); //读取ID的命令
NF_ADDR(0); ID的地址为0吧,应该是
while(NFIsBusy()); 等待空闲
id = NF_RDDATA()<<8;//先读高8位
id |= NF_RDDATA(); //然后读低8位
NF_ChipDs();
return id;
}