jtagonizer

yet another JTAG tool
git clone http://frotz.net/git/jtagonizer.git
Log | Files | Refs | README

jtag-mpsse-driver.c (11736B)


      1 // Copyright 2014 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 #include <stdio.h>
     16 #include <stdlib.h>
     17 #include <string.h>
     18 
     19 #include "jtag-driver.h"
     20 
     21 // USB bulk xfer fails trying to queue > 8192...
     22 #define CMD_MAX (8*1024)
     23 
     24 #define TRACE_IO 0 
     25 #define TRACE_DIS 0 
     26 #define TRACE_USB 0 
     27 #define TRACE_TXN 0
     28 
     29 // FTDI MPSSE Device Info
     30 static struct {
     31 	u16 vid;
     32 	u16 pid;
     33 	u8 ep_in;
     34 	u8 ep_out;
     35 	const char *name;
     36 } devinfo[] = {
     37 	{ 0x0403, 0x6010, 0x81, 0x02, "ftdi" },
     38 	{ 0x0403, 0x6014, 0x81, 0x02, "ftdi" },
     39 	{ 0x0000, 0x0000, 0},
     40 };
     41 
     42 static unsigned char mpsse_init[] = {
     43 	0x85, // loopback off
     44 	0x8a, // disable clock/5
     45 	0x86, 0x01, 0x00, // set divisor
     46 	0x80, 0xe8, 0xeb, // set low state and dir
     47 	0x82, 0x00, 0x00, // set high state and dir
     48 };
     49 
     50 static void dump(char *prefix, void *data, int len) {
     51 	unsigned char *x = data;
     52 	fprintf(stderr,"%s: (%d)", prefix, len);
     53 	while (len > 0) {
     54 		fprintf(stderr," %02x", *x++);
     55 		len--;
     56 	}
     57 	fprintf(stderr,"\n");
     58 }
     59 
     60 #include <libusb-1.0/libusb.h>
     61 
     62 // how to process the reply buffer
     63 #define OP_END		0 // done
     64 #define OP_BITS		1 // copy top n (1-8) bits to ptr
     65 #define OP_BYTES	2 // copy n (1-65536) bytes to ptr
     66 #define OP_1BIT		3 // copy bitmask n to bitmask x of ptr
     67 
     68 typedef struct {
     69 	u8 *ptr;
     70 	u32 n;
     71 	u16 op;
     72 	u16 x;
     73 } JOP;
     74 
     75 struct JDRV {
     76 	struct libusb_device_handle *udev;
     77 	u8 ep_in;
     78 	u8 ep_out;
     79 	int speed;
     80 	u32 expected;
     81 	u32 status;
     82 	u8 *next;
     83 	JOP *nextop;
     84 	u32 read_count;
     85 	u32 read_size;
     86 	u8 *read_ptr;
     87 	u8 cmd[CMD_MAX];
     88 	JOP op[8192];
     89 	u8 read_buffer[512];
     90 };
     91 
     92 static inline u32 cmd_avail(JDRV *d) {
     93 	return CMD_MAX - (d->next - d->cmd);
     94 }
     95 
     96 static int _jtag_setspeed(JDRV *d, int khz) {
     97 	return d->speed;
     98 }
     99 
    100 static void resetstate(JDRV *d) {
    101 	d->status = 0;
    102 	d->next = d->cmd;
    103 	d->nextop = d->op;
    104 	d->expected = 0;
    105 }
    106 
    107 #define FTDI_REQTYPE_OUT	(LIBUSB_REQUEST_TYPE_VENDOR \
    108 	| LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT)
    109 #define FTDI_CTL_RESET		0x00
    110 #define FTDI_CTL_SET_BITMODE	0x0B
    111 #define FTDI_CTL_SET_EVENT_CH	0x06
    112 #define FTDI_CTL_SET_ERROR_CH	0x07
    113 
    114 #define FTDI_IFC_A 1
    115 #define FTDI_IFC_B 2
    116 
    117 static int ftdi_reset(JDRV *d) {
    118 	struct libusb_device_handle *udev = d->udev;
    119 	if (libusb_control_transfer(udev, FTDI_REQTYPE_OUT, FTDI_CTL_RESET,
    120 		0, FTDI_IFC_A, NULL, 0, 10000) < 0) {
    121 		fprintf(stderr, "ftdi: reset failed\n");
    122 		return -1;
    123 	}
    124 	return 0;
    125 }
    126 
    127 static int ftdi_mpsse_enable(JDRV *d) {
    128 	struct libusb_device_handle *udev = d->udev;
    129 	if (libusb_control_transfer(udev, FTDI_REQTYPE_OUT, FTDI_CTL_SET_BITMODE,
    130 		0x0000, FTDI_IFC_A, NULL, 0, 10000) < 0) {
    131 		fprintf(stderr, "ftdi: set bitmode failed\n");
    132 		return -1;
    133 	}
    134 	if (libusb_control_transfer(udev, FTDI_REQTYPE_OUT, FTDI_CTL_SET_BITMODE,
    135 		0x020b, FTDI_IFC_A, NULL, 0, 10000) < 0) {
    136 		fprintf(stderr, "ftdi: set bitmode failed\n");
    137 		return -1;
    138 	}
    139 	if (libusb_control_transfer(udev, FTDI_REQTYPE_OUT, FTDI_CTL_SET_EVENT_CH,
    140 		0, FTDI_IFC_A, NULL, 0, 10000) < 0) {
    141 		fprintf(stderr, "ftdi: disable event character failed\n");
    142 		return -1;
    143 	}
    144 	return 0;	
    145 	if (libusb_control_transfer(udev, FTDI_REQTYPE_OUT, FTDI_CTL_SET_ERROR_CH,
    146 		0, FTDI_IFC_A, NULL, 0, 10000) < 0) {
    147 		fprintf(stderr, "ftdi: disable error character failed\n");
    148 		return -1;
    149 	}
    150 	return 0;	
    151 }
    152 
    153 static int ftdi_open(JDRV *d) {
    154 	struct libusb_device_handle *udev;
    155 	int n;
    156 
    157 	if (libusb_init(NULL) < 0) {
    158 		fprintf(stderr, "jtag_init: failed to init libusb\n");
    159 		return -1;
    160 	}
    161 	for (n = 0; devinfo[n].name; n++) {
    162 		udev = libusb_open_device_with_vid_pid(NULL,
    163 			devinfo[n].vid, devinfo[n].pid);
    164 		if (udev == 0)
    165 	       		continue;
    166 		libusb_detach_kernel_driver(udev, 0);
    167 		if (libusb_claim_interface(udev, 0) < 0) {
    168 			//TODO: close
    169 			continue;
    170 		}
    171 		d->udev = udev;
    172 		d->read_ptr = d->read_buffer;
    173 		d->read_size = 512;
    174 		d->read_count = 0;
    175 		d->ep_in = devinfo[n].ep_in;
    176 		d->ep_out = devinfo[n].ep_out;
    177 		return 0;
    178 	}
    179 	fprintf(stderr, "jtag_init: failed to find usb device\n");
    180 	return -1;
    181 }
    182 
    183 static int usb_bulk(struct libusb_device_handle *udev,
    184 	unsigned char ep, void *data, int len, unsigned timeout) {
    185 	int r, xfer;
    186 #if TRACE_USB
    187 	if (!(ep & 0x80))
    188 		dump("xmit", data, len);
    189 #endif
    190 	r = libusb_bulk_transfer(udev, ep, data, len, &xfer, timeout);
    191 	if (r < 0) {
    192 		fprintf(stderr,"bulk: error: %d\n", r);
    193 		return r;
    194 	}
    195 #if TRACE_USB
    196 	if (ep & 0x80)
    197 		dump("recv", data, xfer);
    198 #endif
    199 	return xfer;
    200 }
    201 
    202 /* TODO: handle smaller packet size for lowspeed version of the part */
    203 /* TODO: multi-packet reads */
    204 /* TODO: asynch/background reads */
    205 static int ftdi_read(JDRV *d, unsigned char *buffer, int count, int timeout) {
    206 	int xfer;
    207 	while (count > 0) {
    208 		if (d->read_count >= count) {
    209 			memcpy(buffer, d->read_ptr, count);
    210 			d->read_count -= count;
    211 			d->read_ptr += count;
    212 			return 0;
    213 		}
    214 		if (d->read_count > 0) {
    215 			memcpy(buffer, d->read_ptr, d->read_count);
    216 			count -= d->read_count;
    217 			buffer += d->read_count;
    218 			d->read_count = 0;
    219 		}
    220 		xfer = usb_bulk(d->udev, d->ep_in, d->read_buffer, d->read_size, 1000);
    221 		if (xfer < 0)
    222 			return -1;
    223 		if (xfer < 2)
    224 			return -1;
    225 		/* discard header */
    226 		d->read_ptr = d->read_buffer + 2;
    227 		d->read_count = xfer - 2;
    228 	}
    229 	return 0;
    230 }
    231 
    232 static int _jtag_close(JDRV *d) {
    233 	if (d->udev) {
    234 		//TODO: close
    235 	}
    236 	free(d);
    237 	return 0;
    238 }
    239 
    240 static int _jtag_init(JDRV *d) {
    241 	d->speed = 15000;
    242 	resetstate(d);
    243 	if (ftdi_open(d))
    244 		goto fail;
    245 	if (ftdi_reset(d))
    246 		goto fail;
    247 	if (ftdi_mpsse_enable(d))
    248 		goto fail;
    249 	if (usb_bulk(d->udev, d->ep_out, mpsse_init, sizeof(mpsse_init), 1000) != sizeof(mpsse_init))
    250 		goto fail;
    251 	return 0;
    252 	
    253 fail:
    254 	_jtag_close(d);
    255 	return -1;
    256 }
    257 
    258 #if TRACE_DIS
    259 static void pbin(u32 val, u32 bits) {
    260 	u32 n;
    261 	for (n = 0; n < bits; n++) {
    262 		fprintf(stderr, "%c", (val & 1) ? '1' : '0');
    263 		val >>= 1;
    264 	}
    265 }
    266 
    267 // display mpsse command stream in a (sortof) human readable form
    268 static void dismpsse(u8 *data, u32 n) {
    269 	u32 x, i;
    270 	while (n > 0) {
    271 		fprintf(stderr,"%02x: ", data[0]);
    272 		switch(data[0]) {
    273 		case 0x6B: // tms rw
    274 			fprintf(stderr, "x1 <- TDO, ");
    275 			// fall through
    276 		case 0x4B: // tms wo
    277 			fprintf(stderr, "TMS <- ");
    278 			pbin(data[2],data[1]+1);
    279 			fprintf(stderr, ", TDI <- ");
    280 			pbin((data[2] & 0x80) ? 0xFF : 0, data[1] + 1);
    281 			fprintf(stderr, "\n");
    282 			data += 3;
    283 			n -= 3;
    284 			break;
    285 		case 0x2A: // ro bits
    286 			fprintf(stderr, "x%d <- TDO\n", data[1] + 1);
    287 			data += 2;
    288 			n -= 2;
    289 			break;
    290 		case 0x28: // ro bytes
    291 			x = ((data[2] << 8) | data[1]) + 1;
    292 			fprintf(stderr, "x%d <- TDO\n", (int) x * 8);
    293 			data += 3;
    294 			n -= 3;
    295 			break;
    296 		case 0x1B: // wo bits
    297 		case 0x3B: // rw bits
    298 			fprintf(stderr, "TDI <- ");
    299 			pbin(data[2], data[1] + 1);
    300 			if (data[0] == 0x3B) {
    301 				fprintf(stderr, ", x%d <- TDO\n", data[1] + 1);
    302 			} else {
    303 				fprintf(stderr, "\n");
    304 			}
    305 			data += 3;
    306 			n -= 3;
    307 			break;
    308 		case 0x19: // wo bytes
    309 		case 0x39: // rw bytes
    310 			x = ((data[2] << 8) | data[1]) + 1;
    311 			fprintf(stderr, "TDI <- ");
    312 			for (i = 0; i < x; i++) pbin(data[3+i], 8);
    313 			if (data[0] == 0x1B) {
    314 				fprintf(stderr, ", x%d <- TDO\n", (int) x);
    315 			} else {
    316 				fprintf(stderr,"\n");
    317 			}
    318 			data += (3 + x);
    319 			n -= (3 + x);
    320 			break;
    321 		case 0x87:
    322 			fprintf(stderr,"FLUSH\n");
    323 			data += 1;
    324 			n -= 1;
    325 			break;
    326 		default:
    327 			fprintf(stderr,"??? 0x%02x\n", data[0]);
    328 			n = 0;
    329 		}
    330 	}
    331 }
    332 #endif
    333 
    334 static u8 MASKBITS[9] = {
    335 	0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF
    336 };
    337 
    338 static int _jtag_commit(JDRV *d) {
    339 	unsigned n = d->next - d->cmd;
    340 	JOP *op;
    341 	u8 *x;
    342 
    343 #if TRACE_TXN
    344 	fprintf(stderr, "jtag_commit: tx(%d) rx(%d)\n", n, (int) d->expected);
    345 #endif
    346 	if (d->status) {
    347 		// if we failed during prep, error out immediately
    348 		fprintf(stderr, "jtag_commit: pre-existing errors\n");
    349 		goto fail;
    350 	}
    351 	if (n == 0) {
    352 		goto done;
    353 	}
    354 
    355 	// always complete with an ioflush
    356 	*d->next = 0x87;
    357 	n++;
    358 	d->nextop->op = OP_END;
    359 
    360 #if TRACE_IO
    361 	dump("tx", d->cmd, n);
    362 #endif
    363 #if TRACE_DIS
    364 	dismpsse(d->cmd, n);
    365 #endif
    366 
    367 	if (usb_bulk(d->udev, d->ep_out, d->cmd, n, 1000) != n) {
    368 		fprintf(stderr, "jtag_commit: write failed\n");
    369 		goto fail;
    370 	}
    371 	if (ftdi_read(d, d->cmd, d->expected, 1000)) {
    372 		fprintf(stderr, "jtag_commit: read failed\n");	
    373 		goto fail;
    374 	}
    375 
    376 #if TRACE_IO
    377 	dump("rx", d->cmd, d->expected);
    378 #endif
    379 
    380 	for (op = d->op, x = d->cmd;;op++) {
    381 		switch(op->op) {
    382 		case OP_END:
    383 			goto done;
    384 		case OP_BITS:
    385 			*op->ptr = ((*x) >> (8 - op->n)) & MASKBITS[op->n];
    386 			x++;
    387 			break;
    388 		case OP_BYTES:
    389 			memcpy(op->ptr, x, op->n);
    390 			x += op->n;
    391 			break;
    392 		case OP_1BIT:
    393 			if (*x & op->n) {
    394 				*op->ptr |= op->x;
    395 			} else {
    396 				*op->ptr &= (~op->x);
    397 			}
    398 			x++;
    399 			break;
    400 		}
    401 	}
    402 done:
    403 	resetstate(d);
    404 	return 0;
    405 fail:
    406 	resetstate(d);
    407 	return -1;
    408 }
    409 
    410 static int _jtag_scan_tms(JDRV *d, u32 obit,
    411 	u32 count, u8 *tbits, u32 ioffset, u8 *ibits) {
    412 	if ((count > 6) || (count == 0)) {
    413 		fprintf(stderr, "jtag_scan_tms: invalid count %d\n", (int) count);
    414 		return (d->status = -1);
    415 	}
    416 	if (cmd_avail(d) < 4) {
    417 		if (_jtag_commit(d))
    418 			return (d->status = -1);
    419 	}
    420 	*d->next++ = ibits ? 0x6B : 0x4B;
    421 	*d->next++ = count - 1;
    422 	*d->next++ = ((obit & 1) << 7) | (*tbits);
    423 	if (ibits) {
    424 		if (ioffset > 7) {
    425 			ibits += (ioffset >> 3);
    426 			ioffset &= 7;
    427 		}
    428 		d->nextop->op = OP_1BIT;
    429 		d->nextop->ptr = ibits;
    430 		d->nextop->n = 1 << (8 - count);
    431 		d->nextop->x = 1 << ioffset;
    432 		d->nextop++;
    433 		d->expected++;
    434 	}
    435 	return -1;
    436 }
    437 
    438 static int _jtag_scan_io(JDRV *d, u32 count, u8 *obits, u8 *ibits) {
    439 	u32 n;
    440 	u32 bcount = count >> 3;
    441 	u8 bytecmd;
    442 	u8 bitcmd;
    443 
    444 	// determine operating mode and ftdi mpsse command byte
    445 	if (obits) {
    446 		if (ibits) {
    447 			// read-write
    448 			bytecmd = 0x39;
    449 			bitcmd = 0x3B;
    450 		} else {
    451 			// write-only
    452 			bytecmd = 0x19;
    453 			bitcmd = 0x1B;
    454 		}
    455 	} else {
    456 		if (ibits) {
    457 			// read-only
    458 			bytecmd = 0x28;
    459 			bitcmd = 0x2A;
    460 		} else {
    461 			// do nothing?!
    462 			fprintf(stderr, "jtag_scan_io: no work?!\n");
    463 			return (d->status = -1);
    464 		}
    465 	}
    466 
    467 	// do as many bytemoves as possible first
    468 	// TODO: for exactly 1 byte, bitmove command is more efficient
    469 	while (bcount > 0) {
    470 		n = cmd_avail(d);
    471 
    472 		if (n < 16) {
    473 			if (_jtag_commit(d))
    474 				return (d->status = -1);
    475 			continue;
    476 		}
    477 		n -= 4; // leave room for header and io commit
    478 		if (n > bcount)
    479 			n = bcount;
    480 		*d->next++ = bytecmd;
    481 		*d->next++ = (n - 1);
    482 		*d->next++ = (n - 1) >> 8;
    483 		if (obits) {
    484 			memcpy(d->next, obits, n);
    485 			d->next += n;
    486 			obits += n;
    487 		}
    488 		if (ibits) {
    489 			d->nextop->op = OP_BYTES;
    490 			d->nextop->ptr = ibits;
    491 			d->nextop->n = n;
    492 			d->nextop++;
    493 			ibits += n;
    494 			d->expected += n;
    495 		}
    496 		bcount -= n;
    497 	}
    498 
    499 	// do a bitmove for any leftover bits
    500 	count = count & 7;
    501 	if (count == 0)
    502        		return 0;
    503 	if (cmd_avail(d) < 4) {
    504 		if (_jtag_commit(d))
    505 			return (d->status = -1);
    506 	}
    507 	*d->next++ = bitcmd;
    508 	*d->next++ = count - 1;
    509 	if (obits) {
    510 		*d->next++ = *obits;
    511 	}
    512 	if (ibits) {
    513 		d->nextop->op = OP_BITS;
    514 		d->nextop->ptr = ibits;
    515 		d->nextop->n = count;
    516 		d->nextop++;
    517 		d->expected++;
    518 	}
    519 	return 0;
    520 }
    521 
    522 static JDVT vtable = {
    523 	.init = _jtag_init,
    524 	.close = _jtag_close,
    525 	.setspeed = _jtag_setspeed,
    526 	.commit = _jtag_commit,
    527 	.scan_tms = _jtag_scan_tms,
    528 	.scan_io = _jtag_scan_io,
    529 };
    530 
    531 int jtag_mpsse_open(JTAG **jtag) {
    532 	JDRV *d;
    533 
    534        	if ((d = malloc(sizeof(JDRV))) == 0) {
    535 		return -1;
    536 	}
    537 	memset(d, 0, sizeof(JDRV));
    538 
    539 	if (jtag_init(jtag, d, &vtable)) {
    540 		_jtag_close(d);
    541 		return -1;
    542 	}
    543 
    544 	return _jtag_init(d);
    545 }
    546