?? jblaster.c
字號:
/******************************************************************/
/* */
/* Module: jblaster.c */
/* */
/* Descriptions: Main source file that manages the configuration */
/* processes. */
/* */
/* Revisions: 1.0 02/22/02 */
/* */
/******************************************************************/
/* $Id: jblaster.c,v 1.1.1.1 2002/12/03 23:49:16 x42 Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jb_io.h"
#include "jb_jtag.h"
#include "jb_const.h"
#include "jb_device.h"
//#if PORT==WINDOWS_NT
void SetPortMode (int mode);
//#endif /* PORT==WINDOWS_NT */
/* JBlaster Controller Functions */
int VerifyChain ();
void DriveSignal (int signal,int data,int clk,int test);
void Configure (int file_id,int dev_seq,int action);
void ProcessFileInput (int finputid);
int CheckStatus (int dev_seq);
void Startup (int dev_seq);
void Help ();
/* CDF Parser Functions */
int ReadCDF (int file_id);
int GetData (char* charset,char* buffer,char* data);
void SearchKeyword (char* buffer,char* data);
int CheckActionCode (char* data);
void CheckAltDev (int dev_seq);
/* JTAG instruction lengths of all devices */
int ji_info[MAX_DEVICE_ALLOW] = {0};
/* extern configuration */
#ifndef LINUX_PARPORT
extern unsigned short lpt_addr;
#else
extern char devicepath[256];
#endif
int main(int argc, char* argv[])
{
int i=0;
int file_id=0;
int config_count=0;
/**********Initialization**********/
/* Introduction */
fprintf(stdout,"\n======================================================\n");
fprintf(stdout," JTAGBlaster (JBlaster) Version %s",VERSION);
fprintf(stdout,"\n Altera Corporation ");
fprintf(stdout,"\n Linux patch 11/02 by Robin Gareus <robin@gareus.org>");
fprintf(stdout,"\n======================================================\n");
/* set default values */
#ifdef LINUX_PARPORT
snprintf(devicepath,255,"/dev/parport0");
#else
lpt_addr = 0x378;
#endif
if(argc > 1)
{
/* Parse Command Line Arguments */
argc--;
argv++;
for (; argc-- > 0; argv++)
{
if (strcmp (*argv, "--help") == 0 || strcmp (*argv, "-h") == 0)
{
Help();
exit(1);
}
else if ((strcmp (*argv, "-d") == 0 || strcmp (*argv, "--device") == 0) && argc > 0)
{
argc--;
argv++;
#ifndef LINUX_PARPORT
{ int x; sscanf(*argv,"%x",&x); lpt_addr= (unsigned short) x;}
printf("Info: using parport address 0x%x.\n",lpt_addr);
#else
snprintf(devicepath,255,"%s",*argv);
printf("Info: using parport device: '%s'.\n",devicepath);
#endif
}
else break;
}
}
if (argc!=0) {
Help();
exit(1);
}
/* Open CDF file */
file_id = jb_fopen(*argv,"rb");
if(file_id)
fprintf(stdout,"Info: Chain Description File: \"%s\" opened..\n", *argv);
else
{
fprintf(stderr,"Error: Could not open Chain Description File (CDF): \"%s\"!\n",*argv);
return(2);
}
/**********Hardware Setup**********/
#if PORT==WINDOWS_NT
InitNtDriver();
/* Check if hardware is properly installed */
if(VerifyHardware())
{
jb_fclose(file_id);
return(2);
}
#elif PORT == LINUX
InitLinuxDriver();
/* Check if hardware is properly installed */
if(VerifyHardware())
{
jb_fclose(file_id);
return(2);
}
#endif
/**********CDF Parsing**********/
fprintf( stdout, "\nInfo: Parsing CDF...\n" );
if(!ReadCDF(file_id))
{
jb_fclose(file_id);
return(2);
}
jb_fclose(file_id);
fprintf( stdout, "Debug: Parsing done.\n" );
if(!device_count)
return(2);
for(i=0;i<device_count;i++)
{
if(!ji_info[i])
{
fprintf(stderr,"Error: JTAG instruction length of device #%d NOT specified!\n",i);
return(2);
}
}
/**********Device Chain Verification**********/
fprintf( stdout, "\nInfo: Verifying device chain...\n" );
/*#if PORT==WINDOWS_NT */ /* why only in Windows? disabled */
SetPortMode(PM_RESET);
/* #endif */ /* PORT==WINDOWS_NT */
/* Verify the JTAG-compatible devices chain */
if(VerifyChain())
return(2);
/**********Show Info***********/
fprintf(stdout,"Debug: (1)jseq_max (2)jseq_conf_done (3)action (4)partname (5)path (6)file (7)inst_len\n");
for(i=0;i<device_count;i++)
{
fprintf(stdout,"Debug: (1)%d (2)%d (3)%c (4)%s (5)%s (6)%s (7)%d\n",
device_list[i].jseq_max,device_list[i].jseq_conf_done,device_list[i].action,device_list[i].partname,
device_list[i].path,device_list[i].file,device_list[i].inst_len);
}
/**********Configuration**********/
file_id=0;
for(i=1;i<device_count+1;i++)
{
char fullpath[CDF_PATH_LEN+CDF_FILE_LEN];
config_count=0;
if(device_list[i-1].action != 'P')
continue;
while(config_count<MAX_CONFIG_COUNT)
{
if(!config_count)
fprintf( stdout, "\nInfo: Configuration setup device #%d\n",i);
else
fprintf( stdout, "\nInfo: Configuration setup device #%d (Retry)\n",i);
config_count++;
/* Open programming file as READ and in BINARY */
jb_strcpy(fullpath,device_list[i-1].path);
jb_strcat(fullpath,device_list[i-1].file);
file_id = jb_fopen( fullpath, "rb" );
if ( file_id )
fprintf( stdout, "Info: Programming file #%d: \"%s\" opened...\n", i,fullpath );
else
{
fprintf( stderr, "Error: Could not open programming file #%d: \"%s\"\n", i,fullpath );
return(2);
}
/* Start configuration */
Configure(file_id,i,(device_list[i-1].idcode? JI_PROGRAM:JI_BYPASS));
// #if PORT==WINDOWS_NT
flush_ports();
// #endif /* PORT==WINDOWS_NT */
jb_fclose(file_id);
if(CheckStatus(i))
{
fprintf( stdout, "\nWarning: Configuration of device #%d NOT successful!\n",i );
}
else
{
Startup(i);
config_count=MAX_CONFIG_COUNT;
fprintf( stdout, "\nInfo: Configuration of device #%d successful...\n",i );
}
}
}
// #if PORT==WINDOWS_NT
SetPortMode(PM_USER);
// #endif /* PORT==WINDOWS_NT */
return(0);
}
/******************************************************************/
/* Name: ReadCDF */
/* */
/* Parameters: file_id */
/* -file handler */
/* */
/* Return Value: The number of devices in chain found in CDF */
/* */
/* Descriptions: ReadCDF parses through the CDF and keeps the */
/* device records. It looks for 'P' or 'N' when */
/* mark=0. Once found, it searches for "ActionCode" */
/* when mark=1 and once mark=2, it starts to */
/* retrieve the data in device record declarations. */
/* */
/******************************************************************/
int ReadCDF(int file_id)
{
char buffer[160]; /* line buffer */
char data[50]; /* device record data between '(' and ')' */
int mark= 0;
while(jb_fgets(buffer,file_id))
{
if (mark==1)
{
mark =2;
if(GetData("ACTIONCODE",buffer,data))
{
if(!CheckActionCode(data))
return 0;
}
device_count++;
SearchKeyword(buffer,data);
/* End of device record and reset flag */
if(jb_str_cmp(";",buffer))
mark=0;
}
else if (mark==2)
{
SearchKeyword(buffer,data);
/* End of device record and reset flag */
if(jb_str_cmp(";",buffer))
mark=0;
}
else if(jb_str_cmp("P ",buffer) || jb_str_cmp("N ",buffer))
{
mark++;
if(GetData("ACTIONCODE",buffer,data))
{
if(!CheckActionCode(data))
return 0;
/* End of device record and reset flag */
if(jb_str_cmp(";",buffer))
{
device_count++;
SearchKeyword(buffer,data);
mark=0;
}
}
}
else
{
continue;
}
}
fprintf( stdout, "Debug: Parsed %i Entrys.\n",device_count);
return device_count;
}
/******************************************************************/
/* Name: GetData */
/* */
/* Parameters: charset, buffer, data */
/* -charset is the character string or keyword to */
/* look for. */
/* -buffer is the line buffer stored when reading */
/* the CDF. */
/* -data is the string between brackets, '(' and ')'*/
/* */
/* Return Value: The position of the first character of charset */
/* found in buffer. */
/* */
/* Descriptions: The function copies the string between brackets */
/* right after charset into data. If charset is not */
/* found in buffer, '0' is returned. */
/* */
/******************************************************************/
int GetData(char* charset,char* buffer,char* data)
{
int char_count=0,i;
char* buff_pointer;
char* data_pointer;
int mark=0;
char * tmpbuf = malloc(sizeof(char)*jb_strlen(buffer));
strncpy (tmpbuf,buffer,jb_strlen(buffer));
jb_toupper(charset);
jb_toupper(tmpbuf);
/* looking for charset in buffer */
char_count= jb_str_cmp(charset,tmpbuf);
/* charset not found in buffer */
if(!char_count)
return 0;
data_pointer= data;
buff_pointer= buffer;
buff_pointer+= char_count-1+jb_strlen(charset);
for(i=0;i<jb_strlen(buffer)-1;i++)
{
if(*buff_pointer=='(')
{
mark++;
}
else if(*buff_pointer==')')
{
if(mark==1)
{
fprintf(stderr,"Error: Invalid Action Code!\n");
return 0;
}
/* put a null-zero to indicate the end of string to data */
*data_pointer= '\0';
break;
}
else if(mark)
{
mark=2;
/* ignore '"' character */
if(*buff_pointer!='"')
{
*data_pointer = *buff_pointer;
data_pointer++;
}
}
else
return 0;
buff_pointer++;
}
// jb_toupper(data);
return char_count;
}
/******************************************************************/
/* Name: CheckActionCode */
/* */
/* Parameters: data */
/* -The 3 character string indicating the action */
/* */
/* Return Value: '0' if valid action code is detected, '1' if not */
/* */
/* Descriptions: Update the action to take in device list. */
/* A 'B' or a 'P' is stored for BYPASS and PORGRAM/ */
/* CONFIGURE respectively. */
/* */
/******************************************************************/
int CheckActionCode(char* data)
{
if(!jb_strcmp(data,"IGN"))
device_list[device_count].action= 'B';
else if(!jb_strcmp(data,"CFG"))
device_list[device_count].action= 'P';
else
{
fprintf(stderr,"\nError: Invalid ActionCode: %s\n",data);
return 0;
}
return 1;
}
/******************************************************************/
/* Name: SearchKeyword */
/* */
/* Parameters: buffer, data */
/* -buffer is the line buffer stored when reading */
/* the CDF. */
/* -data is the string between brackets, '(' and ')'*/
/* found in buffer. */
/* */
/* Return Value: None. */
/* */
/* Descriptions: The function search for device records corres- */
/* pond to part name, path, file name and */
/* instruction length. */
/* */
/******************************************************************/
void SearchKeyword(char* buffer,char* data)
{
char Info_name[4][20] = { "PARTNAME","PATH","FILE","INSTRUCTIONREG" };
int i;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -