📄 nand.c
字号:
#include "init.h"
#include "hardware.h"
#include "hardware_reg.h"
#include "HA_typedef.h"
extern U32 para;
void HA_INIT_NANDFLASH(void)
{
U32 temp;
//Gpio config... Ph5 set to "1"
*(RP)PORTH_SEL = 0x20;
*(RP)PORTH_DATA = 0x020;
*(RP)PORTH_DIR = 0x00;
*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;
*(RP)EMIADDR_NANDADDR = EMIADDR_NANDADDR_INIT;
*(RP)EMIADDR_NANDCOM = EMIADDR_NANDCOM_INIT;
*(RP)EMIADDR_NANDSTATUS = 0x0; /* STATUS REGISTER IS READ-ONLY */
*(RP)EMIADDR_NANDERRORADDR1 = EMIADDR_NANDERRORADDR1_INIT;
*(RP)EMIADDR_NANDERRORADDR2 = EMIADDR_NANDERRORADDR2_INIT;
*(RP)EMIADDR_NANDINTR = EMIADDR_NANDINTR_INIT;
*(RP)EMIADDR_NANDINECC = EMIADDR_NANDINECC_INIT;
*(RP)EMIADDR_NANDIDLE = EMIADDR_NANDIDLE_INIT;
/* 读出所有寄存器的值,检验有无问题 */
temp = *(RP)EMIADDR_NANDADDR;
para = HA_EMI_WRIT(para,temp);
temp = *(RP)EMIADDR_NANDSTATUS;
para = HA_EMI_WRIT(para, temp);
temp = *(RP)EMIADDR_NANDCOM;
para = HA_EMI_WRIT(para, temp);
temp = *(RP)EMIADDR_NANDERRORADDR1;
para = HA_EMI_WRIT(para, temp);
temp = *(RP)EMIADDR_NANDERRORADDR2;
para = HA_EMI_WRIT(para, temp);
temp = *(RP)EMIADDR_NANDCONF;
para = HA_EMI_WRIT(para, temp);
temp = *(RP)EMIADDR_NANDINTR;
para = HA_EMI_WRIT(para, temp);
temp = *(RP)EMIADDR_NANDINECC;
para = HA_EMI_WRIT(para, temp);
temp = *(RP)EMIADDR_NANDIDLE;
para = HA_EMI_WRIT(para, temp);
}
/* esram to nand flash */
U32 Dma_Nand_Write(U32 block_number, U32 page_number, U32 Dma_src_Add, U32 channelnum) //just burst size = 4;
{
U32 j,temp; //直接分配寄存器,编译器的智能化程度很高
U32 tempsrc,tempdest,tempcontrol,tempconfig; //为什么直接分配寄存器
// of registers of channel which is used now
tempsrc = DMACbase + 0x1000 + channelnum * 0x100; //replase registers of channel to be used;
tempdest = DMACbase + 0x1004 + channelnum * 0x100;
tempcontrol = DMACbase + 0x100c + channelnum * 0x100;
tempconfig = DMACbase + 0x1010 + channelnum * 0x100;
//size:num of word,should be muiltpy of 16(words)
*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;
*(RP)EMIADDR_NANDADDR = (U32)((page_number << 8) + (block_number << 13));
*(RP)tempsrc = Dma_src_Add;
*(RP)tempdest = EMI_NAND_DATA; /* it is a buffer address */
j = (U32)((0x80 << 14) + 0x149B); //suradd and desadd not add up
*(RP)tempcontrol = j;
*(RP)tempconfig =0x301B; //channel enable!
*(RP)EMIADDR_NANDCOM = 0x80000080; //write begin!
#if 0
do{
temp = *(RP)tempconfig;
temp &= 0x1;
}while(temp != 0x1);
#endif
//judge Nand flash compish actions
do{
temp = *(RP)EMIADDR_NANDIDLE;
temp &= 0x1;
}while(temp != 0x1);
return 0;
}
U32 Dma_Nand_Read(U32 block_number, U32 page_number, U32 Dma_des_Add, U32 channelnum) //just burst size = 4;
{
U32 j,temp;
U32 tempsrc,tempdest,tempcontrol,tempconfig; //These 4 temp regiser address rariable are used to replase registers
tempsrc = DMACbase + 0x1000 + channelnum * 0x100; //replase registers of channel to be used;
tempdest = DMACbase + 0x1004 + channelnum * 0x100;
tempcontrol = DMACbase + 0x100c + channelnum * 0x100;
tempconfig = DMACbase + 0x1010 + channelnum * 0x100;
*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;
*(RP)EMIADDR_NANDADDR = (U32)((page_number << 8) + (block_number << 13));
*(RP)tempsrc = EMI_NAND_DATA; /* it is a buffer address */
*(RP)tempdest = Dma_des_Add ;
j = (U32)((0x80 << 14) | 0x249B); //suradd and desadd not add up
*(RP)tempcontrol = j;
*(RP)tempconfig =0x031d; //channel enable!
*(RP)EMIADDR_NANDCOM = 0x80000000; //write beg
//judge Nand flash compish actions
do{
temp = *(RP)EMIADDR_NANDIDLE;
temp &= 0x1;
}while(temp != 0x1);
return 0;
}
U32 Dma_Nand_Erase(U32 block_number) //block_number:0x00--0xfff, 4096
{
U32 temp;
*(RP)EMIADDR_NANDCONF = 0x0f100aaa; //3 addresss mode!!!!
*(RP)EMIADDR_NANDADDR = (U32)(block_number<<5);
*(RP)EMIADDR_NANDCOM = 0x80000060;
//judge Nand flash compish actions
do{
temp = *(RP)EMIADDR_NANDIDLE;
temp &= 0x1;
}while(temp != 0x1);
return 0;
}
U32 Dma_Nand_StatusRead(void)
{
U32 temp;
*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL; //re_config
*(RP)EMIADDR_NANDCOM = 0x80000070; //read status command
do{
temp = *(RP)EMIADDR_NANDIDLE;
temp &= 0x1;
}while(temp != 0x1);
para = HA_EMI_WRIT(para, temp);
return 0;
}
U32 Nand_Reset(void)
{
U32 temp;
*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL;
*(RP)EMIADDR_NANDCOM = 0x800000ff;
do{
temp = *(RP)EMIADDR_NANDIDLE;
temp &= 0x1;
}while(temp != 0x0);
return 0;
}
#if 0
U32 HA_NandFlash_IdRead(void)
{
U32 temp;
*(RP)EMIADDR_NANDCONF = EMIADDR_NANDCONF_VAL; //re_config
*(RP)EMIADDR_NANDCOM = 0x80000090; //read status command
do{
temp = *(RP)EMIADDR_NANDIDLE; //judge Nand flash compish actions
}while((temp & 0x01) != 0x01);
temp = *(RP)EMI_NAND_DATA;
para = HA_EMI_WRIT(para, temp);
return 0;
}
#endif
ER NandFlash(void)
{
U32 blocknum, pagenum, sdramaddr1 = 0x30000000, sdramaddr2 = 0x30100000;
HA_INIT_NANDFLASH();
/* write data from ESRAM to NandFlash */
//HA_DMA_TRANS(0x11000200, para, 32, 32, 4, 0, 512); /* read nand flash */
//HA_DMA_TRANS(para, 0x11000200, 32, 32, 4, 0, 512); /* write nand flash */
//Dma_Nand_StatusRead();
/* 在作用域的边界会有跳转指令 */
#if 0
for(blocknum = 0; blocknum < 72; blocknum++){
Dma_Nand_Erase(blocknum);
for(pagenum = 0;pagenum < 32; pagenum++, sdramaddr1 += 0x200, sdramaddr2 += 0x200){
Dma_Nand_Write(blocknum, pagenum, sdramaddr1, 4);
Dma_Nand_Read(blocknum, pagenum, sdramaddr2, 4);
}
}
#endif
//Dma_Nand_StatusRead();
Dma_Nand_Erase(0x2);
Dma_Nand_Read(0x2, 0x0, 0x1fff4000, 1);
Dma_Nand_Erase(0x0);
Dma_Nand_Write(0x0, 0x0, 0x1fff3800, 2);
Dma_Nand_Read(0x0, 0x0, 0x24005000, 3);
compare(0x1fff3800, 0x24005000, 0x200, 32);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -