📄 nand.c
字号:
/*************************************************************************************
* Copyright (c) 2005 by National ASIC System Engineering Research Center.
* PROPRIETARY RIGHTS of ASIC are involved in the subject matter of this
* material. All manufacturing, reproduction, use, and sales rights
* pertaining to this subject matter are governed by the license agreement.
* The recipient of this software implicitly accepts the terms of the license.
*
* File Name: uart.c
*
* File Description:
* The file consists of the function used to config uart
*
* Function Description:
* Created by Wuer
**************************************************************************************/
#include "garfield.h"
#include <string.h>
#include "nand.h"
extern print(char *string);
U32 g_NIN = 0x0L; /* 读写过程出错次数 */
U32 SOURCE = 0x1fff3800; /* 数据存放源地址 */
U32 DEST = 0x1fff3c00; /* 数据读出目标地址 */
U32 TESTNUM = 0x200; /* 每次读写大小(512字节) */
char ch = 0xaa; /* 数据内容 */
int PRINT(char *string)
{
#ifndef USB_ICE
printf(string);
#else
print(string);
#endif
return 0;
}
int main(void)
{
char *s1,*s2;
s1="Error in Nand Flash lab!!!\n";
s2="Succeeded in Nand Flash lab!!!\n";
if(E_OK != ModuleNand())
//printf("Error in Nand Flash lab!!!\n");
PRINT(s1);
else //printf("Succeeded in Nand Flash lab!!!\n");
PRINT(s2);
while(1);
return E_OK;
}
STATUS ModuleNand(void)
{
char *s1,*s2,*s3,*s4,*s5,*s6,*s7,*s8;
s1="____Error in erasing operation!\n";
s2="Erasing operation ok!\n";
s3="____Error in writing operation!\n";
s4="Wrinting operation ok!\n";
s5="____Error in Reading operation!\n";
s6="Reading operation ok!\n";
s7="____Some data is different from original data!\n";
s8="ALL ok!\n";
/* system initialized */
system_init();
/* open EMI interrrupt mask */
init_nand();
unmask_irq(INT_EMI);
DataDefine(SOURCE, ch, TESTNUM); /* 初始化一块数据块 */
clear(DEST, TESTNUM); /* 将需要读出数据存放地址清零 */
if(E_OK != NandErase(0)) /* 需要写入的Nand Flash地址必须先擦除 */
{
//printf("____Error in erasing operation!\n");
PRINT(s1);
return ~E_OK;
}else PRINT(s2);//printf("Erasing operation ok!\n");
if(E_OK != NandWrite(0, SOURCE)) /* 将预先定义的数据(512字节)块写入到Nand Flash中 */
{
PRINT(s3);
//printf("____Error in writing operation!\n");
return ~E_OK;
}else PRINT(s4); //printf("Wrinting operation ok!\n");
if(E_OK != NandRead(0, DEST)) /* 将写入到Nand Flash的数据块读出到目标内存 */
{
PRINT(s5);
//printf("____Error in Reading operation!\n");
return ~E_OK;
}else PRINT(s6); //printf("Reading operation ok!\n");
if(E_OK != check(DEST, SOURCE, TESTNUM)) /* 检查目标内存中的数据是否与写入源数据相同 */
{
PRINT(s7);
//printf("____Some data is different from original data!\n");
return ~E_OK;
}else PRINT(s8); //printf("ALL ok!\n");
return E_OK;
}
STATUS NandErase(U32 page)
{
U32 i,j,NTM = 0x0L;
*(RP)EMIADDR_NANDCONF = 0x0100aaa; //3 addresss mode!!!!(refer to Garfield IV user manual)
*(RP)EMIADDR_NANDADDR = (page >> 9); //just that way(refer to Garfield IV user manual)
*(RP)EMIADDR_NANDCOM = NAND_CMD_ERASE1; //nand flash erase
for(i=0;i<0x1000;i++); //must wait some time, waiting for the transmission's accomplish
i = *(RP)EMIADDR_NANDIDLE; //judge Nand flash compish actions by IDLE register
while((i&0x1) != 0x1)
{
for(j = 0x0; j < 0x1000; j++); //not yet, then wait another period of time
NTM++;
if(NTM == 0x5) break;
i = *(RP)EMIADDR_NANDIDLE;
}
if(NTM == 0x5) return 0; //still time out? then return error!
return E_OK; //OK! return happy!
}
STATUS NandWrite(U32 page, U32 bufferhead)
{
U32 i,j,NTM = 0x0L;
*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL; //4 address mode for write
*(RP)EMIADDR_NANDADDR = (U32)page >> 1; //address right move 1 bit, set to nand address register
*(RP)DMACC0SrcAddr = bufferhead; //DMA source is Sdram address
*(RP)DMACC0DestAddr = EMI_NAND_DATA; //DMA destination is Nand data register
i = (U32)(0x80 << 14);
j=i+0x149B;
*(RP)DMACC0Control = j;
*(RP)DMACC0Configuration =0x301b; //channel enable!
*(RP)EMIADDR_NANDCOM = 0x80000080; //NAND_CMD_SEQIN;
//write begin!
for(j = 0x0; j < 0x1000; j++); //must wait some time, waiting for the transmission's accomplish
i = *(RP)EMIADDR_NANDIDLE; //judge Nand flash compish actions by IDLE register
while((i&0x1) != 0x1) //not yet, then wait another period of time
{
for(j = 0x0; j < 0x1000; j++);
NTM++;
if(NTM == 0x5) break;
i = *(RP)EMIADDR_NANDIDLE;
}
if(NTM == 0x5) return 0; //still time out? then return error!
return E_OK; //OK! return happy!
}
STATUS NandRead(U32 page, U32 bufferhead)
{
U32 i,j,NTM = 0x0L;
*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL; //4 address mode for read
*(RP)EMIADDR_NANDADDR = (U32)page >>1; //address right move 1 bit, set to nand address register
*(RP)DMACC0SrcAddr = EMI_NAND_DATA; //DMA source is Nand data register
*(RP)DMACC0DestAddr = bufferhead ; //DMA destination is Sdram address
i = (U32)(0x80<<14);
j=i+0x249B;
*(RP)DMACC0Control = j;
*(RP)DMACC0Configuration =0x31d; //channel enable!
*(RP)EMIADDR_NANDCOM = NAND_CMD_READ0; //read begin
for(j = 0; j < 0x1000; j++); //must wait some time, waiting for the transmission's accomplish
i = *(RP)EMIADDR_NANDIDLE; //judge Nand flash compish actions by IDLE register
while((i&0x1) != 0x1) //not yet, then wait another period of time
{
for(j = 0; j < 0x1000; j++);
NTM++;
if(NTM == 0x5) break;
i = *(RP)EMIADDR_NANDIDLE;
}
if(NTM == 0x5) return 0; //still time out? then return error!
return E_OK; //OK! return happy!
}
STATUS check(U32 head1, U32 head2, U32 num)
{
RP8 p1, p2;
char data;
char *s;
s="the copyed data is not the orignal one!!\n";
p1 = (RP8)head1;
p2 = (RP8)head2;
while(num-->0)
{
data = *((RP8)p1++);
if(data!= *((RP8)p2++))
{
//printf("the copyed data is not the orignal one!!\n");
PRINT(s);
return ~E_OK;
}
}
return E_OK;
}
void init_nand(void) /* 配置GPIO口PH5为高电平,写使能 */
{
U32 tempsel,tempdata,tempdir;
#ifdef GE00
tempsel = *(RP)GPIO_PH5_SEL;
tempdata = *(RP)GPIO_PH5_DATA;
tempdir = *(RP)GPIO_PH5_DIR;
tempsel |= 0x20;
tempdata |= 0x20;
tempdir &= 0xffffffdf;
*(RP)GPIO_PH5_SEL = tempsel;
*(RP)GPIO_PH5_DATA = tempdata;
*(RP)GPIO_PH5_DIR = tempdir;
#endif
#ifndef GE00
tempsel = *(RP)GPIO_PB9_SEL;
tempdata = *(RP)GPIO_PB9_DATA;
tempdir = *(RP)GPIO_PB9_DIR;
tempsel |= 0x200;
tempdata |= 0x200;
tempdir &= 0x1ff;
*(RP)GPIO_PB9_SEL = tempsel;
*(RP)GPIO_PB9_DATA = tempdata;
*(RP)GPIO_PB9_DIR = tempdir;
#endif
}
void emi_handler(void) /* 中断处理程序 */
{
*(RP)EMIADDR_NANDINTR = 0x0UL; /* 清除中断 */
g_NIN++; /* 中断发生数累加 */
return;
}
void clear(U32 head, U32 num) /* 清楚一块内存内容为全0 */
{
U32 i = 0;
for(i=0; i<num; i++)
{
*(RP8)head++ = (U8)0;
}
return;
}
void DataDefine(U32 head, char data, U32 num) /* 定义一块内存内容为全data */
{
U32 i = 0;
for(i=0; i<num; i++)
{
*(RP8)head++ = data;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -