您的位置:首页 > 其它

潦草的JTAG下载过程分析『原创』

2008-12-18 11:50 162 查看
潦草的JTAG下载过程分析
===========
第一步
OpenPpt 检测端口部分
-----------
首先要检查GiveIo,不知道为何?好像跟系统分配的端口地址有关
nt InstallGiveIo(void)
{
HANDLE h;
OSVERSIONINFO osvi;

osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);

if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
//OS=NT/2000
h = CreateFile("////.//giveio", GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(h);
if(h == INVALID_HANDLE_VALUE)
return 0;
else
return 0x2000;
}
else
{ //OS=WIN98
return 0x0098;
}
}
如果返回为空就说找不到giveio.sys (这个LPT的驱动)

------------
打开并口获取并口号
#define LPT1 0x378
#define LPT2 0x278
#define LPT3 0x3bc

int GetValidPpt(void)//返回值既是端口号
{
// search for valid parallel port
_outp(LPT1, 0x55);
if((int)_inp(LPT1) == 0x55)
return LPT1;

_outp(LPT2, 0x55);
if((int)_inp(LPT2) == 0x55)
return LPT2;

_outp(LPT3, 0x55);
if((int)_inp(LPT3) == 0x55)
return LPT3;

return 0;
}///原理就是先写后读,读出来得是0x55(写的数),就代表该端口开启。说白了还是列举然后挨个试。。。
----------------------
检测端口的最后一步就是趁机再设置一下
#define ECP_ECR (0x402)
#define ECR_STANDARD (0x0)
#define ECR_DISnERRORINT (0x10)
#define ECR_DISDMA (0x0)
#define ECR_DISSVCINT (0x4)

void SetPptCompMode(void)
{

_outp((unsigned short)(validPpt+ECP_ECR),ECR_STANDARD | ECR_DISnERRORINT | ECR_DISDMA | ECR_DISSVCINT);
}
validPpt为已获得的端口号,剩下那几个参数一知半解。。

====================
第二步 初始化JTAG & CPU
----
先要 获取下载文件大小();
------------
JTAG_Reset)(
JTAG_SET(TDI_H|TMS_H|TCK_L);
JTAG_DELAY();
JTAG_SET(TDI_H|TMS_H|TCK_H);
JTAG_DELAY();
//重启N次
------------------
JTAG_SET(TDI_H|TMS_L|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_L|TCK_H);JTAG_DELAY();
//重复4次 启动测试状态

//S3C6400 IDCODE Instruction "1110"
JTAG_SET(TDI_L|TMS_L|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_L|TMS_L|TCK_H);JTAG_DELAY(); // '0'

JTAG_SET(TDI_H|TMS_L|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_L|TCK_H);JTAG_DELAY(); // '1'

JTAG_SET(TDI_H|TMS_L|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_L|TCK_H);JTAG_DELAY(); // '1'

JTAG_SET(TDI_H|TMS_H|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_H|TCK_H);JTAG_DELAY(); // '1', //Exit1-IR

JTAG_SET(TDI_H|TMS_H|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_H|TCK_H);JTAG_DELAY(); // Update_IR

JTAG_SET(TDI_H|TMS_H|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_H|TCK_H);JTAG_DELAY(); // Select-DR-Scan

JTAG_SET(TDI_H|TMS_L|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_L|TCK_H);JTAG_DELAY(); //Capture-DR

JTAG_SET(TDI_H|TMS_L|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_L|TCK_H);JTAG_DELAY(); //Shift-DR

// Read IDcode..
for( i=0 ; i<=30 ; i++)
{
JTAG_SET(TDI_H|TMS_L|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_L|TCK_H);JTAG_DELAY(); //Shift-DR
id[i]=(char)JTAG_GET_TDO();
}

JTAG_SET(TDI_H|TMS_H|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_H|TCK_H);JTAG_DELAY(); //Exit1_DR
id[i]=(char)JTAG_GET_TDO();

JTAG_SET(TDI_H|TMS_H|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_H|TCK_H);JTAG_DELAY(); // Update_DR

JTAG_SET(TDI_H|TMS_L|TCK_L);JTAG_DELAY(); // Why 3 times?
JTAG_SET(TDI_H|TMS_L|TCK_H);JTAG_DELAY(); // Run-Test/Idle
JTAG_SET(TDI_H|TMS_L|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_L|TCK_H);JTAG_DELAY(); // Run-Test/Idle
JTAG_SET(TDI_H|TMS_L|TCK_L);JTAG_DELAY();
JTAG_SET(TDI_H|TMS_L|TCK_H);JTAG_DELAY(); // Run-Test/Idle

//跑流程。。。需要注意的是此过程中的id[i]=(char)JTAG_GET_TDO();语句,它似乎在读什么

后来的

id32=0;
for(i=31 ;i>=0 ;i--)
{
if(id[i]==HIGH)
id32|=(1<<i);
}
就明白了
switch(id32)
{
case 0x00eb509d: //S3C64003X is detected. org : 0x1092009D
printf("> S3C6400X(ID=0x%08x) is detected./n",id32);
break;

default:
printf("ERROR: No CPU is detected(ID=0x%08x)./n",id32);
break;
}
使用来侦测cpu类型的

--------------
接下来是6400的检测 采用S6400_InitCell实现
rdataOutCellIndex[0] = Xm0DATA0_OUT; //refer to S3C6400_070430.bsdl
rdataOutCellIndex[1] = Xm0DATA1_OUT;
rdataOutCellIndex[2] = Xm0DATA2_OUT;
rdataOutCellIndex[3] = Xm0DATA3_OUT;
rdataOutCellIndex[4] = Xm0DATA4_OUT;
rdataOutCellIndex[5] = Xm0DATA5_OUT;
rdataOutCellIndex[6] = Xm0DATA6_OUT;
rdataOutCellIndex[7] = Xm0DATA7_OUT;
rdataOutCellIndex[8] = Xm0DATA8_OUT;
rdataOutCellIndex[9] = Xm0DATA9_OUT;
rdataOutCellIndex[10] = Xm0DATA10_OUT;。。。。。。
初始化了s6400的个个引脚的高低....
=======================

第三步 flash的工作
K9f1g08_Menu
K9f1g08_JtagInit
NF_Init();
id=NF_CheckId();获得nf的id
会得到“K9f1g08(0xeca1) is detected. ID=0xecf1”中的ecf1

然后,菜单选择烧录
K9f1g08_Program
烧录前首先要printf一推提示,
urce size:0h~3ffffh

Available target block number: 0~1024
Input target block number:target start block number =2
target size (0x20000*n) =0x40000

FILE: eboot.nb0
Programe will take about 21 minutes,please wait...

真正的开始(太激动了。)
//////////////////////////////
blockIndex=targetBlock;
while(1)
{
if(noLoad==0)
{
LoadImageFile(blockBuf,0x20000);
}
noLoad=0;

if(blockIndex >= 1024)
{
printf("/nERROR : no enough good block!/n");
return;
}

printf("/n-------->use block %d/n",blockIndex);

#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/n");
srcPt=blockBuf;

for(i=0;i<(targetBlock == 0 ? 2 : 64);i++) // if y download the testcode or OS image, y replace 4 to 64.
{

if(i == 0)
{
//只需第一个页写上3即可
spareBuf[0]=0; //bad
spareBuf[5]=3; //mzy,for bOEMReserved
}
else
{
spareBuf[0]=0xff; //bad
spareBuf[5]=0xff;
}

if(!NF_WritePage(blockIndex,i,srcPt,spareBuf))// block num, page num, buffer
{
programError=1;
break;
}

srcPt+=2048; // Increase buffer raddr one pase size

printf("%d,",i);
}
printf("/n");

if(programError==1)
{
blockIndex++;
noLoad=1;
programError=0;
continue;
}
progSize+=0x20000;
if(progSize>=imageSize)
{
printf("/n==============download==finish===============/n/n/n");
break; // Exit while loop
}
blockIndex++;
//////////////////////////

//负责写入的函数:
static int NF_WritePage(U32 block,U32 page,U8 *buffer,U8 *spareBuf)
{
int i;
U32 blockPage=(block<<6)+page;
U8 *bufPt=buffer;

NF_nFCE_L();
NF_CMD(0x0);//、、、、、、、、、(这是一堆底层指令

S6400_ContRDataBus(LOW); //RD[15:0]=output

S6400_SetPin(Xm0CSn2_OUT,LOW);
S6400_SetPin(Xm0INTsm1_FREn_OUT,HIGH);
S6400_SetPin(Xm0INTsm0_FWEn_OUT,LOW); //Because tCLS=0, CLE & nFWE can be changed simultaneously.

S6400_SetPin(Xm0RDY0_ALE_OUT,LOW);
S6400_SetPin(Xm0RDY1_CLE_OUT,HIGH);

S6400_SetRDataByte(cmd);
JTAG_ShiftDRStateNoTdo(outCellValue);

S6400_SetPin(Xm0INTsm0_FWEn_OUT,HIGH);
JTAG_ShiftDRStateNoTdo(outCellValue);

S6400_SetPin(Xm0RDY1_CLE_OUT,LOW);
S6400_ContRDataBus(HIGH); //RD[15:0]=input
JTAG_ShiftDRStateNoTdo(outCellValue);
)、、、、、、、、、、、、、
NF_CMD(0x80); // Write 1st command
NF_RADDR(0);//也是一陀 // Column A[7:0]=0
NF_RADDR(0); // Column A[11:8]=0
NF_RADDR( (U8)(blockPage&0xff) ); // A[19:12]
NF_RADDR( (U8)((blockPage>>8)&0xff) ); // A[27:20] //

for(i=0;i<2048;i++)
{
NF_WRRDATA(*bufPt++); // Write one page to NFM from buffer
}

if(spareBuf!=NULL)
{
for(i=0;i<64;i++)
{
NF_WRRDATA(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_RDRDATA()&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 void NF_WRRDATA(U8 rdata)
{
S6400_ContRDataBus(LOW); //RD[15:0]=output
S6400_SetPin(Xm0INTsm0_FWEn_OUT,LOW);
S6400_SetRDataByte(rdata);
JTAG_ShiftDRStateNoTdo(outCellValue);

S6400_SetPin(Xm0INTsm0_FWEn_OUT,HIGH);
JTAG_ShiftDRStateNoTdo(outCellValue);
}写入函数

-------
等都写完就 if(progSize>=imageSize)
{
printf("/n==============download==finish===============/n/n/n");了

详见我资源的源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: