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

📄 k9s1208.c

📁 S3C6410 Startup Code,包括nand和onenand2种启动代码
💻 C
字号:
/**************************************************************************************
* 
*	Project Name : S3C6410 Validation
*
*	Copyright 2006 by Samsung Electronics, Inc.
*	All rights reserved.
*
*	Project Description :
*		This software is only for validating functions of the S3C6410.
*		Anybody can use this software without our permission.
*  
*--------------------------------------------------------------------------------------
* 
*	File Name : K9s1208.c
*  
*	File Description : This file implements the functons for Nand Device Access.
*
*	Author : Heemyung.noh
*	Dept. : AP Development Team
*	Created Date : 2007/02/02
*	Version : 0.1 
* 
*	History
*	- Created(Heemyung.noh 2007/02/02)
*  
**************************************************************************************/

#include "def.h"
#include "option.h"
#include "sfr6410.h"
#include "System.h"
#include "Nand.h"

u32 srcAddress;
u32 targetBlock;	    // Block number (0 ~ 4095)
u32 targetSize;	    // Total byte size 

u32 downloadAddress;
u32 downloadProgramSize=0x0;

//*************************************************
//*************************************************
//**           H/W dependent functions           **
//************************************************* 
//*************************************************

//The code is made for bi-endian mode

// block0: reserved for boot strap
// block1~4095: used for OS image
// badblock SE: xx xx xx xx xx 00 ....
// good block SE: ECC0 ECC1 ECC2 FF FF FF ....


#define NF_MECC_UnLock()         	{rNFCONT&=~(1<<7);}
#define NF_MECC_Lock()         		{rNFCONT|=(1<<7);}

#define NF_CMD(cmd)				{rNFCMD=cmd;}
#define NF_ADDR(addr)			{rNFADDR=addr;}
	
#define NF_nFCE_L()				{rNFCONT&=~(1<<1);} 
#define NF_nFCE_H()				{rNFCONT|=(1<<1);}

//for debugging
//#define NF_nFCE_L()				{rNFCONT&=~(1<<2);}
//#define NF_nFCE_H()				{rNFCONT|=(1<<2);}

#define NF_RSTECC()				{rNFCONT|=(1<<5|1<<4);}
#define NF_RDDATA() 				(rNFDATA)
#define NF_RDDATA8() 			((*(volatile unsigned char*)0x70200010) )

#define NF_WRDATA(data) 		{rNFDATA=data;}

#define NF_WAITRB()    			{while(!(rNFSTAT&(1<<4)));} 
	   							 //wait tWB and check F_RNB pin.
// RnB Signal
#define NF_CLEAR_RB()    			{rNFSTAT |= (1<<4);}	// Have write '1' to clear this bit.
#define NF_DETECT_RB()    		{while(!(rNFSTAT&(1<<4)));}

#define ID_K9S1208V0M			0xec76
#define ID_K9K2G16U0M			0xecca

#define	NF16_BAD_OFFSET		(12)

// HCLK=100Mhz
//#define TACLS		0	// 1-clk(0ns) 
//#define TWRPH0		6	// 3-clk(25ns)
//#define TWRPH1		0	// 1-clk(10ns)  //TACLS+TWRPH0+TWRPH1>=50ns

// k9F1208U0B (HCLK 100MHz)
//#define TACLS		3	// 1-clk(0ns) 
//#define TWRPH0		2	// 3-clk(25ns)
//#define TWRPH1		1	// 1-clk(10ns)  //TACLS+TWRPH0+TWRPH1>=50ns
#define TACLS		7	// 1-clk(0ns) 
#define TWRPH0		7	// 3-clk(25ns)
#define TWRPH1		7	// 1-clk(10ns)  //TACLS+TWRPH0+TWRPH1>=50ns

#if (NAND_TYPE == MLC_8BIT)
int NF8_ReadPage(u32 block,u32 page,u8 *buffer)
{
	int i;
	unsigned int blockPage;
//	u32 Mecc;
	u8 *bufPt=buffer;
	u32 uPageSize;
//	u8 temp;

	page=page&0x7f;
	blockPage=(block<<7)+page;
	uPageSize = 512;		//512byte * 4 times

	NF_RSTECC();    // Initialize ECC
//	NF_MECC_UnLock();
    NF_nFCE_L();    
	NF_CLEAR_RB();

	NF_CMD(0x00);
	
	NF_ADDR(0); 
	NF_ADDR(0);
	NF_ADDR(blockPage&0xff);		//
	NF_ADDR((blockPage>>8)&0xff);	// Block & Page num.
	NF_ADDR((blockPage>>16)&0xff);	//
	
	NF_CMD(0x30);
	NF_DETECT_RB();

	for(i=0;i<uPageSize;i++) 
	{
		*bufPt++=NF_RDDATA8();	// Read one page
	}

	NF_CMD(0x05);
	NF_ADDR((512)&0xFF);
	NF_ADDR((512>>8)&0xFF);
	NF_CMD(0xE0);
	for(i=0;i<uPageSize;i++) 
	{
		*bufPt++=NF_RDDATA8();	// Read one page
	}
	
	NF_CMD(0x05);
	NF_ADDR((512*2)&0xFF);
	NF_ADDR(((512*2)>>8)&0xFF);
	NF_CMD(0xE0);
	for(i=0;i<uPageSize;i++) 
	{
		*bufPt++=NF_RDDATA8();	// Read one page
	}
	
	NF_CMD(0x05);
	NF_ADDR((512*3)&0xFF);
	NF_ADDR(((512*3)>>8)&0xFF);
	NF_CMD(0xE0);
	for(i=0;i<uPageSize;i++) 
	{
		*bufPt++=NF_RDDATA8();	// Read one page
	}

/*
 	Mecc = NF_RDDATA8();
 	Mecc |= NF_RDDATA8()<<8;
 	Mecc |= NF_RDDATA8()<<16;
 	Mecc |= NF_RDDATA8()<<24;
 	
 	rNFMECCD0=((Mecc&0xff00)<<8)|(Mecc&0xff);
 	rNFMECCD1=((Mecc&0xff000000)>>8)|((Mecc&0xff0000)>>16);
*/
	NF_nFCE_H();    
/*
	if ((rNFECCERR0&0x3) == 0x0)
	{
		return 1;
	}
	else 
	{
		return 0;
	}
*/
	return 1;
}

#else
int NF8_ReadPage(u32 block,u32 page,u8 *buffer)
{
	int i;
	unsigned int blockPage;
	u32 Mecc;
	u8 *bufPt=buffer;
	u32 uPageSize;
	u8 temp;

#if (NAND_TYPE == NORMAL_8BIT)
	page=page&0x1f;
	blockPage=(block<<5)+page;
	uPageSize = 512;
#elif (NAND_TYPE == ADVANCED_8BIT)
	page=page&0x3f;
	blockPage=(block<<6)+page;
	uPageSize = 2048;
#endif    

	NF_RSTECC();    // Initialize ECC
	NF_MECC_UnLock();
    
	NF_nFCE_L();    

	NF_CLEAR_RB();

#if (NAND_TYPE == NORMAL_8BIT)
	NF_CMD(0x00);	// Read command
	NF_ADDR(0); 	// Column = 0
#elif (NAND_TYPE == ADVANCED_8BIT)
	NF_CMD(0x00);
	NF_ADDR(0); 
	NF_ADDR(0);
#endif 
	

	NF_ADDR(blockPage&0xff);		//
	NF_ADDR((blockPage>>8)&0xff);	// Block & Page num.
	NF_ADDR((blockPage>>16)&0xff);	//
	
#if (NAND_TYPE == ADVANCED_8BIT)
	NF_CMD(0x30);
#endif
	
	NF_DETECT_RB();

	for(i=0;i<uPageSize;i++) 
	{
		*bufPt++=NF_RDDATA8();	// Read one page
	}
	
	NF_MECC_Lock();

#if	(NAND_TYPE == ADVANCED_8BIT)
	temp = NF_RDDATA8();
#endif

 	Mecc = NF_RDDATA8();
 	Mecc |= NF_RDDATA8()<<8;
 	Mecc |= NF_RDDATA8()<<16;
 	Mecc |= NF_RDDATA8()<<24;
 	
 	rNFMECCD0=((Mecc&0xff00)<<8)|(Mecc&0xff);
 	rNFMECCD1=((Mecc&0xff000000)>>8)|((Mecc&0xff0000)>>16);
 
	NF_nFCE_H();    

	if ((rNFECCERR0&0x3) == 0x0)
	{
		return 1;
	}
	else 
	{
		return 0;
	}
}
#endif


void Nand_Reset(void)
{
	NF_nFCE_L();

	NF_CLEAR_RB();
	NF_CMD(0xFF);	//reset command
	NF_DETECT_RB();
	
	NF_nFCE_H();

}

void NF8_Init(void)
{
#if (NAND_TYPE == NORMAL_8BIT)
	rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(1<<2)|(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);
#elif (NAND_TYPE == ADVANCED_8BIT)
	rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(1<<3)|(1<<2)|(1<<0);	
	rNFCONT = (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(0x3<<1)|(1<<0);
#elif (NAND_TYPE == MLC_8BIT)
	rNFCONF = (1<<24)|(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(1<<3)|(1<<2)|(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);
#endif
	
	Nand_Reset();
}


 int NF8_IsBadBlock(u32 block)
{
	unsigned int blockPage;
	u8 data;
    
#if (NAND_TYPE == NORMAL_8BIT)
   	blockPage=(block<<5);	
#elif (NAND_TYPE == ADVANCED_8BIT)
   	blockPage=(block<<6);	
#elif (NAND_TYPE == MLC_8BIT)
    blockPage=(block<<7);	
#endif  
    
	NF_nFCE_L();
	NF_CLEAR_RB();

#if (NAND_TYPE == NORMAL_8BIT)
	NF_CMD(0x50);		 // Spare array read command
	NF_ADDR((512+5)&0xf);		 // Read the mark of bad block in spare array(M addr=5), A4-A7:Don't care
#elif (NAND_TYPE == ADVANCED_8BIT)
	NF_CMD(0x00);
	NF_ADDR((2048)&0xff);		 
	NF_ADDR(((2048)>>8)&0xf);	
#elif (NAND_TYPE == MLC_8BIT)
	NF_CMD(0x00);
	NF_ADDR((2048)&0xff);		 
	NF_ADDR(((2048)>>8)&0xf);	
#endif  

	NF_ADDR(blockPage&0xff);	 // The mark of bad block is in 0 page
	NF_ADDR((blockPage>>8)&0xff);	 // For block number A[24:17]
	NF_ADDR((blockPage>>16)&0xff);  // For block number A[25]

#if (NAND_TYPE != NORMAL_8BIT)
	NF_CMD(0x30);
#endif
		 
	NF_DETECT_RB();	 // Wait tR(max 12us)

   	data=NF_RDDATA();

	NF_CMD(0x00);	// Define the starting address of the 1st half of the register

	NF_nFCE_H();    

	if(data!=0xff) 	
		return 0;
	else  	
		return 1;
    
}


⌨️ 快捷键说明

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