jtag.c (4975B)
1 /* 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