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

📄 k9sxx08.c

📁 jflash-s3c2440是一个工具程序.其能通过JTAG接口将主机端的文件写入基于三星ARM处理器S3C2440的开发板上的NandFlash或NorFlash中.
💻 C
字号:
#include <stdio.h>#include "pin2440.h"#include "jtag.h"#include "k9sxx08.h"#include "sjf.h"#define BAD_CHECK	(0)#define ECC_CHECK	(0)//*************** JTAG dependent functions ***************void K9S1208_JtagInit(void);static void NF_CMD(U8 cmd);static void NF_ADDR(U8 addr);static void NF_nFCE_L(void);static void NF_nFCE_H(void);static U8 NF_RDDATA(void);static void NF_WRDATA(U8 data);static void NF_WAITRB(void);//*************** H/W dependent functions ***************static U16 NF_CheckId(void);static int NF_EraseBlock(U32 blockNum);static int NF_ReadPage(U32 block,U32 page,U8 *buffer,U8 *spareBuf);static int NF_WritePage(U32 block,U32 page,U8 *buffer,U8 *spareBuf);//buffer size is 512 bytesstatic int NF_IsBadBlock(U32 block);static int NF_MarkBadBlock(U32 block);static void NF_Reset(void);static void NF_Init(void);//*******************************************************void K9S1208_PrintBlock(void);void K9S1208_Program(void);static U32 targetBlock;	    // Block number (0 ~ 4095)static U32 targetSize;	    // Total byte size static U8 blockBuf[0x4000];static void *function[][2]={    (void *)K9S1208_Program,		"K9S1208 Program     ",    (void *)K9S1208_PrintBlock,		"K9S1208 Pr BlkPage  ",    (void *)1,			    	"Exit                ",    0,0};void K9S1208_Menu(void){    int i;    U16 id;    printf("\n[K9S1208 NAND Flash JTAG Programmer]\n");    K9S1208_JtagInit();    NF_Init();    id=NF_CheckId();    	if(id!=0xec76)    {	printf("ERROR: K9S1208 is not detected. Detected ID=0x%x.\n",id);	return;    }    else    {    	printf("K9S1208 is detected. ID=0x%x\n",id);    }    while(1)    {	i=0;    	while(1)	{   //display menu	    printf("%2d:%s",i,function[i][1]);	    i++;	    if((int)(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(function)/8)-2)) ) 	    ( (void (*)(void)) (function[i][0]) )();  	else	    break; //Exit menu    }}void K9S1208_Program(void){    int i;    int programError=0;    U32 blockIndex;    int noLoad=0;    U8 spareBuf[16]=	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};    U8 *srcPt;    U32 progSize=0;    printf("\n[SMC(K9S1208V0M) NAND Flash Writing Program]\n");        printf("\nSource size:0h~%xh\n",imageSize-1);    printf("\nAvailable target block number: 0~4095\n");    printf("Input target block number:");    scanf("%d",&targetBlock);    targetSize=((imageSize+0x4000-1)/0x4000)*0x4000;    printf("target start block number     =%d\n",targetBlock);    printf("target size        (0x4000*n) =0x%x\n",targetSize);    printf("STATUS:");    blockIndex=targetBlock;    while(1)    {	if(noLoad==0)	{	    LoadImageFile(blockBuf,0x4000);	}	noLoad=0;	#if BAD_CHECK       	if(NF_IsBadBlock(blockIndex) && blockIndex!=0 )	// 1:bad 0:good        {	    blockIndex++;   // for next block	    noLoad=1;	    continue;	}#endif	if(!NF_EraseBlock(blockIndex))	{	    blockIndex++;   // for next block	    noLoad=1;	    continue;	}	printf("E");	srcPt=blockBuf;	for(i=0;i<32;i++)	{	    if(!NF_WritePage(blockIndex,i,srcPt,NULL/*spareBuf*/))// block num, page num, buffer	    {	        programError=1;	        break;	    }	    srcPt+=512;	// Increase buffer addr one pase size	    printf("p");	}	printf("\n");        if(programError==1)	{	    blockIndex++;	    noLoad=1;	    programError=0;	    continue;	}	progSize+=0x4000;	if(progSize>=imageSize)	    break;	// Exit while loop	blockIndex++;    }}void K9S1208_PrintBlock(void)// Printf one page{    int i;    U16 id;    U32 block,page;    U8	buffer[512+16];    printf("\n[SMC(K9S1208) NAND Flash block read]\n");	        NF_Init();    id=NF_CheckId();    printf("ID=%x(0xec76)\n",id);    if(id!=0xec76)	return;    printf("Input target block number:");    scanf("%d",&block);    printf("Input target page number:");       scanf("%d",&page);        NF_ReadPage(block,page,buffer,buffer+512);        printf("block=%d,page=%d:",block,page);    for(i=0;i<512;i++)    {        if(i%16==0)	    printf("\n%3xh:",i);        printf("%02x ",buffer[i]);    }    printf("\nS.A.:",i);    for(i=512;i<512+16;i++)    {        printf("%02x ",buffer[i]);    }    printf("\n");    	}//*************************************************//*************************************************//**           H/W dependent functions           **//************************************************* //*************************************************// NAND Flash Memory Commands#define	SEQ_DATA_INPUT			(0x80)#define	READ_ID				(0x90)#define	RESET				(0xFF)#define	READ_1_1			(0x00)#define	READ_1_2			(0x01)#define	READ_2				(0x50)#define	PAGE_PROGRAM			(0x10)#define	BLOCK_ERASE			(0x60)#define	BLOCK_ERASE_CONFIRM		(0xD0)#define	READ_STATUS			(0x70)// 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 WRITEVERIFY  (0)  //verifing is enable at writing./*#define NF_CMD(cmd)	{rNFCMD=cmd;}#define NF_ADDR(addr)	{rNFADDR=addr;}	#define NF_nFCE_L()	{rNFCONF&=~(1<<11);}#define NF_nFCE_H()	{rNFCONF|=(1<<11);}#define NF_RSTECC()	{rNFCONF|=(1<<12);}#define NF_RDDATA() 	(rNFDATA)#define NF_WRDATA(data) {rNFDATA=data;}#define NF_WAITRB()    {while(!(rNFSTAT&(1<<0)));} 	    //wait tWB and check F_RNB pin.   */#define ID_K9S1208V0M	0xec76static U8 seBuf[16]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};// 1block=(512+16)bytes x 32pages// 4096block// A[23:14][13:9]//  block   pagestatic int NF_EraseBlock(U32 block){    U32 blockPage=(block<<5);#if BAD_CHECK    if(NF_IsBadBlock(block) && block!=0) //block #0 can't be bad block for NAND boot	return 0;#endif    NF_nFCE_L();        NF_CMD(0x60);   // Erase one block 1st command    NF_ADDR(blockPage&0xff);	    // Page number=0    NF_ADDR((blockPage>>8)&0xff);       NF_ADDR((blockPage>>16)&0xff);    NF_CMD(0xd0);   // Erase one blcok 2nd command        Delay(1); //wait tWB(100ns)    NF_WAITRB();    // Wait tBERS max 3ms.    NF_CMD(0x70);   // Read status command    if (NF_RDDATA()&0x1) // Erase error    {	    	NF_nFCE_H();	printf("[ERASE_ERROR:block#=%d]\n",block);	NF_MarkBadBlock(block);	return 0;    }    else     {    	NF_nFCE_H();        return 1;    }}static int NF_IsBadBlock(U32 block){    unsigned int blockPage;    U8 data;            blockPage=(block<<5);	// For 2'nd cycle I/O[7:5]         NF_nFCE_L();        NF_CMD(0x50);		// Spare array read command    NF_ADDR(517&0xf);		// Read the mark of bad block in spare array(M addr=5)     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]    Delay(1);		// wait tWB(100ns)        NF_WAITRB();	// Wait tR(max 12us)        data=NF_RDDATA();    NF_nFCE_H();        if(data!=0xff)    {    	printf("[block %d:bad block(%x)]\n",block,data);    	return 1;    }    else    {	printf(".");    	return 0;    }}static int NF_MarkBadBlock(U32 block){    int i;    U32 blockPage=(block<<5);     seBuf[0]=0xff;    seBuf[1]=0xff;        seBuf[2]=0xff;        seBuf[5]=0x44;   // Bad blcok mark=0        NF_nFCE_L();     NF_CMD(0x50);       NF_CMD(0x80);   // Write 1st command        NF_ADDR(0x0);		    // The mark of bad block is     NF_ADDR(blockPage&0xff);	    // marked 5th spare array     NF_ADDR((blockPage>>8)&0xff);   // in the 1st page.    NF_ADDR((blockPage>>16)&0xff);          for(i=0;i<16;i++)    {	NF_WRDATA(seBuf[i]);	// Write spare array    }    NF_CMD(0x10);   // Write 2nd command        Delay(1);  //tWB = 100ns.     NF_WAITRB();      // Wait tPROG(200~500us)      NF_CMD(0x70);        Delay(1);	 //twhr=60ns//        if (NF_RDDATA()&0x1) // Spare arrray write error    {	    	NF_nFCE_H();    	printf("[Program error is occurred but ignored]\n");    }    else     {    	NF_nFCE_H();    }    printf("[block #%d is marked as a bad block]\n",block);    return 1;}static int NF_ReadPage(U32 block,U32 page,U8 *buffer,U8 *spareBuf){    int i;    unsigned int blockPage;    U8 *bufPt=buffer;        page=page&0x1f;    blockPage=(block<<5)+page;            NF_nFCE_L();        NF_CMD(0x00);   // Read command    NF_ADDR(0);	    // Column = 0    NF_ADDR(blockPage&0xff);	    //    NF_ADDR((blockPage>>8)&0xff);   // Block & Page num.    NF_ADDR((blockPage>>16)&0xff);  //    Delay(1);	    //wait tWB(100ns)/////??????        NF_WAITRB();    // Wait tR(max 12us)        for(i=0;i<(512);i++)    {    	*bufPt++=NF_RDDATA();	// Read one page    }    if(spareBuf!=NULL)    {	for(i=0;i<16;i++)	    spareBuf[i]=NF_RDDATA();	// Read spare array    }    NF_nFCE_H();        return 1;}static int NF_WritePage(U32 block,U32 page,U8 *buffer,U8 *spareBuf){    int i;    U32 blockPage=(block<<5)+page;    U8 *bufPt=buffer;    NF_nFCE_L();     NF_CMD(0x0);    NF_CMD(0x80);		    // Write 1st command    NF_ADDR(0);			    // Column 0    NF_ADDR(blockPage&0xff);	    //    NF_ADDR((blockPage>>8)&0xff);   // Block & page num.    NF_ADDR((blockPage>>16)&0xff);  //    for(i=0;i<512;i++)    {	NF_WRDATA(*bufPt++);	// Write one page to NFM from buffer    }      if(spareBuf!=NULL)    {	for(i=0;i<16;i++)	{	    NF_WRDATA(spareBuf[i]);	// Write spare array(ECC and Mark)	}    }    NF_CMD(0x10);   // Write 2nd command        Delay(1);	    //tWB = 100ns.     NF_WAITRB();    //wait tPROG 200~500us;     NF_CMD(0x70);   // Read status command           Delay(1);	    //twhr=60ns        if (NF_RDDATA()&0x1) // Page write error    {	    	NF_nFCE_H();	printf("[PROGRAM_ERROR:block#=%d]\n",block);	NF_MarkBadBlock(block);	return 0;    }    else     {    	NF_nFCE_H();    #if (WRITEVERIFY==1)	//return NF_VerifyPage(block,page,pPage);	    #else	return 1;    #endif    }}static U16 NF_CheckId(void){    U16 id;        NF_nFCE_L();        NF_CMD(0x90);    NF_ADDR(0x0);        Delay(1);	//wait tWB(100ns)        id=NF_RDDATA()<<8;	// Maker code(K9S1208V:0xec)    id|=NF_RDDATA();	// Devide code(K9S1208V:0x76)        NF_nFCE_H();        return id;}static void NF_Reset(void){    NF_nFCE_L();    NF_CMD(0xFF);   //reset command    Delay(1);	    //tWB = 100ns.     NF_WAITRB();    //wait 200~500us;         NF_nFCE_H();    }static void NF_Init(void){    NF_Reset();    //NF_nFCE_L();    NF_CMD(READ_1_1);            //NF_nFCE_H();}//*************************************************//*************************************************//**     JTAG dependent primitive functions      **//************************************************* //*************************************************void K9S1208_JtagInit(void){    JTAG_RunTestldleState();    JTAG_ShiftIRState(EXTEST);	//Added to SJF2440 	S2440_SetPin(CLE_CON,LOW);    S2440_SetPin(ALE_CON,LOW);	S2440_SetPin(nFCE_CON,LOW);     S2440_SetPin(nFRE_CON,LOW);     S2440_SetPin(nFWE_CON,LOW); 		S2440_SetPin(CLE,LOW);     S2440_SetPin(ALE,LOW); }static void NF_CMD(U8 cmd){           //Command Latch Cycle    S2440_SetPin(DATA0_7_CON ,LOW); //D[7:0]=output    	S2440_SetPin(nFCE,LOW);     S2440_SetPin(nFRE,HIGH);     S2440_SetPin(nFWE,LOW); //Because tCLS=0, CLE & nFWE can be changed simultaneously.    	S2440_SetPin(ALE,LOW);     S2440_SetPin(CLE,HIGH);     	S2440_SetDataByte(cmd);    JTAG_ShiftDRStateNoTdo(outCellValue);     S2440_SetPin(nFWE,HIGH);    JTAG_ShiftDRStateNoTdo(outCellValue); #if 1    S2440_SetPin(CLE,LOW);	    S2440_SetPin(DATA0_7_CON,HIGH); //D[7:0]=input    JTAG_ShiftDRStateNoTdo(outCellValue); #endif}static void NF_ADDR(U8 addr){    //rNFADDR=addr;    S2440_SetPin(DATA0_7_CON ,LOW); //D[7:0]=output    S2440_SetPin(nFCE,LOW);     S2440_SetPin(nFRE,HIGH);     S2440_SetPin(nFWE,LOW);    S2440_SetPin(ALE,HIGH);    S2440_SetPin(CLE,LOW);    S2440_SetDataByte(addr);    JTAG_ShiftDRStateNoTdo(outCellValue);         S2440_SetPin(nFWE,HIGH);    JTAG_ShiftDRStateNoTdo(outCellValue);     #if 1    S2440_SetPin(ALE,LOW);	    S2440_SetPin(DATA0_7_CON,HIGH); //D[7:0]=input    JTAG_ShiftDRStateNoTdo(outCellValue); #endif}static void NF_nFCE_L(void){    S2440_SetPin(nFCE_CON,LOW);//Added to SJF2440 	S2440_SetPin(nFCE,LOW);     JTAG_ShiftDRStateNoTdo(outCellValue); }static void NF_nFCE_H(void){    S2440_SetPin(nFCE,HIGH);     JTAG_ShiftDRStateNoTdo(outCellValue); }static U8 NF_RDDATA(void){    S2440_SetPin(DATA0_7_CON ,HIGH); //D[7:0]=input    S2440_SetPin(nFRE,LOW);    JTAG_ShiftDRStateNoTdo(outCellValue);         S2440_SetPin(nFRE,HIGH);    JTAG_ShiftDRState(outCellValue,inCellValue);     return S2440_GetDataByte();}static void NF_WRDATA(U8 data){       S2440_SetPin(DATA0_7_CON ,LOW); //D[7:0]=output    S2440_SetPin(nFWE,LOW);    S2440_SetDataByte(data);    JTAG_ShiftDRStateNoTdo(outCellValue);         S2440_SetPin(nFWE,HIGH);    JTAG_ShiftDRStateNoTdo(outCellValue); }static void NF_WAITRB(void){    char c;	while(1)    {	JTAG_ShiftDRState(outCellValue,inCellValue); 		if( S2440_GetPin(RnB)==HIGH)	break;	}}

⌨️ 快捷键说明

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