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

📄 nandmtd.c

📁 nandMtd源码 适用于WIN CE操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -