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

📄 nflash.c

📁 工程模板 使用非常方便适用初学者 敬请下载
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*******************************************************************************
*                          Advanced Reality Tech. Inc.                        *
*                  Copyright (c) 2001, All Rights Reserved                    *
*                                                                             *
* nflash module.                                                   	      *
*                                                                             *
* File : nflash.C                                                             *
* By : thhuang                                                                *
*                                                                             *
* History : 2001/11/01 File created.                                          *
*           2002/01/11 check and set bad block added.                         *
*           2002/01/18 Sequential read supported.                             *
*           2002/08/01 Options for AR2000, AR2001 and AR2010.                 *
*                                                                             *
*******************************************************************************
*/

#include "../include/nflash.h"

unsigned int	seqIn, seqOut;
unsigned char	*seqAddr;

static void nfshCommandLatch(unsigned char cmd);
static void nfshAddressLatch(unsigned long offset);
static void nfshBlockAddressLatch(unsigned long offset);
static void nfshInputDataLatch(unsigned char data[]);
static void nfshReadDataLatch(unsigned char data[]);
static unsigned char nfshStatusRead();
static unsigned int CountZero( unsigned char data );

//************************************** jason
//#define ECC_DEBUG 	1
//#define ECC_CHECK	1	// if didn't define ECC_CHECK , then use the checksum method

#define K8M_byte	8*1024*1024
#define K16M_byte	16*1024*1024
#define K32M_byte	32*1024*1024
#define K64M_byte	64*1024*1024
#define K128M_byte	128*1024*1024

//***********************************************************
// Since NAND_File system structure , we only support the chip (block erase size=16k bytes)
// We don't support 1M,2M,4M,and 8M bytes NAND flash card .
// Note : The prg_cycle was different between (16M, 32M) and (64M, 128M).

flash_chip  flash_table[] =
{
 // evice_id  prg_cycle  block_size  total_size    device_name
 	0xece6		,0	, 8*1024	, K8M_byte	  , "K9f6408"	, 	//Samsung 8M
    0xec73  	,0	, 16*1024   , K16M_byte   , "K9f2808" 	,   //Samsung 16M
    0xec75  	,0	, 16*1024   , K32M_byte   , "K9f5608" 	,   //Samsung 32M
    0xec76  	,1	, 16*1024   , K64M_byte   , "K9d1208" 	,   //Samsung 64M
    0xec79  	,1	, 16*1024   , K128M_byte  , "K9d1G08" 	,   //Samsung 128M
 	0x98e6		,0	, 8*1024	, K8M_byte	  , "TC58NS64"	, 	//Toshiba 8M
    0x9873  	,0	, 16*1024   , K16M_byte   , "TC58NS128"	,   //Toshiba 16M
    0x9875  	,0	, 16*1024   , K32M_byte   , "TC58NS256" ,   //Toshiba 32M
    0x9876  	,1	, 16*1024   , K64M_byte   , "TH58NS512" ,   //Toshiba 64M
    0x9879  	,1	, 16*1024   , K128M_byte  , "TH58NS100" ,   //Toshiba 128M
    0		,0	,0	    ,0		  ,0
};

flash_chip *current_nand_chip ;

//**********************************************************

//********************************************************
// Input  : 256 bytes of data
// Output : 3 bytes of ECC code
//	    bit0 : p1b
//	    bit1 : p1
//	    bit2 : p2b
//	    bit3 : p2
//	    bit4 : p4b
//	    bit5 : p4
//
//	    bit8  : p8b
//	    bit9  : p8
//	    bit10 : p16b
//	    bit11 : p16
//	    bit12 : p32b
//	    bit13 : p32
//	    bit14 : p64b
//	    bit15 : p64

//	    bit16 : p128b
//	    bit17 : p128
//	    bit18 : p256b
//	    bit19 : p256
//	    bit20 : p512b
//	    bit21 : p512
//	    bit22 : p1024b
//	    bit23 : p1024
//
//********************************************************
// void ecc_gen(unsigned char *in_dat,unsigned char *out_dat)
#ifdef ECC_CHECK
void ecc_gen(unsigned char *in_dat , unsigned char *out_dat)
{
unsigned short ii,jj ;
unsigned char b_dat[8] ,temp , cur_ecc;
unsigned char ecc_dat[22] ;

  for (ii=0;ii<22;ii++)
	ecc_dat[ii] = 0 ;

  for (ii=0;ii<256;ii++)
   {
	cur_ecc = 0 ;
	temp = in_dat[ii] ;

        for (jj=0;jj<8;jj++)
	{
	b_dat[jj] = (temp %2) ;
	cur_ecc ^= b_dat[jj] ;
	temp = temp >>1;
	}

	ecc_dat[0] ^= b_dat[0]^b_dat[2]^b_dat[4]^b_dat[6] ;	//* p1b
	ecc_dat[1] ^= b_dat[1]^b_dat[3]^b_dat[5]^b_dat[7] ;	//* p1
	ecc_dat[2] ^= b_dat[0]^b_dat[1]^b_dat[4]^b_dat[5] ;	//* p2b
	ecc_dat[3] ^= b_dat[2]^b_dat[3]^b_dat[6]^b_dat[7] ;	//* p2
	ecc_dat[4] ^= b_dat[0]^b_dat[1]^b_dat[2]^b_dat[3] ;	//* p4b
	ecc_dat[5] ^= b_dat[4]^b_dat[5]^b_dat[6]^b_dat[7] ;	//* p4

	if (ii & 0x01)
		ecc_dat[9] ^= cur_ecc ;		//* p8
	else
		ecc_dat[8] ^= cur_ecc ;		//* p8b
	if (ii & 0x02)
		ecc_dat[11] ^= cur_ecc ;	//* p16
	else
		ecc_dat[10] ^= cur_ecc ;	//* p16b
	if (ii & 0x04)
		ecc_dat[13] ^= cur_ecc ;	//* p32
	else
		ecc_dat[12] ^= cur_ecc ;	//* p32b
	if (ii & 0x08)
		ecc_dat[15] ^= cur_ecc ;	//* p64
	else
		ecc_dat[14] ^= cur_ecc ;	//* p64b
	if (ii & 0x10)
		ecc_dat[17] ^= cur_ecc ;	//* p128
	else
		ecc_dat[16] ^= cur_ecc ;	//* p128b
	if (ii & 0x20)
		ecc_dat[19] ^= cur_ecc ;	//* p256
	else
		ecc_dat[18] ^= cur_ecc ;	//* p256b
	if (ii & 0x40)
		ecc_dat[21] ^= cur_ecc ;	//* p512
	else
		ecc_dat[20] ^= cur_ecc ;	//* p512b
	if (ii & 0x80)
		ecc_dat[23] ^= cur_ecc ;	//* p1024
	else
		ecc_dat[22] ^= cur_ecc ;	//* p1024b
   }

	out_dat[0]=0 ;

	out_dat[0] |=      ecc_dat[0]|(ecc_dat[1]<<1)|(ecc_dat[2]<<2);
	out_dat[0] |= (ecc_dat[3]<<3)|(ecc_dat[4]<<4)|(ecc_dat[5]<<5) ;

	out_dat[1] = 0 ;
	out_dat[1] |=       ecc_dat[8]|(ecc_dat[9]<<1)|(ecc_dat[10]<<2)|(ecc_dat[11]<<3) ;
	out_dat[1] |= (ecc_dat[12]<<4)|(ecc_dat[13]<<5)|(ecc_dat[14]<<6)|(ecc_dat[15]<<7);

	out_dat[2] = 0 ;
	out_dat[2] |=      ecc_dat[16]|(ecc_dat[17]<<1)|(ecc_dat[18]<<2)|(ecc_dat[19]<<3) ;
	out_dat[2] |= (ecc_dat[20]<<4)|(ecc_dat[21]<<5)|(ecc_dat[22]<<6)|(ecc_dat[23]<<7) ;
}

#else

void ecc_gen(unsigned char *in_dat , unsigned char *out_dat)
{
	unsigned long checksum ;
	unsigned short ii ;
	checksum = 0 ;
	for (ii=0;ii<256;ii++)
		checksum += in_dat[ii] ;
	checksum += 0xff ;
	for (ii=0;ii<3;ii++)
	{
	out_dat[ii] = (checksum & 0xff) ;
	checksum = checksum >>8 ;
	}
}

#endif

void check_busy(void)
{
	unsigned long kk=0 ;

#ifdef AR2000
	*(unsigned int *) _READYpoint &= 0x0fdfdfdfd ; // turn on SPS_RXD to be input
	*(unsigned int *) _READYpoint |= 0x02020000 ; // turn on SPS_RXD to be input
#ifdef TARGET_BOARD_PR2000
	while (!((*(unsigned int *) _READYpoint) & 0x02))	// check SPS_RXD
#else
	while (!((*(unsigned int *) _READYpoint) & 0x20))	// check SPS_RXD
#endif
#else

#ifdef NANDBOOT
	while (!((*(unsigned int *) _READYpoint) & 0x08))	// check SPS_RXD, P0.3
#else//NANDBOOT
#ifdef TARGET_BOARD_PR2001
	while (!((*(unsigned int *) _READYpoint) & 0x02))	// check SPS_RXD
#elif defined(TARGET_BOARD_PR2001B) || defined(TARGET_BOARD_PR2001E) || defined(TARGET_BOARD_CHIPMOS) || defined(TARGET_BOARD_PR2001C) || defined(TARGET_BOARD_BR2001D)
	while (!((*(unsigned int *) _READYpoint) & 0x08))	// check SPS_RXD
#else
	while (!((*(unsigned int *) _READYpoint) & 0x08))	// check SPS_RXD
#endif
#endif//NORBOOT
#endif
	{
		if (kk++ >5000)
			break ;
	}
}


static void nfshCommandLatch(unsigned char cmd)
{
#ifdef AR2000
   	NFLASH_CLE = cmd;
#else
	NFLASH_ALE_LOW;
	NFLASH_CLE_HIGH;

	NFLASH_CLE = cmd;

	NFLASH_CLE_LOW;
#endif
}


static void nfshAddressLatch(unsigned long offset)
{
   unsigned char addr7, addr16, addr24,addr32;

   addr7  =  (unsigned char)offset & 0xff;
   addr16 = (unsigned char)(offset >> 9)  & 0xff;
   addr24 = (unsigned char)(offset >> 17) & 0xff;
   addr32 = (unsigned char)(offset >> 25) & 0xff;
#ifndef AR2000
	NFLASH_CLE_LOW;
	NFLASH_ALE_HIGH;
#endif
   NFLASH_ALE = addr7;
   NFLASH_ALE = addr16;
   NFLASH_ALE = addr24;

   if (current_nand_chip->prg_addr)
   {
      NFLASH_ALE = addr32;
   }
#ifndef AR2000
	NFLASH_ALE_LOW;
#endif
}


static void nfshBlockAddressLatch(unsigned long offset)
{
   unsigned char addr16, addr24 , addr32;

   addr16 = (unsigned char)(offset >> 9)  & 0xff;
   addr24 = (unsigned char)(offset >> 17) & 0xff;
   addr32 = (unsigned char)(offset >> 25) & 0xff;
#ifndef AR2000
	NFLASH_CLE_LOW;
	NFLASH_ALE_HIGH;
#endif
   NFLASH_ALE = addr16;
   NFLASH_ALE = addr24;
   if (current_nand_chip->prg_addr)
   {
      NFLASH_ALE = addr32;
   }
#ifndef AR2000
	NFLASH_ALE_LOW;
#endif
}


static void nfshInputDataLatch(unsigned char data[])
{
   register int i;
#ifndef AR2000
	NFLASH_CLE_LOW;
	NFLASH_ALE_LOW;
#endif
   for(i=0; i<NFLASH_FRAME_SIZE; i++) {
      NFLASH_DATA_WRITE = data[i];
   }
}


static void nfshReadDataLatch(unsigned char data[])
{
   register unsigned int	readIndex;
#ifndef AR2000
	NFLASH_CLE_LOW;
	NFLASH_ALE_LOW;
#endif
   for(readIndex=0; readIndex<NFLASH_FRAME_SIZE; readIndex++)
   {
      data[readIndex] = NFLASH_DATA_READ;
   }
}


static void nfshReadDataLatchSeq(unsigned char data[])
{
   register unsigned int	readIndex;
   register unsigned char	readTemp;
#ifndef AR2000
	NFLASH_CLE_LOW;
	NFLASH_ALE_LOW;
#endif
   for(readIndex=0; readIndex<NFLASH_FRAME_SIZE; readIndex++)
   {
      data[readIndex] = NFLASH_DATA_READ;
   }

   for(readIndex=NFLASH_FRAME_SIZE; readIndex<NFLASH_FRAME_SIZE+16; readIndex++)
   {
      readTemp = NFLASH_DATA_READ;
   }
}


static void nfshReadSpareLatch(unsigned char data[])
{
   register int i;
#ifndef AR2000
	NFLASH_CLE_LOW;
	NFLASH_ALE_LOW;
#endif
   for(i=0; i<16; i++)
   {
      data[i] = NFLASH_DATA_READ;
   }
}


// jason
static void nfshWriteSpareLatch(unsigned char data[])
{
   register int i;
#ifndef AR2000
	NFLASH_CLE_LOW;
	NFLASH_ALE_LOW;
#endif
   for(i=0; i<16; i++)
   {
      NFLASH_DATA_WRITE = data[i];
   }
}

static unsigned char nfshStatusRead()
{
   int i;
   unsigned char status;

   nfshCommandLatch(NFLASH_STATUS_READ);
   status = NFLASH_DATA_READ;
   return status;
}

static unsigned int CountZero( unsigned char data )
{
	unsigned int Counter=0;
	unsigned char Mask = 0x01;
	while ( Mask )
	{
		if ( (data & Mask) == 0x00 )// Find zero
			Counter++;
		Mask = Mask << 1;
	}
	return Counter;
}

unsigned long nfshInit()
{
  int chip_ID ;
  unsigned short cou=0 ;
#ifndef AR2000
	// configure device #4( PR2001 is #2 )
	*(unsigned int *) NFLASH_DEVICE = 0x10000007;

#ifdef NANDBOOT
	// switch DATAQ to be Nandflash R/B, input
	*(unsigned int *) _READYpoint &= 0x00f7f7f7;
	*(unsigned int *) _READYpoint |= 0x08080000;

	// configure GPIO2, GPIO1, GPIO0, corresponds to CLE, ALE and Cs repectively
	*(unsigned int *) (0xbfbf00a0) &= 0xf8f8f8f8;
	*(unsigned int *) (0xbfbf00a0) |= 0x00070701;

#else//NANDBOOT

#ifdef TARGET_BOARD_PR2001
	// switch DATAQ to be Nandflash R/B, input
	*(unsigned int *) _READYpoint &= 0xfdfdfdfd;
	*(unsigned int *) _READYpoint |= 0x02020000;

	// configure SM_T, SM_R, SM_CLK as GPIO output, corresponds to CLE, ALE and Cs repectively
	*(unsigned int *) (0xbfbf00b0) &= 0xcfcfcfcf;
	*(unsigned int *) (0xbfbf00b0) |= 0x00303000;
	NFLASH_DIS_CE;
#elif defined(TARGET_BOARD_PR2001B) || defined(TARGET_BOARD_PR2001E) || defined(TARGET_BOARD_CHIPMOS) || defined(TARGET_BOARD_PR2001C) || defined(TARGET_BOARD_BR2001D)
	// switch DATAQ to be Nandflash R/B, input
	*(unsigned int *) _READYpoint &= 0xf7f7f7f7;
	*(unsigned int *) _READYpoint |= 0x08080000;

	// configure SM_T, SM_R, SM_CLK as GPIO output, corresponds to CLE, ALE and Cs respectively
	*(unsigned int *) (0xbfbf00a0) &= 0xf9f9f9f9;
	*(unsigned int *) (0xbfbf00a0) |= 0x00060600;
	NFLASH_DIS_CE;

#else
	// switch DATAQ to be Nandflash R/B, input
	*(unsigned int *) _READYpoint &= 0x00f7f7f7;
	*(unsigned int *) _READYpoint |= 0x08080000;

	// configure SM_T, SM_R, SM_CLK as GPIO output, corresponds to CLE, ALE and Cs respectively
	*(unsigned int *) (0xbfbf00b0) &= 0xc7c7c7c7;
	*(unsigned int *) (0xbfbf00b0) |= 0x00383808;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -