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

📄 onenand.c

📁 s3c6410的jtag程序sjf6410_1.0
💻 C
字号:
/**************************************************************************************
* 
*	Project Name : S3C6410 OneNand SJF
*
*	Copyright 2007 by Samsung Electronics, Inc.
*	All rights reserved.
*
*	Project Description :
*		This software is only for JTAG Flash Fusing of the S3C6410.
*  
*--------------------------------------------------------------------------------------
* 
*	File Name : onenand.c
*  
*	File Description : write to the OneNand Device using JTAG Flash Fusing
*
*	Author : Heemyung.noh
*	Dept. : AP Development Team
*	Created Date : 2007/12/11
*	Version : 0.1 
* 
*	History
*	- Created(Heemyung.noh 2007/12/11)
*  
**************************************************************************************/

#include <stdio.h>
#include "..\include\pin6410.h"
#include "..\include\Jtag.h"
#include "..\include\OneNand.h"
#include "..\include\sjf6410.h"

static U16 OneNandBlockBuf[0x10000]; 

void OneNand_Init(void)
{
	U16 Data;
	
	OneNand_WriteRegister(SYS_CONFIG1, ONENAND_MODE);
	Data = OneNand_ReadRegister(SYS_CONFIG1);
	printf("System Configuration Register1 : 0x%04x\n", Data);
}


void OneNand_UnlockBlock(U16 StartBlock, U16 EndBlock)
{
	U32 i;

	for(i=StartBlock ; i<=EndBlock ; i++)
	{
		OneNand_WriteRegister(START_ADDR1, (U16)(DFS(0)|FBA(0)));
		OneNand_WriteRegister(START_ADDR2, (U16)DBS(0));
		OneNand_WriteRegister(START_BLOCK_ADDR, (U16)SBA(i));
		OneNand_WriteRegister(INTERRUPT, (U16)0);
		OneNand_WriteRegister(COMMAND, (U16)UNLOCK_BLOCK);

		while(1)
		{
			JTAG_ShiftDRState(outCellValue,inCellValue); 

			if( S6410_GetPin(Xm0INTsm0_FWEn_OUT)==HIGH)
				break;
		}	
	}
}


U16 OneNand_EraseBlock(U16 StartBlock, U16 EndBlock)
{
	U16 i, Data;

	for(i=StartBlock ; i<=EndBlock ; i++)
	{
		OneNand_WriteRegister(START_ADDR1, (U16)(DFS(0)|FBA(i)));
		OneNand_WriteRegister(START_ADDR2, (U16)DBS(0));
		OneNand_WriteRegister(INTERRUPT, (U16)0);
		OneNand_WriteRegister(COMMAND, (U16)ERASE_BLOCK);

		while(1)
		{
			JTAG_ShiftDRState(outCellValue,inCellValue); 

			if( S6410_GetPin(Xm0INTsm0_FWEn_OUT)==HIGH)
				break;
		}	

		Data = OneNand_ReadRegister(CON_STATUS);
		if(Data & (1<<10))
		{
			printf("Erase Error[%d Block]\n", i);
			return 0;
		}
	}
	
	return 1;
}


U16 OneNand_WritePage(U16 Block, U16 Page, U16 *Buffer)
{
	U16 i, Address, Data;
	U32 *SrcBuffer;

	Address = DATA_RAM0;
	SrcBuffer = (U32 *)Buffer;
	
	OneNand_WriteRegister(START_ADDR2, (U16)DBS(0));

	for(i=0 ; i<ONENAND_PAGESIZE/2 ; i+=2)
	{
		OneNand_WriteData(Address, *SrcBuffer);
		Address += 2;
		SrcBuffer++;
	}
	
	OneNand_WriteRegister(START_ADDR1, (U16)(DFS(0)|FBA(Block)));
	OneNand_WriteRegister(START_ADDR8, (U16)(FPA(Page)|FSA(0)));
	OneNand_WriteRegister(START_BUFFER, (U16)(BSA(8)|BSC(0)));
	OneNand_WriteRegister(INTERRUPT, (U16)0);
	OneNand_WriteRegister(COMMAND, (U16)PROGRAM_SECTOR);	

	while(1)
	{
		JTAG_ShiftDRState(outCellValue,inCellValue); 

		if( S6410_GetPin(Xm0INTsm0_FWEn_OUT)==HIGH)
			break;
	}	
	
	Data = OneNand_ReadRegister(CON_STATUS);
	if(Data & (1<<10))
	{
		printf("Write Error[%d Block, %d Page]\n", Block, Page);
		return 0;
	}

	return 1;
}



void KFM2G16Q2x_Program(void)
{
	U16 i, WritePageNum, WriteBlockNum;
	U16 WrittenPageCnt, targetBlock;
	U16 Block, Page;
	U16 *OneNandBuffer;

	printf("\n");
	if(imageSize > sizeof(OneNandBlockBuf))
	{
		printf("Image Size(0x%08x) is large than buffer(0x%08x)\n", imageSize, sizeof(OneNandBlockBuf));
		printf("Increase the buffer size in source code(OneNand.c)\n");
		printf("\n");
		return;
	}
	
	printf("Source size:0x%08x\n",imageSize);
	printf("Available target block number: 0~%d\n", ONENAND_NUMOFBLOCK-1);
	printf("\n");
	printf("Input target block number:");
	scanf("%d",&targetBlock);

	LoadImageFile((U8 *)OneNandBlockBuf, imageSize);
	OneNandBuffer = OneNandBlockBuf;
	
	WritePageNum = imageSize/ONENAND_PAGESIZE;
	if(imageSize%ONENAND_PAGESIZE)
		WritePageNum++;
	
	WriteBlockNum = WritePageNum/ONENAND_NUMOFPAGE;
	if(WritePageNum%ONENAND_NUMOFPAGE)
		WriteBlockNum++;	
		
	OneNand_UnlockBlock(targetBlock, (U16)(targetBlock+WriteBlockNum-1));
	printf("Unlock Block is done[%d ~ %d]\n",targetBlock, (U16)(targetBlock+WriteBlockNum-1));

	OneNand_EraseBlock(targetBlock, (U16)(targetBlock+WriteBlockNum-1));
	printf("Erase Block is done[%d ~ %d]\n",targetBlock, (U16)(targetBlock+WriteBlockNum-1));

	WrittenPageCnt = 0;
	Block = targetBlock;
	Page = 0;

	printf("Programming\n");
	for(i=0 ; i<WritePageNum ; i++)
	{
		Page = i%ONENAND_NUMOFPAGE;
		Block = targetBlock + i/ONENAND_NUMOFPAGE;
		
		OneNand_WritePage(Block, Page, OneNandBuffer);

		OneNandBuffer += ONENAND_PAGESIZE/2;	
		printf(".");
	}
	printf("\n\n");
	printf("Program is done\n");
	printf("\n");
}


void OneNand_ReadID(U16 *ManuID, U16 *DevID)
{
	*ManuID = OneNand_ReadRegister(MANUF_ID);
	printf("Manufacturer ID : 0x%04x\n", *ManuID);

	*DevID = OneNand_ReadRegister(DEVICE_ID);
	printf("Device ID : 0x%04x\n", *DevID);

	printf("\n");
}


static void *onenand_function[][2]=
{
	(void *)KFM2G16Q2x_Program,		"X51 OneNand Program     ",
	(void *)1,			    				"Exit                ",
	0,0
};


void ProgramOneNand(void)
{
	int i;
	U16 ManuID, DevID;
	
	printf("\n[OneNand Flash JTAG Programmer]\n");
	OneNand_JtagInit();

	OneNand_Init();
	OneNand_ReadID(&ManuID, &DevID);

	if(ManuID != X5A_MANU_ID)
	{
		printf("Manufacturer ID is not matched(0x04%x)\n", X5A_MANU_ID);
		return;
	}
	if(DevID != X5A_DEV_ID)
	{
		printf("Device ID is not matched(0x04%x)\n", X5A_DEV_ID);
		return;
	}
	
	while(1)
	{

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

		printf("Select the function to test :");
		scanf("%d",&i);
		if( i>=0 && (i<((sizeof(onenand_function)/8)-2)) ) 
			( (void (*)(void)) (onenand_function[i][0]) )();  
		else
			break; //Exit menu
	}
}


//*************************************************
//*************************************************
//**     JTAG dependent primitive functions      **
//************************************************* 
//*************************************************
// rb1004
// 65nm : Xm0DATA[15:0] HIGH=output, LOW=input
// 6400(90nm) : Output LOW, 6410(65nm) : Output HIGH
void OneNand_JtagInit(void)
{
	JTAG_RunTestldleState();
	JTAG_ShiftIRState(EXTEST);

	//Added to SJF6410 
	S6410_SetPin(Xm0CSn2_CON,HIGH); 			//nCS2 : Output
	S6410_SetPin(Xm0RPn_RnB_CON,HIGH); 			//nRP : Output
	S6410_SetPin(Xm0ADRVALIDn_CON,HIGH); 		//nADDRVALID : Output	
	S6410_SetPin(Xm0RDY0_ALE_CON,LOW);		//RDY : Input
	S6410_SetPin(Xm0INTsm0_FWEn_CON,LOW); 	//INT : Input

	S6410_SetPin(Xm0CSn2_OUT,HIGH); 			
	S6410_SetPin(Xm0RPn_RnB_OUT,HIGH); 			
	S6410_SetPin(Xm0ADRVALIDn_OUT,HIGH); 
	S6410_SetPin(Xm0WEn,HIGH); 
	S6410_SetPin(Xm0OEn,HIGH); 	
	JTAG_ShiftDRStateNoTdo(outCellValue); 
}

void OneNand_WriteRegister(U16 Address, U16 Data)
{
	S6410_ContRDataBus(HIGH); 				//Data : output
	
	S6410_SetPin(Xm0CSn2_OUT,LOW); 
	S6410_SetPin(Xm0ADRVALIDn_OUT,LOW); 
	
	S6410_SetRDataHW(Address);
	JTAG_ShiftDRStateNoTdo(outCellValue); 	//Address output

	S6410_SetPin(Xm0ADRVALIDn_OUT,HIGH); 
	S6410_SetPin(Xm0WEn,LOW);	
	JTAG_ShiftDRStateNoTdo(outCellValue); 	//AddrValid HIGH

	S6410_SetRDataHW(Data);
	JTAG_ShiftDRStateNoTdo(outCellValue); 	//Data output

	S6410_SetPin(Xm0WEn,HIGH); 
	S6410_SetPin(Xm0CSn2_OUT,HIGH); 
	JTAG_ShiftDRStateNoTdo(outCellValue);

	S6410_ContRDataBus(LOW);				//Data : Input
	JTAG_ShiftDRStateNoTdo(outCellValue);
}


U16 OneNand_ReadRegister(U16 Address)
{
	U16 Data;
	
	S6410_ContRDataBus(HIGH); 				
	
	S6410_SetPin(Xm0CSn2_OUT,LOW); 
	S6410_SetPin(Xm0ADRVALIDn_OUT,LOW); 
	
	S6410_SetRDataHW(Address);
	JTAG_ShiftDRStateNoTdo(outCellValue); 	

	S6410_ContRDataBus(LOW);
	S6410_SetPin(Xm0ADRVALIDn_OUT,HIGH); 
	S6410_SetPin(Xm0OEn,LOW); 
	JTAG_ShiftDRStateNoTdo(outCellValue); 	

	JTAG_ShiftDRState(outCellValue,inCellValue);
	Data = S6410_GetRDataHW();
	
	S6410_SetPin(Xm0OEn,HIGH); 
	JTAG_ShiftDRStateNoTdo(outCellValue);

	S6410_SetPin(Xm0CSn2_OUT,HIGH); 
	JTAG_ShiftDRStateNoTdo(outCellValue);

	return Data;			
}



void OneNand_WriteData(U16 Address, U32 Data)
{
	U16 DataHW;
	
	S6410_ContRDataBus(HIGH); 				
	
	S6410_SetPin(Xm0CSn2_OUT,LOW); 
	S6410_SetPin(Xm0ADRVALIDn_OUT,LOW); 

	//LSB Half-Word Write
	S6410_SetRDataHW(Address);
	JTAG_ShiftDRStateNoTdo(outCellValue); 
	
	S6410_SetPin(Xm0ADRVALIDn_OUT,HIGH); 
	S6410_SetPin(Xm0WEn,LOW);	
	JTAG_ShiftDRStateNoTdo(outCellValue); 	

	DataHW = Data&0xFFFF;
	S6410_SetRDataHW(DataHW);
	JTAG_ShiftDRStateNoTdo(outCellValue); 	

	S6410_SetPin(Xm0WEn,HIGH); 
	JTAG_ShiftDRStateNoTdo(outCellValue);

	//MSB Half-Word Write
	S6410_SetPin(Xm0ADRVALIDn_OUT,LOW); 
	JTAG_ShiftDRStateNoTdo(outCellValue);

	S6410_SetRDataHW((U16)(Address+1));
	JTAG_ShiftDRStateNoTdo(outCellValue); 
	
	S6410_SetPin(Xm0ADRVALIDn_OUT,HIGH); 
	S6410_SetPin(Xm0WEn,LOW); 
	JTAG_ShiftDRStateNoTdo(outCellValue);	

	DataHW = (Data&0xFFFF0000)>>16;
	S6410_SetRDataHW(DataHW);
	JTAG_ShiftDRStateNoTdo(outCellValue); 	

	S6410_SetPin(Xm0WEn,HIGH); 
	S6410_SetPin(Xm0CSn2_OUT,HIGH); 	
	JTAG_ShiftDRStateNoTdo(outCellValue);	

	//Data Pin : Input
	S6410_ContRDataBus(LOW);				
	JTAG_ShiftDRStateNoTdo(outCellValue);
}

⌨️ 快捷键说明

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