]>
cvs.zerfleddert.de Git - usb-driver/blob - jtagkey.c
c4f2beeb9679deb554d2c7e3496f8aaa680f07e7
   6 #include "usb-driver.h" 
  11 #define USBBUFSIZE 1048576 
  12 #define JTAG_SPEED 100000 
  13 #define BULK_LATENCY 2 
  14 #define OTHER_LATENCY 1 
  16 static struct ftdi_context ftdic
; 
  18 static int jtagkey_latency(int latency
) { 
  19         static int current 
= 0; 
  22         if (current 
!= latency
) { 
  23                 DPRINTF("switching latency\n"); 
  24                 if ((ret 
= ftdi_set_latency_timer(&ftdic
, latency
))  != 0) { 
  25                         fprintf(stderr
, "unable to set latency timer: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
)); 
  35 static int jtagkey_init(unsigned short vid
, unsigned short pid
, unsigned short iface
) { 
  39         if ((ret 
= ftdi_init(&ftdic
)) != 0) { 
  40                 fprintf(stderr
, "unable to initialise libftdi: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
)); 
  44         if ((ret 
= ftdi_usb_open(&ftdic
, vid
, pid
)) != 0) { 
  45                 fprintf(stderr
, "unable to open ftdi device: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
)); 
  49         if ((ret 
= ftdi_usb_reset(&ftdic
)) != 0) { 
  50                 fprintf(stderr
, "unable reset device: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
)); 
  54         if ((ret 
= ftdi_set_interface(&ftdic
, iface
)) != 0) { 
  55                 fprintf(stderr
, "unable to set interface: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
)); 
  59         if ((ret 
= ftdi_write_data_set_chunksize(&ftdic
, USBBUFSIZE
))  != 0) { 
  60                 fprintf(stderr
, "unable to set write chunksize: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
)); 
  64         if ((ret 
= ftdi_read_data_set_chunksize(&ftdic
, USBBUFSIZE
))  != 0) { 
  65                 fprintf(stderr
, "unable to set read chunksize: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
)); 
  69         if ((ret 
= jtagkey_latency(OTHER_LATENCY
)) != 0) 
  73         ftdi_write_data(&ftdic
, &c
, 1); 
  75         if ((ret 
= ftdi_set_bitmode(&ftdic
, JTAGKEY_TCK
|JTAGKEY_TDI
|JTAGKEY_TMS
|JTAGKEY_OEn
, BITMODE_SYNCBB
))  != 0) { 
  76                 fprintf(stderr
, "unable to enable bitbang mode: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
)); 
  80         if ((ret 
= ftdi_set_baudrate(&ftdic
, JTAG_SPEED
))  != 0) { 
  81                 fprintf(stderr
, "unable to set baudrate: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
)); 
  85         if ((ret 
= ftdi_usb_purge_buffers(&ftdic
))  != 0) { 
  86                 fprintf(stderr
, "unable to purge buffers: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
)); 
  93 int jtagkey_open(int num
) { 
  96         ret 
= jtagkey_init(config_usb_vid(num
), config_usb_pid(num
), config_usb_iface(num
)); 
 104 void jtagkey_close(int handle
) { 
 105         if (handle 
== 0xff) { 
 106                 ftdi_disable_bitbang(&ftdic
); 
 107                 ftdi_usb_close(&ftdic
); 
 113 static void jtagkey_state(unsigned char data
) { 
 114         fprintf(stderr
,"Pins high: "); 
 116         if (data 
& JTAGKEY_TCK
) 
 117                 fprintf(stderr
,"TCK "); 
 119         if (data 
& JTAGKEY_TDI
) 
 120                 fprintf(stderr
,"TDI "); 
 122         if (data 
& JTAGKEY_TDO
) 
 123                 fprintf(stderr
,"TDO "); 
 125         if (data 
& JTAGKEY_TMS
) 
 126                 fprintf(stderr
,"TMS "); 
 128         if (data 
& JTAGKEY_VREF
) 
 129                 fprintf(stderr
,"VREF "); 
 131         fprintf(stderr
,"\n"); 
 135 struct jtagkey_reader_arg 
{ 
 140 static void *jtagkey_reader(void *thread_arg
) { 
 141         struct jtagkey_reader_arg 
*arg 
= (struct jtagkey_reader_arg
*)thread_arg
; 
 145         DPRINTF("reader for %d bytes\n", arg
->num
); 
 146         while (i 
< arg
->num
) { 
 147                 i 
+= ftdi_read_data(&ftdic
, arg
->buf 
+ i
, arg
->num 
- i
); 
 153 /* TODO: Interpret JTAG commands and transfer in MPSSE mode */ 
 154 int jtagkey_transfer(WD_TRANSFER 
*tr
, int fd
, unsigned int request
, int ppbase
, int ecpbase
, int num
) { 
 160         static unsigned char last_data 
= 0; 
 161         static unsigned char last_write 
= 0x00; 
 162         static unsigned char writebuf
[USBBUFSIZE
], *writepos 
= writebuf
; 
 163         static unsigned char readbuf
[USBBUFSIZE
], *readpos
; 
 164         unsigned char data
, prev_data
, last_cyc_write
; 
 165         struct jtagkey_reader_arg targ
; 
 166         pthread_t reader_thread
; 
 169         for (i 
= 0; i 
< num
; i
++) 
 170                 if (tr
[i
].cmdTrans 
== PP_READ
) 
 173         /* Write combining */ 
 174         if ((writepos
-writebuf 
> sizeof(writebuf
)-num
) || (nread 
&& writepos
-writebuf
)) { 
 175                 unsigned char *pos 
= writebuf
; 
 178                 DPRINTF("writing %zd bytes due to %d following reads in %d chunks or full buffer\n", writepos
-writebuf
, nread
, num
); 
 179                 jtagkey_latency(BULK_LATENCY
); 
 181                 targ
.num 
= writepos
-pos
; 
 183                 pthread_create(&reader_thread
, NULL
, &jtagkey_reader
, &targ
); 
 185                 while (pos 
< writepos
) { 
 188                         if (len 
> USBBUFSIZE
) 
 191                         DPRINTF("combined write of %d/%zd\n",len
,writepos
-pos
); 
 192                         ftdi_write_data(&ftdic
, pos
, len
); 
 195                 pthread_join(reader_thread
, NULL
); 
 200         last_cyc_write 
= last_write
; 
 202         for (i 
= 0; i 
< num
; i
++) { 
 203                 DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", 
 204                                 (unsigned long)tr
[i
].dwPort
, tr
[i
].cmdTrans
, tr
[i
].dwBytes
, 
 205                                 tr
[i
].fAutoinc
, tr
[i
].dwOptions
); 
 207                 port 
= (unsigned long)tr
[i
].dwPort
; 
 208                 val 
= tr
[i
].Data
.Byte
; 
 211                 if (tr
[i
].cmdTrans 
== 13) 
 212                         DPRINTF("write byte: %d\n", val
); 
 214                 if (tr
[i
].cmdTrans 
== 13) 
 215                         jtagmon(val 
& PP_TCK
, val 
& PP_TMS
, val 
& PP_TDI
); 
 218                 /* Pad writebuf for read-commands in stream */ 
 219                 *writepos 
= last_data
; 
 220                 prev_data 
= last_data
; 
 222                 if (port 
== ppbase 
+ PP_DATA
) { 
 223                         DPRINTF("data port\n"); 
 226                         switch(tr
[i
].cmdTrans
) { 
 228                                         ret 
= 0; /* We don't support reading of the data port */ 
 270                                         fprintf(stderr
,"!!!Unsupported TRANSFER command: %lu!!!\n", tr
[i
].cmdTrans
); 
 276                 if ((tr
[i
].cmdTrans 
== PP_READ
) || (*writepos 
!= prev_data
) || (i 
== num
-1)) 
 282                 DPRINTF("writing %zd bytes\n", writepos
-writebuf
); 
 284                 *writepos 
= last_data
; 
 287                 jtagkey_latency(OTHER_LATENCY
); 
 289                 targ
.num 
= writepos
-writebuf
; 
 291                 pthread_create(&reader_thread
, NULL
, &jtagkey_reader
, &targ
); 
 292                 ftdi_write_data(&ftdic
, writebuf
, writepos
-writebuf
); 
 293                 pthread_join(reader_thread
, NULL
); 
 296                 hexdump(writebuf
, writepos
-writebuf
, "->"); 
 297                 hexdump(readbuf
, i
, "<-"); 
 306         last_write 
= last_cyc_write
; 
 308         for (i 
= 0; i 
< num
; i
++) { 
 309                 DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", 
 310                                 (unsigned long)tr
[i
].dwPort
, tr
[i
].cmdTrans
, tr
[i
].dwBytes
, 
 311                                 tr
[i
].fAutoinc
, tr
[i
].dwOptions
); 
 313                 port 
= (unsigned long)tr
[i
].dwPort
; 
 314                 val 
= tr
[i
].Data
.Byte
; 
 316                 if ((tr
[i
].cmdTrans 
!= PP_READ
) && (val 
== last_write
) && (i 
!= num
-1)) 
 321                 if (port 
== ppbase 
+ PP_DATA
) { 
 322                         if (tr
[i
].cmdTrans 
== PP_WRITE
) { 
 325                 } else if (port 
== ppbase 
+ PP_STATUS
) { 
 326                         DPRINTF("status port (last write: 0x%x)\n", last_write
); 
 327                         switch(tr
[i
].cmdTrans
) { 
 332                                         DPRINTF("READ: 0x%x\n", data
); 
 337                                         if ((data 
& JTAGKEY_TDO
) && (last_write 
& PP_PROG
)) 
 340                                         if (~last_write 
& PP_PROG
) 
 343                                         if (last_write 
& 0x40) 
 350                                         ret 
= 0; /* Status Port is readonly */ 
 354                                         fprintf(stderr
,"!!!Unsupported TRANSFER command: %lu!!!\n", tr
[i
].cmdTrans
); 
 362                 tr
[i
].Data
.Byte 
= val
; 
 364                 DPRINTF("dwPortReturn: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n", 
 365                                 (unsigned long)tr
[i
].dwPort
, tr
[i
].cmdTrans
, tr
[i
].dwBytes
, 
 366                                 tr
[i
].fAutoinc
, tr
[i
].dwOptions
); 
 368                 if (tr
[i
].cmdTrans 
== 10) 
 369                         DPRINTF("read byte: %d\n", tr
[i
].Data
.Byte
);