]> git.zerfleddert.de Git - usb-driver/blob - jtagkey.c
0078e474e064234ee3561f5a8b6ca6c5a17aa2a4
[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 ((ret = ftdi_write_data_set_chunksize(&ftdic, 1)) != 0) {
32 fprintf(stderr, "unable to set write chunksize: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
33 return ret;
34 }
35
36 if ((ret = ftdi_set_latency_timer(&ftdic, 1)) != 0) {
37 fprintf(stderr, "unable to set latency timer: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
38 return ret;
39 }
40
41 if ((ret = ftdi_set_baudrate(&ftdic, 230400)) != 0) {
42 fprintf(stderr, "unable to set baudrate: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
43 return ret;
44 }
45
46 if ((ret = ftdi_set_bitmode(&ftdic, JTAGKEY_TCK|JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_OEn, 1)) != 0) {
47 fprintf(stderr, "unable to enable bitbang mode: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
48 return ret;
49 }
50
51 if ((ret = ftdi_usb_purge_buffers(&ftdic)) != 0) {
52 fprintf(stderr, "unable to purge buffers: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
53 return ret;
54 }
55
56 return ret;
57 }
58
59 void jtagkey_close() {
60 ftdi_disable_bitbang(&ftdic);
61 ftdi_usb_close(&ftdic);
62 ftdi_deinit(&ftdic);
63 }
64
65 void jtagkey_state(unsigned char data) {
66 fprintf(stderr,"Pins high: ");
67
68 if (data & JTAGKEY_TCK)
69 fprintf(stderr,"TCK ");
70
71 if (data & JTAGKEY_TDI)
72 fprintf(stderr,"TDI ");
73
74 if (data & JTAGKEY_TDO)
75 fprintf(stderr,"TDO ");
76
77 if (data & JTAGKEY_TMS)
78 fprintf(stderr,"TMS ");
79
80 if (data & JTAGKEY_VREF)
81 fprintf(stderr,"VREF ");
82
83 fprintf(stderr,"\n");
84 }
85
86 int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int ecpbase, int num) {
87 int ret = 0;
88 int i;
89 unsigned long port;
90 unsigned char val;
91 static unsigned char last_write = 0;
92 unsigned char data;
93
94 for (i = 0; i < num; i++) {
95 DPRINTF("dwPort: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
96 (unsigned long)tr[i].dwPort, tr[i].cmdTrans, tr[i].dwBytes,
97 tr[i].fAutoinc, tr[i].dwOptions);
98
99 port = (unsigned long)tr[i].dwPort;
100 val = tr[i].Data.Byte;
101
102 #ifdef DEBUG
103 if (tr[i].cmdTrans == 13)
104 DPRINTF("write byte: %d\n", val);
105 #endif
106
107 if (port == ppbase + PP_DATA) {
108 DPRINTF("data port\n");
109
110 data = 0x00;
111 switch(tr[i].cmdTrans) {
112 case PP_READ:
113 ret = 0; /* We don't support reading of the data port */
114 break;
115
116 case PP_WRITE:
117 if (val & PP_TDI) {
118 data |= JTAGKEY_TDI;
119 DPRINTF("TDI\n");
120 } else {
121 DPRINTF("!TDI\n");
122 }
123 if (val & PP_TCK) {
124 data |= JTAGKEY_TCK;
125 DPRINTF("TCK\n");
126 } else {
127 DPRINTF("!TCK\n");
128 }
129 if (val & PP_TMS) {
130 data |= JTAGKEY_TMS;
131 DPRINTF("TMS\n");
132 } else {
133 DPRINTF("!TMS\n");
134 }
135 if (val & PP_CTRL) {
136 data |= JTAGKEY_OEn;
137 DPRINTF("CTRL\n");
138 } else {
139 DPRINTF("!CTRL\n");
140 }
141 ftdi_write_data(&ftdic, &data, 1);
142
143 #if 0
144 do {
145 ftdi_read_pins(&ftdic, &tmp);
146 } while ((tmp & (JTAGKEY_TDI|JTAGKEY_TMS|JTAGKEY_TCK|JTAGKEY_TDI)) != data);
147 #endif
148
149 last_write = val;
150 break;
151
152 default:
153 fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr[i].cmdTrans);
154 ret = -1;
155 break;
156 }
157 } else if (port == ppbase + PP_STATUS) {
158 DPRINTF("status port (last write: %d)\n", last_write);
159 switch(tr[i].cmdTrans) {
160 case PP_READ:
161 ftdi_read_pins(&ftdic, &data);
162 #ifdef DEBUG
163 DPRINTF("READ: 0x%x\n", data);
164 jtagkey_state(data);
165 #endif
166
167 val = 0x00;
168 if (data & JTAGKEY_TDO)
169 val |= PP_TDO;
170
171 if (last_write & 0x40)
172 val |= 0x20;
173 else
174 val |= 0x80;
175 break;
176
177 case PP_WRITE:
178 ret = 0; /* Status Port is readonly */
179 break;
180
181 default:
182 fprintf(stderr,"!!!Unsupported TRANSFER command: %lu!!!\n", tr[i].cmdTrans);
183 ret = -1;
184 break;
185 }
186 } else if (port == ppbase + PP_CONTROL) {
187 DPRINTF("control port\n");
188 } else if ((port == ecpbase + PP_ECP_CFGA) && ecpbase) {
189 DPRINTF("ECP_CFGA port\n");
190 } else if ((port == ecpbase + PP_ECP_CFGB) && ecpbase) {
191 DPRINTF("ECP_CFGB port\n");
192 } else if ((port == ecpbase + PP_ECP_ECR) && ecpbase) {
193 DPRINTF("ECP_ECR port\n");
194 } else {
195 DPRINTF("access to unsupported address range!\n");
196 ret = 0;
197 }
198
199 tr[i].Data.Byte = val;
200
201 DPRINTF("dwPortReturn: 0x%lx, cmdTrans: %lu, dwbytes: %ld, fautoinc: %ld, dwoptions: %ld\n",
202 (unsigned long)tr[i].dwPort, tr[i].cmdTrans, tr[i].dwBytes,
203 tr[i].fAutoinc, tr[i].dwOptions);
204 #ifdef DEBUG
205 if (tr[i].cmdTrans == 10)
206 DPRINTF("read byte: %d\n", tr[i].Data.Byte);
207 #endif
208 }
209
210 return ret;
211 }
Impressum, Datenschutz