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

📄 onenand.c

📁 Samsung S3C2443 Test program source code
💻 C
📖 第 1 页 / 共 2 页
字号:
#if USE_DMA
				if (data_write&1)
					dma_memcpy( (U32)Address, __OND_DataRAM1_BASE, 0, DATABUFFERSIZE );
				else
					dma_memcpy( (U32)Address, __OND_DataRAM0_BASE, 0, DATABUFFERSIZE );
#else
				if (data_write&1)
					memcpy( (U32 *)__OND_DataRAM1_BASE, Address, DATABUFFERSIZE);
				else
					memcpy( (U32 *)__OND_DataRAM0_BASE, Address, DATABUFFERSIZE);
#endif

				Address+=(DATABUFFERSIZE>>2);
				data_write++;
			}
		}

		if (data_write > 1) {
			while (!(rOND_INT_STATUS & (1<<15)));

			if (rOND_CON_STATUS & (1<<10))
				printf("ECC Fail.\n");
			else			
				data_program++;
		}
	}
}


//======================== [ OneNAND test code ] ===========================
void OneNAND_ReadID( void)
{
	printf("\n\n< Read OneNAND information >\n");
	printf("Manufacturer ID       : 0x%02x\n",rOND_MANU);
	printf("Device ID             : 0x%02x\n",rOND_DEV);
	printf("Version ID            : 0x%02x\n",rOND_VER);
	printf("Data buffer size      : %d KB\n",((rOND_DBUFSIZE<<1)/(rOND_BUFAMOUNT>>8))>>10);
	printf("Boot buffer size      : %d KB\n",((rOND_BBUFSIZE<<1)/(rOND_BUFAMOUNT&0xff))>>10);
	printf("Amount of D/B buffers : %d, %d\n",rOND_BUFAMOUNT>>8,rOND_BUFAMOUNT&0xff);
	printf("Technology            : 0x%02x\n\n", rOND_TECH);
}


void OneNAND_Program( void)
{
	U16	block;
	U32	size;
	
	printf("\nOneNAND block program from [0x%08x]\n",(_NONCACHE_STARTADDRESS+0x00500000));

	printf("Enter block # to program : ");
	block = GetIntNum();

	printf("Enter size to program : ");
	size = GetIntNum();

	OND_write( (U32 *)(_NONCACHE_STARTADDRESS+0x00500000), size, block);

	printf("Program complete.\n");
}


void OneNAND_Read_Page( void)
{
	U16	block=0;
	U16	page=0;
	U32	i;
	U32	*Addr;

	printf("\nOneNAND block read\n");

	printf("Enter block # to read : ");
	block = GetIntNum();

	printf("Enter page # to read : ");
	page = GetIntNum();

	if (OND_page_load(block,page)==0) {

		Addr=(U32 *)__OND_DataRAM0_BASE;

		for(i=0;i<DATABUFFERSIZE;i+=sizeof(U32)) {

			if ((i&0x1f)==0)
				printf("\n%08x : ",i);

			printf("%08x ",*Addr++);
		
		}
		putchar('\n');
	}
}


void OneNAND_Write_Page( void)
{
	U16	block=0;
	U16	page=0;

	printf("\nOneNAND block write\n");

	printf("Enter block # to write : ");
	block = GetIntNum();

	printf("Enter page # to write : ");
	page = GetIntNum();

	if (OND_page_program(block,page)==0)
		printf("Block %d, page %d was writed.\n",block,page);

	printf("\n");
}


void OneNAND_Erase_All( void)
{
	U16	block;
	
	printf("\nOneNAND all block erase\n");
	
	for(block=0;block<1024;block++) {
		OND_unlock_block( block);
		OND_erase_block( block);
		if ((block&0x3f)==0)
			printf("[%d]",block);
	}

	printf("\nAll block was erased.\n");
	
	printf("\n");
}


void OneNAND_Erase_Block( void)
{
	U16	block=0;

	printf("\nOneNAND block erase\n");

	printf("Enter block # to erase : ");
	block = GetIntNum();
	
	OND_unlock_block( block);
	
	if (OND_erase_block( block)==0)
		printf("Block %d was erased.\n",block);
	
	printf("\n");
}


void OneNAND_Unlock_Block( void)
{
	U16	block=0;

	printf("\nOneNAND block unlock\n");

	printf("Enter block # to unlock : ");
	block = GetIntNum();
	
	OND_unlock_block( block);

	printf("\n");
}


void OneNAND_Lock_Block( void)
{
	U16	block=0;

	printf("\nOneNAND block lock\n");

	printf("Enter block # to lock : ");
	block = GetIntNum();
	
	OND_lock_block( block);
		
	printf("\n");
}


void SMC_Config4OneNAND(U32 nBank)
{
  	U32 sel_sync = 2;
  	U32 sel_burst = 4; 
  	U32 burst_mode = 1;
  	U32 mux_mode = 0;
	U16 sysconfig1;
	volatile SMC_REGS *pSmcRegs;
	
	pSmcRegs = (volatile SMC_REGS *)(SMC_REG_BASE+SMC_REG_OFFSET*nBank);

	printf("Select OneNAND interface mode, Demuxed mode(0-D)/Muxed mode(1) : ");
	mux_mode = GetIntNum();
	if (mux_mode == 1) 
		rSMBONETYPER |= (1<<nBank); // muxed mode
	else 
		rSMBONETYPER &= ~(1<<nBank); // demuxed mode

	printf("Select sync mode, Synchronous(1)/Asynchronous(2-D) : ");
	sel_sync = GetIntNum();
	if (sel_sync == 1)	
	{
		printf("Select burst mode, no burst(0-D)/4-words(1)/8-words(2)/16-words(3)/Continuous(4) : ");
		sel_burst = GetIntNum();
		burst_mode = 1;
		if ( (sel_burst == (U32)(-1)) || (sel_burst == 0) )
		{
			sel_burst = 4;			
			burst_mode = 0; // default no burst
		}
	}
		
	// defualt setting for reading correct rOND_SYS_CONFIG1
	pSmcRegs->rSmbWstRdr = 3;	// read wait state. [4:0] 1 ~ 10. only 4 @ 50MHz(Mux). sync burst only 4
	pSmcRegs->rSmbWstWrr = 3;	// write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
	pSmcRegs->rSmbWstOenr = 2;	// OE assertion delay. [3:0] 1 ~ 2. min 3 @ 50MHz
	pSmcRegs->rSmbWstWenr = 2;	// WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz

	sysconfig1=rOND_SYS_CONFIG1; // reading 
	printf("rOND_SYS_CONFIG1 = 0x%x \n", sysconfig1);

	//  ensure that ther are no memory transfers.
	rCLKDIV0 = (rCLKDIV0 & ~(1<<3)) | (1<<3); // select HALFHCLK : 0=HCLK, 1=HCLK/2
	rSMCCR = (rSMCCR & ~(3<<1)) | (1<<1)|(1); // SMC MemClkRatio setting should be equal HALFHCLK of CLKDIV0
	pSmcRegs->rSmbIdCyr = 0;
	printf("rCLKDIV0 = 0x%x\n", rCLKDIV0);
	printf("rSMBIDCYR%d = 0x%x\n", nBank, pSmcRegs->rSmbIdCyr);
	//  wait 4 SMC clocks

	switch(sel_sync) {
		case 1: // sync.
			printf("rSMBCR%d = 0x%x \n", nBank, pSmcRegs->rSmbCr);
			// rOND_SYS_CONFIG1
			// [15] : sync(1), async(0), 
			// [12:14] : Burst read latency. same as WSTRD value in demux. 
			// [9:11] : Continuous(0), 4word(1), 8word(2), 16word(3), 32word(4) - only burst
			rOND_SYS_CONFIG1 = (sysconfig1& ~(0x7f<<9))|(1<<15)|(3<<12)|((sel_burst%4)<<9);

			Delay(1);
			printf("sync = %d, sel burst = %d, burst mode = %d\n", sel_sync, sel_burst, burst_mode);
		
			// rSMBCR0
			// [10:11] : 4word(0), 8word(1), 16word(2), continuous(3) - only burst
			// [9] : sync(1), async(0)
			// [8] : burst(1), no burst(0)
			pSmcRegs->rSmbCr = (pSmcRegs->rSmbCr & ~((0xf<<8)|(0xf<<16)|(1<<14)|0x3)) 
					|((sel_burst-1)<<10)|(1<<9)|(burst_mode<<8) 	// set SSMC as read burst. 
					|(0<<18)|(0<<17)|(0<<16) 	// set SSMC write 
					|(0<<14)|(0<<1)|(1); // caution! SMWAIT polarity setting. now active low.
			pSmcRegs->rSmbWstBrdr = 0;
			printf("rSMBONETYPER = 0x%x\n",rSMBONETYPER);
			printf("\nSynchronous access mode \n");

			if (mux_mode)
			{   				
				pSmcRegs->rSmbWstRdr = 3;	// read wait state. [4:0] 1 ~ 10. only 4 @ 50MHz(Mux). sync burst only 4
				pSmcRegs->rSmbWstWrr = 3;	// write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
				pSmcRegs->rSmbWstOenr = 2;	// OE assertion delay. [3:0] 1 ~ 2. min 3 @ 50MHz
				pSmcRegs->rSmbWstWenr = 2;	// WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz
			}
			else // previous setting 3,3,1,2
			{
				pSmcRegs->rSmbWstRdr = 3;	// read wait state. [4:0] 1 ~ 10. only 4 @ 50MHz(Mux). sync burst only 4
				pSmcRegs->rSmbWstWrr = 3;	// write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
				pSmcRegs->rSmbWstOenr = 2;	// OE assertion delay. [3:0] 1 ~ 2. min 3 @ 50MHz
				pSmcRegs->rSmbWstWenr = 2;	// WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz
			}
		break;
		default: // async.
			rOND_SYS_CONFIG1 = (sysconfig1& ~(0xf<<12))|(0<<15)|(3<<12);
			pSmcRegs->rSmbCr = (pSmcRegs->rSmbCr & ~(0xf<<8))|(0<<10)|(0<<9)|(0<<8); 	// set SSMC as async read. 
			printf("Asynchronous access mode \n");

			// defualt setting 3,3,2,3
			pSmcRegs->rSmbWstRdr = 3;	// read wait state. [4:0] 1 ~ 10. min 3 @ 50MHz(Mux)
			pSmcRegs->rSmbWstWrr = 3;	// write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
			pSmcRegs->rSmbWstOenr = 2;	// OE assertion delay. [3:0] 1 ~ 2. min 2 @ 50MHz
			pSmcRegs->rSmbWstWenr = 2;	// WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz
		break;
	}

	sysconfig1=rOND_SYS_CONFIG1;
	printf("rOND_SYS_CONFIG1 = 0x%x \n", sysconfig1);
	printf("rSMBCR%d = 0x%x \n", nBank, pSmcRegs->rSmbCr);
	printf("rSMBWSTRDR%d = 0x%x\n", nBank, pSmcRegs->rSmbWstRdr);	
	printf("rSMBWSTWRR%d = 0x%x\n", nBank, pSmcRegs->rSmbWstWrr);	
	printf("rSMBWSTOENR%d = 0x%x\n", nBank, pSmcRegs->rSmbWstOenr);	
	printf("rSMBWSTWENR%d = 0x%x\n\n", nBank, pSmcRegs->rSmbWstWenr);	
//	rSMCCR = (1<<1)|(1<<0);
}


void OneNAND_Performance_Test(void)
{
	U16	block=0;
	U32	size=0;
	U32	i;
	U32	*SrcAddr, *DstAddr;
	U32	t_cnt=1;
	U8	d_correct=0;
	
#if USE_DMA
	U8	dma_burst;
	U8	dma_tw;
#endif
	
	SetResStopwatch(1000); // stopwatch 
	
//	rGPDCON = rGPDCON & ~(3<<22) | (1<<22); // GPD11 output setn - B'd TPD01
//	rGPDDAT |= (1<<11); // high

	// SSMC parameter value setting 
	SMC_Config4OneNAND(OND_BANK);
	
	printf("\nrOND_SYS_CONFIG1 = 0x%x \n", rOND_SYS_CONFIG1);
	printf("rOND_DBUFSIZE = 0x%x \n", rOND_DBUFSIZE);
	printf("rOND_BBUFSIZE = 0x%x \n", rOND_BBUFSIZE);
	printf("rOND_BUFAMOUNT = 0x%x \n", rOND_BUFAMOUNT);
	
	printf("\n Enter start block # to write [D:700]: ");
	block = GetIntNum();
	printf(" Enter data size # to write [D:2MB, MAX:10MB]: ");
	size = GetIntNum();
	
#if USE_DMA
	printf(" Enter dma transfer width [0]1byte, [1]2byte, [2]4byte : ");
	dma_tw = (U8)GetIntNum();
	printf("\n Enter dma burst size [0]1, [1]4, [2]8, [3]16, [4]32, [5]64, [6]128, [7]256 : ");
	dma_burst = (U8)GetIntNum();
	set_dma_control(dma_burst, dma_tw);
#endif

	// Default test block variable setting
	if ( (block == (U16)(-1)) || (block<1) )
		block 	= 700; // start block
	if ( (size == (U32)(-1)) || (size<2048) )	
		size 	= 0x200000; // 16 blocks = 2MB
	SrcAddr	= (U32 *)(_NONCACHE_STARTADDRESS+0x00500000);
	printf(" Start block : %d, Data size : %d Bytes\n", block, size);

	// fill buffer data
	for (i=0; i<size ;i+=4)
		*SrcAddr++ = i;
	
//	rGPDDAT &= ~(1<<11); // low
//	Delay(1);
//	rGPDDAT |= (1<<11); // high
	// write test by block unit(internally page unit), Write-While-Program Operation
	StartStopwatch();
	OND_write( (U32 *)(_NONCACHE_STARTADDRESS+0x00500000), size, block);
	t_cnt = EndStopwatch();
//	rGPDDAT &= ~(1<<11); // low
//	Delay(2);
//	rGPDDAT |= (1<<11); // high
	printf("\n %d Bytes WRITE time by block unit : %d us", size, t_cnt);
	printf("\n %.3f Byte/sec\n", (float)size/(float)t_cnt*1000000 ); // for us order

	printf("Press any key to continue\n");
	getchar();
	
	// read test by block unit(internally page unit), Read-While-Load Operation
	StartStopwatch();
	OND_read( (U32 *)(_NONCACHE_STARTADDRESS+0x01000000), size, block);
	t_cnt = EndStopwatch();
	printf("\n %d Bytes READ time by block unit : %d us", size, t_cnt);
	printf("\n %.3f Byte/sec\n", (float)size/(float)t_cnt*1000000 );

	// verify data	
	SrcAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x00500000);
	DstAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x01000000);
	for (i=0; i<size ;i+=4)
		if (*SrcAddr++ != *DstAddr++)
			d_correct = 1;
	if(d_correct == 1)
		printf("\n Copied data error!! \n\n");
	else printf("\n Copied data OK!! \n\n");

}


void OneNAND_TimingCheck( void)
{
	U32 R1, R2, R3, R4, W1, W2, W3, W4;
	volatile SMC_REGS *pSmcRegs;
	
	pSmcRegs = (volatile SMC_REGS *)(SMC_REG_BASE+SMC_REG_OFFSET*OND_BANK);
	
	printf("Read, write test \n");

	pSmcRegs->rSmbWstRdr = 4;	// read wait state. [4:0] 1 ~ 10. only 4 @ 50MHz(Mux). sync burst only 4
	pSmcRegs->rSmbWstWrr = 3;	// write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
	pSmcRegs->rSmbWstOenr = 1;	// OE assertion delay. [3:0] 1 ~ 2. min 3 @ 50MHz
	pSmcRegs->rSmbWstWenr = 3;	// WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz
	R1 = rOND_DEV; // read
	rOND_START_ADDR1 = 0x8355; // write, addr1 is effective about 0~8,15bit
	W1 = rOND_START_ADDR1; // read
	
	pSmcRegs->rSmbWstRdr = 10;	// read wait state. [4:0] 1 ~ 10. only 4 @ 50MHz(Mux). sync burst only 4
	pSmcRegs->rSmbWstWrr = 10;	// write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
	pSmcRegs->rSmbWstOenr = 5;	// OE assertion delay. [3:0] 1 ~ 2. min 3 @ 50MHz
	pSmcRegs->rSmbWstWenr = 5;	// WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz
	R2 = rOND_DEV; // read
	rOND_START_ADDR1 = 0x8355; // write
	W2 = rOND_START_ADDR1; // read

	pSmcRegs->rSmbWstRdr = 4;	// read wait state. [4:0] 1 ~ 10. only 4 @ 50MHz(Mux). sync burst only 4
	pSmcRegs->rSmbWstWrr = 3;	// write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
	pSmcRegs->rSmbWstOenr = 2;	// OE assertion delay. [3:0] 1 ~ 2. min 3 @ 50MHz
	pSmcRegs->rSmbWstWenr = 2;	// WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz
	R3 = rOND_DEV; // read
	rOND_START_ADDR1 = 0x8355; // write
	W3 = rOND_START_ADDR1; // read

	pSmcRegs->rSmbWstRdr = 7;	// read wait state. [4:0] 1 ~ 10. only 4 @ 50MHz(Mux). sync burst only 4
	pSmcRegs->rSmbWstWrr = 7;	// write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
	pSmcRegs->rSmbWstOenr = 1;	// OE assertion delay. [3:0] 1 ~ 2. min 3 @ 50MHz
	pSmcRegs->rSmbWstWenr = 3;	// WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz
	R4 = rOND_DEV; // read
	rOND_START_ADDR1 = 0x8355; // write
	W4 = rOND_START_ADDR1; // read

	printf("R1 = 0x%x, R2 = 0x%x, R3 = 0x%x, R4 = 0x%x\n",R1,R2,R3,R4);
	printf("W1 = 0x%x, W2 = 0x%x, W3 = 0x%x, W4 = 0x%x\n",W1,W2,W3,W4);

	printf("\n\n< Read OneNAND information >\n");
	printf("Manufacturer ID       : 0x%02x\n",rOND_MANU);
	printf("Device ID             : 0x%02x\n",rOND_DEV);
	printf("Version ID            : 0x%02x\n",rOND_VER);
	printf("Data buffer size      : %d KB\n",((rOND_DBUFSIZE<<1)/(rOND_BUFAMOUNT>>8))>>10);
	printf("Boot buffer size      : %d KB\n",((rOND_BBUFSIZE<<1)/(rOND_BUFAMOUNT&0xff))>>10);
	printf("Amount of D/B buffers : %d, %d\n",rOND_BUFAMOUNT>>8,rOND_BUFAMOUNT&0xff);
	printf("Technology            : 0x%02x\n\n", rOND_TECH);
}


void OneNAND_Burst_Read( void)
{
	U16	block=0;
	U16	page=0;
	U32	i;
	U32	*Addr;

	printf("\nOneNAND block read\n");

	printf("Enter block # to read : ");
	block = GetIntNum();

	printf("Enter page # to read : ");
	page = GetIntNum();

	if (OND_page_load(block,page)==0) {

		memcpy( (U32 *)(_NONCACHE_STARTADDRESS+0x01000000), (U32 *)__OND_DataRAM0_BASE, DATABUFFERSIZE);

		Addr=(U32 *)(_NONCACHE_STARTADDRESS+0x01000000);
	
		for(i=0;i<DATABUFFERSIZE;i+=sizeof(U32)) {

			if ((i&0x1f)==0)
				printf("\n%08x : ",i);

			printf("%08x ",*Addr++);
		
		}
		putchar('\n');
	}
}


// temporary
void set_dma_control(U8 burst, U8 tw)
{
	return;
}


void dma_memcpy(U32 s_addr, U32 d_addr, U32 N_LLI, U32 trans_size)
{
	return;	
}

⌨️ 快捷键说明

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