OpenCores
URL https://opencores.org/ocsvn/s80186/s80186/trunk

Subversion Repositories s80186

[/] [s80186/] [trunk/] [vendor/] [altera-jtag/] [jtag.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jamieiles
/* Copyright 2012 Brian Swetland <swetland@frotz.net>
2
 *
3
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * you may not use this file except in compliance with the License.
5
 * You may obtain a copy of the License at
6
 *
7
 *     http://www.apache.org/licenses/LICENSE-2.0
8
 *
9
 * Unless required by applicable law or agreed to in writing, software
10
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * See the License for the specific language governing permissions and
13
 * limitations under the License.
14
 */
15
 
16
#include <stdio.h>
17
#include <stdlib.h>
18
#include <unistd.h>
19
#include <string.h>
20
#include <ctype.h>
21
 
22
#include <libusb-1.0/libusb.h>
23
 
24
#define TRACE_USB       0
25
#define TRACE_JTAG      0
26
 
27
static struct libusb_device_handle *udev;
28
static int usb_open(unsigned vid, unsigned pid) {
29
        if (libusb_init(NULL) < 0)
30
                return -1;
31
 
32
        if (!(udev = libusb_open_device_with_vid_pid(NULL, vid, pid))) {
33
                fprintf(stderr,"cannot find device\n");
34
                return -1;
35
        }
36
 
37
        if (libusb_claim_interface(udev, 0) < 0) {
38
                fprintf(stderr,"cannot claim interface\n");
39
                return -1;
40
        }
41
        return 0;
42
}
43
static void usb_close(void) {
44
        libusb_exit(NULL);
45
}
46
#if TRACE_USB
47
static void dump(char *prefix, void *data, int len) {
48
        unsigned char *x = data;
49
        fprintf(stderr,"%s: (%d)", prefix, len);
50
        while (len > 0) {
51
                fprintf(stderr," %02x", *x++);
52
                len--;
53
        }
54
        fprintf(stderr,"\n");
55
}
56
#endif
57
static int usb_bulk(unsigned char ep, void *data, int len, unsigned timeout) {
58
        int r, xfer;
59
#if TRACE_USB
60
        if (!(ep & 0x80))
61
                dump("xmit", data, len);
62
#endif
63
        r = libusb_bulk_transfer(udev, ep, data, len, &xfer, timeout);
64
        if (r < 0) {
65
                fprintf(stderr,"bulk: error: %d\n", r);
66
                return r;
67
        }
68
#if TRACE_USB
69
        if (ep & 0x80)
70
                dump("recv", data, xfer);
71
#endif
72
        return xfer;
73
}
74
 
75
#define EP1_IN  0x81
76
#define EP2_OUT 0x02
77
 
78
#define UB_BYTEMODE     0x80
79
#define UB_BITMODE      0x00
80
#define UB_READBACK     0x40
81
 
82
/* bits in bit mode */
83
#define UB_OE           0x20
84
#define UB_TDI          0x10
85
#define UB_nCS          0x08
86
#define UB_nCE          0x04
87
#define UB_TMS          0x02
88
#define UB_TCK          0x01
89
 
90
/* bytecount for data bytes that follow in byte mode */
91
#define UB_COUNT(n)     ((n) & 0x3F)
92
 
93
int jtag_move(int count, unsigned bits){
94
        unsigned char buf[64];
95
        int n = 0;
96
#if TRACE_JTAG
97
        fprintf(stderr,"move: %08x (%d)\n", bits, count);
98
#endif
99
        while (count-- > 0) {
100
                if (bits & 1) {
101
                        buf[n++] = UB_TMS;
102
                        buf[n++] = UB_TMS | UB_TCK;
103
                } else {
104
                        buf[n++] = 0;
105
                        buf[n++] = UB_TCK;
106
                }
107
                bits >>= 1;
108
        }
109
        return usb_bulk(EP2_OUT, buf, n, 1000);
110
}
111
 
112
int jtag_shift(int count, unsigned bits, unsigned *out) {
113
        unsigned char buf[64];
114
        unsigned RB = out ? UB_READBACK : 0;
115
        int n = 0;
116
        int readcount = count;
117
        int r,bit;
118
#if TRACE_JTAG
119
        fprintf(stderr,"xfer: %08x (%d)\n", bits, count);
120
#endif
121
        while (count-- > 0) {
122
                if (bits & 1) {
123
                        buf[n++] = UB_TDI;
124
                        buf[n++] = UB_TDI | UB_TCK | RB;
125
                } else {
126
                        buf[n++] = 0;
127
                        buf[n++] = UB_TCK | RB;
128
                }
129
                bits >>= 1;
130
        }
131
        buf[n-1] |= UB_TMS;
132
        buf[n-2] |= UB_TMS;
133
        r = usb_bulk(EP2_OUT, buf, n, 1000);
134
        if (r < 0)
135
                return r;
136
        if (!out)
137
                return 0;
138
        bits = 0;
139
        bit = 1;
140
        while (readcount > 0) {
141
                r = usb_bulk(EP1_IN, buf, 64, 1000);
142
                if (r < 0)
143
                        return r;
144
                if (r < 3)
145
                        continue;
146
                for (n = 2; n < r; n++) {
147
                        if (buf[n] & 1)
148
                                bits |= bit;
149
                        bit <<= 1;
150
                        readcount--;
151
                        if (readcount == 0) {
152
#if TRACE_JTAG
153
                                fprintf(stderr,"    : %08x\n", bits);
154
#endif
155
                                *out = bits;
156
                                return 0;
157
                        }
158
                }
159
        }
160
        return -1;
161
}
162
 
163
/* JTAG notes
164
 *
165
 * TMS is sampled on +TCK
166
 * Capture-XR state loads shift register on +TCK as state is exited
167
 * Shift-XR state TDO goes active (containing shiftr[0]) on the first -TCK
168
 *          after entry, shifts occur on each +TCK, *including* the +TCK
169
 *          that will exist Shift-XR when TMS=1 again
170
 * Update-XR update occurs on the -TCK after entry to state
171
 *
172
 * Any -> Reset: 11111
173
 * Any -> Reset -> RTI: 111110
174
 * RTI -> ShiftDR: 100
175
 * ShiftDR shifting: 0 x N
176
 * ShiftDR -> UpdateDR -> RTI: 110
177
 * ShiftDR -> UpdateDR -> ShiftDR: 11100
178
 * RTI -> ShiftIR: 1100
179
 * ShiftIR shifting: 0 x N
180
 * ShiftIR -> UpdateIR -> RTI: 110
181
 */
182
 
183
#define RESET   8,0b01111111
184
#define SHIFTDR 3,0b001
185
#define SHIFTIR 4,0b0011
186
#define DONE    2,0b01
187
#define AGAIN   4,0b0011
188
 
189
int jtag_ir(unsigned sz, unsigned bits) {
190
        int r;
191
        if ((r = jtag_move(SHIFTIR)) < 0) return r;
192
        if ((r = jtag_shift(sz, bits, 0)) < 0) return r;
193
        if ((r = jtag_move(DONE)) < 0) return r;
194
        return 0;
195
}
196
 
197
int jtag_dr(unsigned sz, unsigned bits, unsigned *out) {
198
        int r;
199
        if ((r = jtag_move(SHIFTDR)) < 0) return r;
200
        if ((r = jtag_shift(sz, bits, out)) < 0) return r;
201
        if ((r = jtag_move(DONE)) < 0) return r;
202
        return 0;
203
}
204
 
205
static int jtag_is_open = 0;
206
 
207
int jtag_open(void) {
208
        int r;
209
        if (!jtag_is_open) {
210
                r = usb_open(0x09fb, 0x6001);
211
                if (r < 0)
212
                        return r;
213
                jtag_is_open = 1;
214
        }
215
        return 0;
216
}
217
int jtag_close(void) {
218
        if (jtag_is_open) {
219
                usb_close();
220
                jtag_is_open = 0;
221
        }
222
        return 0;
223
}
224
int jtag_reset(void) {
225
        return jtag_move(RESET);
226
}
227
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.