亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? nand.c

?? 三星 s3c6400測試代碼
?? C
?? 第 1 頁 / 共 5 頁
字號:
/**************************************************************************************
* 
*	Project Name : S3C6400 Validation
*
*	Copyright 2006 by Samsung Electronics, Inc.
*	All rights reserved.
*
*	Project Description :
*		This software is only for validating functions of the S3C6400.
*		Anybody can use this software without our permission.
*  
*--------------------------------------------------------------------------------------
* 
*	File Name : nand.c
*  
*	File Description : This file implements the API functons for Nand controller.
*
*	Author : Heemyung.noh
*	Dept. : AP Development Team
*	Created Date : 2006/12/05
*	Version : 0.1 
* 
*	History
*	- Created(Heemyung.noh 2006/12/05)
*  
**************************************************************************************/

#include <stdio.h>

#include "def.h"
#include "option.h"
#include "library.h"
#include "sfr6400.h"
#include "system.h"
#include "sysc.h"
#include "intc.h"
#include "nand.h"
#include "dma.h"
#include "gpio.h"

#define NAND_REG_BUG		(FALSE)
//#define NAND_EVT1			(TRUE)

#define NAND(__n) 		( ( volatile oNAND_REGS * ) ( NAND_pBase[__n] ) )

typedef struct tag_NAND_REGS
{
	u32 rNFCONF;
	u32 rNFCONT;
	u32 rNFCMMD;
	u32 rNFADDR;
	u32 rNFDATA;
	u32 rNFMECCD0;
	u32 rNFMECCD1;
	u32 rNFSECCD;
	u32 rNFSBLK;
	u32 rNFEBLK;
	u32 rNFSTAT;
	u32 rNFECCERR0;
	u32 rNFECCERR1;
	u32 rNFMECC0;
	u32 rNFMECC1;
	u32 rNFSECC;
	u32 rNFMLCBITPT;
} 
oNAND_REGS;

static void *NAND_pBase[NAND_CONNUM];
static u8 aNand_Spare_Data[NAND_SPARE_MAX] = {	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
												0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
												0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
												0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
u8 aNand_Spare_Data_Temp[NAND_SPARE_MAX] = {	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
												0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
												0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
												0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
static volatile u32 g_Nand_RnBTransition, g_Nand_4bitEccEncDone, g_Nand_4bitEccDecDone, g_Nand_IllegalAccError;
NAND_oInform NAND_Inform[NAND_CONNUM];
NAND_oEccError NAND_EccError;

#if (NAND_TRANSFER_MODE == DMA_TRANSFER)
	static volatile u32 Nand_DmaDone;
#endif
	
DMAC g_oNandDmac1;

//////////
// Function Name : NAND_Init
// Function Description : This function initializes a certain Nand Controller
// Input : 	Controller - Nand Controller Port Number 
// Output : 	TRUE - Memory Device is initialized
//			FALSE - Memory Device is not initialized
bool	NAND_Init(u32 Controller)
{
	u32 uBaseAddress, uTemp;
	u32 uTacls, uTwrph0, uTwrph1;

	if(Controller == 0)
	{
		uBaseAddress = NFCON_BASE;
	}
	else		
	{
		// S3C6400 has 1 Nand Controller
		return FALSE;
	}
	
	NAND_pBase[Controller] = (void *)uBaseAddress;

	INTC_SetVectAddr(NUM_NFC, NAND_ISR0);
	
	NAND_GetDurationValue(Controller, &uTacls, &uTwrph0, &uTwrph1);

	if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
	{
		Outp32(&NAND(Controller)->rNFCONF, (uTacls<<12)|(uTwrph0<<8)|(uTwrph1<<4)|(0<<3)|(1<<2)|((NAND_Inform[Controller].uAddrCycle-3)<<1));
		Outp32(&NAND(Controller)->rNFCONT, (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(0x3<<1)|(1<<0));
	}
	else if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
	{
		Outp32(&NAND(Controller)->rNFCONF, (uTacls<<12)|(uTwrph0<<8)|(uTwrph1<<4)|(1<<3)|(1<<2)|((NAND_Inform[Controller].uAddrCycle-4)<<1));
		Outp32(&NAND(Controller)->rNFCONT, (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(0x3<<1)|(1<<0));
	}
	else if(NAND_Inform[Controller].uNandType == NAND_MLC8bit)
	{
		Outp32(&NAND(Controller)->rNFCONF, (1<<24)|(uTacls<<12)|(uTwrph0<<8)|(uTwrph1<<4)|(1<<3)|(1<<2)|((NAND_Inform[Controller].uAddrCycle-4)<<1));
		Outp32(&NAND(Controller)->rNFCONT, (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(0x3<<1)|(1<<0));

		uTemp = Inp32(&(NAND(Controller)->rNFCONF));
		if(g_HCLK  > 66000000)
			uTemp &= ~(1<<30);
		else
			uTemp |= (1<<30);
		Outp32(&(NAND(Controller)->rNFCONF), uTemp);
	}
	else
	{
		return FALSE;
	}		

	NAND_Reset(Controller);
	
#if NAND_TRANSFER_MODE == DMA_TRANSFER
		DMAC_InitCh(DMA1, DMA_ALL, &g_oNandDmac1);
		INTC_SetVectAddr(NUM_DMA1,  NAND_DmaISR);
		SYSC_SelectDMA(eSEL_PWM, 1);
		INTC_Enable(NUM_DMA1);
#endif	

	//GPIO_SetMem0DrvStrength(0xffffffff);

	return TRUE;
}


void	NAND_GetDurationValue(u32 Controller, u32 *uTacls, u32 *uTwrph0, u32 *uTwrph1)
{
	u32 uTemp;
	float fTemp;

	uTemp = (NAND_Inform[Controller].uTacls * (g_HCLK/1000))/1000000;
	fTemp = (((float)NAND_Inform[Controller].uTacls * (float)(g_HCLK/1000))/(float)1000000);
	fTemp -= uTemp;

	if(fTemp != (float)0)
		*uTacls = uTemp+1;

	else
		*uTacls = uTemp;

	uTemp = (NAND_Inform[Controller].uTwrph0 * (g_HCLK/1000))/1000000;
	fTemp = (((float)NAND_Inform[Controller].uTwrph0 * (float)(g_HCLK/1000))/(float)1000000);
	fTemp -= uTemp;

	if(fTemp != (float)0)
		*uTwrph0 = uTemp;

	else
	{
		if(uTemp > 0)
			*uTwrph0 = uTemp-1;

		else
			*uTwrph0 = 0;
	}
	
	uTemp = (NAND_Inform[Controller].uTwrph1 * (g_HCLK/1000))/1000000;
	fTemp = (((float)NAND_Inform[Controller].uTwrph1 * (float)(g_HCLK/1000))/(float)1000000);
	fTemp -= uTemp;

	if(fTemp != (float)0){
		*uTwrph1 = uTemp;
	UART_Printf("uTwrph1 = %x",*uTwrph1);}
	else
	{
		if(uTemp > 0)
			*uTwrph1 = uTemp-1;
		else
			*uTwrph1 = 0;
	}
}
	

//////////
// Function Name : NAND_TimingParaSetting
// Function Description : This function set the Timing Parameter(TACLS, TWRPH0, TWRPH1)
// Input : 	Controller - Nand Controller Port Number 
// Output : 	None
void NAND_TimingParaSetting(u32 Controller)
{
	u32 uTacls, uTwrph0, uTwrph1, uTemp0, uTemp1;

	NAND_GetDurationValue(Controller, &uTacls, &uTwrph0, &uTwrph1);

	uTemp0 = Inp32(&NAND(Controller)->rNFCONF);
	uTemp0 = (uTemp0 & ~((0x07<<12)|(0x07<<8)|(0x07<<4))) | ((uTacls<<12)|(uTwrph0<<8)|(uTwrph1<<4));
	Outp32(&NAND(Controller)->rNFCONF, uTemp0);

	 if(NAND_Inform[Controller].uNandType == NAND_MLC8bit)
	{
		uTemp1 = Inp32(&(NAND(Controller)->rNFCONF));
		if(g_HCLK  > 66000000)
			uTemp1 &= ~(1<<30);
		else
			uTemp1 |= (1<<30);
		Outp32(&(NAND(Controller)->rNFCONF), uTemp1);
	}

	UART_Printf("Nand Timing Parameter : TACLS(%d Clock), TWRPH0(%d Clock), TWRPH1(%d Clock)\n", uTacls, uTwrph0+1, uTwrph1+1);
}



//////////
// Function Name : NAND_ISR
// Function Description : Nand IRQ routine
// Input : 	None
// Output : 	None
void __irq NAND_ISR0(void)
{
	u32 uIntSource;
	
	// rb1004 : must be modified
	//INT_Disable1(BIT_INT_NFC);
	INTC_Disable(NUM_NFC);

	uIntSource = Inp32(&NAND(0)->rNFSTAT);

	if(uIntSource & NAND_4BITECC_ENC)
	{
		Outp32(&NAND(0)->rNFSTAT, (1<<7));
		g_Nand_4bitEccEncDone = 1;
	}
	else if(uIntSource & NAND_4BITECC_DEC)
	{
		Outp32(&NAND(0)->rNFSTAT, (1<<6));
		g_Nand_4bitEccDecDone = 1;
	}
	else if(uIntSource & NAND_ILLEGAL_ACCESS)
	{
		Outp32(&NAND(0)->rNFSTAT, (1<<5));
		g_Nand_IllegalAccError = 1;
		UART_Printf("NAND Illegal Access Error.........!!\n");
		UART_Getc();
	}
	else if(uIntSource & NAND_RnB_TRANS)
	{
		Outp32(&NAND(0)->rNFSTAT, (1<<4));
		g_Nand_RnBTransition = 1;
	}

	// rb1004 : must be modified
	//INT_Enable1(BIT_INT_NFC);
	//Write_VECTADDR(0x0);	
	INTC_Enable(NUM_NFC);
	INTC_ClearVectAddr();
}


//////////
// Function Name : NAND_DmaISR
// Function Description : Nand DMA transfer IRQ routine
// Input : 	None
// Output : 	None
#if (NAND_TRANSFER_MODE == DMA_TRANSFER)
void __irq NAND_DmaISR(void)
{
  	DMACH_ClearIntPending(&g_oNandDmac1);

	//UART_Printf ("DMA ISR %d\n", Nand_DmaDone);

	Nand_DmaDone = 1;
	INTC_ClearVectAddr();
}
#endif

//////////
// Function Name : NAND_ReadID
// Function Description : This function get the ID of external NAND Device
// Input : 	Controller - Nand Controller Port Number 
// Output : 	Nand Memory ID
u32 NAND_ReadID(u32 Controller)
{
	u32 i;
	//u8 ucID1, ucID2, ucID3, ucID4;
	u32 usID;

	NF_nFCE_L(Controller);
	
	NF_CMD(Controller, 0x90);
	NF_ADDR(Controller, 0x0);

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

#if 0
	ucID1 = (u8)NF_RDDATA8(Controller);	// read 4byte.
	ucID2 = (u8)NF_RDDATA8(Controller);
	ucID3 = (u8)NF_RDDATA8(Controller);
	ucID4 = (u8)NF_RDDATA8(Controller);
	usID = (ucID4<<24)|(ucID3<<16)|(ucID2<<8)|(ucID1<<0);
#else
	usID = NF_RDDATA(Controller);
#endif

	NF_nFCE_H(Controller);
	
	return 	usID;	
}

//////////
// Function Name : NAND_Reset
// Function Description : This function reset the external NAND Device
// Input : 	Controller - Nand Controller Port Number 
// Output : 	None
void NAND_Reset(u32 Controller)
{
    	u32 i;
   
	NF_nFCE_L(Controller);

	NF_CLEAR_RnB(Controller);
	NF_CMD(Controller, 0xFF);	//reset command

	if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
	{
		for(i=0;i<1000;i++);
	}
	else
	{
		for(i=0;i<10;i++);  //tWB = 100ns. //??????
		NF_DETECT_RnB(Controller);
	}
	NF_nFCE_H(Controller);
}

//////////
// Function Name : NAND_CheckInvalidBlock
// Function Description : This function check the invalid block of external NAND device
// Input : 	Controller - Nand Controller Port Number 
//			uBlock - Check Block
// Output : 	Nand Error Type
NAND_eERROR NAND_CheckInvalidBlock(u32 Controller, u32 uBlock)
{
	u32 uBlockPage, uPageSize;
	u8 ucData;

	if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
	{
		uBlockPage=(uBlock<<5);
		//uPageSize = NAND_PAGE_512;
		uPageSize = NAND_Inform[Controller].uPageSize;
	}
	else if(NAND_Inform[Controller].uNandType == NAND_Advanced8bit)
	{
		uBlockPage=(uBlock<<6);
		//uPageSize = NAND_PAGE_2048;
		uPageSize = NAND_Inform[Controller].uPageSize;
	}
	else if(NAND_Inform[Controller].uNandType == NAND_MLC8bit)
	{
		uBlockPage=(uBlock<<7);
		//uPageSize = NAND_PAGE_2048;
		uPageSize = NAND_Inform[Controller].uPageSize;
	}
	else
		return eNAND_EtcError;

	NF_nFCE_L(Controller);
	NF_CLEAR_RnB(Controller);

	//if(NAND_Inform[Controller].uNandType == NAND_Normal8bit)
	if(NAND_Inform[Controller].uAddrCycle == 4)
	{
		NF_CMD(Controller, 0x50);		 		// Spare array read command
		NF_ADDR(Controller, (uPageSize+5)&0xf);	// 6th byte in the Spare Area
	}
	else	 if(NAND_Inform[Controller].uAddrCycle == 5)
	{
		NF_CMD(Controller, 0x00);				// 1st Read Command
		NF_ADDR(Controller, (uPageSize+0)&0xff);			
		NF_ADDR(Controller, ((uPageSize+0)>>8)&0xff);		// 1st byte in the Spare Area		
	}			

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

	if((NAND_Inform[Controller].uNandType == NAND_Advanced8bit) || (NAND_Inform[Controller].uNandType == NAND_MLC8bit) )
		NF_CMD(Controller, 0x30);	// 2'nd command
	 
	NF_DETECT_RnB(Controller);	 // Wait tR(max 12us)
	NF_CLEAR_RnB(Controller);

	ucData=NF_RDDATA8(Controller);

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

	NF_nFCE_H(Controller);    

	if(ucData!=0xff)
	{
		//UART_Printf("[block %d has been marked as a bad block(%x)]\n",uBlock,ucData);
		return eNAND_InvalidBlock;
	}
	else
	{
		return eNAND_NoError;
	}
}



?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人精品免费网站| 成人午夜在线播放| 一区二区三区四区视频精品免费 | 国产精品美女久久久久aⅴ国产馆| 欧美午夜影院一区| 欧美性猛交xxxxxx富婆| 色偷偷久久一区二区三区| 91久久免费观看| 欧美日韩综合不卡| 欧美丰满一区二区免费视频| 91精品婷婷国产综合久久竹菊| 欧美日本一区二区在线观看| 制服丝袜成人动漫| 日韩女优毛片在线| 国产午夜精品理论片a级大结局| 久久久久久久久久久电影| 国产精品网站在线观看| 亚洲精品视频免费看| 午夜欧美大尺度福利影院在线看| 欧美aⅴ一区二区三区视频| 美腿丝袜亚洲色图| 国产不卡高清在线观看视频| 成人听书哪个软件好| 欧美日韩一级二级三级| 精品国产电影一区二区| 亚洲国产成人一区二区三区| 一区二区三区在线观看欧美| 日韩经典一区二区| 成人久久18免费网站麻豆| 在线观看区一区二| 欧美成人一区二区三区在线观看 | 6080日韩午夜伦伦午夜伦| 日韩精品影音先锋| 亚洲少妇中出一区| 免费黄网站欧美| 成人精品国产一区二区4080| 欧美日韩一区二区三区免费看| 精品国产一区a| 亚洲精品伦理在线| 国产伦理精品不卡| 欧美视频一区二| 国产精品久久久久久久久免费相片| 亚洲一二三四久久| 成人一区二区视频| 欧美一区二区成人6969| 亚洲欧美激情小说另类| 激情综合亚洲精品| 欧美日韩国产高清一区| 国产精品久久综合| 国产一区二区三区香蕉| 欧美美女直播网站| 日韩美女视频一区| 国产一区二区三区免费看| 欧美在线一区二区| 国产精品久99| 精品一区二区在线观看| 欧美精品久久久久久久多人混战 | 风间由美中文字幕在线看视频国产欧美| 91精彩视频在线观看| 国产亚洲成aⅴ人片在线观看 | 91丨porny丨蝌蚪视频| 国产亚洲一区二区三区在线观看 | 日韩视频永久免费| 一区二区三区影院| 97精品久久久久中文字幕| 久久久99精品免费观看不卡| 奇米亚洲午夜久久精品| 91精品综合久久久久久| 亚洲大型综合色站| 精品视频999| 亚洲一区在线观看免费 | 成人精品鲁一区一区二区| 精品国产乱码久久久久久牛牛| 日韩av高清在线观看| 91麻豆精品国产91久久久更新时间| 亚洲精品水蜜桃| 在线观看av一区二区| 亚洲国产日韩av| 在线综合亚洲欧美在线视频| 日韩av网站免费在线| 欧美第一区第二区| 国产一区 二区| 欧美激情综合网| 色一情一伦一子一伦一区| 亚洲在线一区二区三区| 777精品伊人久久久久大香线蕉| 日韩电影一区二区三区四区| 欧美xfplay| 成人激情图片网| 亚洲综合在线五月| 欧美日韩一区成人| 玖玖九九国产精品| 久久精品人人做人人爽人人| 成人精品视频.| 亚洲一区二区三区小说| 欧美一卡2卡3卡4卡| 黄页网站大全一区二区| 中文字幕在线一区| 欧美熟乱第一页| 老司机免费视频一区二区| 亚洲国产成人在线| 欧美日韩精品欧美日韩精品一综合| 奇米色777欧美一区二区| 国产欧美久久久精品影院| 一本色道久久综合狠狠躁的推荐| 日韩中文字幕91| 国产精品视频看| 91精品国产入口在线| 国产剧情一区在线| 夜夜嗨av一区二区三区中文字幕| 日韩精品一区二区三区中文精品| 成人网页在线观看| 蜜桃一区二区三区在线观看| 中文字幕一区av| 日韩精品一区二区三区视频在线观看| 国产v日产∨综合v精品视频| 亚洲国产精品久久久久秋霞影院 | 色诱视频网站一区| 久久电影国产免费久久电影| 国产精品成人免费精品自在线观看| 欧美日韩一区二区在线观看| 国模娜娜一区二区三区| 亚洲国产成人tv| 国产精品久99| 自拍偷拍欧美精品| 91精品国产色综合久久不卡蜜臀| av电影一区二区| 国产精品一线二线三线| 日韩二区在线观看| 亚洲午夜一二三区视频| 国产精品久久久久9999吃药| 久久久噜噜噜久久中文字幕色伊伊 | 精品对白一区国产伦| 91久久奴性调教| 99re亚洲国产精品| 成人久久18免费网站麻豆| 国产一区二区三区av电影 | 日韩一区二区电影网| 一本久久a久久免费精品不卡| 风间由美一区二区av101| 久草这里只有精品视频| 日韩高清不卡在线| 三级影片在线观看欧美日韩一区二区| 亚洲精品免费看| 亚洲欧美aⅴ...| 亚洲欧美另类图片小说| 亚洲日本中文字幕区| 国产精品二区一区二区aⅴ污介绍| 国产婷婷色一区二区三区四区| 久久综合九色综合久久久精品综合| 欧美一二三四在线| 精品日韩一区二区三区| 欧美大肚乱孕交hd孕妇| 欧美变态tickle挠乳网站| 日韩一区二区免费电影| 日韩免费电影一区| 精品国产凹凸成av人网站| 日韩欧美高清一区| 亚洲精品一区二区三区精华液| 精品福利一区二区三区| 国产亚洲成aⅴ人片在线观看| 日本一区二区三区免费乱视频| 国产欧美一区二区三区鸳鸯浴| 国产精品网曝门| 亚洲精品成人a在线观看| 午夜影视日本亚洲欧洲精品| 日韩制服丝袜av| 国产一区二区视频在线播放| 成人综合激情网| 色狠狠色狠狠综合| 欧美高清视频在线高清观看mv色露露十八| 欧美巨大另类极品videosbest| 欧美tk—视频vk| 国产精品视频一二三| 亚洲宅男天堂在线观看无病毒| 天堂成人国产精品一区| 精品一区二区三区在线观看| 风间由美一区二区三区在线观看| 91麻豆精东视频| 欧美一区二区精品久久911| 久久精品日韩一区二区三区| 亚洲蜜臀av乱码久久精品| 亚洲国产成人va在线观看天堂| 激情综合网av| 一本大道综合伊人精品热热| 91精品婷婷国产综合久久竹菊| 国产亚洲精品bt天堂精选| 亚洲在线成人精品| 国产精品羞羞答答xxdd| 色94色欧美sute亚洲线路二| 日韩精品专区在线影院重磅| 亚洲欧洲成人精品av97| 日韩电影在线免费| 色综合久久88色综合天天免费| 日韩欧美色综合| 一区二区三区四区蜜桃| 国产成人99久久亚洲综合精品| 欧美日韩在线三区| 亚洲欧洲国产日本综合| 黄色精品一二区|