📄 nandmtd.c
字号:
#include "tffs/flflash.h"
#include "tffs/reedsol.h"
#include "stdio.h"
#include "config.h"
/*与sysTffs.c中定义相同*/
#define FLASH_BASE_ADRS (0x00000000)
#define FLASH_SIZE (0x04000000) /*NANDFlash大小*/
#define FLASH_BOOT_ADRS (0x00000000)
#define FLASH_BOOT_SIZE (0x00000000)
/*2440 datasheet上的寄存器地址*/
#define WRITE_COMMAND(val) (*(volatile char *)0x4E000008 = (char)(val))
#define WRITE_ADDRESS(val) (*(volatile char *)0x4E00000C = (char)(val))
#define WRITE_DATA(val) (*(volatile char *)0x4E000010 = (char)(val))
#define READ_DATA(val) ((char)(val) = *(volatile char *)0x4E000010)
#define NFCONT (*(volatile unsigned *)0x4e000004)
#define NFCONF (*(volatile unsigned *)0x4e000000)
#define NFSTAT(val) ((int)(val) = *(volatile int *)0x4E000020)
#define NAND_INIT1() {NFCONF|=0xfff0;}
#define NAND_INIT() {NFCONT =0x0011;}
#define NAND_InitECC() {NFCONT &= ~(1<<4);} /*将NFCONT寄存器的值的第4位置1,Initialize ECC decoder/encoder*/
#define NAND_DISABLE_CE() {NFCONT |= (1<<1);} /*将NFCONT寄存器的值的第1位置1,Disable chip select*/
#define NAND_ENABLE_CE() {NFCONT &= ~(1<<1);} /*将NFCONT寄存器的值的第1位置0,enable chip select*/
#define NAND_ENABLE_CONT() {NFCONT |= (1<<0);} /*将NFCONT寄存器的值的第0位置1,NAND Flash Ctroller Enable*/
#define NAND_DISABLE_CONT() {NFCONT &= ~(1<<0);} /*将NFCONT寄存器的值的第0位置0,NAND Flash Ctroller Disable*/
#define NAND_BW8() {NFCONF |= (1<<0);} /*将NFCONF寄存器的值的第0位置1,8-bit bus*/
#define NAND_BW16() {NFCONF &= ~(1<<0);} /*将NFCONF寄存器的值的第0位置0,16-bit bus*/
#define PAGES_PER_BLOCK 32 /*32 pages per block on a single chip*/
/*Flash IDs*/
/*#define K9F1208UOM_FLASH 0xec76 */
/* Flash commands:*/
#define SERIAL_DATA_INPUT 0x80
#define READ_MODE 0x00
#define READ_MODE_2 0x50
#define RESET_FLASH 0xff
#define SETUP_WRITE 0x10
#define SETUP_ERASE 0x60
#define CONFIRM_ERASE 0xd0
#define READ_STATUS 0x70
#define READ_ID 0x90
#define FAIL 0x01
#define RB 0x40
/*#define DEBUG_PRINT printf*/
/* commands for moving flash pointer to areeas A,B or C of page*/
typedef enum { AREA_A = READ_MODE, AREA_B = 0x01, AREA_C = READ_MODE_2 } PointerOp;
/* customization for this MTD*/
typedef struct {
unsigned short vendorID;
unsigned short chipID;
unsigned short pageSize ; /* all....................*/
unsigned short pageMask ; /* ...these...............*/
unsigned short pageAreaSize ; /* .......variables.......*/
unsigned short tailSize ; /* .............interleave*/
unsigned short noOfBlocks ; /* total erasable blocks in flash device*/
FLBuffer *buffer; /* buffer for map through buffer */
} Vars;
static Vars mtdVars[DRIVES];
#define thisVars ((Vars *) vol.mtdVars)
#define thisBuffer (thisVars->buffer->data)
/* Auxiliary methods */
/* 测试函数 */
/*----------------------------------------------------------------------*/
/* checkAllBlock */
/*----------------------------------------------------------------------*/
void checkAllBlock(void)
{
int i, j;
int address;
unsigned char data;
for(i=0; i<1024; i++)
{
for(j=0; j<2; j++)
{
address = 0x2000 * i + 0x200 * j + 0x06;
WRITE_COMMAND(READ_MODE_2);
WRITE_ADDRESS((unsigned char)address);
WRITE_ADDRESS((unsigned char)(address >> 9));
WRITE_ADDRESS((unsigned char)(address >> 17));
WRITE_ADDRESS((unsigned char)(address >> 25));
waitForReady();
READ_DATA(data);
if(data != 0xFF)
{
printf("Block %d is a invalid block", i);
break;
}
}
}
}
/*----------------------------------------------------------------------*/
/* f l a s h R e a d */
/*----------------------------------------------------------------------*/
void flashRead(int address, int length, int mode)
{
int i, bit8;
unsigned char data;
printf("readFlash: address = 0x%x, length = %d\n", address, length);
if(mode == 0)
{
bit8 = (unsigned short)address & 0x100;
if(bit8 == 0)
WRITE_COMMAND(0x00);
else
WRITE_COMMAND(0x01);
}
else
WRITE_COMMAND(0x50);
WRITE_ADDRESS((unsigned char)address);
WRITE_ADDRESS((unsigned char)(address >> 9));
WRITE_ADDRESS((unsigned char)(address >> 17));
WRITE_ADDRESS((unsigned char)(address >> 25));
waitForReady();
for(i=0; i<length; i++)
{
READ_DATA(data);
printf("readFlash: data = 0x%x\n", data);
}
}
/*----------------------------------------------------------------------*/
/* f l a s h W r i t e */
/*----------------------------------------------------------------------*/
void flashWrite(int address, int len, unsigned char data, int mode)
{
int i, bit8;
/*printf("readFlash: address = 0x%x, length = %d\n", address, length);*/
if(mode == 0)
{
bit8 = (unsigned short)address & 0x100;
if(bit8 == 0)
WRITE_COMMAND(0x00);
else
WRITE_COMMAND(0x01);
}
else
WRITE_COMMAND(0x50);
address += 1;
WRITE_COMMAND(SERIAL_DATA_INPUT);
WRITE_ADDRESS((unsigned char)address);
WRITE_ADDRESS((unsigned char)(address >> 9));
WRITE_ADDRESS((unsigned char)(address >> 17));
WRITE_ADDRESS((unsigned char)(address >> 25));
for(i=0; i<len; i++)
{
WRITE_DATA(data);
/* printf("WriteFlash: data = 0x%x\n", data);*/
}
WRITE_COMMAND(SETUP_WRITE);
waitForReady();
if(readStatus() & FAIL)
return flWriteFault;
}
/*----------------------------------------------------------------------*/
/* f l a s h E r a s e */
/*----------------------------------------------------------------------*/
void flashErase(int blockNo)
{
unsigned short pageNo = blockNo * PAGES_PER_BLOCK ;
WRITE_COMMAND(SETUP_ERASE);
WRITE_ADDRESS((unsigned char)pageNo); /* A9 ~ A16 */
WRITE_ADDRESS((unsigned char)(pageNo >> 8)); /* A17 ~ A22 */
WRITE_ADDRESS((unsigned char)(pageNo >> 16)); /* A25 */
WRITE_COMMAND(CONFIRM_ERASE);
waitForReady();
if(readStatus() & FAIL)
return flWriteFault;
}
/*----------------------------------------------------------------------*/
/* f l a s h E r a s e A l l */
/*----------------------------------------------------------------------*/
void flashEraseAll(void)
{
int i;
for(i=0; i<4096; i++)
{
flashErase(i);
}
}
/* MTD函数 */
/*----------------------------------------------------------------------*/
/* t f f s c p y 1 6 */
/* */
/* Move data in 16-bit words. */
/* */
/* Parameters: */
/* dst : destination buffer */
/* src : source buffer */
/* len : bytes to move */
/* */
/*----------------------------------------------------------------------*/
static void tffscpy16 (unsigned char FAR0 *dst,
const unsigned char FAR0 *src,
int len)
{
register int i = 0;
/* move data in 16-bit words */
for (i = 0; i < (len >> 1); i++)
*((unsigned short *) dst + i) = *((unsigned short *) src + i);
/* move last byte (if any) */
if (len & 1)
*(dst + len-1) = *(src + len-1);
}
/*----------------------------------------------------------------------*/
/* t f f s s e t 1 6 */
/* */
/* Set data buffer in 16-bit words. */
/* */
/* Parameters: */
/* dst : destination buffer */
/* val : byte value tofill the buffer */
/* len : setination buffer size in bytes */
/* */
/*----------------------------------------------------------------------*/
static void tffsset16 (unsigned char FAR0 *dst,
unsigned char val,
int len)
{
register unsigned short wval = ((unsigned short)val << 8) | val;
register int i = 0;
/* set data in 16-bit words */
for (i = 0; i < (len >> 1); i++)
*((unsigned short *) dst + i) = wval;
/* set last byte (if any) */
if (len & 1)
*(dst + len-1) = val;
}
/*----------------------------------------------------------------------*/
/* w a i t F o r R e a d y */
/* */
/* Wait for the selected device to be ready. */
/* */
/* Author: 王辉 Date: 2004-8-21 */
/* */
/* Parameters: */
/* void */
/* */
/* Returns: */
/* TRUE if device is ready */
/* */
/*----------------------------------------------------------------------*/
FLBoolean waitForReady (void)
{
int val;
do
{
NFSTAT(val);
val &= 0x01; /* 读NFSTAT第0位(RnB)状态,判断设备状态 */
} while(val == 0);
return TRUE;
}
/*----------------------------------------------------------------------*/
/* m a k e C o m m a n d */
/* */
/* Set Page Pointer to Area A, B or C in page. */
/* */
/* Author: 王辉 Date:2004-8-21 */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* cmd : receives command relevant to area */
/* addr : receives the address to the right area. */
/* modes : mode of operation (EXTRA ...) */
/* */
/*----------------------------------------------------------------------*/
static void makeCommand (PointerOp *cmd, CardAddress address, int modes)
{
int bit8;
if (modes & EXTRA)
*cmd = AREA_C;
else
{
bit8 = (unsigned short)address & 0x100;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -