📄 jtagio.c
字号:
//JFLASH V1.2#define VERSION "1.2"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h> /* toupper() */#include <time.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/ioctl.h>#include "sa1110jtag.h"#define INSTRUCTION_LENGTH 5 /* all opcodes are 5 bits long */#define READ 0 // Flags used to modify the SA-1110 JTAG chain data depending on#define WRITE 1 // the access mode of the Flash Memory#define SETUP 2#define HOLD 3#define RS 4#define IP 0 // Flag used when accessing the parallel port#define RP 1 // RP = 'read port', IP = 'ignore port', using IP will speed access#define SA1110ID "**** 1001001001100001 00000001001 1" // JTAG ID-codes for the SA-1110int dat_order[] = { D0_OUT, D1_OUT, D2_OUT, D3_OUT, D4_OUT, D5_OUT, D6_OUT, D7_OUT, D8_OUT, D9_OUT,D10_OUT,D11_OUT,D12_OUT,D13_OUT,D14_OUT,D15_OUT, D16_OUT,D17_OUT,D18_OUT,D19_OUT,D20_OUT,D21_OUT,D22_OUT,D23_OUT, D24_OUT,D25_OUT,D26_OUT,D27_OUT,D28_OUT,D29_OUT,D30_OUT,D31_OUT};long access_rom(int, long, long, int); // Passes read/write/setup data for the Flash memorylong access_bus(int, long, long, int); // Read/write access to the SA-1110 pinsint pin[300]; /* longer than JTAG chain length */void flash_write_val_hold(long addr, long val){ access_rom(WRITE, addr, val, IP); access_rom(HOLD, addr, val, IP);}void flash_write_val(long addr, long val){ access_rom(SETUP, addr, val, IP); // clear status register flash_write_val_hold(addr, val);}long flash_read_val(long addr){ return access_rom(READ, addr, 0, RP);}void flash_write_cmd(unsigned addr, int val){ flash_write_val(addr, bothbanks(val));}static int local_fd = -1;int local_return;int jcaiotrace = 0;void _outp(int a, int b){static struct { int i; char bozo[50];} st;st.i = b;if (local_fd < 0) { local_fd = open("/dev/shortint", O_RDWR); if (local_fd < 0) printf ("error opening /dev/shortint\n");}ioctl(local_fd, TIOCPKT_DATA, &st.i); /* write data/read status */local_return = st.i;if (jcaiotrace) printf ("outp(%x,%x)=%x;", a, b, local_return);}int _inp(int a){static struct { int i; char bozo[50];} st;if (local_fd < 0) { local_fd = open("/dev/shortint", O_RDWR); if (local_fd < 0) printf ("error opening /dev/shortint\n");}ioctl(local_fd, TIOCPKT_STOP, &st.i); /* read_status */local_return = st.i;if (jcaiotrace) printf ("inp(%x) = %x\n", a, local_return);return local_return;}void reset_port(void){static struct { int i; char bozo[50];} st;int original_control; if (local_fd < 0) { local_fd = open("/dev/shortint", O_RDWR); if (local_fd < 0) printf ("error opening /dev/shortint\n"); } ioctl(local_fd, TIOCPKT_NOSTOP, &st.i); /* read control */ printf ("current control %x\n", st.i);original_control = 0xe0;// = st.i; st.i = original_control; ioctl(local_fd, TIOCPKT_DOSTOP, &st.i); /* write control */ st.i = original_control | 0x02; ioctl(local_fd, TIOCPKT_DOSTOP, &st.i); /* write control */ st.i = original_control; ioctl(local_fd, TIOCPKT_DOSTOP, &st.i); /* write control */ memset(pin, sizeof(pin), 0); pin[nRESET_OUT_OUT]=1; pin[UDCmUDCp_IN]=1; pin[nCAS0_OUT]=1; pin[nCAS1_OUT]=1; pin[nCAS2_OUT]=1; pin[nCAS3_OUT]=1; pin[nRAS0_OUT]=1; pin[nWE_OUT]=1; pin[nPCE1_OUT]=1; pin[nPCE2_OUT]=1; pin[SDCKE1_OUT]=1; pin[PWR_EN_OUT]=1; pin[nPIOW_OUT]=1; pin[nPIOR_OUT]=1; pin[nPWE_OUT]=1; pin[nPOE_OUT]=1;#if 0 pin[nRAS1_OUT]=1; pin[nRAS2_OUT]=1; pin[nRAS3_OUT]=1; pin[nSDCAS_OUT]=1; pin[nSDRAS_OUT]=1; pin[nPREG_OUT]=1; pin[PSKTSEL_OUT]=1; pin[SDCKE0_OUT]=1; pin[SDCLK0_OUT]=1; pin[SDCLK1_OUT]=1; pin[SDCLK2_OUT]=1; pin[SFRM_C_OUT]=1;#endif}int putp(int tdi, int tms, int rp){int lpt_address = 0;// Cable used had 100 ohm resistors between the following pins// (Cable shipped as part of SA-1110 Development Kit)// Output pins (LPT driving)// LPT D0 Pin 2 and TCK J10 Pin 4// LPT D1 Pin 3 and TDI J10 Pin 11// LPT D2 Pin 4 and TMS J10 Pin 9//// Input pin (SA-1110 board drives)// LPT Busy Pin 11 and TDO J10 Pin 13 int tdo = -1; _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 tdo = !((int)_inp(lpt_address + 1) >> 7); // get TDO data } return tdo;}void tap_submit_instr(int arg_command){int i; 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 for (i = 0; i < INSTRUCTION_LENGTH - 1; i++) { putp(arg_command & 1,0,IP); arg_command >>= 1; } putp(arg_command & 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}long access_rom(int rw, long address, long data, int rp){ // Shift Flash address making A2 the LSB return(access_bus(rw, address << 2, data, rp));}long access_bus(int rw, long address, long data, int rp){long li;int i;int out_dat[300];long busdat; // Preset SA-1110 pins to default values (all others set in sa1110jtag.h) pin[nCS0_OUT] = 1; pin[nCS1_OUT] = 1; pin[nCS2_OUT] = 1; pin[nCS3_OUT] = 1; pin[nCS4_OUT] = 1; pin[nCS5_OUT] = 1; pin[nOE_OUT] = 1; pin[nWE_OUT] = 1; pin[RD_nWR_OUT] = 0; pin[D31_0_EN] = 1; for(i = 0; i < 26; i++) pin[i+A0_OUT] = (int)((address >> i) & 1); // set address 0 thru 25 if(rw == READ || rw == WRITE) 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; case 8: pin[nCS4_OUT] = 0; break; case 9: pin[nCS5_OUT] = 0; break; } if(rw == READ) { pin[RD_nWR_OUT] = 1; pin[nOE_OUT] = 0; } //rw == RS is setup prior to RD_nWR_OUT if (rw == WRITE || rw == SETUP || rw == HOLD) { for(li = 0L; li < 32L; li++) pin[dat_order[li]] = (int)((data >> li) & 1L); // set data pins if(rw == WRITE) pin[nWE_OUT] = 0; pin[D31_0_EN] = 0; // switch data pins to drive } 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 for(i = 0; i < SA1110_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 busdat = 0; for(i = 0; i < 32; i++) // convert serial data to single long busdat = busdat | (long)(out_dat[dat_order[i] - 2] << i); tap_submit_instr(EXTEST); return(busdat);}void test_logic_reset(void){ putp(1,1,IP); // keep TMS set to 1 force a test logic reset putp(1,1,IP); // no matter where you are in the TAP controller putp(1,1,IP); putp(1,1,IP); putp(1,1,IP); putp(1,1,IP);}int check_id(char *device_id){ // compare passed device ID to the one returned from the ID command char in_id[40]; int error_flag = 0; int i; for(i = 34; i >= 0; i--) { if(i == 4 || i == 21 || i == 33) in_id[i--] = ' '; if(putp(1,0,RP) == 0) in_id[i] = '0'; else in_id[i] = '1'; if((in_id[i] != device_id[i]) && (device_id[i] != '*')) error_flag = 1; } in_id[35] = 0; if(error_flag) { printf("error, failed to read device ID\n"); printf("ACT: %s\n",in_id); printf("EXP: %s\n\n",device_id); return -1; } if(!strcmp(device_id,SA1110ID)) // print SA-1110 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("SA-1110 revision A0\n"); break; case 4: printf("SA-1110 revision B0\n"); break; case 5: printf("SA-1110 revision B1\n"); break; case 6: printf("SA-1110 revision B2\n"); break; case 8: printf("SA-1110 revision B4\n"); break; default: printf("SA-1110 revision B4 + %d\n",sa_rev - 8); } } return 0;}void id_command(void){ tap_submit_instr(IDCODE); putp(1,1,IP); putp(1,0,IP); if(check_id(SA1110ID)) { printf("failed to read device ID for the SA-1110\n"); exit(-1); } 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 flash_wait(long max_erase_time){ time_t start, now; time(&start); while(access_rom(RS, 0, 0, RP) != 0x800080L) {// Loop until successful status return flash_read_val(0); time(&now); if(difftime(now,start) > max_erase_time + 1) { // Check for status timeout printf("\nError, Flash timed out\n"); exit(-1); } }}void set_vppen(void){#ifdef CONFIG_SA1100_H3800 flash_write_val_hold(0x49001f00>>2, 1);#else /* CONFIG_SA1100_JORNADA56X */ pin[GP26_EN]=1; pin[GP26_OUT]=1;#endif}void clr_vppen(void){#ifdef CONFIG_SA1100_H3800 flash_write_val_hold(0x49001f00>>2, 0);#else /* CONFIG_SA1100_JORNADA56X */ pin[GP26_EN]=1; pin[GP26_OUT]=0;#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -