⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nandmtd.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * $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 + -