📄 jflash.cpp
字号:
*
*******************************************************************************
*/
int putp(int tdi, int tms, int rp)
{
#ifdef PARALLEL_JTAG
int tdo = -1;
// TMS is D2, TDI is D1, and TCK is D0, so construct an output by creating a
// rising edge on TCK with TMS and TDI data set.
_outp(lpt_address, tms*4+tdi*2+8); // TCK low
_outp(lpt_address, tms*4+tdi*2+1+8); // TCK high
// if we want to read the port, set TCK low because TDO is sampled on the
// TCK falling edge.
if(rp == READ_PORT)
_outp(lpt_address, tms*4+tdi*2+8); // TCK low
if(rp == READ_PORT)
tdo = !((int)_inp(lpt_address + 1) >> 7); // get TDO data
#endif
#ifdef INSIGHT_JTAG
// There's some bit clearing here that isn't needed. It should make this
// code easier to understand.
//defines for the INSIGHT IJC-1 JTAG cable
/* the output port (lpt_address) */
#define INSIGHT_CLK 0x02
#define INSIGHT_DIN 0x01
#define nINSIGHT_PROG 0x10 /* This causes the TDO line to be driven. We'll leave it high.*/
#define INSIGHT_TMS_IN 0x04
#define nINSIGHT_CTRL 0x08 /* Output Enable for the standard JTAG outputs
(not TDO since this is an output from the
chip we want to talk to */
/*the input port (lpt_address + 1)*/
#define TDO_INPUT 0x10
#define TDO_INPUT_BITPOS 4
int tdo = -1;
int lpt_data;
//form the data we want to write to the parallel port
lpt_data = nINSIGHT_PROG; //Output to TDO off
lpt_data &= ~nINSIGHT_CTRL; //Enable the outputs
if(tms == 1) lpt_data |= INSIGHT_TMS_IN;
if(tdi == 1) lpt_data |= INSIGHT_DIN;
// construct an output by creating a
// rising edge on TCK with TMS and TDI data set.
lpt_data &= ~INSIGHT_CLK;
_outp(lpt_address, lpt_data); // TCK low
lpt_data |= INSIGHT_CLK;
_outp(lpt_address, lpt_data); // TCK high
// if we want to read the port, set TCK low because TDO is sampled on the
// TCK falling edge.
if(rp == READ_PORT){
lpt_data &= ~INSIGHT_CLK;
_outp(lpt_address, lpt_data); // TCK high
tdo = ((int)_inp(lpt_address + 1) & TDO_INPUT) >> TDO_INPUT_BITPOS; // get TDO data
}
#endif
// #ifdef DEBUG
// printf("TDI = %d, TMS = %d, TDO = %d\n",tdi,tms,tdo);
// #endif
return tdo;
}
/*
*******************************************************************************
*
* FUNCTION: id_command
*
* DESCRIPTION: extract and verify the id codes of the devices in the chain
*
* INPUT PARAMETERS: void
*
* RETURNS: void
*
*******************************************************************************
*/
void id_command(void)
{
pre_IRSCAN();
controller_scan_code(COT_IDCODE, IGNORE_PORT, TERMINATE);
post_IRSCAN();
pre_DRSCAN();
if(check_id(COTULLAID))
error_out("failed to read device ID for the Cotulla");
post_DRSCAN();
}
/*
*******************************************************************************
*
* FUNCTION: bypass_all
*
* DESCRIPTION: put all devices into bypass mode
*
* INPUT PARAMETERS: void
*
* RETURNS: void
*
*******************************************************************************
*/
void bypass_all(void)
{
pre_IRSCAN();
controller_scan_code(COT_BYPASS, IGNORE_PORT, TERMINATE);
post_IRSCAN();
}
/*
*******************************************************************************
*
* FUNCTION: extest
*
* DESCRIPTION: put the processor into extest (drive pins) mode, and all
* others into bypass mode.
*
* INPUT PARAMETERS: void
*
* RETURNS: void
*
*******************************************************************************
*/
void extest(void)
{
pre_IRSCAN();
controller_scan_code(COT_EXTEST, IGNORE_PORT, TERMINATE);
post_IRSCAN();
}
/*
*******************************************************************************
*
* FUNCTION: access_rom
*
* DESCRIPTION: This is just an access-bus with the address multiplied by 4
*
* INPUT PARAMETERS: int - rw, or access mode
* DWORD - address
* DWORD - data
* int rp - whether to read or ignore the parallel port
*
* RETURNS: DWORD - returned data
*
*******************************************************************************
*/
DWORD access_rom_32(int rw, DWORD address, DWORD data, int rp)
{
DWORD returnvalue;
// Shift Flash address making A2 the LSB
#ifdef DEBUG
printf("ACCESS_ROM: inp addr = %X, inp data = %X\n", address, data);
#endif
returnvalue = access_bus(rw, address << 2, data, rp);
#ifdef DEBUG
printf("ACCESS_ROM Returns %X\n", returnvalue);
#endif
return returnvalue;
}
WORD access_rom_16(int rw, DWORD address, WORD data16, int rp)
{
WORD returnvalue;
DWORD data;
data=(DWORD)data16;
// Shift Flash address making A2 the LSB
#ifdef DEBUG
printf("ACCESS_ROM_16: inp addr = %X, inp data = %X\n", address, data);
#endif
returnvalue =(WORD)access_bus(rw, address << 1, data, rp);
#ifdef DEBUG
printf("ACCESS_ROM_16 Returns %X\n", returnvalue);
#endif
return returnvalue;
}
/*
*******************************************************************************
*
* FUNCTION: access_bus
*
* DESCRIPTION: This routine manipulates the memory bus to do reads
* and writes to any memory location.
*
* INPUT PARAMETERS: int rw - mode of READ, WRITE, SETUP, HOLD, or RS
* DWORD - address of access
* DWORD - data to write
* int rp - read or ignore port data
*
* RETURNS: DWORD - returned data
*
*******************************************************************************
*/
DWORD access_bus(int rw, DWORD address, DWORD data, int rp)
{
int i;
// Preset SA-1110 or Cotulla pins to default values (all others set in Cotullajtag.h)
clear_chip_selects();
mem_output_enable(ENABLE);
mem_write_enable(DISABLE);
mem_rw_mode(WRITE);
mem_data_driver(HIZ);
#ifdef DEBUG
printf("Chain initial state\n");
dump_chain();
#endif
set_address(address);
//----------------------------------------------
if(rw == READ)
{
#ifdef DEBUG
printf("Read Mode\n");
#endif
mem_rw_mode(READ);
set_pin_chip_select(address);
}
//----------------------------------------------
if(rw == WRITE)
{
#ifdef DEBUG
printf("Write Mode\n");
#endif
mem_write_enable(ENABLE);
mem_output_enable(DISABLE);
mem_data_driver(DRIVE);
set_pin_chip_select(address);
set_data(data);
}
//----------------------------------------------
if(rw == SETUP || rw == HOLD) // just like a write except WE, WE needs setup time
{
#ifdef DEBUG
printf("Setup or Hold Mode\n");
#endif
mem_output_enable(DISABLE);
mem_data_driver(DRIVE);
set_data(data);
}
//----------------------------------------------
if(rw == RS) // setup prior to RD_nWR_OUT
{
#ifdef DEBUG
printf("RS Mode\n");
#endif
mem_output_enable(DISABLE);
}
// Common finish
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
putp(1,1,IP); //select DR scan
putp(1,0,IP); //capture DR
putp(1,0,IP); //shift IR
int out_dat[420];
for(i = 1; i < 409; i++) // shift write data in to JTAG port and read data out
out_dat[i] = putp(pin[i],0,rp);
// fudge factor because chain appears to be shifted by 1
// DEBUG LATER
putp(0,1,IP); //Exit1-DR
putp(1,1,IP); //Update-DR
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
#ifdef XHYPER255B
DWORD busdat = 0;
for(i = 0; i < 32; i++) // convert serial data to single DWORD
{
busdat = busdat | ((DWORD)(out_dat[input_dat_order[i]] << i));
}
#else
WORD busdat = 0;
for(i = 0; i < 16; i++) // convert serial data to single DWORD
{
busdat = busdat | ((WORD)(out_dat[input_dat_order[i]] << i));
}
#endif
extest();
#ifdef DEBUG
printf("just before return\n");
dump_chain();
#endif
return(busdat);
}
/*
*******************************************************************************
*
* FUNCTION: test_port
*
* DESCRIPTION: Searches for a valid parallel port
*
* INPUT PARAMETERS: void
*
* RETURNS: int - Address of the port or zero if none available
*
*******************************************************************************
*/
int test_port(void)
{
// search for valid parallel port
if( io_access_on(LPT1) ){
_outp(LPT1, 0x55);
if((int)_inp(LPT1) == 0x55)
{
#ifdef DEBUG
printf("Parallel Com port found at I/O address: %X\n", LPT1);
#endif
return LPT1;
}
io_access_off(LPT1);
}
if( io_access_on(LPT2) ){
_outp(LPT2, 0x55);
if((int)_inp(LPT2) == 0x55)
{
#ifdef DEBUG
printf("Parallel Com port found at I/O address: %X\n", LPT2);
#endif
return LPT2;
}
io_access_off(LPT2);
}
if( io_access_on(LPT3) ){
_outp(LPT3, 0x55);
if((int)_inp(LPT3) == 0x55)
{
#ifdef DEBUG
printf("Parallel Com port found at I/O address: %X\n", LPT3);
#endif
return LPT3;
}
io_access_off(LPT3);
}
return(0); // return zero if none found
}
/*
*******************************************************************************
*
* FUNCTION: check_id
*
* DESCRIPTION: Compare an ID string returned from the device with the expected string.
*
* INPUT PARAMETERS: char * device_id - a pointer to the string returned from the device
*
* RETURNS: int - 0 if ID matches expected, -1 if a match fails
*
*******************************************************************************
*/
int check_id(char *device_id)
{
// compare passed device ID to the one returned from the ID command
char in_id[40];
BOOL error_flag = FALSE;
printf("\n");
for(int i = 34; i >= 0; i--)
{
// skip over the spaces in the ID string
if(i == 4 || i == 21 || i == 33)
{
in_id[i] = ' ';
i--;
}
if(putp(1,0,READ_PORT) == 0)
in_id[i] = '0';
else
in_id[i] = '1';
if((in_id[i] != *(device_id + i)) && (*(device_id + i) != '*'))
{
error_flag = TRUE;
}
}
in_id[35] = 0;
printf("ACT: %s\n",in_id);
printf("EXP: %s\n\n",device_id);
if(error_flag)
{
printf("error, failed to read device ID\n");
printf("check cables and power\n");
printf("ACT: %s\n",in_id);
printf("EXP: %s\n\n",device_id);
return -1;
}
if(!strcmp(device_id, COTULLAID)) // print Cotulla device revision
{
int sa_rev =
(int)(in_id[0] - '0') * 8 +
(int)(in_id[1] - '0') * 4 +
(int)(in_id[2] - '0') * 2 +
(int)(in_id[3] - '0');
switch(sa_rev)
{
case 0: printf("PXA255 revision ?? + %d\n\n",sa_rev); break;
case 1: printf("PXA255 revision ?? + %d\n\n",sa_rev); break;
case 2: printf("PXA255 revision ?? + %d\n\n",sa_rev); break;
case 3: printf("PXA255 revision ?? + %d\n\n",sa_rev); break;
case 4: printf("PXA255 revision ?? + %d\n\n",sa_rev); break;
case 5: printf("PXA255 revision ?? + %d\n\n",sa_rev); break;
case 6: printf("PXA255 revision ?? + %d\n\n",sa_rev); break;
case 8: printf("PXA255 revision ?? + %d\n\n",sa_rev); break;
default: printf("PXA255 revision ?? + %d\n\n",sa_rev - 8);
}
}
return 0;
}
/*
*******************************************************************************
*
* FUNCTION: error_out
*
* DESCRIPTION: generic error printout and program exit.
*
* INPUT PARAMETERS: char * error_string to print before exit
*
* RETURNS: void
*
* GLOBAL EFFECTS: Exits the program
*******************************************************************************
*/
void error_out(char *error_string)
{
printf("%s\n",error_string);
exit(0);
}
/*
*******************************************************************************
*
* FUNCTION: erase_flash
*
* DESCRIPTION: erases a selected number of flash blocks
*
* INPUT PARAMETERS: DWORD base_address of flash device
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -