📄 nandmtd.c
字号:
/*
* $Log: V:/nandMtd.c_v $
*
* Rev 1.28 06 Oct 2004 13:55:05 Wanghui
*
* Rev 1.27 06 Oct 1997 18:37:34 ANDRY
* no COBUX
*
* Rev 1.26 06 Oct 1997 18:04:34 ANDRY
* 16-bit access only for interleave 2 cards, COBUX
*
* Rev 1.25 05 Oct 1997 12:02:32 danig
* Support chip ID 0xEA
*
* Rev 1.24 10 Sep 1997 16:14:08 danig
* Got rid of generic names
*
* Rev 1.23 08 Sep 1997 17:47:00 danig
* fixed setAddress for big-endian
*
* Rev 1.22 04 Sep 1997 13:59:44 danig
* Debug messages
*
* Rev 1.21 31 Aug 1997 15:18:04 danig
* Registration routine return status
*
* Rev 1.20 28 Aug 1997 17:47:08 danig
* Buffer\remapped per socket
*
* Rev 1.19 28 Jul 1997 15:10:36 danig
* setPowerOnCallback & moved standard typedefs to flbase.h
*
* Rev 1.18 24 Jul 1997 18:04:12 amirban
* FAR to FAR0
*
* Rev 1.17 21 Jul 1997 18:56:00 danig
* nandBuffer static
*
* Rev 1.16 20 Jul 1997 18:21:14 danig
* Moved vendorID and chipID to Vars
*
* Rev 1.15 20 Jul 1997 17:15:06 amirban
* Added Toshiba 8MB
*
* Rev 1.14 07 Jul 1997 15:22:26 amirban
* Ver 2.0
*
* Rev 1.13 02 Jul 1997 14:59:22 danig
* More wait for socket to power up
*
* Rev 1.12 01 Jul 1997 13:39:54 danig
* Wait for socket to power up
*
* Rev 1.11 22 Jun 1997 18:34:32 danig
* Documentation
*
* Rev 1.10 12 Jun 1997 17:22:24 amirban
* Allow long extra read/writes
*
* Rev 1.9 08 Jun 1997 19:18:06 danig
* BIG_PAGE & FULL_PAGE moved to flash.h
*
* Rev 1.8 08 Jun 1997 17:03:40 amirban
* Fast Toshiba and power on callback
*
* Rev 1.7 05 Jun 1997 12:31:38 amirban
* Write corrections, and att reg changes
*
* Rev 1.6 03 Jun 1997 18:45:14 danig
* powerUp()
*
* Rev 1.5 01 Jun 1997 13:42:52 amirban
* Rewrite of read/write extra + major reduction
*
* Rev 1.4 25 May 1997 16:41:38 amirban
* Bg-endian, Toshiba fix & simplifications
*
* Rev 1.3 18 May 1997 17:34:50 amirban
* Use 'dataError'
*
* Rev 1.2 23 Apr 1997 11:02:14 danig
* Update to TFFS revision 1.12
*
* Rev 1.1 15 Apr 1997 18:48:02 danig
* Fixed FAR pointer issues.
*
* Rev 1.0 08 Apr 1997 18:29:28 danig
* Initial revision.
*/
/************************************************************************/
/* */
/* FAT-FTL Lite Software Development Kit */
/* Copyright (C) M-Systems Ltd. 1995-1997 */
/* */
/************************************************************************/
#include "flflash.h"
#include "reedsol.h"
extern void nand_write_command(UINT8 command);
extern void nand_write_address(UINT8 address);
extern UINT8 nand_read_data();
extern void nand_write_data(UINT8 data);
extern void nand_reset();
extern void nand_ce_low();
extern void nand_ce_high();
extern void nand_init();
#define PAGES_PER_BLOCK 32 /* 32 pages per block on a single chip*/
#undef VERIFY_AFTER_WRITE
/* Flash IDs*/
#define K9F1208_FLASH 0xec76
#define K9F6408X0C_FLASH 0xece6
#define KM29N16000_FLASH 0xec64
#define KM29N32000_FLASH 0xece5
/*#define KM29V64000_FLASH 0xece6 */
#define NM29N16_FLASH 0x8f64
#define NM29N32_FLASH 0x8fe5
#define NM29N64_FLASH 0x8fe6
#define TC5816_FLASH 0x9864
#define TC5832_FLASH 0x98e5
#define TC5864_FLASH 0x98e6
/* 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
#undef 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 */
/* 测试函数 */
#if 0
/*----------------------------------------------------------------------*/
/* 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;
nand_write_command(READ_MODE_2);
nand_ale_high();
nand_write_address((unsigned char)address);
nand_write_address((unsigned char)(address >> 9));
nand_write_address((unsigned char)(address >> 17));
nand_write_address((unsigned char)(address >> 25));
nand_ale_low();
waitForReady();
data=nand_read_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;
nand_ce_low(); /*片选有效*/
printf("readFlash: address = 0x%x, length = %d\n", address, length);
if(mode == 0)
{
bit8 = (unsigned short)address & 0x100;
if(bit8 == 0)
{
nand_write_command(0x00);
}
else
{
nand_write_command(0x01);
}
}
else
{
nand_write_command(0x50);
}
nand_ale_high();
nand_write_address((unsigned char)address);
nand_write_address((unsigned char)(address >> 9));
nand_write_address((unsigned char)(address >> 17));
nand_write_address((unsigned char)(address >> 25));
nand_ale_low();
taskDelay(1);
for(i=0; i<length; i++)
{
data=nand_read_data();
printf("readFlash: data = 0x%x\n", data);
}
nand_ce_high(); /*片选取消*/
}
/*----------------------------------------------------------------------*/
/* f l a s h W r i t e */
/*----------------------------------------------------------------------*/
int flashWrite(int address, int len, unsigned char data, int mode)
{
int i, bit8;
/*printf("readFlash: address = 0x%x, length = %d\n", address, length);*/
nand_ce_low(); /*片选有效*/
if(mode == 0)
{
bit8 = (unsigned short)address & 0x100;
if(bit8 == 0)
{
nand_write_command(0x00);
}
else
{
nand_write_command(0x01);
}
}
else
{
nand_write_command(0x50);
}
nand_write_command(SERIAL_DATA_INPUT);
nand_ale_high();
nand_write_address((unsigned char)address);
nand_write_address((unsigned char)(address >> 9));
nand_write_address((unsigned char)(address >> 17));
nand_write_address((unsigned char)(address >> 25));
nand_ale_low();
for(i=0; i<len; i++)
{
nand_write_data(data);
printf("WriteFlash: data = 0x%x\n", data);
}
nand_write_command(SETUP_WRITE);
waitForReady();
if(readStatus() & FAIL)
{
nand_ce_high(); /*片选取消*/
return flWriteFault;
}
else
{
nand_ce_high(); /*片选取消*/
return flOK;
}
}
/*----------------------------------------------------------------------*/
/* f l a s h E r a s e */
/*----------------------------------------------------------------------*/
int flashErase(int blockNo)
{
unsigned short pageNo = blockNo * PAGES_PER_BLOCK ;
nand_ce_low(); /*片选有效*/
nand_write_command(SETUP_ERASE);
nand_ale_high();
nand_write_address((unsigned char)pageNo); /* A9 ~ A16 */
nand_write_address((unsigned char)(pageNo >> 8)); /* A17 ~ A22 */
nand_write_address((unsigned char)(pageNo >> 16)); /* A17 ~ A22 */
nand_ale_low();
nand_write_command(CONFIRM_ERASE);
waitForReady();
if(readStatus() & FAIL)
{
nand_ce_high(); /*片选取消*/
return flWriteFault;
}
else
{
nand_ce_high(); /*片选取消*/
return flOK;
}
}
/*----------------------------------------------------------------------*/
/* f l a s h E r a s e A l l */
/*----------------------------------------------------------------------*/
void flashEraseAll(void)
{
int i;
for(i=0; i<1024; i++)
{
flashErase(i);
}
}
#endif
/* 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:kuangyaowen Date: 2007-11-21 */
/* */
/* Parameters: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -