S5PV210裸机(七):Nand和iNand

本文聚焦210Nand和iNand相关知识。介绍了NandFlash的型号命名、功能、操作流程及相关寄存器,如Nand是矩阵式存储,Page是读写最小单位,Block是擦除最小单位。还阐述了iNand/eMMC/SDCard/MMCCard的特点,以及210SD/iNand寄存器的设置等内容。

        本文主要探讨210Nand和iNand相关知识。

NandFlash
        型号与命
                
K9F2G08:K9F为发行商,2G为Nand大小是2Gbit(256MB),08为Nand是8位(8数据线即接口为8位:传输数据,地址,命令)

        功能
                
Nand是矩阵式存储,每块可存1bit位
                Nand单次访问最小单元为Page,Page大小是2KB+64B,每次读写n*2KB,random read模式可读1字节
                210中 1 block = 64 page,1 Device = 2028 block = 2048 × 64 × 2K = 256MB
                Page是读写最小单位,Block是擦除最小单位
                Nand芯片:Nand存储 + Nand接口
                Nand读写时地址通过IO线发送,地址有30位而IO只有8位,需要多个cycle才能完成
                SoC通过发送命令、地址、数据等信给Nand控制器来访问Nand(接口)

                 I/O8~15用在X16设备且仅用于输入命令和地址,用于数据输入和接口输出

        ECC(软件或硬件寄存器)
                2KB存储数据,64用于管理功能(存储ECC数据、存储坏块标志···),
                读取或写入前后会做校验,校验不通过则证明已损坏,会将坏块信息存储信息到Nand时会产生        

                ECC(校验信息)存储到64字节内,下次读写跳过坏块

        Nand操作流程
              
  坏块检查
                        nand使用前要擦除(块单位),擦除完后全是1,擦除后检测是否为0xff可知是否为坏块

                页写
                        写前需要擦除
                SoC写Flash通过命令线在IO线依次发送写入开始命令、要写入的页地址、要写入数据,写入结束命令
                SOC与Nand建立写入连接后,写入一页数据发给Nand接口,接口接收数据缓冲区,再写入Nand存储区
                nand接收和写入数据需要延时,通过状态寄存器判断是否写完,写完后再发送写入结束命令,再做ECC校验写入是否正常

        擦除
                擦除读写要发送对齐地址

        页读 

        210Nand相关寄存器

                gpio  

                nand configure 

 

 

demo1: 

                nand功能

nand.h

void nand_init(void);

void nand_read_id(void);

int nand_block_erase(unsigned long block_num);

int copy_nand_to_sdram(unsigned char *sdram_addr, unsigned long nand_addr, unsigned long length);

int copy_sdram_to_nand(unsigned char *sdram_addr, unsigned long nand_addr, unsigned long length);

int nand_page_read(unsigned int pgaddr, unsigned char *buf, unsigned int length);

int nand_page_write(unsigned int pgaddr, const unsigned char *buf, unsigned int length);

int nand_random_read(unsigned long pgaddr,unsigned short offset, unsigned char *data);

int nand_random_write(unsigned long pgaddr,unsigned short offset,unsigned char wrdata);

nand.c 

#include "nand.h"
#include "stdio.h"

#define rNFCONF 			( *((volatile unsigned long *)0xB0E00000) )
#define rNFCONT 			( *((volatile unsigned long *)0xB0E00004) )
#define rNFCMMD 			( *((volatile unsigned long *)0xB0E00008) )
#define rNFADDR 			( *((volatile unsigned long *)0xB0E0000C) )
#define rNFDATA 			( *((volatile unsigned long *)0xB0E00010) )
#define rNFDATA8 			( *((volatile unsigned char *)0xB0E00010) )
#define rNFSTAT 			( *((volatile unsigned long *)0xB0E00028) )

#define rMP0_1CON 			( *((volatile unsigned long *)0xE02002E0) )
#define rMP0_2CON 			( *((volatile unsigned long *)0xE0200300) )
#define rMP0_3CON 			( *((volatile unsigned long *)0xE0200320) )

#define MAX_NAND_BLOCK  			  8192 			
#define NAND_PAGE_SIZE  			  2048 			
#define NAND_BLOCK_SIZE 			  64  			

//dealy time(12ns)
#define TACLS    					  1				
#define TWRPH0   					  4
#define TWRPH1   					  1

//command
#define NAND_CMD_READ_1st             0x00			
#define NAND_CMD_READ_2st             0x30

#define NAND_CMD_READ_CB_1st          0x00
#define NAND_CMD_READ_CB_2st          0x35

#define NAND_CMD_RANDOM_WRITE         0x85
#define NAND_CMD_RANDOM_READ_1st      0x05
#define NAND_CMD_RANDOM_READ_2st      0xe0

#define NAND_CMD_READ_ID              0x90
#define NAND_CMD_RESET                0xff
#define NAND_CMD_READ_STATUS          0x70

#define NAND_CMD_WRITE_PAGE_1st       0x80
#define NAND_CMD_WRITE_PAGE_2st       0x10

#define NAND_CMD_BLOCK_ERASE_1st      0x60
#define NAND_CMD_BLOCK_ERASE_2st      0xd0


#define ECC_EN						  (1<<4)
#define CONTROL_EN					  (1<<0)


static void nand_reset(void);
static void nand_wait_idle(void);
static void nand_select_chip(void);
static void nand_deselect_chip(void);
static void nand_send_cmd(unsigned long cmd);
static void nand_send_addr(unsigned long addr);
static unsigned char nand_read8(void);
static void nand_write8(unsigned char data);
static unsigned int nand_read32(void);
static void nand_write32(unsigned int data);

typedef struct nand_id_info
{
	//marker code
	unsigned char IDm; 
	//device code
	unsigned char IDd; 
	unsigned char ID3rd;
	unsigned char ID4th;
	unsigned char ID5th;
}nand_id_info;

//reset  
void nand_reset(void)
{
	nand_select_chip();
	nand_send_cmd(NAND_CMD_RESET);
	nand_wait_idle();
	nand_deselect_chip();
}

//waite busy or read status  over
void nand_wait_idle(void)
{
	unsigned long i;
	while( !(rNFSTAT & (1<<4)) )
		for(i=0; i<10; i++);
}

//connect nand  
void nand_select_chip(void)
{
	unsigned long i;
	rNFCONT &= ~(1<<1);
	for(i=0; i<10; i++);
}

//disconnect nand  
void nand_deselect_chip(void)
{
	unsigned long i = 0;
	rNFCONT |= (1<<1);
	for(i=0; i<10; i++);
}

//send command 
void nand_send_cmd(unsigned long cmd)
{
	unsigned long i = 0;

	rNFCMMD = cmd;
	for(i=0; i<10; i++);
}

//send address  
void nand_send_addr(unsigned long addr)
{
	unsigned long i;
	unsigned long col, row;

	//address of interior page  
	col = addr % NAND_PAGE_SIZE;		
	//address of page  			
	row = addr / NAND_PAGE_SIZE;

	//write Column Address A0~A7  
	rNFADDR = col & 0xff;			
	for(i=0; i<10; i++);		

	//write  Column Address A8~A11  
	rNFADDR = (col >> 8) & 0x0f; 		
	for(i=0; i<10; i++);

	//write Row Address A12~A19	
	rNFADDR = row & 0xff;			
	for(i=0; i<10; i++);

	//write Row Address A20~A27	
	rNFADDR = (row >> 8) & 0xff;
	for(i=0; i<10; i++);

	//write Row Address A28~A30(A28,low level)	
	rNFADDR = (row >> 16) & 0xff;
	for(i=0; i<10; i++);
}

//read nand(word)
unsigned int nand_read32(void)
{
	return rNFDATA;
}

//write nand(word)
void nand_write32(unsigned int data)
{
	rNFDATA = data;
}

//read nand(half word)  
unsigned char nand_read8(void)
{
	return rNFDATA8;
}

//write nand(half word) 
void nand_write8(unsigned char data)
{
	rNFDATA8 = data;
}

//get nand status
unsigned char nand_read_status(void)
{
	unsigned char ch;
	int i;

	//connect nand 
	nand_select_chip();

	//get nand status  
	nand_send_cmd(NAND_CMD_READ_STATUS);
	for(i=0; i<10; i++);
	//read nand
	ch = nand_read8();

	//disconnect nand
	nand_deselect_chip();
	return ch;
}

// nand init
void nand_init(void)
{

	//set read nand signal dealy 
	rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值