📄 nandflash.c
字号:
/****************************************************************************
【文 件 名 称】NandFlash.c
【功 能 描 述】FS2410XP教学平台实验程序
【程 序 版 本】3.0
【创建及创建日期】优龙公司/2005-XX-XX
【修改及修改日期】2005-5-23
****************************************************************************/
//头文件定义
#include "../inc/def.h"
#include "../inc/config.h"
#include "../inc/board.h"
#include "2410addr.h"
#ifdef NAND_FLASH_SUPPORT
struct NFChipInfo {
U32 id;
U32 size;
}
static NandFlashChip[] = {
{0xec73, SIZE_16M},
{0xec75, SIZE_32M},
{0xec76, SIZE_64M},
{0xec79, SIZE_128M},
{0, 0},
};
#define BLK_IDXL 8
#define BLK_IDXH 9
#define FMT_TAG 15
char format_tags[] = "Formatted For NAND FLASH Driver"; //must be less than 32
/***********************************************************/
//nand ecc utils
typedef unsigned char u_char;
static u_char eccpos[6] = {0, 1, 2, 3, 6, 7};
/*
* Pre-calculated 256-way 1 byte column parity
*/
static const u_char nand_ecc_precalc_table[] = {
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
};
/**
* nand_trans_result - [GENERIC] create non-inverted ECC
* @reg2: line parity reg 2
* @reg3: line parity reg 3
* @ecc_code: ecc
*
* Creates non-inverted ECC code from line parity
*/
static void nand_trans_result(u_char reg2, u_char reg3,
u_char *ecc_code)
{
u_char a, b, i, tmp1, tmp2;
/* Initialize variables */
a = b = 0x80;
tmp1 = tmp2 = 0;
/* Calculate first ECC byte */
for (i = 0; i < 4; i++) {
if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
tmp1 |= b;
b >>= 1;
if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
tmp1 |= b;
b >>= 1;
a >>= 1;
}
/* Calculate second ECC byte */
b = 0x80;
for (i = 0; i < 4; i++) {
if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
tmp2 |= b;
b >>= 1;
if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
tmp2 |= b;
b >>= 1;
a >>= 1;
}
/* Store two of the ECC bytes */
ecc_code[0] = tmp1;
ecc_code[1] = tmp2;
}
/********************************************************************
Function name: nand_calculate_ecc
Parameter : *dat:要校验的数据指针 *ecc_code:存放数据校验码指针
Description : 无
Return : void
Argument : 数据校验
Autor & date :
*********************************************************************/
/**
* nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for 256 byte block
* @dat: raw data
* @ecc_code: buffer for ECC
*/
int nand_calculate_ecc(const u_char *dat, u_char *ecc_code)
{
u_char idx, reg1, reg2, reg3;
int j;
/* Initialize variables */
reg1 = reg2 = reg3 = 0;
ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
/* Build up column parity */
for(j = 0; j < 256; j++) {
/* Get CP0 - CP5 from table */
idx = nand_ecc_precalc_table[dat[j]];
reg1 ^= (idx & 0x3f);
/* All bit XOR = 1 ? */
if (idx & 0x40) {
reg3 ^= (u_char) j;
reg2 ^= ~((u_char) j);
}
}
/* Create non-inverted ECC code from line parity */
nand_trans_result(reg2, reg3, ecc_code);
/* Calculate final ECC code */
ecc_code[0] = ~ecc_code[0];
ecc_code[1] = ~ecc_code[1];
ecc_code[2] = ((~reg1) << 2) | 0x03;
return 0;
}
struct Partition *pNandPart;
U32 NandFlashSize;
static U16 NandAddr;
static U16 support;
#define READCMD0 0
#define READCMD1 1
#define READCMD2 0x50
#define ERASECMD0 0x60
#define ERASECMD1 0xd0
#define PROGCMD0 0x80
#define PROGCMD1 0x10
#define QUERYCMD 0x70
#define READIDCMD 0x90
void NFChipSel(U32);
int NFIsReady(void);
void NFWrCmd(int);
void NFWrAddr(int);
void NFWrDat(int);
U8 NFRdDat(void);
#define NFChipEn() NFChipSel(1)
#define NFChipDs() NFChipSel(0)
#define NFIsBusy() (!NFIsReady())
/********************************************************************
Function name: NFChipSel(U32 sel)
Parameter : U32 sel : 用来使能NAND FLASH的
0:禁止 1:使能
Description : 无
Return : void
Argument : 用来使能或禁止NAND FLASH芯片
Autor & date :
*********************************************************************/
void NFChipSel(U32 sel)
{
if(sel)
rNFCONF &= ~0x800;
else
rNFCONF |= 0x800;
}
/********************************************************************
Function name: NFIsReady(void)
Parameter : void
Description : 返回NAND FLASH R/B脚的状态
Return : 返回R/B脚的状态
Argument : R/B输出低时,表示读写,擦除操作正在进行
Autor & date :
*********************************************************************/
int NFIsReady(void)
{
return rNFSTAT&1;
}
/********************************************************************
Function name: NFWrCmd(int cmd)
Parameter : int cmd : 命令参数
Description : 向NAND FLASH 输入一个命令
Return : void
Argument :
Autor & date : void
*********************************************************************/
void NFWrCmd(int cmd)
{
rNFCMD = cmd;
}
/********************************************************************
Function name: NFWrAddr(int addr)
Parameter : int addr : 地址
Description : 向NAND FLASH 输入一个地址
Return : void
Argument :
Autor & date : void
*********************************************************************/
void NFWrAddr(int addr)
{
rNFADDR = addr;
}
/********************************************************************
Function name: NFWrDat(int dat)
Parameter : int dat : 数据
Description : 向NAND FLASH 输入一个数据
Return : void
Argument :
Autor & date : void
*********************************************************************/
void NFWrDat(int dat)
{
rNFDATA = dat;
}
/********************************************************************
Function name: NFRdDat(int dat)
Parameter : int dat : 数据
Description : 向NAND FLASH读一个数据
Return : void
Argument :
Autor & date : void
*********************************************************************/
U8 NFRdDat(void)
{
return rNFDATA;
}
/********************************************************************
Function name: NFWaitBusy
Parameter : void
Description : 检测NAND FLASH是否忙
Return : 返回相应的状态信息
Argument :
Autor & date : void
*********************************************************************/
#ifdef WIAT_BUSY_HARD
#define NFWaitBusy() while(NFIsBusy())
#else
static U32 NFWaitBusy(void)
{
U8 stat;
NFWrCmd(QUERYCMD);
do {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -