]>
git.zerfleddert.de Git - usb-driver/blob - jtagkey.c
129cfe1cc652d9d9f4214f74bfb1483d0036a4bd
5 #include "usb-driver.h"
9 #define USBBUFSIZE 1048576
10 #define JTAG_SPEED 100000
11 #define SLOW_AND_SAFE 1
13 static struct ftdi_context ftdic
;
14 static unsigned char bitbang_mode
;
16 static int jtagkey_init(unsigned short vid
, unsigned short pid
) {
20 if ((ret
= ftdi_init(&ftdic
)) != 0) {
21 fprintf(stderr
, "unable to initialise libftdi: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
25 if ((ret
= ftdi_usb_open(&ftdic
, vid
, pid
)) != 0) {
26 fprintf(stderr
, "unable to open ftdi device: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
30 if ((ret
= ftdi_usb_reset(&ftdic
)) != 0) {
31 fprintf(stderr
, "unable reset device: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
35 if ((ret
= ftdi_set_interface(&ftdic
, INTERFACE_A
)) != 0) {
36 fprintf(stderr
, "unable to set interface: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
40 if ((ret
= ftdi_write_data_set_chunksize(&ftdic
, USBBUFSIZE
)) != 0) {
41 fprintf(stderr
, "unable to set write chunksize: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
45 if ((ret
= ftdi_read_data_set_chunksize(&ftdic
, USBBUFSIZE
)) != 0) {
46 fprintf(stderr
, "unable to set read chunksize: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
50 if ((ret
= ftdi_set_latency_timer(&ftdic
, 1)) != 0) {
51 fprintf(stderr
, "unable to set latency timer: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
56 ftdi_write_data(&ftdic
, &c
, 1);
58 if ((ret
= ftdi_set_bitmode(&ftdic
, JTAGKEY_TCK
|JTAGKEY_TDI
|JTAGKEY_TMS
|JTAGKEY_OEn
, BITMODE_SYNCBB
)) != 0) {
59 fprintf(stderr
, "unable to enable bitbang mode: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
63 if ((ret
= ftdi_set_baudrate(&ftdic
, JTAG_SPEED
)) != 0) {
64 fprintf(stderr
, "unable to set baudrate: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
68 bitbang_mode
= BITMODE_SYNCBB
;
70 if ((ret
= ftdi_usb_purge_buffers(&ftdic
)) != 0) {
71 fprintf(stderr
, "unable to purge buffers: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
78 int jtagkey_open(int num
) {
81 ret
= jtagkey_init(config_usb_vid(num
), config_usb_pid(num
));
89 void jtagkey_close(int handle
) {
91 ftdi_disable_bitbang(&ftdic
);
92 ftdi_usb_close(&ftdic
);
98 static int jtagkey_set_bbmode(unsigned char mode
) {
101 if (bitbang_mode
!= mode
) {
102 DPRINTF("switching bitbang-mode!\n");
104 /* Wait for the latency-timer to kick in */
106 if ((ret
= ftdi_set_bitmode(&ftdic
, JTAGKEY_TCK
|JTAGKEY_TDI
|JTAGKEY_TMS
|JTAGKEY_OEn
, mode
)) != 0) {
107 fprintf(stderr
, "unable to enable bitbang mode: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
110 if ((ret
= ftdi_usb_purge_buffers(&ftdic
)) != 0) {
111 fprintf(stderr
, "unable to purge buffers: %d (%s)\n", ret
, ftdi_get_error_string(&ftdic
));
114 /* Wait for the FTDI2232 to settle */
124 void jtagkey_state(unsigned char data
) {
125 fprintf(stderr
,"Pins high: ");
127 if (data
& JTAGKEY_TCK
)
128 fprintf(stderr
,"TCK ");
130 if (data
& JTAGKEY_TDI
)
131 fprintf(stderr
,"TDI ");
133 if (data
& JTAGKEY_TDO
)
134 fprintf(stderr
,"TDO ");
136 if (data
& JTAGKEY_TMS
)
137 fprintf(stderr
,"TMS ");
139 if (data
& JTAGKEY_VREF
)
140 fprintf(stderr
,"VREF ");
142 fprintf(stderr
,"\n");
145 struct jtagkey_reader_arg
{
150 static void *jtagkey_reader(void *thread_arg
) {
151 struct jtagkey_reader_arg
*arg
= (struct jtagkey_reader_arg
*)thread_arg
;
156 DPRINTF("reader for %d bytes\n", arg
->num
);
157 while (i
< arg
->num
) {
158 i
+= ftdi_read_data(&ftdic
, arg
->buf
+ i
, arg
->num
- i
);
164 int jtagkey_transfer(WD_TRANSFER
*tr
, int fd
, unsigned int request
, int ppbase
, int ecpbase
, int num
) {
170 static unsigned char last_data
= 0;
171 static unsigned char last_write
= 0x00;
172 static unsigned char writebuf
[USBBUFSIZE
], *writepos
= writebuf
;
173 static unsigned char readbuf
[USBBUFSIZE
], *readpos
;
174 unsigned char data
, prev_data
;
175 struct jtagkey_reader_arg targ
;
176 pthread_t reader_thread
;
179 for (i
= 0; i
< num
; i
++)
180 if (tr
[i
].cmdTrans
== PP_READ
)
183 /* Write combining */
184 if ((writepos
-writebuf
> sizeof(writebuf
)-num
) || (nread
&& writepos
-writebuf
)) {
185 unsigned char *pos
= writebuf
;
188 DPRINTF("writing %d bytes due to %d following reads in %d chunks or full buffer\n", writepos
-writebuf
, nread
, num
);
190 #ifndef SLOW_AND_SAFE
191 jtagkey_set_bbmode(BITMODE_BITBANG
);
194 targ
.num
= writepos
-pos
;
196 pthread_create(&reader_thread
, NULL
, &jtagkey_reader
, &targ
);
198 while (pos
< writepos
) {
201 if (len
> USBBUFSIZE
)
204 DPRINTF("combined write of %d/%d\n",len
,writepos
-pos
);
205 ftdi_write_data(&ftdic
, pos
, len
);
209 pthread_join(reader_thread
, NULL
);
215 for (i
= 0; i
< num
; i
++) {
216 DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
217 (unsigned long)tr
[i
].dwPort
, tr
[i
].cmdTrans
, tr
[i
].dwBytes
,
218 tr
[i
].fAutoinc
, tr
[i
].dwOptions
);
220 port
= (unsigned long)tr
[i
].dwPort
;
221 val
= tr
[i
].Data
.Byte
;
224 if (tr
[i
].cmdTrans
== 13)
225 DPRINTF("write byte: %d\n", val
);
228 /* Pad writebuf for read-commands in stream */
229 *writepos
= last_data
;
230 prev_data
= last_data
;
232 if (port
== ppbase
+ PP_DATA
) {
233 DPRINTF("data port\n");
236 switch(tr
[i
].cmdTrans
) {
238 ret
= 0; /* We don't support reading of the data port */
280 fprintf(stderr
,"!!!Unsupported TRANSFER command: %lu!!!\n", tr
[i
].cmdTrans
);
286 if (nread
|| (*writepos
!= prev_data
) || (i
== num
-1))
292 DPRINTF("writing %d bytes\n", writepos
-writebuf
);
294 *writepos
= last_data
;
297 #ifndef SLOW_AND_SAFE
298 jtagkey_set_bbmode(BITMODE_SYNCBB
);
300 targ
.num
= writepos
-writebuf
;
302 pthread_create(&reader_thread
, NULL
, &jtagkey_reader
, &targ
);
303 ftdi_write_data(&ftdic
, writebuf
, writepos
-writebuf
);
304 pthread_join(reader_thread
, NULL
);
308 hexdump(writebuf
, writepos
-writebuf
);
320 for (i
= 0; i
< num
; i
++) {
321 DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
322 (unsigned long)tr
[i
].dwPort
, tr
[i
].cmdTrans
, tr
[i
].dwBytes
,
323 tr
[i
].fAutoinc
, tr
[i
].dwOptions
);
325 port
= (unsigned long)tr
[i
].dwPort
;
326 val
= tr
[i
].Data
.Byte
;
329 if (port
== ppbase
+ PP_DATA
) {
330 if (tr
[i
].cmdTrans
== PP_WRITE
) {
333 } else if (port
== ppbase
+ PP_STATUS
) {
334 DPRINTF("status port (last write: 0x%x)\n", last_write
);
335 switch(tr
[i
].cmdTrans
) {
340 DPRINTF("READ: 0x%x\n", data
);
345 if ((data
& JTAGKEY_TDO
) && (last_write
& PP_PROG
))
348 if (!(last_write
& PP_PROG
))
351 if (last_write
& 0x40)
358 ret
= 0; /* Status Port is readonly */
362 fprintf(stderr
,"!!!Unsupported TRANSFER command: %lu!!!\n", tr
[i
].cmdTrans
);
370 tr
[i
].Data
.Byte
= val
;
372 DPRINTF("dwPortReturn: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
373 (unsigned long)tr
[i
].dwPort
, tr
[i
].cmdTrans
, tr
[i
].dwBytes
,
374 tr
[i
].fAutoinc
, tr
[i
].dwOptions
);
376 if (tr
[i
].cmdTrans
== 10)
377 DPRINTF("read byte: %d\n", tr
[i
].Data
.Byte
);