Chinaunix首页 | 论坛 | 博客
  • 博客访问: 239704
  • 博文数量: 76
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 440
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-20 14:21
文章分类

全部博文(76)

文章存档

2015年(76)

我的朋友

分类: 其他平台

2015-05-11 14:49:16

#define MEM_SYS_CFG     (*((volatile unsigned long *)0x7E00F120)) //Configure memory subsystem
#define NFCONF          (*((volatile unsigned long *)0x70200000)) //nand flash Configuration register
#define NFCONT          (*((volatile unsigned long *)0x70200004)) //nand flash Control register
#define NFCMMD          (*((volatile unsigned long *)0x70200008)) //nand flash Command register
#define NFADDR          (*((volatile unsigned long *)0x7020000C)) //nand flash Address register
#define NFDATA          (*((volatile unsigned char *)0x70200010)) //nand flash Data register
#define NFSTAT          (*((volatile unsigned long *)0x70200028)) //nand flash Status register

#define TACLS     0
#define TWRPH0    1
#define TWRPH1    0

void nand_select(void)
{
NFCONT &= ~(1<<1); //Force Xm0CSn2 to low(Enable chip select) 
}

void nand_deselect(void)
{
NFCONT |= (1<<1); //Force Xm0CSn2 to High(Disable chip select) 
}

void nand_cmd(unsigned char cmd)
{
NFCMMD = cmd; //set nand flash command value
}

void nand_addr(unsigned char addr)
{
NFADDR = addr; //set nand flash address value
}

unsigned char nand_get_data(void)
{
return NFDATA; //get nand flash data value
}

void wait_ready(void)
{
while ((NFSTAT & 0x1) == 0); //wait till nand flash is ready
}

//reset nand flash
void nand_reset(void)
{
/* 选中 */
nand_select();

/* 发出0xff命令 */
nand_cmd(0xff);

/* 等待就绪 */
wait_ready();

/* 取消选中 */
nand_deselect();
}

//initialize nand flash
void nand_init(void)
{
/* 让xm0csn2用作nand flash cs0 片选引脚 */
MEM_SYS_CFG &= ~(1<<1);

/* 设置时间参数 */
NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4));
NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4));

/* 使能nand flash controller */
NFCONT |= 1;
nand_reset();
}

//because I can't find data sheet of K9GAG08U0A, so I can only refer to data sheet of K9GAG08U0D
//some details are different but the theories are the same
//refer to "K9GAG08X0D Array Organization" in the K9GAG08U0D manual
void nand_send_addr(unsigned int addr)
{
nand_addr(addr & 0xff);         /* a0~a7 */
nand_addr((addr >> 8) & 0x7);   /* 程序的角度: a8~a10 */

nand_addr((addr >> 11) & 0xff); /* 程序的角度: a11~a18 */
nand_addr((addr >> 19) & 0xff); /* 程序的角度: a19~a26 */
nand_addr((addr >> 27) & 0xff); /* 程序的角度: a27~    */
}

//copy [len] bytes from [nand_start] on nand flash to [ddr_start] on sdram
int nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
unsigned int addr = nand_start;
int i, count = 0;
unsigned char *dest = (unsigned char *)ddr_start;

/* 选中芯片 */
nand_select();
while (count < len)
{
/* 发出命令0x00 */
nand_cmd(0x00);

/* 发出地址 */
nand_send_addr(addr);

/* 发出命令0x30 */
nand_cmd(0x30);

/* 等待就绪 */
wait_ready();

/* 读数据 */
for (i = 0; i < 2048 && count < len; i++)
{
dest[count++] = nand_get_data();
}

addr += 2048;
}

/* 取消片选 */
nand_deselect();
return 0;
}

//the whole process to copy [len] bytes from [nand_start] on nand flash to [ddr_start] on sdram
int copy2ddr(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
int ret;

/* 初始化nand flash controller */
nand_init();

/* 读nand flash */
ret = nand_read(nand_start, ddr_start, len);

return ret;
}



阅读(1075) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~