]> cvs.zerfleddert.de Git - usb-driver/blob - jtagkey.c
improve performance by
[usb-driver] / jtagkey.c
1 #include <stdio.h>
2 #include <ftdi.h>
3 #include "usb-driver.h"
4 #include "jtagkey.h"
5
6 static struct ftdi_context ftdic;
7
8 int jtagkey_init(unsigned short vid, unsigned short pid) {
9 int ret = 0;
10
11 if ((ret = ftdi_init(&ftdic)) != 0) {
12 fprintf(stderr, "unable to initialise libftdi: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
13 return ret;
14 }
15
16 if ((ret = ftdi_usb_open(&ftdic, vid, pid)) != 0) {
17 fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
18 return ret;
19 }
20
21 if ((ret = ftdi_usb_reset(&ftdic)) != 0) {
22 fprintf(stderr, "unable reset device: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
23 return ret;
24 }
25
26 if ((ret = ftdi_set_interface(&ftdic, INTERFACE_A)) != 0) {
27 fprintf(stderr, "unable to set interface: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
28 return ret;
29 }
30
31 #if 0
32 if ((ret = ftdi_write_data_set_chunksize(&ftdic, 3)) != 0) {
33 fprintf(stderr, "unable to set write chunksize: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
34 return ret;
35 }
36 #endif
37
38 if ((ret = ftdi_set_latency_timer(&ftdic, 1)) != 0) {
39 fprintf(stderr, "unable to set latency timer: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
40 return ret;
41 }
42
43 if ((ret = ftdi_set_baudrate(&ftdic, 1000000)) != 0) {
44 fprintf(stderr, "unable to set baudrate: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
45 return ret;
46 }
47
48 if ((ret = ftdi_set_bitmode(&ftdic, JTAGKEY_TCK|JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_OEn, BITMODE_SYNCBB)) != 0) {
49 fprintf(stderr, "unable to enable bitbang mode: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
50 return ret;
51 }
52
53 if ((ret = ftdi_usb_purge_buffers(&ftdic)) != 0) {
54 fprintf(stderr, "unable to purge buffers: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
55 return ret;
56 }
57
58 return ret;
59 }
60
61 void jtagkey_close() {
62 ftdi_disable_bitbang(&ftdic);
63 ftdi_usb_close(&ftdic);
64 ftdi_deinit(&ftdic);
65 }
66
67 void jtagkey_state(unsigned char data) {
68 fprintf(stderr,"Pins high: ");
69
70 if (data & JTAGKEY_TCK)
71 fprintf(stderr,"TCK ");
72
73 if (data & JTAGKEY_TDI)
74 fprintf(stderr,"TDI ");
75
76 if (data & JTAGKEY_TDO)
77 fprintf(stderr,"TDO ");
78
79 if (data & JTAGKEY_TMS)
80 fprintf(stderr,"TMS ");
81
82 if (data & JTAGKEY_VREF)
83 fprintf(stderr,"VREF ");
84
85 fprintf(stderr,"\n");
86 }
87
88 int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int ecpbase, int num) {
89 int ret = 0;
90 int i;
91 unsigned long port;
92 unsigned char val;
93 static unsigned char last_write = 0, last_data = 0;
94 unsigned char data;
95 unsigned char writebuf[4096], readbuf[4096], *pos;
96
97 pos = writebuf;
98 for (i = 0; i < num; i++) {
99 DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
100 (unsigned long)tr[i].dwPort, tr[i].cmdTrans, tr[i].dwBytes,
101 tr[i].fAutoinc, tr[i].dwOptions);
102
103 port = (unsigned long)tr[i].dwPort;
104 val = tr[i].Data.Byte;
105
106 #ifdef DEBUG
107 if (tr[i].cmdTrans == 13)
108 DPRINTF("write byte: %d\n", val);
109 #endif
110
111 /* Pad writebuf for read-commands in stream */
112 if (tr[i].cmdTrans == 10) {
113 *pos = last_data;
114 pos++;
115 }
116
117 if (port == ppbase + PP_DATA) {
118 DPRINTF("data port\n");
119
120 data = 0x00;
121 switch(tr[i].cmdTrans) {
122 case PP_READ:
123 ret = 0; /* We don't support reading of the data port */
124 break;
125
126 case PP_WRITE:
127 if (val & PP_TDI) {
128 data |= JTAGKEY_TDI;
129 DPRINTF("TDI\n");
130 } else {
131 DPRINTF("!TDI\n");
132 }
133 if (val & PP_TCK) {
134 data |= JTAGKEY_TCK;
135 DPRINTF("TCK\n");
136 } else {
137 DPRINTF("!TCK\n");
138 }
139 if (val & PP_TMS) {
140 data |= JTAGKEY_TMS;
141 DPRINTF("TMS\n");
142 } else {
143 DPRINTF("!TMS\n");
144 }
145 if (val & PP_CTRL) {
146 data |= JTAGKEY_OEn;
147 DPRINTF("CTRL\n");
148 } else {
149 DPRINTF("!CTRL\n");
150 }
151 *pos = data;
152 pos++;
153
154 last_write = val;
155 last_data = data;
156 break;
157
158 default:
159 fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr[i].cmdTrans);
160 ret = -1;
161 break;
162 }
163 }
164 }
165
166 ftdi_usb_purge_buffers(&ftdic);
167 ftdi_write_data(&ftdic, writebuf, pos-writebuf);
168
169 i = 0;
170 do {
171 #if 0
172 ftdi_write_data(&ftdic, &last_data, 1);
173 #endif
174 i += ftdi_read_data(&ftdic, readbuf, sizeof(readbuf));
175 } while (i < pos-writebuf);
176
177 #ifdef DEBUG
178 DPRINTF("write: ");
179 hexdump(writebuf, pos-writebuf);
180 DPRINTF("read: ");
181 hexdump(readbuf, i);
182 #endif
183
184 pos = readbuf;
185
186 for (i = 0; i < num; i++) {
187 DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
188 (unsigned long)tr[i].dwPort, tr[i].cmdTrans, tr[i].dwBytes,
189 tr[i].fAutoinc, tr[i].dwOptions);
190
191 port = (unsigned long)tr[i].dwPort;
192 val = tr[i].Data.Byte;
193 pos++;
194
195 if (port == ppbase + PP_STATUS) {
196 DPRINTF("status port (last write: %d)\n", last_write);
197 switch(tr[i].cmdTrans) {
198 case PP_READ:
199 data = *pos;
200 #ifdef DEBUG
201 DPRINTF("READ: 0x%x\n", data);
202 jtagkey_state(data);
203 #endif
204
205 val = 0x00;
206 if (data & JTAGKEY_TDO)
207 val |= PP_TDO;
208
209 if (last_write & 0x40)
210 val |= 0x20;
211 else
212 val |= 0x80;
213 break;
214
215 case PP_WRITE:
216 ret = 0; /* Status Port is readonly */
217 break;
218
219 default:
220 fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr[i].cmdTrans);
221 ret = -1;
222 break;
223 }
224 } else {
225 ret = 0;
226 }
227
228 tr[i].Data.Byte = val;
229
230 DPRINTF("dwPortReturn: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
231 (unsigned long)tr[i].dwPort, tr[i].cmdTrans, tr[i].dwBytes,
232 tr[i].fAutoinc, tr[i].dwOptions);
233 #ifdef DEBUG
234 if (tr[i].cmdTrans == 10)
235 DPRINTF("read byte: %d\n", tr[i].Data.Byte);
236 #endif
237 }
238
239 return ret;
240 }
Impressum, Datenschutz