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

来源:互联网 发布:巨人网络吴萌老婆 编辑:程序博客网 时间:2024/05/01 19:59

潦草的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");了

 

详见我资源的源码

原创粉丝点击