?? onenand.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 + -