📄 jflash.cpp
字号:
// each of these needs a voltage limiter like this, to clamp the voltage to 3V, as the SA1100 is not 5V tolerant :-
//
//LPTport --->---/\/\-----|-------|-->Jtag connector
// 1K | |
// _|_ === 470pf
// LED (Yellow) \ / |
// (one per line) __V__ _|_ JTAG & LPTPORT ground
// |
// | <---tie all 3 of these points together
// _|_
// 1N4148 \ /
// (one per widget) __V__
// |
// __________________|____________________ JTAG & LPTPORT ground
//
// Input pin (SA-1110 board drives)
// LPT Busy Pin 11 and TDO J10 Pin 13
// (steve) TDO does go straight to the port, although I suspect a 33R resistor
// in series would be a good thing.
// (Steve) nTRST I tied on the PCB to nRESET (pin 2 of the MAX811). (I see no
// downside to doing this on future versions of the LART - it's what I've
// done on SA1100 designs before)
//
int tdo = -1;
#ifndef IODIRECT
// MMPOutp(lpt_address, tms*4+tdi*2); //TCK low
MMPOutp(lpt_address, tms*4+tdi*2+1); // TCK high
// if(rp == RP)MMPOutp(lpt_address, tms*4+tdi*2); // TCK low
MMPOutp(lpt_address, tms*4+tdi*2); // TCK low
if(rp == RP)tdo = !((int)MMPInp(lpt_address + 1) >> 7); // get TDO data
#else
_outp(lpt_address, tms*4+tdi*2); // TCK low
_outp(lpt_address, tms*4+tdi*2+1); // TCK high
if(rp == RP)_outp(lpt_address, tms*4+tdi*2); // TCK low
if(rp == RP)tdo = !((int)_inp(lpt_address + 1) >> 7); // get TDO data
#endif
return tdo;
}
void id_command(void)
{
putp(1,1,IP); //get to TLR
putp(1,1,IP);
putp(1,1,IP);
putp(1,1,IP);
putp(1,1,IP);
putp(1,1,IP);
putp(1,1,IP);
putp(1,1,IP);
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);
putp(1,1,IP); //select IR scan
putp(1,0,IP); //capture IR
putp(1,0,IP); //shift IR
putp(0,0,IP); //SA1100 IDCODE
putp(1,0,IP); //
putp(1,0,IP); //
putp(0,0,IP); //
putp(0,1,IP); //Exit1-IR
putp(1,1,IP); //Update-IR
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); //sel_DR
putp(1,0,IP);
if(check_id(SA1100ID))
error_out("failed to read device ID for the SA-1100");
putp(1,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
}
void bypass_all(void)
{
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);
putp(1,1,IP); //select IR scan
putp(1,0,IP); //capture IR
putp(1,0,IP); //shift IR
putp(1,0,IP); //SA1100 BYPASS
putp(1,0,IP); //
putp(1,0,IP); //
putp(1,0,IP); //
putp(1,1,IP); //Exit1-IR
putp(1,1,IP); //Update-IR
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
}
void extest(void)
{
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);
putp(1,1,IP); //select IR scan
putp(1,0,IP); //capture IR
putp(1,0,IP); //shift IR
putp(0,0,IP); //SA110 extest
putp(0,0,IP); //
putp(0,0,IP); //
putp(0,0,IP); //
putp(0,1,IP); //
putp(1,1,IP); //Update-IR
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
putp(1,0,IP); //Run-Test/Idle
}
DWORD access_rom(int rw, DWORD address, DWORD data, int rp, int plait)
{
// Shift Flash address making A2 the LSB
return(access_bus(rw, address << 2, data, rp, plait));
}
DWORD access_bus(int rw, DWORD address, DWORD data, int rp, int plait)
{
// Preset SA-1100 pins to default values (all others set in sa1100jtag.h)
pin[nCS0_OUT] = 1;
pin[nCS1_OUT] = 1;
pin[nCS2_OUT] = 1;
pin[nCS3_OUT] = 1;
pin[nOE_OUT] = 0;
pin[nWE_OUT] = 1;
//pin[RD_nWR_OUT] = 0;
pin[D31_0_EN] = 1;
for(int i = 0; i < 26; i++)
pin[i+28] = (int)((address >> i) & 1); // set address 0 thru 25
if(rw == READ)
{
//pin[RD_nWR_OUT] = 1;
if (debug_jtag) printf ("READ from %8x ",address);
switch(address >> 27)
{
case 0:{pin[nCS0_OUT] = 0; break;}
case 1:{pin[nCS1_OUT] = 0; break;}
case 2:{pin[nCS2_OUT] = 0; break;}
case 3:{pin[nCS3_OUT] = 0; break;}
}
}
if(rw == WRITE)
{
if (debug_jtag) printf ("WRITE %8x to %8x ", data, address);
pin[nWE_OUT] = 0;
pin[nOE_OUT] = 1;
pin[D31_0_EN] = 0; // switch data pins to drive
switch(address >> 27) // set CS pin for corresponding address
{
case 0:{pin[nCS0_OUT] = 0; break;}
case 1:{pin[nCS1_OUT] = 0; break;}
case 2:{pin[nCS2_OUT] = 0; break;}
case 3:{pin[nCS3_OUT] = 0; break;}
}
for(DWORD li = 0L; li < 32L; li++)
if (plait)
{
pin[command_dat_order[li]] = (int)((data >> li) & 1L); // set data pins
}
else
{
pin[data_dat_order[li]] = (int)((data >> li) & 1L); // set data pins
}
}
if(rw == SETUP || rw == HOLD) // just like a write except WE, WE needs setup time
{
if (debug_jtag) printf ("SET/HOLD at %8x ", address);
pin[nOE_OUT] = 1;
pin[D31_0_EN] = 0;
for(DWORD li = 0L; li < 32L; li++)
if (plait)
{
pin[command_dat_order[li]] = (int)((data >> li) & 1L); // set data pins
}
else
{
pin[data_dat_order[li]] = (int)((data >> li) & 1L); // set data pins
}
}
if(rw == RS) // setup prior to RD_nWR_OUT
{
if (debug_jtag) printf ("RS ");
pin[nOE_OUT] = 1;
}
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 DR
int out_dat[300];
int i;
for(i = 0; i < (SA1100_CHAIN_LENGTH - 1); i++) // shift write data in to JTAG port and read data out
out_dat[i] = putp(pin[i],0,rp);
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
DWORD busdat = 0;
for(i = 0; i < 32; i++) // convert serial data to single DWORD
{
if (plait)
{
busdat = busdat | (DWORD)(out_dat[command_dat_order[i] - 2] << i);
}
else
{
busdat = busdat | (DWORD)(out_dat[data_dat_order[i] - 2] << i);
}
}
extest();
if (debug_jtag) if (rp == RP) printf("prev.busdat = %8x\n\r",busdat); else printf("\n\r");
return(busdat);
}
#ifdef __linux__
int io_access_on( unsigned long port )
{
if (ioperm (port, 3, 1)) {
perror ("ioperm()");
return 0;
}
return 1;
}
void io_access_off( unsigned long port )
{
ioperm (port, 3, 0);
}
#else
#define io_access(x) (1)
#define io_access(x)
#endif
int test_port(void)
{
// search for valid parallel port
#ifndef IODIRECT
MMPOutp(LPT1, 0x55);
if((int)MMPInp(LPT1) == 0x55)return LPT1;
MMPOutp(LPT2, 0x55);
if((int)MMPInp(LPT2) == 0x55)return LPT2;
MMPOutp(LPT1, 0x55);
if((int)MMPInp(LPT3) == 0x55)return LPT3;
#else
if( io_access_on(LPT1) ){
_outp(LPT1, 0x55);
if((int)_inp(LPT1) == 0x55)return LPT1;
io_access_off(LPT1);
}
if( io_access_on(LPT2) ){
_outp(LPT2, 0x55);
if((int)_inp(LPT2) == 0x55)return LPT2;
io_access_off(LPT2);
}
if( io_access_on(LPT3) ){
_outp(LPT1, 0x55);
if((int)_inp(LPT3) == 0x55)return LPT3;
io_access_off(LPT3);
}
#endif
return(0); // return zero if none found
}
int check_id(char *device_id)
{
// compare passed device ID to the one returned from the ID command
char in_id[40];
for(int i = 34; i >= 0; i--)
{
if(i == 4 || i == 21 || i == 33)
{
in_id[i] = ' ';
i--;
}
if(putp(1,0,RP) == 0)
in_id[i] = '0';
else
in_id[i] = '1';
}
in_id[35] = 0;
if(strcmp(device_id+4,in_id+4)) // add 4 to compare all but the device version
{
printf("error, failed to read device ID\n");
printf("ACT: %s\n",in_id);
printf("EXP: %s\n\n",device_id);
return -1;
}
return 0;
}
void error_out(char *error_string)
{
#ifndef IODIRECT
MMPClose();
#endif
printf("%s\n",error_string);
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -