📄 nflash.c
字号:
/*
1、NAND Flash ID
16M EC 33
EC 73
32M EC 35
EC 75
64M EC 36
EC 76
128M EC 78
EC 79
256M EC AA
EC DA
512M EC AC
EC DC
*/
#include "..\inc\44b.h"
#include "nflash.h"
/* nflash 操作命令定义 */
//引脚在 PortC
#define ALE (0x01 << 9 ) //PortC.9
#define CLE (0x01 << 8 ) //PortC.8
#define CE0 (0x01 << 10) //PortC.10
#define CE1 (0x01 << 11) //PortC.11
#define RB (0x01 << 14) //PortC.14
#define KEY (0x01 << 15) //PortC.15
#define FC_CMD0() rPDATC |= CLE ; rPDATC &= ~(ALE) ; rPDATC &= ~(CE0) //CLE ALE CE 100
#define FC_ADDR0() rPDATC |= ALE ; rPDATC &= ~(CLE) ; rPDATC &= ~(CE0)
#define FC_DATA0() rPDATC &= ~(ALE|CLE) ; rPDATC &= ~(CE0)
#define FC_INACTIVE0() rPDATC |= CE0 ; rPDATC &= ~(ALE|CLE)
#define rNF_DATA0 (*(volatile unsigned char *)0x04000000)
#define WAITRB0() while(!(rPDATC & RB))
#define FC_CMD1() rPDATC |= CLE ; rPDATC &= ~(ALE) ; rPDATC &= ~(CE1) //CLE ALE CE 100
#define FC_ADDR1() rPDATC |= ALE ; rPDATC &= ~(CLE) ; rPDATC &= ~(CE1)
#define FC_DATA1() rPDATC &= ~(ALE|CLE) ; rPDATC &= ~(CE1)
#define FC_INACTIVE1() rPDATC |= CE1 ; rPDATC &= ~(ALE|CLE)
#define rNF_DATA1 (*(volatile unsigned char *)0x05000000)
#define WAITRB1() while(!(rPDATC & RB))
//=============================================
//SMC 卡容量定义
//=============================================
static unsigned char __SMCID[6][2] =
{
{0x33,0x73},
{0x35,0x75},
{0x36,0x76},
{0x78,0x79},
{0xAA,0xDA},
{0xAC,0xDC}
};
static char *__SMCSIZE[6] =
{
"16MB",
"32MB",
"64MB",
"128MB",
"256MB",
"512MB"
};
unsigned int HDSizeNO(unsigned int ID);
char* HDSize(unsigned int ID);
unsigned int HDSizeNO(unsigned int ID)
{
unsigned int i;
unsigned char buf = ID & 0xFF;
for( i = 0 ; i < 6 ; i++ )
{
if( buf == __SMCID[i][0] || buf == __SMCID[i][1] ) break;
}
return i;
}
char* HDSize(unsigned int ID)
{
if( ID > 5 ) return 0;
return __SMCSIZE[ID];
}
/*此函数在 WrRd_nflash.s */
/* 内置nFlash */
extern void __RdPage528_0(unsigned char *pPageBuf);
extern void __WrPage528_0(unsigned char *pPageBuf);
/* 外置SMC卡 */
extern void __RdPage528_1(unsigned char *pPageBuf);
extern void __WrPage528_1(unsigned char *pPageBuf);
/*初始化nflash*/
void NF_Init()
{
unsigned int i;
FC_INACTIVE0();
for( i = 0 ; i < 3000; i++ );
NF_Reset();
FC_INACTIVE0();
}
int NF_CheckID()
{
int i;
int ID;
/************************************************************
* 命令字 地址 数据 *
* 0x90 0x00(1字节) Device Code(2字节:0xEC73) *
************************************************************/
FC_CMD0();
rNF_DATA0 = 0x90;
FC_ADDR0();
for( i = 0 ; i < 5 ; i++ );
rNF_DATA0 = 0x00;
FC_DATA0();
for( i = 0 ; i < 5 ; i++ );
ID = rNF_DATA0 << 8;
ID += rNF_DATA0;
FC_INACTIVE0();
return ID;
}
void NF_Reset()
{
int i;
FC_CMD0();
rNF_DATA0 = 0xff;
for (i=0;i<3000;i++);
WAITRB0();
}
/***********************************************************/
/*功能:擦除FLASH的1Block(对应文件系统为1Cluster) */
/* 每一个簇为16KB,因此KM29U128共有1024个簇 */
/*输入:unsigned int cluster/block(需要擦除的Block Number) */
/*返回:OK或FAIL */
/***********************************************************/
unsigned char NF_EraseBlock(unsigned int Block)
{
unsigned int blockPage = (Block<<5);
int i;
FC_CMD0();
rNF_DATA0 = 0x60;
FC_ADDR0();
rNF_DATA0 = blockPage & 0xff;
rNF_DATA0 = (blockPage>>8) & 0xff;
for(i=0;i<3;i++); //tWC 50ns
FC_CMD0();
rNF_DATA0 = 0xd0;
for(i=0;i<3;i++);
FC_DATA0();
WAITRB0(); //wait max 3ms
FC_CMD0();
rNF_DATA0 = 0x70;
FC_DATA0();
if (rNF_DATA0 & 0x1) //erase error
{
FC_INACTIVE0();
return NF_FAIL;
}
else
{
FC_INACTIVE0();
return NF_OK;
}
}
/*****************************************************************/
/*功能:读取FLASH的某个Block中的1page数据 */
/* 在文件系统中,有如下对应关系:Block=Cluster */
/* Page =Sector */
/*输入:unsigned int block,page,unsigned char *pPage(存放数据的地址)*/
/*****************************************************************/
void NF_ReadPage(unsigned int block,unsigned int page,unsigned char *pPage)
{
int i;
unsigned int blockPage = (block<<5) + page;
FC_CMD0();
rNF_DATA0 = 0x00;
FC_ADDR0();
rNF_DATA0 = 0;
rNF_DATA0 = blockPage & 0xff;
rNF_DATA0 = (blockPage>>8) & 0xff;
for(i = 0 ; i < 10 ; i++ );
FC_DATA0();
WAITRB0();
__RdPage528_0(pPage);
FC_INACTIVE0();
}
/*****************************************************************/
/*功能:向FLASH的某个Block中的1page写入数据 */
/* 在文件系统中,有如下对应关系:Block=Cluster */
/* Page =Sector */
/*输入:unsigned int block,page,unsigned char *pPage(存放数据的地址)*/
/*输出:0:Fail;1:OK */
/*****************************************************************/
unsigned char NF_WritePage(unsigned int block,unsigned int page,unsigned char *pPage)
{
unsigned int blockPage = (block<<5) + page;
int i;
FC_CMD0();
rNF_DATA0 = 0x80;
FC_ADDR0();
rNF_DATA0 = 0;
rNF_DATA0 = blockPage & 0xff;
rNF_DATA0 = (blockPage>>8) & 0xff;
FC_DATA0();
__WrPage528_0(pPage);
FC_CMD0();
rNF_DATA0 = 0x10;
for(i=0;i<10;i++);
WAITRB0();
rNF_DATA0 = 0x70;
FC_DATA0();
for( i = 0 ; i < 3 ; i++ );
if((rNF_DATA0 & 0x1))
{
FC_INACTIVE0();
return NF_FAIL;
}
else
{
FC_INACTIVE0();
return NF_OK;
}
}
/***************************************
* SMC 卡 *
***************************************/
/*初始化nflash*/
void SMC_Init()
{
unsigned int i;
FC_INACTIVE1();
for( i = 0 ; i < 3000; i++ );
SMC_Reset();
FC_INACTIVE1();
}
int SMC_CheckID()
{
int i;
int ID;
/************************************************************
* 命令字 地址 数据 *
* 0x90 0x00(1字节) Device Code(2字节:0xEC73) *
************************************************************/
FC_CMD1();
rNF_DATA1 = 0x90;
FC_ADDR1();
for( i = 0 ; i < 5 ; i++ );
rNF_DATA1 = 0x00;
FC_DATA1();
for( i = 0 ; i < 5 ; i++ );
ID = rNF_DATA1 << 8;
ID += rNF_DATA1;
FC_INACTIVE1();
return ID;
}
void SMC_Reset()
{
int i;
FC_CMD1();
rNF_DATA1 = 0xff;
for (i=0;i<3000;i++);
WAITRB1();
}
/***********************************************************/
/*功能:擦除FLASH的1Block(对应文件系统为1Cluster) */
/* 每一个簇为16KB,因此KM29U128共有1024个簇 */
/*输入:unsigned int cluster/block(需要擦除的Block Number) */
/*返回:OK或FAIL */
/***********************************************************/
unsigned char SMC_EraseBlock(unsigned int Block)
{
unsigned int blockPage = (Block<<5);
int i;
FC_CMD1();
rNF_DATA1 = 0x60;
FC_ADDR1();
rNF_DATA1 = blockPage & 0xff;
rNF_DATA1 = (blockPage>>8) & 0xff;
for(i=0;i<3;i++); //tWC 50ns
FC_CMD1();
rNF_DATA1 = 0xd0;
for(i=0;i<3;i++);
FC_DATA1();
WAITRB1(); //wait max 3ms
FC_CMD1();
rNF_DATA1 = 0x70;
FC_DATA1();
if (rNF_DATA1 & 0x1) //erase error
{
FC_INACTIVE1();
return NF_FAIL;
}
else
{
FC_INACTIVE1();
return NF_OK;
}
}
/*****************************************************************/
/*功能:读取FLASH的某个Block中的1page数据 */
/* 在文件系统中,有如下对应关系:Block=Cluster */
/* Page =Sector */
/*输入:unsigned int block,page,unsigned char *pPage(存放数据的地址)*/
/*****************************************************************/
void SMC_ReadPage(unsigned int block,unsigned int page,unsigned char *pPage)
{
int i;
unsigned int blockPage = (block<<5) + page;
FC_CMD1();
rNF_DATA1 = 0x00;
FC_ADDR1();
rNF_DATA1 = 0;
rNF_DATA1 = blockPage & 0xff;
rNF_DATA1 = (blockPage>>8) & 0xff;
for(i = 0 ; i < 10 ; i++ );
FC_DATA1();
WAITRB1();
__RdPage528_1(pPage);
FC_INACTIVE1();
}
/*****************************************************************/
/*功能:向FLASH的某个Block中的1page写入数据 */
/* 在文件系统中,有如下对应关系:Block=Cluster */
/* Page =Sector */
/*输入:unsigned int block,page,unsigned char *pPage(存放数据的地址)*/
/*输出:0:Fail;1:OK */
/*****************************************************************/
unsigned char SMC_WritePage(unsigned int block,unsigned int page,unsigned char *pPage)
{
unsigned int blockPage = (block<<5) + page;
int i;
FC_CMD1();
rNF_DATA1 = 0x80;
FC_ADDR1();
rNF_DATA1 = 0;
rNF_DATA1 = blockPage & 0xff;
rNF_DATA1 = (blockPage>>8) & 0xff;
FC_DATA1();
__WrPage528_1(pPage);
FC_CMD1();
rNF_DATA1 = 0x10;
for(i=0;i<10;i++);
WAITRB1();
rNF_DATA1 = 0x70;
FC_DATA1();
for( i = 0 ; i < 3 ; i++ );
if((rNF_DATA1 & 0x1))
{
FC_INACTIVE1();
return NF_FAIL;
}
else
{
FC_INACTIVE1();
return NF_OK;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -