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

📄 secnand.c

📁 samsung 最新芯片2450 的测试程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "system.h"
#include "Nand.h"
#include "SecNand.h"

#define		__POLLING		(0)

/*
*	Chip ID list
*
*	Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
*	options
*
* 	Pagesize; 0, 256, 512
*	0 	get this information from the extended chip ID
+	256	256 Byte page size
*	512	512 Byte page size
*/
struct nand_flash_dev nand_flash_ids[] = {
	{"NAND 1MiB 5V 8-bit", 		0x6e, 256, 1, 0x1000, 0},
	{"NAND 2MiB 5V 8-bit", 		0x64, 256, 2, 0x1000, 0},
	{"NAND 4MiB 5V 8-bit", 		0x6b, 512, 4, 0x2000, 0},
	{"NAND 1MiB 3,3V 8-bit", 	0xe8, 256, 1, 0x1000, 0},
	{"NAND 1MiB 3,3V 8-bit", 	0xec, 256, 1, 0x1000, 0},
	{"NAND 2MiB 3,3V 8-bit", 	0xea, 256, 2, 0x1000, 0},
	{"NAND 4MiB 3,3V 8-bit", 	0xd5, 512, 4, 0x2000, 0},
	{"NAND 4MiB 3,3V 8-bit", 	0xe3, 512, 4, 0x2000, 0},
	{"NAND 4MiB 3,3V 8-bit", 	0xe5, 512, 4, 0x2000, 0},
	{"NAND 8MiB 3,3V 8-bit", 	0xd6, 512, 8, 0x2000, 0},

	{"NAND 8MiB 1,8V 8-bit", 	0x39, 512, 8, 0x2000, 0},
	{"NAND 8MiB 3,3V 8-bit", 	0xe6, 512, 8, 0x2000, 0},
	{"NAND 8MiB 1,8V 16-bit", 	0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
	{"NAND 8MiB 3,3V 16-bit", 	0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},

	{"NAND 16MiB 1,8V 8-bit", 	0x33, 512, 16, 0x4000, 0},
	{"NAND 16MiB 3,3V 8-bit", 	0x73, 512, 16, 0x4000, 0},
	{"NAND 16MiB 1,8V 16-bit", 	0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
	{"NAND 16MiB 3,3V 16-bit", 	0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},

	{"NAND 32MiB 1,8V 8-bit", 	0x35, 512, 32, 0x4000, 0},
	{"NAND 32MiB 3,3V 8-bit", 	0x75, 512, 32, 0x4000, 0},
	{"NAND 32MiB 1,8V 16-bit", 	0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
	{"NAND 32MiB 3,3V 16-bit", 	0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},

	{"NAND 64MiB 1,8V 8-bit", 	0x36, 512, 64, 0x4000, 0},
	{"NAND 64MiB 3,3V 8-bit", 	0x76, 512, 64, 0x4000, 0},
	{"NAND 64MiB 1,8V 16-bit", 	0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
	{"NAND 64MiB 3,3V 16-bit", 	0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},

	{"NAND 128MiB 1,8V 8-bit", 	0x78, 512, 128, 0x4000, 0},
	{"NAND 128MiB 1,8V 8-bit", 	0x39, 512, 128, 0x4000, 0},
	{"NAND 128MiB 3,3V 8-bit", 	0x79, 512, 128, 0x4000, 0},
	{"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
	{"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
	{"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
	{"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},

	{"NAND 256MiB 3,3V 8-bit", 	0x71, 512, 256, 0x4000, 0},

	/* These are the new chips with large page size. The pagesize
	* and the erasesize is determined from the extended id bytes
	*/
	/*512 Megabit */
	{"NAND 64MiB 1,8V 8-bit", 	0xA2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 64MiB 3,3V 8-bit", 	0xF2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 64MiB 1,8V 16-bit", 	0xB2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
	{"NAND 64MiB 3,3V 16-bit", 	0xC2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},

	/* 1 Gigabit */
	{"NAND 128MiB 1,8V 8-bit", 	0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 128MiB 3,3V 8-bit", 	0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 128MiB 1,8V 16-bit", 	0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
	{"NAND 128MiB 3,3V 16-bit", 	0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},

	/* 2 Gigabit */
	{"NAND 256MiB 1,8V 8-bit", 	0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 256MiB 3,3V 8-bit", 	0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 256MiB 1,8V 16-bit", 	0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
	{"NAND 256MiB 3,3V 16-bit", 	0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},

	/* 4 Gigabit */
	{"NAND 512MiB 1,8V 8-bit", 	0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 512MiB 3,3V 8-bit", 	0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 512MiB 1,8V 16-bit", 	0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
	{"NAND 512MiB 3,3V 16-bit", 	0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},

	/* 8 Gigabit */
	{"NAND 1GiB 1,8V 8-bit", 	0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 1GiB 3,3V 8-bit", 	0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 1GiB 1,8V 16-bit", 	0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
	{"NAND 1GiB 3,3V 16-bit", 	0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},

	/* 16 Gigabit */
	{"NAND 2GiB 1,8V 8-bit", 	0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 2GiB 3,3V 8-bit", 	0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
	{"NAND 2GiB 1,8V 16-bit", 	0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
	{"NAND 2GiB 3,3V 16-bit", 	0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},

	/* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
	 * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
	 * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
	 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
	 * There are more speed improvements for reads and writes possible, but not implemented now
	 */
	{"AND 128MiB 3,3V 8-bit",	0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},

	{NULL,}
};


static unsigned char g_uSpareData[128];

/*
*	Manufacturer ID list
*/
struct nand_manufacturers nand_manuf_ids[] = {
	{MAN_ID_TOSHIBA, "Toshiba"},
	{MAN_ID_SAMSUNG, "Samsung"},
	{MAN_ID_FUJITSU, "Fujitsu"},
	{MAN_ID_NATIONAL, "National"},
	{MAN_ID_RENESAS, "Renesas"},
	{MAN_ID_STMICRO, "ST Micro"},
    {MAN_ID_HYNIX, "Hynix"},
	{0x0, "Unknown"}
};

NANDINFO	sNandInfo;

extern int NFConDone;
extern int NFECCDecDone;
extern int NFECCEncDone;

#define		PAGE_LEN_ECC8		512
#define		VAL_LEN_ECC8		13


unsigned int PrintNandInfo(void)
{
	if(!sNandInfo.uPageSize)
	{
		printf("\n Error : No Page Size");
	}
	else
	{		
	printf("\n===========================================================");
	printf("\n1th ID : 0x%x\t Manufacterer", sNandInfo.uId[0]);
	printf("\n2nd ID : 0x%x\t Device ID", sNandInfo.uId[1]);
	printf("\n3rh ID : 0x%x", sNandInfo.uId[2]);
	printf("\n4th ID : 0x%x", sNandInfo.uId[3]);
	printf("\n5th ID : 0x%x", sNandInfo.uId[4]);
	printf("\nNand Size :  %ld MB, \t%d B", sNandInfo.uNandSize>>20, sNandInfo.uNandSize);
	printf("\nPage Size : %d Bytes", sNandInfo.uPageSize);
	printf("\nBlock Size : %d KBytpes\n", sNandInfo.uBlockSize >> 10);
	printf("\n512Bytes Per Page : %d", sNandInfo.u512BytesPerPage);
	
	printf("\nNand Col Cycle : %d", sNandInfo.uColCycle);
	printf("\nNand Row Cycle : %d", sNandInfo.uRowCycle);	
	printf("\nNand Row Addr By Block Size : %d", sNandInfo.uBlockShift);
	printf("\nPages per Block : %d pages\n", sNandInfo.uPagesPerBlock);
	
	printf("\nNand Total Address : A%d", sNandInfo.uAddrCycleNum);
	printf("\nIs MLC ? : %d", sNandInfo.uIsMLC);
	printf("\nInter Chip Number : %d", sNandInfo.uIntChipNum);
	printf("\nCell Type : %d Level Cell", sNandInfo.uCellType);
	printf("\nNumber of Simultaneously Programmed Pages : %d", sNandInfo.uNSimProgPages);
	printf("\nInterleave Program Between multiple chips : %d", sNandInfo.uInterleaveProg);
	printf("\nCache Program : %d", sNandInfo.uCacheProg);	
	printf("\nRedundant Area Size : %d(byte/512bytes)", sNandInfo.uRedundantAreaSize);
	printf("\nOrganization : x%d", sNandInfo.uOrganization);
	printf("\nSerial Access Minimum : %d", sNandInfo.uSerialAccessMin);
	printf("\nPlane Number : %d", sNandInfo.uPlaneNum);
	printf("\nPlane Size : %dMB", sNandInfo.uPlaneSize>>20);
	printf("\n===========================================================");
	}
	return 0;	
}



void ResetNand(void)
{
	NF_nFCE_L();

	NF_CLEAR_RB();
	NF_CMD(CMD_RESET);	//reset command
	NF_DETECT_RB();
	
	NF_nFCE_H();

}

	/////// for S3C2450		///////////////////////////////////////////////////////////
	//--> [NFCONF]
	// TACLS			[14:12]	CLE&ALE duration = HCLK*TACLS.
	// TWRPH0			[10:8]	TWRPH0 duration = HCLK*(TWRPH0+1)
	// TWRPH1			[6:4]	TWRPH1 duration = HCLK*(TWRPH1+1)
	// PageSize(R)		[3]		NAND memory page size
	//							when [3]==0, 0:512, 1:2048 bytes/page.
	//							when [3]==1, 0:2048, 1:4096 bytes/page by PageSize_Ext
	// PageSize_Ext(R)	[2]		when [2]==0, Small Size Nand Flash
	//							when [2]==1, Large Size Nand Flash
	// AddrCycle(R)		[1]		NAND flash addr size
	//							when [3]==0, 0:3-addr, 1:4-addr.
	//							when [3]==1, 0:4-addr, 1:5-addr.
	// BusWidth(R/W) 	[0]		NAND bus width. 0:8-bit, 1:16-bit.
	
	//--> [NFCONT]
	// ECC Direction	[18]	0:Decoding(4/8 ECC)
	//							1:Encoding(4/8 ECC)
	// Lock-tight		[17]	0:Disable lock, 1:Enable lock.
	// Soft Lock		[16]	0:Disable lock, 1:Enable lock.
	// EnbECCDecINT 	[12]	0:Disable Interrupt,	1:Enable Interrupt (Enable/Disable 4/8ECC decoding Done Interrupt)
	// 8bit Stop		[11]	8-bit ECC en/decoding operation initialization
	// EnablillegalAcINT[10]	Illegal access interupt control. 0:Disable, 1:Enable
	// EnbRnBINT		[9]		RnB interrupt. 0:Disable, 1:Enable
	// RnB_TrandMode	[8]		RnB transition detection config. 0:Low to High, 1:High to Low
	// SpareECCLock		[7]		0:Unlock, 1:Lock
	// MainECCLock		[6]		0:Unlock, 1:Lock
	// InitMECC(W)		[5]		1:Init main area ECC decoder/encoder.
	// InitSECC(W)		[4]		1:Init spare area ECC decoder/encoder.
	// Reg_nCE1			[2]		0:nFCE=0, 1:nFCE=1.
	// Reg_nCE0			[1]		0:nFCE=0, 1:nFCE=1.
	// NANDC Enable		[0]		operating mode. 0:Disable, 1:Enable.
	
	
void * nfc_func[][2]=
{  	
	(void *)ReadID,				"Read ID         ",
	(void *)ResetNand,			"Nand reset      ",  
	(void *)TestEraseBlock,		"Erase Block     ",
	(void *)TestReadPage,		"Read Page       ",  
	(void *)TestWritePage,		"Write Page      ",  
	(void *)Test_Lock,			"Lock Test       ",
	(void *)ClearSoftLock, 		"Clear Soft Lock ",
	(void *)WriteDramImage2Nand,"Write Dram Image",
	(void *)ReadNandImage2Dram, "Read From Nand  ",
	0,0
};


static void PrintSubMessage(void)
{
	int i;
	
	i=0;	
	printf("\n\n");
	while(1)
	{   //display menu
	    printf("%2d:%s",i,nfc_func[i][1]);
	    i++;
	    if((int)(nfc_func[i][0])==0)
	    {
		 printf("\n");
		 break;
	    }
	    if((i%4)==0) printf("\n");
	}
}


void TestNFC(void)
{
	int i;	

	ReadID();
  	while(1) 
  	{
		PrintSubMessage();
		printf("\nSelect(-1 to exit): ");
		i = GetIntNum();
		
		if(i==-1) break;
		
		if(i>=0 && (i<(sizeof(nfc_func)/8)) ) 
	    	( (void (*)(void)) (nfc_func[i][0]) )();	// execute selected function.
	}

}


//Normal Initalization of NFC
void InitNFC(void)
{
	rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);		
	rNFCONT = (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(0x3<<1)|(1<<0);			  
}



void ReadID(void)
{
	unsigned char uId[16], i, uScan;	
	unsigned int uTemp, uSize;
	
	memset(&sNandInfo,0,sizeof(NANDINFO));
	
	InitNFC();
	printf("\nK9F5608 : 2 IDs");
	printf("\nK9F1208 : 4 IDs");
	printf("\nK9HBG08U1M / K9MZG08U3M / K9LAG08U0M / K9MCG08U5M : 5 IDs");
	printf("\nK9GAG08U0M / K9HCG08U5M / K9GAG08B0M / K9LBG08U1M : 5 IDs");	
	printf("\n\nHow Many IDs? (2/3/4/5/6/7) : ");
		
	sNandInfo.uNId = 5;

	NF_nFCE_L();
	NF_CMD(CMD_READID);
    NF_ADDR(0x00);

	for (i=0; i<10; i++);//delay

	for(i=0; i<sNandInfo.uNId; i++)	
		sNandInfo.uId[i] = NF_RDDATA8();
				
	NF_nFCE_H();		
	
	
	if((sNandInfo.uId[0]==0xEC || sNandInfo.uId[0]==0x98) && ((sNandInfo.uId[1]==0x76)||(sNandInfo.uId[1]==0x75)))	sNandInfo.uNId = 4;
	
	if(sNandInfo.uNId < 5)
	{
		sNandInfo.uPageSize = 512;
		sNandInfo.uNandSize = 64*1024*1024;
		sNandInfo.uColCycle = 1;
		if((sNandInfo.uId[1]==0x75))
		{			
			sNandInfo.uRowCycle = 2;
		}
		else
		{			
			sNandInfo.uRowCycle = 3;
		}
		sNandInfo.uBlockSize = 16*1024;
		sNandInfo.u512BytesPerPage = 1;
		sNandInfo.uRedundantAreaSize = 16;
		
		//Scan Cell Type	
		uTemp = (sNandInfo.uId[2]>>2)& 0x03;
		sNandInfo.uCellType = 1;
		for(i=0;i<=uTemp;i++)	sNandInfo.uCellType *= 2;
		sNandInfo.uIsMLC = uTemp;		
	}
	else
	{
		//------> 3rd ID
		uTemp = sNandInfo.uId[2]& 0x03;
		//Scan Internal Chip Number
		sNandInfo.uIntChipNum = 1;					
		for(i=0;i<uTemp;i++)	sNandInfo.uIntChipNum *= 2;				
			
		//Scan Cell Type	
		uTemp = (sNandInfo.uId[2]>>2)& 0x03;
		sNandInfo.uCellType = 1;
		for(i=0;i<=uTemp;i++)	sNandInfo.uCellType *= 2;
		sNandInfo.uIsMLC = uTemp;
			
			
		uTemp = (sNandInfo.uId[2]>>4)& 0x03;
		sNandInfo.uNSimProgPages = 1;
		for(i=0;i<uTemp;i++)	sNandInfo.uNSimProgPages *= 2;				
			
		sNandInfo.uInterleaveProg = (sNandInfo.uId[2]>>6)& 0x01;
		sNandInfo.uCacheProg = (sNandInfo.uId[2]>>7)& 0x01;
		
		//------> 4th ID
		uTemp = sNandInfo.uId[3]& 0x03;
		sNandInfo.uPageSize = 1024;					
		for(i=0;i<uTemp;i++)	sNandInfo.uPageSize *=2;
		sNandInfo.u512BytesPerPage = sNandInfo.uPageSize >> 9;		
					
		uTemp = (sNandInfo.uId[3]>>2)& 0x01;
		if(uTemp)		sNandInfo.uRedundantAreaSize = 16;
		else			sNandInfo.uRedundantAreaSize = 8;
		
		uTemp = (sNandInfo.uId[3]>>4)& 0x03;
		sNandInfo.uBlockSize = 64*1024;
		for(i=0;i<uTemp;i++)	sNandInfo.uBlockSize *=2;
					
		uTemp = (sNandInfo.uId[3]>>6)& 0x01;//TBD
		if(uTemp)		sNandInfo.uOrganization = 16;
		else			sNandInfo.uOrganization = 8;

		//------> 5th ID
		uTemp = (sNandInfo.uId[4]>>2)& 0x03;
		sNandInfo.uPlaneNum = 1;					
		for(i=0;i<uTemp;i++)	sNandInfo.uPlaneNum *= 2;				
			
		uTemp = (sNandInfo.uId[4]>>4)& 0x07;
		sNandInfo.uPlaneSize = (8388608); //64*1024*1024/8
		for(i=0;i<uTemp;i++)	sNandInfo.uPlaneSize *=2;	
		
		sNandInfo.uNandSize = sNandInfo.uPlaneNum*sNandInfo.uPlaneSize;
		
		uTemp = sNandInfo.uPageSize;		
		for(i=0; uTemp>1; i++)		uTemp>>=1;
		uTemp = i;
		sNandInfo.uAddrCycleNum+=uTemp;
		for(i=1; uTemp>8; i++)		uTemp-=8;		
		sNandInfo.uColCycle = i;		
		
		uTemp = sNandInfo.uPageSize;
		uSize = sNandInfo.uNandSize;
		for(i=0; uTemp>1; i++)
		{	
			uTemp>>=1;			
			uSize>>=1;
		}
		for(i=0; uSize>1; i++)			uSize>>=1;
		uSize = i;
		sNandInfo.uAddrCycleNum+=uSize;
		for(i=1; uSize>8; i++)			uSize-=8;
		sNandInfo.uRowCycle = i;			
		
	}	
	sNandInfo.uAddrCycle = sNandInfo.uColCycle + sNandInfo.uRowCycle;	
	uTemp = sNandInfo.uPageSize;
	uSize = sNandInfo.uBlockSize;
	
	for(i=0; uTemp>1; i++)
	{	
		uTemp>>=1;			
		uSize>>=1;
	}
	if(sNandInfo.u512BytesPerPage > 1)  //large block
	{		
		rNFCONF |= (1<<2);
		if(sNandInfo.uAddrCycle ==4) //addr cycle : 4
		{
			rNFCONF &= ~(1<<1);
			if(sNandInfo.u512BytesPerPage == 4)
			{
				rNFCONF &= ~(1<<3);
			}
			else
			{
				rNFCONF |= (1<<3);
			}
		}

⌨️ 快捷键说明

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