📄 nanddriver.c
字号:
/*
**************************************************************************************************************************
*filename: NandDriver.C
*author: wuer
*create date: 2005.5
*description:
*modify history:
*misc:
*****************************************************************************************************************************
*/
#include "HA_TypeDef.h"
#include "hardware.h"
#include "hardware_reg.h"
#include "stdio.h"
U32 g_NIN = 0x0L;
U32 g_NTN = 0x0L;
U32 *g_flash_pagebuf=(U32 *)0x1fff3400;
U32 *g_flash_esrambuf = (U32 *)0x1fff3800;
void init_nand(void) /* 配置GPIO口PH5为高电平,写使能 */
{
U32 tempsel,tempdata,tempdir;
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;
return;
}
void int_serv_emi(void)
{
*(RP)GFD_NAND_INTR = 0x0UL; //clear interrupt bit
g_NIN++;
}
int nand_rd_page(U32 page, U32*buffer, U32 do_read)
{
U32 status,i;
U32 tempg_NIN,tempg_NTN;
U32 nand_addr = page<<9;
g_NIN = 0x0;
g_NTN = 0x0;
//printf("\tpage [%08d] [0x%08x] [%s]\n",page, (U32)buffer, do_read?"R":"Write");
while((g_NIN < 2) & (g_NTN < 3))
{
if(do_read&1)
nand_read_page_com(nand_addr,(U32*)g_flash_esrambuf);
else
{
for(i=0;i<128;i++)
{
g_flash_esrambuf[i] = buffer[i];
}
nand_write_page_com(nand_addr,(U32*)g_flash_esrambuf);
}
for(i=0;i<0x1000;i++);
if(g_NIN >= 2)
return NO;
status = *(RP)GFD_NAND_IDLE;
if((status&0x1) == 0x1)
{
if(do_read&1)
{
for(i=0;i<128;i++)
{
buffer[i] = g_flash_esrambuf[i];
}
return YES; //read success!
}
else
{
tempg_NIN = g_NIN; //aviod g_var be changed!
tempg_NTN = g_NTN;
//for(i=0;i<128;i++) g_flash_pagebuf[i] = 0;
status = nand_rd_page(page,g_flash_pagebuf,0x1);
g_NIN = tempg_NIN;
g_NTN = tempg_NTN;
if( status == 1 )
{
#ifdef READOUT_CHECK
for(i=0; i<128; i++)
{
if(g_flash_pagebuf[i] !=buffer[i])
{
printf("error address is NO 0x%x word in page 0x%x!\n",i,page);
printf("Value at g_flash_pagebuf[0x%08x] is 0x%x \n and at buffer[0x%08x] is 0x%x\n",i,g_flash_pagebuf[i],i,buffer[i]);
return NO;
}
}
#endif
return YES; //write success!
}
else
return NO; //write Ok, but reread fail!
}
}
else
{
for(i=0;i<0x1000;i++);
g_NTN ++;
}
}
if(g_NTN >= 3)
return NO;
return NO;
}
int nand_erase_block(U32 page)
{
U32 i,j,NTM = 0x0L;
*(RP)GFD_NAND_CONF = 0x0100aaa; //3 addresss mode!!!!(refer to Garfield IV user manual)
*(RP)GFD_NAND_ADDR = (page ); //just that way(refer to Garfield IV user manual)
*(RP)GFD_NAND_COM = NAND_CMD_ERASE1; //nand flash erase
for(i=0;i<0x1000;i++); //must wait some time, waiting for the transmission's accomplish
i = *(RP)GFD_NAND_IDLE; //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)GFD_NAND_IDLE;
}
if(NTM == 0x5) return NO; //still time out? then return error!
return YES; //OK! return happy!
}
int nand_read_page_com (U32 from, U32 *buf)
{
*(RP)GFD_NAND_CONF = 0x2200aaa; // Nand 4 address mode config
*(RP)GFD_NAND_ADDR = ((U32)from) >> 1; //address config according to EMI refference
*(RP)DMACC0SrcAddr = GFD_NAND_DATA; //Nand data register is the source address of DMA
*(RP)DMACC0DestAddr = (U32)buf; //data buffer is the target address of DMA
*(RP)DMACC0Control = 0x20249b; //word-word burst=4 size=128words
*(RP)DMACC0Configuration = 0x31d; //enable DMA channel
*(RP)GFD_NAND_COM = (NAND_CMD_READ0 ); //send the read command, transportation begin now!!
return YES;
}
int nand_write_page_com(U32 to, U32 *buf)
{
*(RP)GFD_NAND_CONF = 0x02200aaa; // Nand 4 address mode config
*(RP)GFD_NAND_ADDR = ((U32)to) >> 1; //address config according to EMI refference
*(RP)DMACC0SrcAddr = (U32)buf ; //data buffer is the source address of DMA
*(RP)DMACC0DestAddr = GFD_NAND_DATA; //Nand data register is the target address of DMA
*(RP)DMACC0Control = 0x0020149B; //word-word burst=4 size=128words
*(RP)DMACC0Configuration = 0x301b; //enable DMA channel
*(RP)GFD_NAND_COM = (NAND_CMD_SEQIN); //send the write command, transportation begin now!!
return YES;
}
void pmc_init(U32 sysclk, U32 module)
{
U32 i;
U32 n,m;
*(RP)(PMU_PCSR) |= module; //open all module
*(RP)(PMU_PMDR) = 0X01;
*(RP)(PMU_PLTR) = 0x00d200cd; //MLTV=210,ULTV=205
for(i=0;i<100;i++);
n = 2;
m = 8*sysclk/10000000;
*(RP)(PMU_PMCR) = (n << 8) | m;
*(RP)(PMU_PMCR) = (1 << 12) | (n << 8) | m;
*(RP)(PMU_PUCR)=0x1530; //parameter PD=5,D=48
return ;
}
void system_init(void)
{
/* PLL initialized */
pmc_init(70000000, 0x17fff);
/* Interrupt initialize */
INT_INIT();
/* set GPIO PH5 to "1" */
init_nand();
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -