?? jblaster.c
字號:
for(i=0;i<4;i++)
{
if(GetData(Info_name[i],buffer,data))
{
switch(i)
{
case 0:
jb_strcpy(device_list[device_count-1].partname,data);
CheckAltDev(device_count);
break;
case 1:
jb_strcpy(device_list[device_count-1].path,data);
break;
case 2:
jb_strcpy(device_list[device_count-1].file,data);
break;
case 3:
device_list[device_count-1].inst_len= jb_atoi(data);
fprintf(stderr,"parsed %s to %i\n",data, device_list[device_count-1].inst_len);
ji_info[device_count-1]=device_list[device_count-1].inst_len;
break;
default:
break;
}
}
}
}
/******************************************************************/
/* Name: CheckAltDev */
/* */
/* Parameters: dev_seq */
/* -dev_seq is the device sequence in JTAG chain. */
/* */
/* Return Value: None. */
/* */
/* Descriptions: The function matches the partname specified in */
/* CDF with Altera devices list. If matches, the */
/* JTAG chain information will be updated in device */
/* _list. The action code is updated by ActionCode. */
/* If the partname is not recognized, the device */
/* will be bypassed. */
/* */
/******************************************************************/
void CheckAltDev(int dev_seq)
{
int i,j,altera=0;
dev_seq--;
for(i=0;i<MAX_DEV_LIST;i++)
{
if(!jb_strcmp(device_list[dev_seq].partname,device_name[i]))
{
if(!(device_info[i][0] && device_info[i][1] && device_info[i][2]))
{
device_list[dev_seq].inst_len = device_info[i][3];
ji_info[dev_seq] = device_list[dev_seq].inst_len;
fprintf(stdout,"Warning: Device #%d not supported! Bypassed!\n",dev_seq+1);
}
else
{
device_list[dev_seq].idcode = device_info[i][0];
device_list[dev_seq].jseq_max = device_info[i][1];
device_list[dev_seq].jseq_conf_done = device_info[i][2];
device_list[dev_seq].inst_len = device_info[i][3];
ji_info[dev_seq] = device_list[dev_seq].inst_len;
altera = 1;
break;
}
}
}
for(j=0;j<MAX_DEV_FAMILY;j++)
{
if(i<start_of_device_family[j])
{
device_family = j-1;
fprintf(stdout,"family: %s(%d)\n",family_name[j-1],j);
break;
}
}
if(!altera)
{
device_list[dev_seq].idcode=0;
device_list[dev_seq].jseq_max=0;
device_list[dev_seq].jseq_conf_done=0;
device_list[dev_seq].action='B';
}
}
/******************************************************************/
/* Name: VerifyChain */
/* */
/* Parameters: None. */
/* */
/* Return Value: None. */
/* */
/* Descriptions: Putting all devices in BYPASS mode, a 8-bit */
/* vector is driven to TDI, the number of '0' */
/* detected indicates the number of devices in */
/* chain. The 8-bit vector must follows the zeroes. */
/* */
/******************************************************************/
int VerifyChain()
{
unsigned int data=0,temp=0,test_vect=0x55;
int i,num=0,error=0;
Js_Reset();
/* Load BYPASS instruction and test JTAG chain with a few vectors */
if(Ji_Bypass(device_count,ji_info))
return (1);
Js_Shiftdr();
/* Drive a 8-bit vector of "10101010" (right to left) to test */
data = ReadTDO(8+device_count,test_vect,0);
/* The number of leading '0' detected must equal to the number of devices specified */
temp = data;
for(i=0;i<device_count;i++)
{
temp = temp&1;
if(temp)
break;
else
num++;
temp = data>>(i+1);
}
if(temp==test_vect)
fprintf(stdout,"Info: Detected %d device(s) in chain...\n", num);
else
{
fprintf(stderr,"Error: JTAG chain broken or #device in chain unmatch!\n");
return (1);
}
Js_Updatedr();
/* Read device IDCODE */
Ji_Idcode(device_count,ji_info);
Js_Shiftdr();
for(i=device_count-1;i>=0;i--)
{
data = ReadTDO(CDF_IDCODE_LEN,0,0);
if(device_list[i].idcode)
{
/* The partname specified in CDF must match with its ID Code */
if((unsigned)device_list[i].idcode != data)
{
fprintf(stderr,"Error: Expected 0x%X but detected 0x%X!\n",device_list[i].idcode,data);
error=1;
}
else
fprintf(stdout,"Info: Dev%d: Altera: 0x%X\n",i+1,data);
}
else
{
fprintf(stdout,"Info: Dev%d: Non-Altera: 0x%X\n",i+1,data);
}
}
Js_Updatedr();
Js_Runidle();
return error;
}
/******************************************************************/
/* Name: Configure */
/* */
/* Parameters: file_id,dev_seq,action */
/* -file_id is the ID of the file. */
/* -dev_seq is the device sequence in chains. */
/* -action is the action to take:BYPASS or PROGRAM */
/* */
/* Return Value: None. */
/* */
/* Descriptions: Issue PROGRAM instruction to the device to be */
/* configured and BYPASS for the rest of the devices*/
/* Call function that processes the source file. */
/* */
/******************************************************************/
void Configure(int file_id,int dev_seq,int action)
{
int i;
/* Load PROGRAM instruction */
SetupChain(device_count,dev_seq,ji_info,action);
if(action==JI_PROGRAM)
{
/* Drive TDI HIGH while moving JSM to SHIFTDR */
DriveSignal(SIG_TDI,1,0,1);
Js_Shiftdr();
/* Issue MAX_JTAG_INIT_CLOCK clocks in SHIFTDR state */
for(i=0;i<MAX_JTAG_INIT_CLOCK[device_family];i++)
{
DriveSignal(SIG_TDI,1,1,0);
}
/* Start dumping configuration bits into TDI and clock with TCK */
ProcessFileInput(file_id);
/* Move JSM to RUNIDLE */
Js_Updatedr();
Js_Runidle();
}
}
/******************************************************************/
/* Name: CheckStatus */
/* */
/* Parameters: dev_seq */
/* -dev_seq is the device sequence in chains. */
/* */
/* Return Value: '0' if CONF_DONE is HIGH;'1' if it is LOW. */
/* */
/* Descriptions: Issue CHECK_STATUS instruction to the device to */
/* be configured and BYPASS for the rest of the */
/* devices. */
/* */
/* <conf_done_bit> = */
/* ((<Maximum JTAG sequence> - */
/* <JTAG sequence for CONF_DONE pin>)*3) + 1 */
/* */
/* The formula calculates the number of bits */
/* to be shifted out from the device, excluding the */
/* 1-bit register for each device in BYPASS mode. */
/* */
/******************************************************************/
int CheckStatus(int dev_seq)
{
int bit,data=0,error=0;
int jseq_max=0,jseq_conf_done=0,conf_done_bit=0;
fprintf( stdout, "Info: Checking Status\n" );
/* Load CHECK_STATUS instruction */
SetupChain(device_count,dev_seq,ji_info,JI_CHECK_STATUS);
Js_Shiftdr();
/* Maximum JTAG sequence of the device in chain */
jseq_max= device_list[dev_seq-1].jseq_max;
jseq_conf_done= device_list[dev_seq-1].jseq_conf_done;
conf_done_bit = ((jseq_max-jseq_conf_done)*3)+1;
/* Compensate for 1 bit unloaded from every Bypass register */
conf_done_bit+= (device_count-dev_seq);
for(bit=0;bit<conf_done_bit;bit++)
{
DriveSignal(SIG_TDI,0,1,1);
}
data = ReadTDO(1,0,0);
if(!data)
error++;
/* Move JSM to RUNIDLE */
Js_Updatedr();
Js_Runidle();
return (error);
}
/******************************************************************/
/* Name: Startup */
/* */
/* Parameters: dev_seq */
/* -the device sequence in the chain. */
/* */
/* Return Value: None. */
/* */
/* Descriptions: Issue STARTUP instruction to the device to */
/* be configured and BYPASS for the rest of the */
/* devices. */
/* */
/******************************************************************/
void Startup(int dev_seq)
{
int i;
/* Load STARTUP instruction to move the device to USER mode */
SetupChain(device_count,dev_seq,ji_info,JI_STARTUP);
Js_Runidle();
for(i=0;i<INIT_COUNT;i++)
{
DriveSignal(SIG_TCK,0,0,0);
DriveSignal(SIG_TCK,1,0,0);
}
/* Reset JSM after the device is in USER mode */
Js_Reset();
}
/******************************************************************/
/* Name: ProcessFileInput */
/* */
/* Parameters: finputid */
/* -programming file pointer. */
/* */
/* Return Value: None. */
/* */
/* Descriptions: Get programming file size, parse through every */
/* single byte and dump to parallel port. */
/* */
/******************************************************************/
void ProcessFileInput(int finputid)
{
int seek_position=0,one_byte=0;
long int file_size=0,i=0;
/* Get file size */
seek_position = jb_fseek(finputid,0,S_END);
if(seek_position)
{
fprintf( stderr, "Error: End of file could not be located!" );
return;
}
file_size = jb_ftell(finputid);
/* Start configuration */
/* Reset file pointer */
jb_fseek(finputid,0,S_SET);
fprintf(stdout,"Info: Start configuration process.\n Please wait...");
/* Loop through every single byte */
for(i=0;i<file_size;i++)
{
int bit = 0,j;
one_byte = jb_fgetc(finputid);
/* Progaram a byte,from LSb to MSb */
for (j=0;j<8;j++ )
{
bit = one_byte >> j;
bit = bit & 0x1;
/* Dump to TDI and drive a positive edge pulse at the same time */
DriveSignal(SIG_TDI,bit,1,0);
}
}
#if PORT==WINDOWS_NT
/* Flush out the remaining data in Port0 */
flush_ports();
#endif /* PORT==WINDOWS_NT */
fprintf(stdout," done\n");
}
/******************************************************************/
/* Name: DriveSignal */
/* */
/* Parameters: signal,data,clk,test */
/* -the name of the signal (SIG_*). */
/* -the value to be dumped to the signal,'1' or '0' */
/* -driving a LOW to HIGH transition to SIG_TCK */
/* together with signal. */
/* -test is used by WritePort function. */
/* */
/* Return Value: None. */
/* */
/* Descriptions: Dump data to signal. If clk is '1', a clock pulse*/
/* is driven after the data is dumped to signal. */
/* */
/******************************************************************/
void DriveSignal(int signal,int data,int clk,int test)
{
/* Get signal port number */
int port = sig_port_maskbit[signal][0];
/* Get signal mask bit*/
int mask;
/* If clk == 1, drive signal with [data] and drive SIG_DCLK with '0' together. Then drive SIG_DCLK with '1' */
/* That is to create a positive edge pulse */
if(clk)
mask = sig_port_maskbit[signal][1] | sig_port_maskbit[SIG_TCK][1];
else
mask = sig_port_maskbit[signal][1];
/* AND signal bit with '0', then OR with [data] */
mask = ~mask;
port_data[port] = (port_data[port]&mask) | (data*sig_port_maskbit[signal][1]);
WritePort(port,port_data[port],test);
if(clk)
{
WritePort(port,(port_data[port] | sig_port_maskbit[SIG_TCK][1]),test);
WritePort(port,port_data[port],test);
}
}
/******************************************************************/
/* Name: SetPortMode */
/* */
/* Parameters: mode */
/* - The mode of the port (PM_*) */
/* */
/* Return Value: None. */
/* */
/* Descriptions: Set the parallel port registers to a particular */
/* values. */
/* */
/******************************************************************/
void SetPortMode(int mode)
{
/* write to Port 0 and Port 2 with predefined values */
port_data[0] = port_mode_data[mode][0];
port_data[2] = port_mode_data[mode][2];
WritePort( 0, port_data[0], 1 );
WritePort( 2, port_data[2], 1 );
}
/******************************************************************/
/* Name: Help */
/* */
/* Parameters: None. */
/* */
/* Return Value: None. */
/* */
/* Descriptions: Print help to standard output. */
/* */
/******************************************************************/
void Help()
{
#ifdef LINUX_PARPORT
fprintf(stderr,"Error: Invalid number of argument! \nSyntax: \"jblaster [-d <device>] <Chain Description File(.cdf)>\"\n");
fprintf(stderr,"Example: \"jblaster samples/chain1.cdf\"\n");
fprintf(stderr,"Example: \"jblaster -d /dev/parport1 project.cdf\"\n");
#else
fprintf(stderr,"Error: Invalid number of argument! \nSyntax: \"jblaster [-d <parport io address>] <Chain Description File(.cdf)>\"\n");
fprintf(stderr,"Example: \"jblaster samples/chain1.cdf\"\n");
fprintf(stderr,"Example: \"jblaster -d 378 project.cdf\"\n");
#endif
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -