?? 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 + -