1 /*
2 * FT-232R / FT-231X USB JTAG programmer
3 *
4 * Copyright (c) 2010 - 2018 Marko Zec, University of Zagreb
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 /*
29 * TODO:
30 *
31 * - WIN32: check for USB device string description
32 *
33 * - JTAG scan / identify chain on entry.
34 *
35 * - verify SRAM / FLASH
36 *
37 * - RUN TEST delay downscaling.
38 *
39 * - disable resetting the TAP on entry / leave?
40 *
41 * - execute SVF commands provided as command line args?
42 */
43
44 static const char *verstr = "ULX2S / ULX3S JTAG programmer v 3.0.92";
45
46
47 #include <ctype.h>
48 #include <errno.h>
49 #include <fcntl.h>
50 #include <stdint.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <unistd.h>
55
56 #ifdef __FreeBSD__
57 #define USE_PPI
58 #endif
59
60 #if defined(__linux__) || defined(WIN32)
61 #define isnumber(x) (x >= '0' && x <= '9')
62 #endif
63
64 #ifdef WIN32
65 #include <windows.h>
66 #include <ftd2xx.h>
67 #include <conio.h>
68 #else
69 #include <sys/ioctl.h>
70 #include <sys/time.h>
71 #include <termios.h>
72 #ifdef USE_PPI
73 #include <dev/ppbus/ppi.h>
74 #include <dev/ppbus/ppbconf.h>
75 #endif
76 #include <ftdi.h>
77 #endif
78
79 #ifdef WIN32
80 #define BITMODE_OFF 0x0
81 #define BITMODE_BITBANG 0x1
82 #define BITMODE_SYNCBB 0x4
83 #define BITMODE_CBUS 0x20
84 #endif
85
86 /* Forward declarations */
87 static int commit(int);
88 static void set_state(int);
89 static int exec_svf_tokenized(int, char **);
90 static int send_dr(int, char *, char *, char *);
91 static int send_ir(int, char *, char *, char *);
92 static int exec_svf_mem(char *, int, int);
93 static int cmp_chip_ids(char *, char *);
94
95
96 enum svf_cmd {
97 SVF_SDR, SVF_SIR, SVF_STATE, SVF_RUNTEST, SVF_HDR, SVF_HIR,
98 SVF_TDR, SVF_TIR, SVF_ENDDR, SVF_ENDIR, SVF_FREQUENCY, SVF_UNKNOWN
99 };
100
101 static struct svf_cmdtable {
102 enum svf_cmd cmd_id;
103 char *cmd_str;
104 } svf_cmdtable[] = {
105 {SVF_SDR, "SDR"},
106 {SVF_SIR, "SIR"},
107 {SVF_STATE, "STATE"},
108 {SVF_RUNTEST, "RUNTEST"},
109 {SVF_HDR, "HDR"},
110 {SVF_HIR, "HIR"},
111 {SVF_TDR, "TDR"},
112 {SVF_TIR, "TIR"},
113 {SVF_ENDDR, "ENDDR"},
114 {SVF_ENDIR, "ENDIR"},
115 {SVF_FREQUENCY, "FREQUENCY"},
116 {SVF_UNKNOWN, NULL}
117 };
118
119
120 enum tap_state {
121 RESET, IDLE,
122 DRSELECT, DRCAPTURE, DRSHIFT, DREXIT1, DRPAUSE, DREXIT2, DRUPDATE,
123 IRSELECT, IRCAPTURE, IRSHIFT, IREXIT1, IRPAUSE, IREXIT2, IRUPDATE,
124 UNDEFINED, UNSUPPORTED,
125 };
126
127 static struct tap_statetable {
128 enum tap_state state_id;
129 char *state_str;
130 } tap_statetable[] = {
131 {RESET, "RESET"},
132 {IDLE, "IDLE"},
133 {DRSELECT, "DRSELECT"},
134 {DRCAPTURE, "DRCAPTURE"},
135 {DRSHIFT, "DRSHIFT"},
136 {DREXIT1, "DREXIT1"},
137 {DRPAUSE, "DRPAUSE"},
138 {DREXIT2, "DREXIT2"},
139 {DRUPDATE, "DRUPDATE"},
140 {IRSELECT, "IRSELECT"},
141 {IRCAPTURE, "IRCAPTURE"},
142 {IRSHIFT, "IRSHIFT"},
143 {IREXIT1, "IREXIT1"},
144 {IRPAUSE, "IRPAUSE"},
145 {IREXIT2, "IREXIT2"},
146 {IRUPDATE, "IRUPDATE"},
147 {UNDEFINED, "UNDEFINED"},
148 {UNSUPPORTED, NULL}
149 };
150
151 #define STATE2STR(state) (tap_statetable[state].state_str)
152
153
154 static enum port_mode {
155 PORT_MODE_ASYNC, PORT_MODE_SYNC, PORT_MODE_UART, PORT_MODE_UNKNOWN
156 } port_mode = PORT_MODE_UNKNOWN;
157
158
159 static enum cable_hw {
160 CABLE_HW_USB, CABLE_HW_PPI, CABLE_HW_COM, CABLE_HW_UNKNOWN
161 } cable_hw = CABLE_HW_UNKNOWN;
162
163
164 static struct cable_hw_map {
165 int cable_hw;
166 int usb_vid;
167 int usb_pid;
168 char *cable_path;
169 char tck, tms, tdi, tdo;
170 char cbus_led;
171 } cable_hw_map[] = {
172 {
173 .cable_hw = CABLE_HW_USB,
174 .usb_vid = 0x0403,
175 .usb_pid = 0x6001,
176 .cable_path = "FER ULXP2 board JTAG / UART",
177 .tck = 0x20,
178 .tms = 0x80,
179 .tdi = 0x08,
180 .tdo = 0x40,
181 .cbus_led = 0x02
182 },
183 {
184 .cable_hw = CABLE_HW_USB,
185 .usb_vid = 0x0403,
186 .usb_pid = 0x6001,
187 .cable_path = "FER ULX2S board JTAG / UART",
188 .tck = 0x20,
189 .tms = 0x80,
190 .tdi = 0x08,
191 .tdo = 0x40,
192 .cbus_led = 0x02
193 },
194 {
195 .cable_hw = CABLE_HW_USB,
196 .usb_vid = 0x0403,
197 .usb_pid = 0x6015,
198 .cable_path = "ULX3S FPGA board",
199 .tck = 0x20,
200 .tms = 0x40,
201 .tdi = 0x80,
202 .tdo = 0x08,
203 .cbus_led = 0x00
204 },
205 {
206 .cable_hw = CABLE_HW_USB,
207 .usb_vid = 0x0403,
208 .usb_pid = 0x6015,
209 .cable_path = "ULX3S FPGA v1.7",
210 .tck = 0x20,
211 .tms = 0x40,
212 .tdi = 0x80,
213 .tdo = 0x08,
214 .cbus_led = 0x00
215 },
216 {
217 .cable_hw = CABLE_HW_USB,
218 .usb_vid = 0x0403,
219 .usb_pid = 0x6015,
220 .cable_path = "ULX3S FPGA 25K v1.7",
221 .tck = 0x20,
222 .tms = 0x40,
223 .tdi = 0x80,
224 .tdo = 0x08,
225 .cbus_led = 0x00
226 },
227 {
228 .cable_hw = CABLE_HW_USB,
229 .usb_vid = 0x0403,
230 .usb_pid = 0x6015,
231 .cable_path = "ULX3S FPGA 45K v1.7",
232 .tck = 0x20,
233 .tms = 0x40,
234 .tdi = 0x80,
235 .tdo = 0x08,
236 .cbus_led = 0x00
237 },
238 {
239 .cable_hw = CABLE_HW_USB,
240 .usb_vid = 0x0403,
241 .usb_pid = 0x6015,
242 .cable_path = "ULX3S FPGA 12K v2.1.2",
243 .tck = 0x20,
244 .tms = 0x40,
245 .tdi = 0x80,
246 .tdo = 0x08,
247 .cbus_led = 0x00
248 },
249 {
250 .cable_hw = CABLE_HW_USB,
251 .usb_vid = 0x0403,
252 .usb_pid = 0x6015,
253 .cable_path = "ULX3S FPGA 25K v2.1.2",
254 .tck = 0x20,
255 .tms = 0x40,
256 .tdi = 0x80,
257 .tdo = 0x08,
258 .cbus_led = 0x00
259 },
260 {
261 .cable_hw = CABLE_HW_USB,
262 .usb_vid = 0x0403,
263 .usb_pid = 0x6015,
264 .cable_path = "ULX3S FPGA 45K v2.1.2",
265 .tck = 0x20,
266 .tms = 0x40,
267 .tdi = 0x80,
268 .tdo = 0x08,
269 .cbus_led = 0x00
270 },
271 {
272 .cable_hw = CABLE_HW_USB,
273 .usb_vid = 0x0403,
274 .usb_pid = 0x6015,
275 .cable_path = "ULX3S FPGA 85K v2.1.2",
276 .tck = 0x20,
277 .tms = 0x40,
278 .tdi = 0x80,
279 .tdo = 0x08,
280 .cbus_led = 0x00
281 },
282 {
283 .cable_hw = CABLE_HW_USB,
284 .usb_vid = 0x0403,
285 .usb_pid = 0x6015,
286 .cable_path = "ULX3S FPGA 12K v3.0.3",
287 .tck = 0x20,
288 .tms = 0x40,
289 .tdi = 0x80,
290 .tdo = 0x08,
291 .cbus_led = 0x00
292 },
293 {
294 .cable_hw = CABLE_HW_USB,
295 .usb_vid = 0x0403,
296 .usb_pid = 0x6015,
297 .cable_path = "ULX3S FPGA 25K v3.0.3",
298 .tck = 0x20,
299 .tms = 0x40,
300 .tdi = 0x80,
301 .tdo = 0x08,
302 .cbus_led = 0x00
303 },
304 {
305 .cable_hw = CABLE_HW_USB,
306 .usb_vid = 0x0403,
307 .usb_pid = 0x6015,
308 .cable_path = "ULX3S FPGA 45K v3.0.3",
309 .tck = 0x20,
310 .tms = 0x40,
311 .tdi = 0x80,
312 .tdo = 0x08,
313 .cbus_led = 0x00
314 },
315 {
316 .cable_hw = CABLE_HW_USB,
317 .usb_vid = 0x0403,
318 .usb_pid = 0x6015,
319 .cable_path = "ULX3S FPGA 85K v3.0.3",
320 .tck = 0x20,
321 .tms = 0x40,
322 .tdi = 0x80,
323 .tdo = 0x08,
324 .cbus_led = 0x00
325 },
326 {
327 .cable_hw = CABLE_HW_USB,
328 .usb_vid = 0x0403,
329 .usb_pid = 0x6015,
330 .cable_path = "ULX3S FPGA 12K v3.0.7",
331 .tck = 0x20,
332 .tms = 0x40,
333 .tdi = 0x80,
334 .tdo = 0x08,
335 .cbus_led = 0x00
336 },
337 {
338 .cable_hw = CABLE_HW_USB,
339 .usb_vid = 0x0403,
340 .usb_pid = 0x6015,
341 .cable_path = "ULX3S FPGA 25K v3.0.7",
342 .tck = 0x20,
343 .tms = 0x40,
344 .tdi = 0x80,
345 .tdo = 0x08,
346 .cbus_led = 0x00
347 },
348 {
349 .cable_hw = CABLE_HW_USB,
350 .usb_vid = 0x0403,
351 .usb_pid = 0x6015,
352 .cable_path = "ULX3S FPGA 45K v3.0.7",
353 .tck = 0x20,
354 .tms = 0x40,
355 .tdi = 0x80,
356 .tdo = 0x08,
357 .cbus_led = 0x00
358 },
359 {
360 .cable_hw = CABLE_HW_USB,
361 .usb_vid = 0x0403,
362 .usb_pid = 0x6015,
363 .cable_path = "ULX3S FPGA 85K v3.0.7",
364 .tck = 0x20,
365 .tms = 0x40,
366 .tdi = 0x80,
367 .tdo = 0x08,
368 .cbus_led = 0x00
369 },
370 {
371 .cable_hw = CABLE_HW_USB,
372 .usb_vid = 0x0403,
373 .usb_pid = 0x6010,
374 .cable_path = "Lattice ECP5 Evaluation Board",
375 .tck = 0x01,
376 .tms = 0x08,
377 .tdi = 0x02,
378 .tdo = 0x04,
379 .cbus_led = 0x10
380 },
381 {
382 .cable_hw = CABLE_HW_USB,
383 .usb_vid = 0x0403,
384 .usb_pid = 0x6011,
385 .cable_path = "Digilent FFC",
386 .tck = 0x01,
387 .tms = 0x08,
388 .tdi = 0x02,
389 .tdo = 0x04,
390 .cbus_led = 0x00
391 },
392 {
393 .cable_hw = CABLE_HW_UNKNOWN,
394 .cable_path = "UNKNOWN"
395 }
396 };
397
398
399 #define USB_BAUDS 1000000
400
401 #define USB_TCK (hmp->tck)
402 #define USB_TMS (hmp->tms)
403 #define USB_TDI (hmp->tdi)
404 #define USB_TDO (hmp->tdo)
405 #define USB_CBUS_LED (hmp->cbus_led)
406
407 #define PPI_TCK 0x02
408 #define PPI_TMS 0x04
409 #define PPI_TDI 0x01
410 #define PPI_TDO 0x40
411
412 #define USB_BUFLEN_ASYNC 8192
413 #ifdef WIN32
414 #define USB_BUFLEN_SYNC 4096
415 #else
416 #define USB_BUFLEN_SYNC 384
417 #endif
418
419 #define BUFLEN_MAX USB_BUFLEN_ASYNC /* max(SYNC, ASYNC) */
420
421 #define LED_BLINK_RATE 250
422
423 #define BREAK_MS 250
424
425 #define SPI_PAGE_SIZE 256
426 #define SPI_SECTOR_SIZE (256 * SPI_PAGE_SIZE)
427
428 static char *statc = "-\\|/";
429
430 /* Runtime globals */
431 static int cur_s = UNDEFINED;
432 static uint8_t txbuf[64 * BUFLEN_MAX];
433 static uint8_t rxbuf[64 * BUFLEN_MAX];
434 static int txpos;
435 static int need_led_blink; /* Schedule CBUS led toggle */
436 static int last_ledblink_ms; /* Last time we toggled the CBUS LED */
437 static int led_state; /* CBUS LED indicator state */
438 static int blinker_phase;
439 static int progress_perc;
440 static int bauds = 115200; /* async terminal emulation baudrate */
441 static int xbauds; /* binary transfer baudrate */
442 static int port_index;
443 static int terminal; /* terminal emulation mode */
444 static int reload; /* send break to reset f32c */
445 static int quiet; /* suppress standard messages */
446 char *svf_name; /* SVF output name */
447 static int txfu_ms; /* txt file upload character delay (ms) */
448 static int tx_binary; /* send in raw (0) or binary (1) format */
449 static const char *txfname; /* file to send */
450 static const char *com_name; /* COM / TTY port name for -a or -t */
451 static int spi_addr; /* Base address for -j flash programming */
452 static int global_debug;
453
454 static struct cable_hw_map *hmp; /* Selected cable hardware map */
455 #ifdef WIN32
456 static FT_HANDLE ftHandle; /* USB port handle */
457 static HANDLE com_port; /* COM port file */
458 static struct _DCB tty; /* COM port TTY handle */
459 #else
460 static struct ftdi_context fc; /* USB port handle */
461 static int com_port; /* COM port file */
462 static struct termios tty; /* COM port TTY handle */
463 #ifdef USE_PPI
464 static int ppi; /* Parallel port handle */
465 #endif
466 #endif
467
468
469 /* ms_sleep() sleeps for at least the number of milliseconds given as arg */
470 #define ms_sleep(delay_ms) usleep((delay_ms) * 1000)
471
472
473 static long
ms_uptime(void)474 ms_uptime(void)
475 {
476 long ms;
477 #ifndef WIN32
478 struct timeval tv;
479
480 gettimeofday(&tv, 0);
481 ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
482 #else
483 ms = GetTickCount();
484 #endif
485 return (ms);
486 }
487
488
489 static int
set_port_mode(int mode)490 set_port_mode(int mode)
491 {
492 int res = 0;
493
494 /* No-op if already in requested mode, or not using USB */
495 if (!need_led_blink &&
496 (port_mode == mode || cable_hw != CABLE_HW_USB)) {
497 port_mode = mode;
498 return (0);
499 }
500
501 /* Flush any stale TX buffers */
502 commit(1);
503
504 /* Blink status LED by deactivating CBUS pulldown pin */
505 if (need_led_blink) {
506 need_led_blink = 0;
507 led_state ^= USB_CBUS_LED;
508 if (!quiet && progress_perc < 100) {
509 fprintf(stderr, "\rProgramming: %d%% %c ",
510 progress_perc, statc[blinker_phase]);
511 fflush(stderr);
512 }
513 blinker_phase = (blinker_phase + 1) & 0x3;
514 }
515
516 #ifdef WIN32
517 if (mode == PORT_MODE_ASYNC)
518 mode = PORT_MODE_SYNC;
519 #endif
520
521 switch (mode) {
522 case PORT_MODE_SYNC:
523 #ifdef WIN32
524 /*
525 * If switching to SYNC mode, attempt to allow for TX
526 * buffers to drain first.
527 */
528 if (port_mode != PORT_MODE_SYNC)
529 ms_sleep(20);
530
531 res = FT_SetBitMode(ftHandle,
532 #else
533 res = ftdi_set_bitmode(&fc,
534 #endif
535 USB_TCK | USB_TMS | USB_TDI | led_state,
536 BITMODE_SYNCBB | (BITMODE_CBUS * (USB_CBUS_LED != 0)));
537
538 if (port_mode == PORT_MODE_SYNC)
539 break;
540
541 /* Flush any stale RX buffers */
542 #ifdef WIN32
543 for (res = 0; res < 2; res++) {
544 do {
545 ms_sleep(10);
546 } while (FT_StopInTask(ftHandle) != FT_OK);
547 FT_Purge(ftHandle, FT_PURGE_RX);
548 do {} while (FT_RestartInTask(ftHandle) != FT_OK);
549 ms_sleep(10);
550 }
551 #else
552 do {
553 res = ftdi_read_data(&fc, &txbuf[0], sizeof(txbuf));
554 } while (res == sizeof(txbuf));
555 #endif
556 break;
557
558 case PORT_MODE_ASYNC:
559 #ifdef WIN32
560 res = FT_SetBitMode(ftHandle,
561 #else
562 res = ftdi_set_bitmode(&fc,
563 #endif
564 USB_TCK | USB_TMS | USB_TDI | led_state,
565 BITMODE_BITBANG | (BITMODE_CBUS * (USB_CBUS_LED != 0)));
566 break;
567
568 case PORT_MODE_UART:
569 res = 0;
570 if (port_mode == PORT_MODE_UART)
571 break;
572 /* Pull TCK low so that we don't incidentally pulse it. */
573 memset(txbuf, 0, 10);
574 #ifdef WIN32
575 FT_Write(ftHandle, txbuf, 100, (DWORD *) &res);
576 if (res < 0) {
577 fprintf(stderr, "FT_Write() failed\n");
578 return (res);
579 }
580 res = FT_SetBitMode(ftHandle, 0, BITMODE_OFF);
581 #else
582 res = ftdi_write_data(&fc, &txbuf[0], 10);
583 if (res < 0) {
584 fprintf(stderr, "ftdi_write_data() failed\n");
585 return (res);
586 }
587 res = ftdi_disable_bitbang(&fc);
588 #endif
589 break;
590
591 default:
592 res = -1;
593 }
594
595 port_mode = mode;
596 return (res);
597 }
598
599
600 #ifdef WIN32
601 static int
setup_usb(void)602 setup_usb(void)
603 {
604 FT_STATUS res;
605 FT_DEVICE ftDevice;
606 DWORD deviceID;
607 char SerialNumber[16];
608 char Description[64];
609
610 res = FT_Open(port_index, &ftHandle);
611 if (res != FT_OK) {
612 fprintf(stderr, "FT_Open() failed\n");
613 return (res);
614 }
615
616 res = FT_GetDeviceInfo(ftHandle, &ftDevice, &deviceID, SerialNumber,
617 Description, NULL);
618 if (res != FT_OK) {
619 fprintf(stderr, "FT_GetDeviceInfo() failed\n");
620 return (res);
621 }
622 for (hmp = cable_hw_map; hmp->cable_hw != CABLE_HW_UNKNOWN; hmp++) {
623 if ((deviceID == hmp->usb_vid << 16 | hmp->usb_pid)
624 && strcmp(Description, hmp->cable_path) == 0)
625 break;
626 }
627 if (hmp->cable_hw == CABLE_HW_UNKNOWN)
628 return (-1);
629
630 if (!quiet)
631 printf("Using USB cable: %s\n", hmp->cable_path);
632
633 res = FT_SetBaudRate(ftHandle, USB_BAUDS);
634 if (res != FT_OK) {
635 fprintf(stderr, "FT_SetBaudRate() failed\n");
636 return (res);
637 }
638
639 #ifdef NOTYET
640 FT_setUSB_Parameters();
641 res = ftdi_write_data_set_chunksize(&fc, BUFLEN_MAX);
642 if (res < 0) {
643 fprintf(stderr, "ftdi_write_data_set_chunksize() failed\n");
644 return (res);
645 }
646 #endif
647
648 res = FT_SetLatencyTimer(ftHandle, 1);
649 if (res != FT_OK) {
650 fprintf(stderr, "FT_SetLatencyTimer() failed\n");
651 return (res);
652 }
653
654 res = FT_SetFlowControl(ftHandle, FT_FLOW_NONE, 0, 0);
655 if (res != FT_OK) {
656 fprintf(stderr, "FT_SetFlowControl() failed\n");
657 return (res);
658 }
659
660 res = FT_SetBitMode(ftHandle, 0, BITMODE_BITBANG);
661 if (res != FT_OK) {
662 fprintf(stderr, "FT_SetBitMode() failed\n");
663 return (res);
664 }
665
666 res = FT_SetTimeouts(ftHandle, 1000, 1000);
667 if (res != FT_OK) {
668 fprintf(stderr, "FT_SetTimeouts() failed\n");
669 return (res);
670 }
671
672 FT_Purge(ftHandle, FT_PURGE_TX);
673 FT_Purge(ftHandle, FT_PURGE_RX);
674
675 return (0);
676 }
677
678
679 static int
shutdown_usb(void)680 shutdown_usb(void)
681 {
682
683 int res;
684
685 /* Allow for the USB FIFO to drain, just in case. */
686 ms_sleep(10);
687
688 /* Clean up */
689 res = set_port_mode(PORT_MODE_UART);
690 if (res < 0) {
691 fprintf(stderr, "set_port_mode() failed\n");
692 return (res);
693 }
694
695 res = FT_SetLatencyTimer(ftHandle, 20);
696 if (res < 0) {
697 fprintf(stderr, "FT_SetLatencyTimer() failed\n");
698 return (res);
699 }
700
701 res = FT_Close(ftHandle);
702 if (res < 0) {
703 fprintf(stderr, "FT_Close() failed\n");
704 return (res);
705 }
706
707 return (0);
708 }
709 #endif /* WIN32 */
710
711
712 #ifndef WIN32
713 #ifdef USE_PPI
714 static int
setup_ppi(void)715 setup_ppi(void)
716 {
717 char c = 0;
718
719 ppi = open("/dev/ppi0", O_RDWR);
720 if (ppi < 0)
721 return (errno);
722
723 ioctl(ppi, PPISDATA, &c);
724 ioctl(ppi, PPISSTATUS, &c);
725 ioctl(ppi, PPIGSTATUS, &c);
726 if ((c & 0xb6) != 0x06) {
727 close (ppi);
728 return (EINVAL);
729 }
730
731 return (0);
732 }
733
734
735 static void
shutdown_ppi(void)736 shutdown_ppi(void)
737 {
738
739 /* Pull TCK low so that we don't incidentally pulse it on next run. */
740 txbuf[0] = 0;
741 ioctl(ppi, PPISDATA, &txbuf[0]);
742
743 close (ppi);
744 }
745 #endif
746
747
748 static int
setup_usb(void)749 setup_usb(void)
750 {
751 int res;
752
753 #ifdef __APPLE__
754 setuid(0);
755 system("/sbin/kextunload"
756 " -bundle-id com.FTDI.driver.FTDIUSBSerialDriver");
757 system("/sbin/kextunload"
758 " -bundle-id com.apple.driver.AppleUSBFTDI");
759 #endif
760
761 res = ftdi_init(&fc);
762 if (res < 0) {
763 fprintf(stderr, "ftdi_init() failed\n");
764 return (res);
765 }
766
767 for (hmp = cable_hw_map; hmp->cable_hw != CABLE_HW_UNKNOWN; hmp++) {
768 res = ftdi_usb_open_desc_index(&fc, hmp->usb_vid, hmp->usb_pid,
769 hmp->cable_path, NULL, port_index);
770 if (res == 0)
771 break;
772 }
773 if (res < 0) {
774 res = ftdi_usb_open_desc_index(&fc, 0x0403, 0x6001,
775 NULL, NULL, port_index);
776 if (res < 0) {
777 #ifdef __APPLE__
778 system("/sbin/kextload"
779 " -bundle-id com.FTDI.driver.FTDIUSBSerialDriver");
780 system("/sbin/kextload"
781 " -bundle-id com.apple.driver.AppleUSBFTDI");
782 #endif
783 return (res);
784 }
785 }
786
787 res = ftdi_set_baudrate(&fc, USB_BAUDS);
788 if (res < 0) {
789 fprintf(stderr, "ftdi_set_baudrate() failed\n");
790 return (res);
791 }
792
793 res = ftdi_write_data_set_chunksize(&fc, BUFLEN_MAX);
794 if (res < 0) {
795 fprintf(stderr, "ftdi_write_data_set_chunksize() failed\n");
796 return (res);
797 }
798
799 /* Reducing latency to 1 ms for BITMODE_SYNCBB is crucial! */
800 res = ftdi_set_latency_timer(&fc, 1);
801 if (res < 0) {
802 fprintf(stderr, "ftdi_set_latency_timer() failed\n");
803 return (res);
804 }
805
806 res = ftdi_set_bitmode(&fc, USB_TCK | USB_TMS | USB_TDI,
807 BITMODE_BITBANG);
808 if (res < 0) {
809 fprintf(stderr, "ftdi_set_bitmode() failed\n");
810 return (EXIT_FAILURE);
811 }
812
813 return (0);
814 }
815
816
817 static int
shutdown_usb(void)818 shutdown_usb(void)
819 {
820 int res;
821
822 /* Clean up */
823 res = set_port_mode(PORT_MODE_UART);
824 if (res < 0) {
825 fprintf(stderr, "ftdi_disable_bitbang() failed\n");
826 return (res);
827 }
828
829 res = ftdi_set_latency_timer(&fc, 20);
830 if (res < 0) {
831 fprintf(stderr, "ftdi_set_latency_timer() failed\n");
832 return (res);
833 }
834
835 #ifdef __linux__
836 usb_reset((void *) fc.usb_dev);
837 #else
838 res = ftdi_usb_close(&fc);
839 if (res < 0) {
840 fprintf(stderr, "unable to close ftdi device: %d (%s)\n",
841 res, ftdi_get_error_string(&fc));
842 return (res);
843 }
844 #endif
845
846 ftdi_deinit(&fc);
847
848 #ifdef __APPLE__
849 system("/sbin/kextload"
850 " -bundle-id com.FTDI.driver.FTDIUSBSerialDriver");
851 system("/sbin/kextload"
852 " -bundle-id com.apple.driver.AppleUSBFTDI");
853 #endif
854
855 return (0);
856 }
857 #endif /* !WIN32 */
858
859
860 static void
set_tms_tdi(int tms,int tdi)861 set_tms_tdi(int tms, int tdi)
862 {
863 int val = 0;
864
865 if (cable_hw == CABLE_HW_USB) {
866 if (tms)
867 val |= USB_TMS;
868 if (tdi)
869 val |= USB_TDI;
870 txbuf[txpos++] = val;
871 txbuf[txpos++] = val | USB_TCK;
872 } else { /* PPI */
873 if (tms)
874 val |= PPI_TMS;
875 if (tdi)
876 val |= PPI_TDI;
877 txbuf[txpos++] = val;
878 txbuf[txpos++] = val | PPI_TCK;
879 }
880
881 if (txpos > sizeof(txbuf)) {
882 fprintf(stderr, "txbuf overflow\n");
883 if (cable_hw == CABLE_HW_USB)
884 shutdown_usb();
885 exit(EXIT_FAILURE);
886 }
887 }
888
889
890 static int
send_generic(int bits,char * tdi,char * tdo,char * mask)891 send_generic(int bits, char *tdi, char *tdo, char *mask)
892 {
893 int res, i, bitpos, tdomask, tdoval, maskval, val = 0, txval = 0;
894 int rxpos, rxlen;
895
896 if (cable_hw == CABLE_HW_USB)
897 tdomask = USB_TDO;
898 else
899 tdomask = PPI_TDO;
900
901 i = strlen(tdi);
902 if (i != (bits + 3) / 4) {
903 fprintf(stderr, "send_generic(): bitcount and tdi "
904 "data length do not match\n");
905 return (EXIT_FAILURE);
906 }
907 if (tdo != NULL && strlen(tdo) != i) {
908 if (mask != NULL && strlen(mask) != i) {
909 fprintf(stderr, "send_generic(): tdi, tdo and mask "
910 "must be of same length\n");
911 return (EXIT_FAILURE);
912 }
913 fprintf(stderr, "send_generic(): tdi and tdo "
914 "must be of same length\n");
915 return (EXIT_FAILURE);
916 }
917
918 if (cur_s == DRPAUSE || cur_s == IRPAUSE ) {
919 /* Move from *PAUSE to *EXIT2 state */
920 set_tms_tdi(1, 0);
921 }
922
923 /* Move from *CAPTURE or *EXIT2 to *SHIFT state */
924 set_tms_tdi(0, 0);
925
926 /* Set up receive index / length */
927 rxpos = txpos + 2;
928 rxlen = bits;
929
930 for (bitpos = 0; bits > 0; bits--) {
931 if (bitpos == 0) {
932 i--;
933 val = tdi[i];
934 if (val >= '0' && val <= '9')
935 val = val - '0';
936 else if (val >= 'A' && val <= 'F')
937 val = val + 10 - 'A';
938 else {
939 fprintf(stderr, "send_generic():"
940 "TDI data not in hex format\n");
941 return (EXIT_FAILURE);
942 }
943 }
944
945 txval = val & 0x1;
946 if (bits > 1)
947 set_tms_tdi(0, txval);
948 else
949 set_tms_tdi(1, txval);
950
951 val = val >> 1;
952 bitpos = (bitpos + 1) & 0x3;
953 }
954
955 /* Move from *EXIT1 to *PAUSE state */
956 set_tms_tdi(0, txval);
957
958 /* Send / receive data on JTAG port */
959 res = commit(0);
960
961 /* Translate received bitstream into hex, apply mask, store in tdi */
962 if (port_mode == PORT_MODE_SYNC) {
963 if (mask != NULL)
964 mask += strlen(tdi);
965 if (tdo != NULL)
966 tdo += strlen(tdi);
967 tdi += strlen(tdi);
968 val = 0;
969 for (i = rxpos, bits = 0; bits < rxlen; i += 2) {
970 val += (((txbuf[i] & tdomask) != 0) << (bits & 0x3));
971 bits++;
972 if ((bits & 0x3) == 0 || bits == rxlen) {
973 if (mask != NULL) {
974 /* Apply mask to received data */
975 mask--;
976 maskval = *mask;
977 if (maskval >= '0' && maskval <= '9')
978 maskval = maskval - '0';
979 else if (maskval >= 'A' &&
980 maskval <= 'F')
981 maskval = maskval + 10 - 'A';
982 val &= maskval;
983 /* Apply mask to expected TDO as well */
984 if (tdo != NULL) {
985 tdo--;
986 tdoval = *tdo;
987 if (tdoval >= '0' &&
988 tdoval <= '9')
989 tdoval = tdoval - '0';
990 else if (tdoval >= 'A' &&
991 tdoval <= 'F')
992 tdoval =
993 tdoval + 10 - 'A';
994 tdoval &= maskval;
995 if (tdoval < 10)
996 *tdo = tdoval + '0';
997 else
998 *tdo =
999 tdoval - 10 + 'A';
1000 }
1001 }
1002 tdi--;
1003 if (val < 10)
1004 *tdi = val + '0';
1005 else
1006 *tdi = val - 10 + 'A';
1007 val = 0;
1008 }
1009 }
1010 }
1011
1012 return (res);
1013 }
1014
1015
1016 static int
send_dr(int bits,char * tdi,char * tdo,char * mask)1017 send_dr(int bits, char *tdi, char *tdo, char *mask)
1018 {
1019 int res;
1020
1021 if (cur_s != DRPAUSE) {
1022 fprintf(stderr, "Must be in DRPAUSE on entry to send_dr()!\n");
1023 return (EXIT_FAILURE);
1024 }
1025 res = send_generic(bits, tdi, tdo, mask);
1026 cur_s = DRPAUSE;
1027 return (res);
1028 }
1029
1030
1031 static int
send_ir(int bits,char * tdi,char * tdo,char * mask)1032 send_ir(int bits, char *tdi, char *tdo, char *mask)
1033 {
1034 int res;
1035
1036 if (cur_s != IRPAUSE) {
1037 fprintf(stderr, "Must be in IRPAUSE on entry to send_ir()!\n");
1038 return (EXIT_FAILURE);
1039 }
1040 res = send_generic(bits, tdi, tdo, mask);
1041 cur_s = IRPAUSE;
1042 return (res);
1043 }
1044
1045
1046 static int
commit_usb(void)1047 commit_usb(void)
1048 {
1049 int txchunklen, res, i;
1050
1051 for (i = 0; i < txpos; i += txchunklen) {
1052 txchunklen = txpos - i;
1053 if (port_mode == PORT_MODE_SYNC && txchunklen > USB_BUFLEN_SYNC)
1054 txchunklen = USB_BUFLEN_SYNC;
1055 #ifdef WIN32
1056 FT_Write(ftHandle, &txbuf[i], txchunklen, (DWORD *) &res);
1057 #else
1058 res = ftdi_write_data(&fc, &txbuf[i], txchunklen);
1059 #endif
1060 if (res != txchunklen) {
1061 fprintf(stderr, "ftdi_write_data() failed\n");
1062 return (EXIT_FAILURE);
1063 }
1064
1065 if (port_mode == PORT_MODE_SYNC) {
1066 #ifdef WIN32
1067 FT_Read(ftHandle, &txbuf[i], txchunklen,
1068 (DWORD *) &res);
1069 #else
1070 int rep = 0;
1071 for (res = 0; res < txchunklen && rep < 8;
1072 rep++) {
1073 res += ftdi_read_data(&fc, &txbuf[i],
1074 txchunklen - res);
1075 }
1076 #endif
1077 if (res != txchunklen) {
1078 #ifdef WIN32
1079 fprintf(stderr, "FT_Read() failed: "
1080 "expected %d, received %d bytes\n",
1081 txchunklen, res);
1082 #else
1083 fprintf(stderr, "ftdi_read_data() failed\n");
1084 #endif
1085 return (EXIT_FAILURE);
1086 }
1087 }
1088 }
1089 txpos = 0;
1090
1091 /* Schedule CBUS LED blinking */
1092 i = ms_uptime();
1093 if (i - last_ledblink_ms >= LED_BLINK_RATE) {
1094 last_ledblink_ms += LED_BLINK_RATE;
1095 need_led_blink = 1;
1096 }
1097
1098 return (0);
1099 }
1100
1101
1102 #ifdef USE_PPI
1103 static int
commit_ppi(void)1104 commit_ppi(void)
1105 {
1106 int i, val;
1107
1108 for (i = 0; i < txpos; i++) {
1109 val = txbuf[i];
1110 if (port_mode == PORT_MODE_SYNC && !(i & 1)) {
1111 ioctl(ppi, PPIGSTATUS, &txbuf[i]);
1112 }
1113 ioctl(ppi, PPISDATA, &val);
1114 }
1115
1116 txpos = 0;
1117 return (0);
1118 }
1119 #endif
1120
1121
1122 static int
commit(int force)1123 commit(int force)
1124 {
1125
1126 if (txpos == 0 || (!force && port_mode != PORT_MODE_SYNC &&
1127 txpos < sizeof(txbuf) / 2))
1128 return (0);
1129
1130 #ifdef USE_PPI
1131 if (cable_hw == CABLE_HW_PPI)
1132 return (commit_ppi());
1133 #endif
1134 if (cable_hw == CABLE_HW_USB)
1135 return (commit_usb());
1136 else
1137 return (EINVAL);
1138 }
1139
1140
1141 static int
str2tapstate(char * str)1142 str2tapstate(char *str)
1143 {
1144 int i;
1145
1146 for (i = 0; tap_statetable[i].state_str != NULL; i++) {
1147 if (strcmp(str, tap_statetable[i].state_str) == 0)
1148 break;
1149 }
1150 return (tap_statetable[i].state_id);
1151 }
1152
1153
1154 static void
set_state(int tgt_s)1155 set_state(int tgt_s) {
1156 int i, res = 0;
1157
1158 switch (tgt_s) {
1159 case RESET:
1160 for (i = 0; i < 6; i++)
1161 set_tms_tdi(1, 0);
1162 break;
1163
1164 case IDLE:
1165 switch (cur_s) {
1166 case RESET:
1167 case DRUPDATE:
1168 case IRUPDATE:
1169 case IDLE:
1170 set_tms_tdi(0, 0);
1171 break;
1172
1173 case UNDEFINED:
1174 set_state(RESET);
1175 set_state(IDLE);
1176 break;
1177
1178 case DRPAUSE:
1179 set_state(DREXIT2);
1180 set_state(DRUPDATE);
1181 set_state(IDLE);
1182 break;
1183
1184 case IRPAUSE:
1185 set_state(IREXIT2);
1186 set_state(IRUPDATE);
1187 set_state(IDLE);
1188 break;
1189
1190 default:
1191 res = -1;
1192 }
1193 break;
1194
1195 case DRSELECT:
1196 switch (cur_s) {
1197 case IDLE:
1198 case DRUPDATE:
1199 case IRUPDATE:
1200 set_tms_tdi(1, 0);
1201 break;
1202
1203 default:
1204 res = -1;
1205 }
1206 break;
1207
1208 case DRCAPTURE:
1209 switch (cur_s) {
1210 case DRSELECT:
1211 set_tms_tdi(0, 0);
1212 break;
1213
1214 case IDLE:
1215 set_state(DRSELECT);
1216 set_state(DRCAPTURE);
1217 break;
1218
1219 case IRPAUSE:
1220 set_state(IDLE);
1221 set_state(DRSELECT);
1222 set_state(DRCAPTURE);
1223 break;
1224
1225 default:
1226 res = -1;
1227 }
1228 break;
1229
1230 case DREXIT1:
1231 switch (cur_s) {
1232 case DRCAPTURE:
1233 set_tms_tdi(1, 0);
1234 break;
1235
1236 default:
1237 res = -1;
1238 }
1239 break;
1240
1241 case DRPAUSE:
1242 switch (cur_s) {
1243 case DREXIT1:
1244 set_tms_tdi(0, 0);
1245 break;
1246
1247 case IDLE:
1248 set_state(DRSELECT);
1249 set_state(DRCAPTURE);
1250 set_state(DREXIT1);
1251 set_state(DRPAUSE);
1252 break;
1253
1254 case IRPAUSE:
1255 set_state(IREXIT2);
1256 set_state(IRUPDATE);
1257 set_state(DRSELECT);
1258 set_state(DRCAPTURE);
1259 set_state(DREXIT1);
1260 set_state(DRPAUSE);
1261 break;
1262
1263 case DRPAUSE:
1264 break;
1265
1266 default:
1267 res = -1;
1268 }
1269 break;
1270
1271 case DREXIT2:
1272 switch (cur_s) {
1273 case DRPAUSE:
1274 set_tms_tdi(1, 0);
1275 break;
1276
1277 default:
1278 res = -1;
1279 }
1280 break;
1281
1282 case DRUPDATE:
1283 switch (cur_s) {
1284 case DREXIT2:
1285 set_tms_tdi(1, 0);
1286 break;
1287
1288 default:
1289 res = -1;
1290 }
1291 break;
1292
1293 case IRSELECT:
1294 switch (cur_s) {
1295 case DRSELECT:
1296 set_tms_tdi(1, 0);
1297 break;
1298
1299 default:
1300 res = -1;
1301 }
1302 break;
1303
1304 case IRCAPTURE:
1305 switch (cur_s) {
1306 case IRSELECT:
1307 set_tms_tdi(0, 0);
1308 break;
1309
1310 case IDLE:
1311 set_state(DRSELECT);
1312 set_state(IRSELECT);
1313 set_state(IRCAPTURE);
1314 break;
1315
1316 case DRPAUSE:
1317 set_state(DREXIT2);
1318 set_state(DRUPDATE);
1319 set_state(DRSELECT);
1320 set_state(IRSELECT);
1321 set_state(IRCAPTURE);
1322 break;
1323
1324 default:
1325 res = -1;
1326 }
1327 break;
1328
1329 case IREXIT1:
1330 switch (cur_s) {
1331 case IRCAPTURE:
1332 set_tms_tdi(1, 0);
1333 break;
1334
1335 default:
1336 res = -1;
1337 }
1338 break;
1339
1340 case IRPAUSE:
1341 switch (cur_s) {
1342 case IREXIT1:
1343 set_tms_tdi(0, 0);
1344 break;
1345
1346 case IDLE:
1347 set_state(DRSELECT);
1348 set_state(IRSELECT);
1349 set_state(IRCAPTURE);
1350 set_state(IREXIT1);
1351 set_state(IRPAUSE);
1352 break;
1353
1354 case DRPAUSE:
1355 set_state(DREXIT2);
1356 set_state(DRUPDATE);
1357 set_state(DRSELECT);
1358 set_state(IRSELECT);
1359 set_state(IRCAPTURE);
1360 set_state(IREXIT1);
1361 set_state(IRPAUSE);
1362 break;
1363
1364 case IRPAUSE:
1365 break;
1366
1367 default:
1368 res = -1;
1369 }
1370 break;
1371
1372 case IREXIT2:
1373 switch (cur_s) {
1374 case IRPAUSE:
1375 set_tms_tdi(1, 0);
1376 break;
1377
1378 default:
1379 res = -1;
1380 }
1381 break;
1382
1383 case IRUPDATE:
1384 switch (cur_s) {
1385 case IREXIT2:
1386 set_tms_tdi(1, 0);
1387 break;
1388
1389 default:
1390 res = -1;
1391 }
1392 break;
1393
1394 default:
1395 res = -1;
1396 }
1397
1398 if (res) {
1399 fprintf(stderr, "Don't know how to proceed: %s -> %s\n",
1400 STATE2STR(cur_s), STATE2STR(tgt_s));
1401 if (cable_hw == CABLE_HW_USB)
1402 shutdown_usb();
1403 exit(EXIT_FAILURE);
1404 }
1405
1406 cur_s = tgt_s;
1407 }
1408
1409
1410 static int
exec_svf_tokenized(int tokc,char * tokv[])1411 exec_svf_tokenized(int tokc, char *tokv[])
1412 {
1413 static int last_sdr = PORT_MODE_UNKNOWN;
1414 int cmd, i, res = 0;
1415 int repeat = 1, delay_ms = 0;
1416
1417 for (i = 0; svf_cmdtable[i].cmd_str != NULL; i++) {
1418 if (strcmp(tokv[0], svf_cmdtable[i].cmd_str) == 0)
1419 break;
1420 }
1421
1422 cmd = svf_cmdtable[i].cmd_id;
1423 switch (cmd) {
1424 case SVF_SDR:
1425 case SVF_SIR:
1426 if (tokc == 4) {
1427 if (cmd == SVF_SDR && last_sdr == PORT_MODE_ASYNC)
1428 set_port_mode(PORT_MODE_ASYNC);
1429 tokv[5] = NULL;
1430 tokv[7] = NULL;
1431 if (cmd == SVF_SDR)
1432 last_sdr = PORT_MODE_ASYNC;
1433 } else if (tokc == 6 || tokc == 8) {
1434 set_port_mode(PORT_MODE_SYNC);
1435 if (tokc == 5)
1436 tokv[7] = NULL;
1437 if (cmd == SVF_SDR)
1438 last_sdr = PORT_MODE_SYNC;
1439 } else {
1440 res = EXIT_FAILURE;
1441 break;
1442 }
1443 if (cmd == SVF_SDR) {
1444 set_state(DRPAUSE);
1445 res = send_dr(atoi(tokv[1]), tokv[3], tokv[5], tokv[7]);
1446 } else {
1447 set_state(IRPAUSE);
1448 res = send_ir(atoi(tokv[1]), tokv[3], tokv[5], tokv[7]);
1449 }
1450 if (res)
1451 break;
1452 if ((tokc == 6 || tokc == 8) && strcmp(tokv[3], tokv[5]) != 0) {
1453 if (strlen(tokv[3]) == 8 && strlen(tokv[5]) == 8 &&
1454 strcmp(tokv[7], "FFFFFFFF") == 0 &&
1455 cmp_chip_ids(tokv[3], tokv[5]) == 0)
1456 return (ENODEV);
1457 fprintf(stderr, "Received and expected data "
1458 "do not match!\n");
1459 if (tokc == 6)
1460 fprintf(stderr, "TDO: %s Expected: %s\n",
1461 tokv[3], tokv[5]);
1462 if (tokc == 8)
1463 fprintf(stderr, "TDO: %s Expected: %s "
1464 "mask: %s\n", tokv[3], tokv[5], tokv[7]);
1465 res = EXIT_FAILURE;
1466 }
1467 break;
1468
1469 case SVF_STATE:
1470 set_state(str2tapstate(tokv[1]));
1471 res = commit(0);
1472 break;
1473
1474 case SVF_RUNTEST:
1475 for (i = 2; i < tokc; i += 2) {
1476 if (strcmp(tokv[i + 1], "TCK") == 0) {
1477 repeat = atoi(tokv[i]);
1478 if (repeat < 1 || repeat > 1000) {
1479 fprintf(stderr,
1480 "Unexpected token: %s\n",
1481 tokv[i]);
1482 res = EXIT_FAILURE;
1483 break;
1484 }
1485 } else if (strcmp(tokv[i + 1], "SEC") == 0) {
1486 float f;
1487 sscanf(tokv[i], "%f", &f);
1488 delay_ms = (f + 0.0005) * 1000;
1489 if (delay_ms < 1 || delay_ms > 120000) {
1490 fprintf(stderr,
1491 "Unexpected token: %s\n",
1492 tokv[i]);
1493 res = EXIT_FAILURE;
1494 break;
1495 }
1496 /* Silently reduce insanely long waits */
1497 if (delay_ms > 3000)
1498 delay_ms = 3000;
1499 } else {
1500 fprintf(stderr, "Unexpected token: %s\n",
1501 tokv[i + 1]);
1502 res = EXIT_FAILURE;
1503 break;
1504 }
1505 }
1506 set_state(str2tapstate(tokv[1]));
1507 i = delay_ms * (USB_BAUDS / 2000);
1508 #ifdef USE_PPI
1509 /* libftdi is relatively slow in sync mode on FreeBSD */
1510 if (port_mode == PORT_MODE_SYNC && i > USB_BUFLEN_SYNC / 2)
1511 i /= 2;
1512 #endif
1513 if (i > repeat)
1514 repeat = i;
1515 for (i = 0; i < repeat; i++) {
1516 txbuf[txpos++] = 0;
1517 txbuf[txpos++] = USB_TCK;
1518 if (txpos >= sizeof(txbuf) / 2) {
1519 commit(0);
1520 if (need_led_blink)
1521 set_port_mode(port_mode);
1522 }
1523 }
1524 break;
1525
1526 case SVF_HDR:
1527 case SVF_HIR:
1528 case SVF_TDR:
1529 case SVF_TIR:
1530 if (tokc != 2 || strcmp(tokv[1], "0") != 0)
1531 res = EINVAL;
1532 break;
1533
1534 case SVF_ENDDR:
1535 if (tokc != 2 ||
1536 (strcmp(tokv[1], "DRPAUSE") != 0 &&
1537 strcmp(tokv[1], "IDLE") != 0))
1538 res = EINVAL;
1539 break;
1540
1541 case SVF_ENDIR:
1542 if (tokc != 2 ||
1543 (strcmp(tokv[1], "IRPAUSE") != 0 &&
1544 strcmp(tokv[1], "IDLE") != 0))
1545 res = EINVAL;
1546 break;
1547
1548 case SVF_FREQUENCY:
1549 /* Silently ignored. */
1550 break;
1551
1552 default:
1553 res = EOPNOTSUPP;
1554 }
1555
1556 return (res);
1557 }
1558
1559
1560 enum jed_states {
1561 JED_INIT, JED_PACK_KNOWN, JED_SIZE_KNOWN, JED_PROG_INITIATED,
1562 JED_FUSES, JED_FUSES_DONE, JED_SED_CRC, JED_HAVE_SED_CRC, JED_USER_SIG
1563 };
1564
1565 enum jed_target {
1566 JED_TGT_SRAM, JED_TGT_FLASH, JED_TGT_UNKNOWN
1567 };
1568
1569 static struct jed_devices {
1570 char *name;
1571 int id;
1572 int fuses;
1573 int col_width;
1574 int row_width;
1575 } jed_devices[] = {
1576 {
1577 .name = "LFXP2-5E",
1578 .id = 0x01299043,
1579 .fuses = 1236476,
1580 .col_width = 638,
1581 .row_width = 1938,
1582 },
1583 {
1584 .name = "LFXP2-8E",
1585 .id = 0x0129A043,
1586 .fuses = 1954736,
1587 .col_width = 772,
1588 .row_width= 2532,
1589 },
1590 {
1591 .name = "LFXP2-17E",
1592 .id = 0x0129B043,
1593 .fuses = 3627704,
1594 .col_width = 2188,
1595 .row_width = 1658,
1596 },
1597 {
1598 .name = "LFXP2-30E",
1599 .id = 0x0129D043,
1600 .fuses = 5954320,
1601 .col_width = 2644,
1602 .row_width = 2532,
1603 },
1604 {
1605 .name = "LFXP2-40E",
1606 .id = 0x0129E043,
1607 .fuses = 8304368,
1608 .col_width = 3384,
1609 .row_width = 2454,
1610 },
1611 {
1612 .name = "LFE5U-12F",
1613 .id = 0x21111043,
1614 .fuses = 5681848,
1615 .col_width = 592,
1616 .row_width = 7562,
1617 },
1618 {
1619 .name = "LFE5U-25F",
1620 .id = 0x41111043,
1621 .fuses = 5681848,
1622 .col_width = 592,
1623 .row_width = 7562,
1624 },
1625 {
1626 .name = "LFE5U-45F",
1627 .id = 0x41112043,
1628 .fuses = 10208312,
1629 .col_width = 848,
1630 .row_width = 9470,
1631 },
1632 {
1633 .name = "LFE5U-85F",
1634 .id = 0x41113043,
1635 .fuses = 19244856,
1636 .col_width = 1136,
1637 .row_width = 13294,
1638 },
1639 {
1640 .name = "LFE5UM-25F",
1641 .id = 0x01111043,
1642 .fuses = 5681848,
1643 .col_width = 592,
1644 .row_width = 7562,
1645 },
1646 {
1647 .name = "LFE5UM-45F",
1648 .id = 0x01112043,
1649 .fuses = 10208312,
1650 .col_width = 848,
1651 .row_width = 9470,
1652 },
1653 {
1654 .name = "LFE5UM-85F",
1655 .id = 0x01113043,
1656 .fuses = 19244856,
1657 .col_width = 1136,
1658 .row_width = 13294,
1659 },
1660 {NULL, 0, 0}
1661 };
1662
1663
1664 static int
cmp_chip_ids(char * got,char * exp)1665 cmp_chip_ids(char *got, char *exp)
1666 {
1667 int got_id, exp_id;
1668 struct jed_devices *got_jd, *exp_jd;
1669
1670 sscanf(got, "%x", &got_id);
1671 sscanf(exp, "%x", &exp_id);
1672
1673 for (got_jd = jed_devices; got_jd->name != NULL; got_jd++)
1674 if (got_jd->id == got_id)
1675 break;
1676 for (exp_jd = jed_devices; exp_jd->name != NULL; exp_jd++)
1677 if (exp_jd->id == exp_id)
1678 break;
1679
1680 if (exp_jd->name == NULL && got_jd->name == NULL)
1681 return (EXIT_FAILURE);
1682
1683 fprintf(stderr, "\nFound ");
1684 if (got_jd->name)
1685 fprintf(stderr, "%s", got_jd->name);
1686 else
1687 fprintf(stderr, "unknown (%s)", got);
1688 fprintf(stderr, " device, but the bitstream is for ");
1689 if (exp_jd->name)
1690 fprintf(stderr, "%s", exp_jd->name);
1691 else
1692 fprintf(stderr, "unknown (%s)", exp);
1693 fprintf(stderr, ".\n");
1694 return (0);
1695 }
1696
1697 /*
1698 * Parse a Lattice XP2 JEDEC file and convert it into a SVF stream stored
1699 * in a contiguos chunk of memory. If parsing is sucessfull proceed with
1700 * calling exec_svf_mem().
1701 */
1702 static int
exec_jedec_file(char * path,int target,int debug)1703 exec_jedec_file(char *path, int target, int debug)
1704 {
1705 char *inbuf, *outbuf, *incp, *outcp;
1706 char tmpbuf[2048];
1707 FILE *fd;
1708 long flen;
1709 int jed_state = JED_INIT;
1710 int jed_dev = -1;
1711 int i, j, val, row, res;
1712
1713 fd = fopen(path, "r");
1714 if (fd == NULL) {
1715 fprintf(stderr, "open(%s) failed\n", path);
1716 return (EXIT_FAILURE);
1717 }
1718
1719 fseek(fd, 0, SEEK_END);
1720 flen = ftell(fd);
1721 fseek(fd, 0, SEEK_SET);
1722
1723 inbuf = malloc(flen);
1724 outbuf = malloc(flen * 2); /* XXX rough estimate */
1725 if (inbuf == NULL || outbuf == NULL) {
1726 fprintf(stderr, "malloc(%ld) failed\n", flen);
1727 return (EXIT_FAILURE);
1728 }
1729
1730 incp = inbuf;
1731 outcp = outbuf;
1732 while (!feof(fd) && fgets(incp, flen, fd) != NULL) {
1733 /* Trim CR / LF chars from the tail of the line */
1734 incp += strlen(incp) - 1;
1735 while (incp >= inbuf && (*incp == 10 || *incp == 13))
1736 incp--;
1737 incp[1] = 0;
1738
1739 /* Is this the first line of an "L" command? */
1740 if (*inbuf == 'L') {
1741 if (jed_state < JED_PROG_INITIATED) {
1742 fprintf(stderr, "Invalid bitstream file\n");
1743 return (EXIT_FAILURE);
1744 }
1745 if (jed_state == JED_PROG_INITIATED)
1746 jed_state = JED_FUSES;
1747 else
1748 jed_state = JED_SED_CRC;
1749 incp = inbuf;
1750 continue;
1751 }
1752
1753 /* Does the command terminate on this line? */
1754 if (*incp != '*') {
1755 incp++;
1756 continue;
1757 } else
1758 *incp = 0;
1759
1760 /* Is this the SED_CRC fuses string? */
1761 if (jed_state == JED_SED_CRC) {
1762 val = 0;
1763 for (i = 32, j = 0; i > 0; i--, val <<= 1) {
1764 val += (inbuf[i - 1] == '1');
1765 if ((i & 0x3) == 1) {
1766 if (val < 10)
1767 tmpbuf[j++] = '0' +
1768 val;
1769 else
1770 tmpbuf[j++] = 'A' +
1771 val - 10;
1772 val = 0;
1773 }
1774 }
1775 tmpbuf[j++] = 0;
1776 if (strlen(tmpbuf) != 8) {
1777 fprintf(stderr, "Invalid bitstream file\n");
1778 return (EXIT_FAILURE);
1779 }
1780 jed_state = JED_HAVE_SED_CRC;
1781 }
1782
1783 /* Is this the main fuses string? */
1784 if (jed_state == JED_FUSES) {
1785
1786 outcp += sprintf(outcp, "\n\n! Program Fuse Map\n\n");
1787 *outcp++ = 0;
1788 outcp += sprintf(outcp, "SIR 8 TDI (21);\n");
1789 *outcp++ = 0;
1790 outcp += sprintf(outcp,
1791 "RUNTEST IDLE 3 TCK 1.00E-002 SEC;\n");
1792 *outcp++ = 0;
1793
1794 if (target == JED_TGT_SRAM) {
1795 outcp += sprintf(outcp,
1796 "SIR 8 TDI (67);\n");
1797 *outcp++ = 0;
1798 }
1799
1800 for (incp = inbuf, row = 1;
1801 row <= jed_devices[jed_dev].row_width; row++) {
1802 if (target == JED_TGT_FLASH) {
1803 outcp += sprintf(outcp,
1804 "SIR 8 TDI (67);\n");
1805 *outcp++ = 0;
1806 }
1807
1808 val = 0;
1809 for (i = jed_devices[jed_dev].col_width, j = 0;
1810 i > 0; i--, val <<= 1) {
1811 val += (incp[i - 1] == '1');
1812 if ((i & 0x3) == 1) {
1813 if (val < 10)
1814 tmpbuf[j++] = '0' +
1815 val;
1816 else
1817 tmpbuf[j++] = 'A' +
1818 val - 10;
1819 val = 0;
1820 }
1821 }
1822 tmpbuf[j++] = 0;
1823 incp += jed_devices[jed_dev].col_width;
1824
1825 outcp += sprintf(outcp,
1826 "! Shift in Data Row = %d\n", row);
1827 *outcp++ = 0;
1828 outcp += sprintf(outcp,
1829 "SDR %d TDI (%s);\n",
1830 jed_devices[jed_dev].col_width, tmpbuf);
1831 *outcp++ = 0;
1832 if (target == JED_TGT_FLASH) {
1833 outcp += sprintf(outcp,
1834 "RUNTEST IDLE"
1835 " 3 TCK 1.00E-003 SEC;\n");
1836 } else {
1837 outcp += sprintf(outcp,
1838 "RUNTEST IDLE 3 TCK;\n");
1839 }
1840 *outcp++ = 0;
1841
1842 if (target == JED_TGT_FLASH) {
1843 outcp += sprintf(outcp,
1844 "SIR 8 TDI (52);\n");
1845 *outcp++ = 0;
1846
1847 outcp += sprintf(outcp,
1848 "SDR 1 TDI (0)\n");
1849 *outcp++ = 0;
1850 outcp += sprintf(outcp,
1851 " TDO (1);\n");
1852 *outcp++ = 0;
1853 }
1854 }
1855
1856 /* Check that we have consumed all fuse bits */
1857 if (strlen(incp) != 0) {
1858 fprintf(stderr, "Invalid bitstream file\n");
1859 return (EXIT_FAILURE);
1860 }
1861
1862 jed_state++;
1863 }
1864
1865 /* Is this a comment line? */
1866 if (*inbuf == 'N') {
1867 if (jed_state == JED_INIT) {
1868 outcp += sprintf(outcp, "! %s\n", inbuf);
1869 *outcp++ = 0;
1870 }
1871 if (strncmp(inbuf, "NOTE DEVICE NAME:", 17) == 0) {
1872 incp = &inbuf[18];
1873 for (jed_dev = 0;
1874 jed_devices[jed_dev].name != NULL;
1875 jed_dev++) {
1876 if (strncmp(jed_devices[jed_dev].name,
1877 incp, strlen(
1878 jed_devices[jed_dev].name)) == 0)
1879 break;
1880 }
1881 if (jed_devices[jed_dev].name == NULL) {
1882 fprintf(stderr, "Bitstream for "
1883 "unsupported target: %s\n", incp);
1884 return (EXIT_FAILURE);
1885 }
1886 }
1887 incp = inbuf;
1888 continue;
1889 }
1890
1891 /* Packaging line? */
1892 if (*inbuf == 'Q') {
1893 i = atoi(&inbuf[2]);
1894 if (inbuf[1] == 'P') {
1895 if (jed_dev < 0 || jed_state != JED_INIT) {
1896 fprintf(stderr,
1897 "Invalid bitstream file\n");
1898 return (EXIT_FAILURE);
1899 }
1900 jed_state = JED_PACK_KNOWN;
1901 } else if (inbuf[1] == 'F') {
1902 if (jed_dev < 0 || jed_state != JED_PACK_KNOWN
1903 || jed_devices[jed_dev].fuses != i) {
1904 fprintf(stderr,
1905 "Invalid bitstream file\n");
1906 return (EXIT_FAILURE);
1907 }
1908 jed_state = JED_SIZE_KNOWN;
1909 } else {
1910 fprintf(stderr, "Invalid bitstream file\n");
1911 return (EXIT_FAILURE);
1912 }
1913 }
1914
1915 /* "F" line? */
1916 if (*inbuf == 'F') {
1917 if (jed_state != JED_SIZE_KNOWN) {
1918 fprintf(stderr, "Invalid bitstream file\n");
1919 return (EXIT_FAILURE);
1920 }
1921 jed_state = JED_PROG_INITIATED;
1922
1923 outcp += sprintf(outcp, "\n\n! Check the IDCODE\n\n");
1924 *outcp++ = 0;
1925 outcp += sprintf(outcp, "STATE RESET;\n");
1926 *outcp++ = 0;
1927 outcp += sprintf(outcp, "STATE IDLE;\n");
1928 *outcp++ = 0;
1929 outcp += sprintf(outcp, "SIR 8 TDI (16);\n");
1930 *outcp++ = 0;
1931 outcp += sprintf(outcp,
1932 "SDR 32 TDI (FFFFFFFF)\n");
1933 *outcp++ = 0;
1934 outcp += sprintf(outcp, " TDO (%08X)\n",
1935 jed_devices[jed_dev].id);
1936 *outcp++ = 0;
1937 outcp += sprintf(outcp,
1938 " MASK (FFFFFFFF);\n");
1939 *outcp++ = 0;
1940
1941 if (target == JED_TGT_SRAM) {
1942 outcp += sprintf(outcp,
1943 "\n\n! Program Bscan register\n\n");
1944 *outcp++ = 0;
1945 outcp += sprintf(outcp,
1946 "SIR 8 TDI (1C);\n");
1947 *outcp++ = 0;
1948 outcp += sprintf(outcp, "STATE DRPAUSE;\n");
1949 *outcp++ = 0;
1950 outcp += sprintf(outcp, "STATE IDLE;\n");
1951 *outcp++ = 0;
1952
1953 outcp += sprintf(outcp,
1954 "\n\n! Enable SRAM programming mode\n\n");
1955 *outcp++ = 0;
1956 outcp += sprintf(outcp,
1957 "SIR 8 TDI (55);\n");
1958 *outcp++ = 0;
1959 outcp += sprintf(outcp, "RUNTEST IDLE"
1960 " 3 TCK 1.00E-003 SEC;\n");
1961 *outcp++ = 0;
1962
1963 outcp += sprintf(outcp,
1964 "\n\n! Erase the device\n\n");
1965 *outcp++ = 0;
1966 outcp += sprintf(outcp,
1967 "SIR 8 TDI (03);\n");
1968 *outcp++ = 0;
1969 outcp += sprintf(outcp, "RUNTEST IDLE"
1970 " 3 TCK 1.00E-003 SEC;\n");
1971 *outcp++ = 0;
1972 } else {
1973 outcp += sprintf(outcp,
1974 "\n\n! Enable XPROGRAM mode\n\n");
1975 *outcp++ = 0;
1976 outcp += sprintf(outcp,
1977 "SIR 8 TDI (35);\n");
1978 *outcp++ = 0;
1979 outcp += sprintf(outcp, "RUNTEST IDLE"
1980 " 3 TCK 1.00E-003 SEC;\n");
1981 *outcp++ = 0;
1982
1983 outcp += sprintf(outcp,
1984 "\n\n! Check the Key Protection fuses\n\n");
1985 *outcp++ = 0;
1986
1987 outcp += sprintf(outcp,
1988 "SIR 8 TDI (B2);\n");
1989 *outcp++ = 0;
1990 outcp += sprintf(outcp, "RUNTEST IDLE"
1991 " 3 TCK 1.00E-003 SEC;\n");
1992 *outcp++ = 0;
1993 outcp += sprintf(outcp,
1994 "SDR 8 TDI (00)\n");
1995 *outcp++ = 0;
1996 outcp += sprintf(outcp,
1997 " TDO (00)\n");
1998 *outcp++ = 0;
1999 outcp += sprintf(outcp,
2000 " MASK (10);\n");
2001 *outcp++ = 0;
2002
2003 outcp += sprintf(outcp,
2004 "SIR 8 TDI (B2);\n");
2005 *outcp++ = 0;
2006 outcp += sprintf(outcp, "RUNTEST IDLE"
2007 " 3 TCK 1.00E-003 SEC;\n");
2008 *outcp++ = 0;
2009 outcp += sprintf(outcp,
2010 "SDR 8 TDI (00)\n");
2011 *outcp++ = 0;
2012 outcp += sprintf(outcp,
2013 " TDO (00)\n");
2014 *outcp++ = 0;
2015 outcp += sprintf(outcp,
2016 " MASK (40);\n");
2017 *outcp++ = 0;
2018
2019 outcp += sprintf(outcp,
2020 "SIR 8 TDI (B2);\n");
2021 *outcp++ = 0;
2022 outcp += sprintf(outcp, "RUNTEST IDLE"
2023 " 3 TCK 1.00E-003 SEC;\n");
2024 *outcp++ = 0;
2025 outcp += sprintf(outcp,
2026 "SDR 8 TDI (00)\n");
2027 *outcp++ = 0;
2028 outcp += sprintf(outcp,
2029 " TDO (00)\n");
2030 *outcp++ = 0;
2031 outcp += sprintf(outcp,
2032 " MASK (04);\n");
2033 *outcp++ = 0;
2034
2035 outcp += sprintf(outcp,
2036 "\n\n! Erase the device\n\n");
2037 *outcp++ = 0;
2038 outcp += sprintf(outcp,
2039 "SIR 8 TDI (03);\n");
2040 *outcp++ = 0;
2041 outcp += sprintf(outcp, "RUNTEST IDLE"
2042 " 3 TCK 1.20E+002 SEC;\n");
2043 *outcp++ = 0;
2044
2045 outcp += sprintf(outcp,
2046 "SIR 8 TDI (52);\n");
2047 *outcp++ = 0;
2048 outcp += sprintf(outcp,
2049 "SDR 1 TDI (0)\n");
2050 *outcp++ = 0;
2051 outcp += sprintf(outcp,
2052 " TDO (1);\n");
2053 *outcp++ = 0;
2054
2055 outcp += sprintf(outcp,
2056 "SIR 8 TDI (B2);\n");
2057 *outcp++ = 0;
2058 outcp += sprintf(outcp, "RUNTEST IDLE"
2059 " 3 TCK 1.00E-003 SEC;\n");
2060 *outcp++ = 0;
2061 outcp += sprintf(outcp,
2062 "SDR 8 TDI (00)\n");
2063 *outcp++ = 0;
2064 outcp += sprintf(outcp,
2065 " TDO (00)\n");
2066 *outcp++ = 0;
2067 outcp += sprintf(outcp,
2068 " MASK (01);\n");
2069 *outcp++ = 0;
2070 }
2071 }
2072
2073 /* "U" line? */
2074 if (*inbuf == 'U') {
2075 if (inbuf[1] != 'H' || jed_state != JED_HAVE_SED_CRC) {
2076 fprintf(stderr, "Invalid bitstream file\n");
2077 return (EXIT_FAILURE);
2078 }
2079
2080 outcp += sprintf(outcp, "\n\n! Program USERCODE\n\n");
2081 *outcp++ = 0;
2082 outcp += sprintf(outcp, "SIR 8 TDI (1A);\n");
2083 *outcp++ = 0;
2084 outcp += sprintf(outcp,
2085 "SDR 32 TDI (%s);\n", &inbuf[2]);
2086 *outcp++ = 0;
2087 outcp += sprintf(outcp,
2088 "RUNTEST IDLE 3 TCK 1.00E-002 SEC;\n");
2089 *outcp++ = 0;
2090
2091 if (target == JED_TGT_FLASH) {
2092 outcp += sprintf(outcp,
2093 "\n\n! Read the status bit;\n\n");
2094 *outcp++ = 0;
2095 outcp += sprintf(outcp,
2096 "SIR 8 TDI (B2);\n");
2097 *outcp++ = 0;
2098 outcp += sprintf(outcp, "RUNTEST IDLE"
2099 " 3 TCK 1.00E-003 SEC;\n");
2100 *outcp++ = 0;
2101 outcp += sprintf(outcp,
2102 "SDR 8 TDI (00)\n");
2103 *outcp++ = 0;
2104 outcp += sprintf(outcp,
2105 " TDO (00)\n");
2106 *outcp++ = 0;
2107 outcp += sprintf(outcp,
2108 " MASK (01);\n");
2109 *outcp++ = 0;
2110 }
2111
2112 outcp += sprintf(outcp,
2113 "\n\n! Program and Verify 32 bits SED_CRC\n\n");
2114 *outcp++ = 0;
2115 outcp += sprintf(outcp, "SIR 8 TDI (45);\n");
2116 *outcp++ = 0;
2117 outcp += sprintf(outcp,
2118 "SDR 32 TDI (%s);\n", tmpbuf);
2119 *outcp++ = 0;
2120 outcp += sprintf(outcp,
2121 "RUNTEST IDLE 3 TCK 1.00E-002 SEC;\n");
2122 *outcp++ = 0;
2123
2124 outcp += sprintf(outcp, "SIR 8 TDI (44);\n");
2125 *outcp++ = 0;
2126 outcp += sprintf(outcp,
2127 "RUNTEST IDLE 3 TCK 1.00E-003 SEC;\n");
2128 *outcp++ = 0;
2129
2130 outcp += sprintf(outcp,
2131 "SDR 32 TDI (00000000)\n");
2132 *outcp++ = 0;
2133 outcp += sprintf(outcp,
2134 " TDO (%s);\n", tmpbuf);
2135 *outcp++ = 0;
2136
2137 outcp += sprintf(outcp, "SIR 8 TDI (B2);\n");
2138 *outcp++ = 0;
2139 outcp += sprintf(outcp,
2140 "RUNTEST IDLE 3 TCK 1.00E-003 SEC;\n");
2141 *outcp++ = 0;
2142 outcp += sprintf(outcp, "SDR 8 TDI (00)\n");
2143 *outcp++ = 0;
2144 outcp += sprintf(outcp, " TDO (00)\n");
2145 *outcp++ = 0;
2146 outcp += sprintf(outcp, " MASK (01);\n");
2147 *outcp++ = 0;
2148
2149 outcp += sprintf(outcp,
2150 "\n\n! Program DONE bit\n\n");
2151 *outcp++ = 0;
2152 outcp += sprintf(outcp, "SIR 8 TDI (2F);\n");
2153 *outcp++ = 0;
2154 if (target == JED_TGT_FLASH) {
2155 outcp += sprintf(outcp, "RUNTEST IDLE"
2156 " 3 TCK 2.00E-001 SEC;\n");
2157 } else {
2158 outcp += sprintf(outcp, "RUNTEST IDLE"
2159 " 3 TCK;\n");
2160 }
2161 *outcp++ = 0;
2162 outcp += sprintf(outcp, "SIR 8 TDI (B2);\n");
2163 *outcp++ = 0;
2164 outcp += sprintf(outcp,
2165 "RUNTEST IDLE 3 TCK 1.00E-003 SEC;\n");
2166 *outcp++ = 0;
2167 outcp += sprintf(outcp, "SDR 8 TDI (00)\n");
2168 *outcp++ = 0;
2169 outcp += sprintf(outcp, " TDO (02)\n");
2170 *outcp++ = 0;
2171 outcp += sprintf(outcp, " MASK (03);\n");
2172 *outcp++ = 0;
2173
2174 if (target == JED_TGT_FLASH) {
2175 outcp += sprintf(outcp,
2176 "\n\n! Verify DONE bit\n\n");
2177 *outcp++ = 0;
2178 outcp += sprintf(outcp,
2179 "SIR 8 TDI (B2)\n");
2180 *outcp++ = 0;
2181 outcp += sprintf(outcp,
2182 " TDO (FF)\n");
2183 *outcp++ = 0;
2184 outcp += sprintf(outcp,
2185 " MASK (04);\n");
2186 *outcp++ = 0;
2187 }
2188
2189 outcp += sprintf(outcp,
2190 "\n\n! Exit the programming mode\n\n");
2191 *outcp++ = 0;
2192 outcp += sprintf(outcp, "SIR 8 TDI (1E);\n");
2193 *outcp++ = 0;
2194 outcp += sprintf(outcp,
2195 "RUNTEST IDLE 3 TCK 2.00E-003 SEC;\n");
2196 *outcp++ = 0;
2197 outcp += sprintf(outcp, "SIR 8 TDI (FF);\n");
2198 *outcp++ = 0;
2199 outcp += sprintf(outcp,
2200 "RUNTEST IDLE 3 TCK 1.00E-003 SEC;\n");
2201 *outcp++ = 0;
2202 outcp += sprintf(outcp,
2203 "STATE RESET;\n");
2204 *outcp++ = 0;
2205 }
2206
2207 incp = inbuf;
2208 }
2209 fclose(fd);
2210
2211 /* Count number of lines in outbuf, store in j */
2212 for (i = 0, j = 0; outcp > outbuf; outcp--)
2213 if (*outcp == 0)
2214 j++;
2215
2216 if (svf_name) {
2217 int of;
2218
2219 if (strncmp(svf_name, "-", 1) == 0)
2220 of = 0;
2221 else
2222 of = open(svf_name, O_RDWR | O_CREAT | O_TRUNC, 0644);
2223 if (of < 0) {
2224 res = errno;
2225 goto done;
2226 }
2227 res = 0;
2228 for (i = 0, outcp = outbuf; i < j; i++) {
2229 write(of, outcp, strlen(outcp));
2230 outcp += (strlen(outcp) + 1);
2231 }
2232 if (of)
2233 close(of);
2234 } else
2235 res = exec_svf_mem(outbuf, j, debug);
2236
2237 done:
2238 free(outbuf);
2239 free(inbuf);
2240 return (res);
2241 }
2242
2243
2244 #define bitrev(a) ((a & 0x1) << 7) | ((a & 0x2) << 5) | ((a & 0x4) << 3) | ((a & 0x8) << 1) | ((a & 0x10) >> 1) | ((a & 0x20) >> 3) | ((a & 0x40) >> 5) | ((a & 0x80) >> 7)
2245
2246 #define buf_sprintf(p, ...) do { \
2247 (p) += sprintf((p), ## __VA_ARGS__); \
2248 *(p)++ = 0; \
2249 } while (0)
2250
2251 /*
2252 * Parse a Lattice ECP5 bitstream file and convert it into a SVF stream,
2253 * stored in a contiguos chunk of memory. If parsing is sucessfull proceed
2254 * with calling exec_svf_mem().
2255 */
2256 static int
exec_bit_file(char * path,int jed_target,int debug)2257 exec_bit_file(char *path, int jed_target, int debug)
2258 {
2259 uint8_t *inbuf;
2260 char *outbuf, *op;
2261 char *outcp;
2262 FILE *fd;
2263 long flen, got;
2264 uint32_t idcode;
2265 int i, j, n, addr;
2266 int row_size = 64000 / 8;
2267 int hexlen = 50;
2268 int res;
2269
2270 fd = fopen(path, "rb");
2271 if (fd == NULL) {
2272 fprintf(stderr, "open(%s) failed\n", path);
2273 return (EXIT_FAILURE);
2274 }
2275
2276 fseek(fd, 0, SEEK_END);
2277 flen = ftell(fd);
2278 fseek(fd, 0, SEEK_SET);
2279
2280 inbuf = malloc(flen);
2281 outbuf = malloc(flen * 4); /* XXX rough estimate */
2282 if (inbuf == NULL || outbuf == NULL) {
2283 fprintf(stderr, "malloc(%ld) failed\n", flen);
2284 return (EXIT_FAILURE);
2285 }
2286 op = outbuf;
2287
2288 got = fread(inbuf, 1, flen, fd);
2289 if (got != flen) {
2290 fprintf(stderr, "short read: %ld instead of %ld\n",
2291 got, flen);
2292 return (EXIT_FAILURE);
2293 }
2294
2295 buf_sprintf(op, "STATE IDLE;\n");
2296 buf_sprintf(op, "STATE RESET;\n");
2297 buf_sprintf(op, "STATE IDLE;\n\n");
2298
2299 if (strcasecmp(&path[strlen(path) - 4], ".img") != 0) {
2300 /* Search for bitstream preamble and IDCODE markers */
2301 for (i = 0, j = 0; i < flen - 32 && i < 2000; i++)
2302 if (inbuf[i] == 0xbd && inbuf[i + 1] == 0xb3
2303 && inbuf[i + 10] == 0xe2 && inbuf[i + 11] == 0
2304 && inbuf[i + 12] == 0 && inbuf[i + 13] == 0) {
2305 j = i;
2306 break;
2307 }
2308 if (j == 0) {
2309 fprintf(stderr,
2310 "can't find IDCODE, invalid bitstream\n");
2311 return (EXIT_FAILURE);
2312 }
2313 idcode = inbuf[i + 14] << 24;
2314 idcode += inbuf[i + 15] << 16;
2315 idcode += inbuf[i + 16] << 8;
2316 idcode += inbuf[i + 17];
2317
2318 /* IDCODE_PUB(0xE0): check IDCODE */
2319 buf_sprintf(op, "SIR 8 TDI (E0);\n");
2320 buf_sprintf(op, "SDR 32 TDI (00000000)\n");
2321 buf_sprintf(op, " TDO (%08X)\n", idcode);
2322 buf_sprintf(op, " MASK (FFFFFFFF);\n\n");
2323 }
2324
2325 /* LSC_PRELOAD(0x1C): Program Bscan register */
2326 buf_sprintf(op, "SIR 8 TDI (1C);\n");
2327 buf_sprintf(op, "SDR 510 TDI (3FFFFFFFFFFFFFF"
2328 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
2329 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);\n\n");
2330
2331 /* ISC ENABLE(0xC6): Enable SRAM programming mode */
2332 buf_sprintf(op, "SIR 8 TDI (C6);\n");
2333 buf_sprintf(op, "SDR 8 TDI (00);\n");
2334 buf_sprintf(op, "RUNTEST IDLE 2 TCK;\n\n");
2335
2336 /* ISC ERASE(0x0e): Erase the SRAM */
2337 buf_sprintf(op, "SIR 8 TDI (0e);\n");
2338 buf_sprintf(op, "SDR 8 TDI (01);\n");
2339 buf_sprintf(op, "RUNTEST IDLE 32 TCK 1.00E-01 SEC;\n\n");
2340
2341 /* LSC_READ_STATUS(0x3c) */
2342 buf_sprintf(op, "SIR 8 TDI (3C);\n");
2343 buf_sprintf(op, "SDR 32 TDI (00000000)\n");
2344 buf_sprintf(op, " TDO (00000000)\n");
2345 buf_sprintf(op, " MASK (0000B000);\n\n");
2346
2347 if (jed_target == JED_TGT_FLASH) {
2348 buf_sprintf(op, "STATE RESET;\n");
2349 buf_sprintf(op, "STATE IDLE;\n");
2350
2351 /* BYPASS(0xFF) */
2352 buf_sprintf(op, "SIR 8 TDI(FF);\n");
2353 buf_sprintf(op, "RUNTEST IDLE 32 TCK;\n");
2354
2355 /* LSC_PROG_SPI(0x3A) */
2356 buf_sprintf(op, "SIR 8 TDI(3A);\n");
2357 buf_sprintf(op, "SDR 16 TDI(68FE);\n");
2358 buf_sprintf(op, "RUNTEST IDLE 32 TCK;\n\n");
2359
2360 /* Erase sectors */
2361 for (i = 0; i < flen; i += SPI_SECTOR_SIZE) {
2362 addr = i + spi_addr;
2363
2364 /* SPI write enable */
2365 buf_sprintf(op, "SDR 8 TDI(60);\n");
2366
2367 /* Read status register (some chips won't clear WIP without this) */
2368 buf_sprintf(op, "SDR 16 TDI(00A0)\n");
2369 buf_sprintf(op, " TDO(40FF)\n");
2370 buf_sprintf(op, " MASK(C100);\n\n");
2371
2372 buf_sprintf(op, "SDR 32 TDI(0000%02x1B);\n",
2373 bitrev(addr / SPI_SECTOR_SIZE));
2374 buf_sprintf(op, "RUNTEST DRPAUSE 5.50E-01 SEC;\n");
2375
2376 /* Read status register */
2377 buf_sprintf(op, "SDR 16 TDI(00A0)\n");
2378 buf_sprintf(op, " TDO(00FF)\n");
2379 buf_sprintf(op, " MASK(C100);\n\n");
2380 }
2381
2382 /* SPI write disable */
2383 buf_sprintf(op, "SDR 8 TDI(20);\n\n");
2384
2385 row_size = SPI_PAGE_SIZE;
2386 } else {
2387 /* LSC_INIT_ADDRESS(0x46) */
2388 buf_sprintf(op, "SIR 8 TDI (46);\n");
2389 buf_sprintf(op, "SDR 8 TDI (01);\n");
2390 buf_sprintf(op, "RUNTEST IDLE 2 TCK;\n\n");
2391
2392 /* LSC_BITSTREAM_BURST(0x7a) */
2393 buf_sprintf(op, "SIR 8 TDI (7A);\n");
2394 buf_sprintf(op, "RUNTEST IDLE 2 TCK;\n\n");
2395 }
2396
2397 for (i = 0; i < flen; i += row_size) {
2398 n = flen - i;
2399 if (n > row_size)
2400 n = row_size;
2401 if (jed_target == JED_TGT_FLASH) {
2402 /* Skip write if all bits set in a block */
2403 for (j = 0; j < n; j++)
2404 if (inbuf[i + j] != 0xff)
2405 break;
2406 if (j == n)
2407 continue;
2408
2409 buf_sprintf(op, "SDR 8 TDI(60);\n");
2410 buf_sprintf(op, "SDR %d TDI (", n * 8 + 32);
2411 } else
2412 buf_sprintf(op, "SDR %d TDI (", n * 8);
2413 do {
2414 n--;
2415 op += sprintf(op, "%02X", bitrev(inbuf[i + n]));
2416 if (n % hexlen == 0 && n > 0)
2417 buf_sprintf(op, "\n\t");
2418 } while (n > 0);
2419 if (jed_target == JED_TGT_FLASH) {
2420 addr = i + spi_addr;
2421
2422 buf_sprintf(op, "%02x%02x%02x40);\n\n",
2423 bitrev(addr % 256), bitrev((addr / 256) % 256),
2424 bitrev((addr / 65536) % 256));
2425 buf_sprintf(op, "RUNTEST DRPAUSE 2.00E-03 SEC;\n");
2426 buf_sprintf(op, "SDR 16 TDI(00A0)\n");
2427 buf_sprintf(op, " TDO(00FF)\n");
2428 buf_sprintf(op, " MASK(C100);\n\n");
2429 } else
2430 buf_sprintf(op, ");\n\n");
2431 }
2432
2433 /* BYPASS(0xFF) */
2434 buf_sprintf(op, "SIR 8 TDI (FF);\n");
2435 buf_sprintf(op, "RUNTEST IDLE 100 TCK;\n\n");
2436
2437 /* ISC DISABLE(Ox26): exit the programming mode */
2438 buf_sprintf(op, "SIR 8 TDI (26);\n");
2439 buf_sprintf(op, "RUNTEST IDLE 2 TCK 2.00E-03 SEC;\n\n");
2440 buf_sprintf(op, "SIR 8 TDI (FF);\n");
2441 buf_sprintf(op, "RUNTEST IDLE 2 TCK 1.00E-03 SEC;\n\n");
2442
2443 if (jed_target == JED_TGT_FLASH) {
2444 /* LSC_REFRESH(0x79) */
2445 buf_sprintf(op, "SIR 8 TDI (79);\n");
2446 buf_sprintf(op, "SDR 24 TDI (000000);\n");
2447 buf_sprintf(op, "RUNTEST IDLE 2 TCK 1.00E-01 SEC;\n\n");
2448 } else {
2449 /* LSC_READ_STATUS(0x3c): verify status register */
2450 buf_sprintf(op, "SIR 8 TDI (3C);\n");
2451 buf_sprintf(op, "SDR 32 TDI (00000000)\n");
2452 buf_sprintf(op, " TDO (00000100)\n");
2453 buf_sprintf(op, " MASK (00002100);\n\n");
2454 }
2455 op--;
2456 i = 0;
2457 do {
2458 if (*op == '\n')
2459 i++;
2460 } while (op-- != outbuf);
2461
2462 if (svf_name) {
2463 int of;
2464
2465 if (strncmp(svf_name, "-", 1) == 0)
2466 of = 0;
2467 else
2468 of = open(svf_name, O_RDWR | O_CREAT | O_TRUNC, 0644);
2469 if (of < 0) {
2470 res = errno;
2471 return(res);
2472 }
2473 res = 0;
2474 for (j = 0, outcp = outbuf; j < i; j++) {
2475 write(of, outcp, strlen(outcp));
2476 outcp += (strlen(outcp) + 1);
2477 }
2478 if (of)
2479 close(of);
2480 } else
2481 res = exec_svf_mem(outbuf, i, debug);
2482
2483 free(outbuf);
2484 free(inbuf);
2485 return (res);
2486 }
2487
2488
2489 /*
2490 * Load a SVF file in a contiguos chunk of memory, count number of lines,
2491 * and then call exec_svf_mem().
2492 */
2493 static int
exec_svf_file(char * path,int debug)2494 exec_svf_file(char *path, int debug)
2495 {
2496 char *linebuf, *fbuf;
2497 FILE *fd;
2498 long flen;
2499 int lines_tot = 1;
2500 int res;
2501
2502 fd = fopen(path, "r");
2503 if (fd == NULL) {
2504 fprintf(stderr, "open(%s) failed\n", path);
2505 return (EXIT_FAILURE);
2506 }
2507
2508 fseek(fd, 0, SEEK_END);
2509 flen = 2 * ftell(fd);
2510 fseek(fd, 0, SEEK_SET);
2511
2512 fbuf = malloc(flen);
2513 if (fbuf == NULL) {
2514 fprintf(stderr, "malloc(%ld) failed\n", flen);
2515 return (EXIT_FAILURE);
2516 }
2517
2518 for (linebuf = fbuf; !feof(fd); linebuf += strlen(linebuf) + 1) {
2519 if (fgets(linebuf, flen, fd) == NULL)
2520 break;
2521 lines_tot++;
2522 flen -= strlen(linebuf) + 1;
2523 }
2524 fclose(fd);
2525 *linebuf = 0;
2526
2527 res = exec_svf_mem(fbuf, lines_tot, debug);
2528 free(fbuf);
2529 return (res);
2530 }
2531
2532
2533 /*
2534 * Parse SVF command lines stored in a contiguos chunk of memory and
2535 * execute appropriate JTAG actions, line by line, all in a single pass.
2536 */
2537 static int
exec_svf_mem(char * fbuf,int lines_tot,int debug)2538 exec_svf_mem(char *fbuf, int lines_tot, int debug)
2539 {
2540 char cmdbuf[128 * 1024];
2541 int lno, tokc, cmd_complete, parentheses_open;
2542 int res = 0;
2543 int llen = 0;
2544 char *cp, *c1;
2545 char *sep = " \t\n\r";
2546 char *linebuf, *item, *brkt;
2547 char *tokv[256];
2548
2549 cp = cmdbuf;
2550 cmd_complete = 0;
2551 parentheses_open = 0;
2552 linebuf = fbuf;
2553
2554 for (lno = 1; lno < lines_tot; lno++, linebuf += llen) {
2555 if (debug)
2556 printf("%d: %s", lno, linebuf);
2557
2558 llen = strlen(linebuf) + 1;
2559 progress_perc = lno * 1005 / (lines_tot * 10);
2560
2561 /* Pre-parse input, join multiple lines to a single command */
2562 for (item = strtok_r(linebuf, sep, &brkt); item;
2563 item = strtok_r(NULL, sep, &brkt)) {
2564 /* Skip comments */
2565 if (item[0] == '!')
2566 break;
2567 if (item[0] == '/' && item[1] == '/')
2568 break;
2569
2570 /* If command is complete we shouldn't end up here! */
2571 if (cmd_complete) {
2572 fprintf(stderr, "Line %d: multiple commands "
2573 "on single line\n", lno);
2574 return (EXIT_FAILURE);
2575 }
2576
2577 /* End of command? */
2578 c1 = item + strlen(item) - 1;
2579 if (*c1 == ';') {
2580 *c1-- = 0;
2581 cmd_complete = 1;
2582 }
2583
2584 /* Check for parentheses */
2585 if (*item == '(') {
2586 item++;
2587 if (parentheses_open) {
2588 fprintf(stderr,
2589 "Line %d: too many '('s\n", lno);
2590 return (EXIT_FAILURE);
2591 }
2592 parentheses_open = 1;
2593 }
2594 if (!parentheses_open)
2595 for (char *ct = item; ct < c1; ct++)
2596 if (*ct == '(') {
2597 *ct = ' ';
2598 parentheses_open = 1;
2599 break;
2600 }
2601 if (*c1 == ')') {
2602 *c1 = 0;
2603 if (!parentheses_open) {
2604 fprintf(stderr,
2605 "Line %d: too many ')'s\n", lno);
2606 return (EXIT_FAILURE);
2607 }
2608 parentheses_open = 0;
2609 }
2610
2611 /* Copy to command buffer */
2612 strcpy(cp, item);
2613 cp += strlen(item);
2614 if (!parentheses_open && !cmd_complete)
2615 *cp++ = ' ';
2616 }
2617
2618 /* Proceed to next line if command is not complete yet */
2619 if (!cmd_complete)
2620 continue;
2621
2622 /* Unmatched parentheses are not permitted */
2623 if (parentheses_open) {
2624 fprintf(stderr, "Line %d: missing ')'\n", lno);
2625 return (EXIT_FAILURE);
2626 }
2627
2628 /* Normalize to all upper case letters, separate tokens */
2629 tokc = 0;
2630 tokv[0] = cmdbuf;
2631 for (cp = cmdbuf; *cp != 0; cp++) {
2632 if (*cp == ' ') {
2633 *cp++ = 0;
2634 tokc++;
2635 tokv[tokc] = cp;
2636 }
2637 *cp = toupper(*cp);
2638 }
2639 if (*tokv[tokc] != 0)
2640 tokc++;
2641
2642 /* Execute command */
2643 res = exec_svf_tokenized(tokc, tokv);
2644 if (res) {
2645 if (res != ENODEV)
2646 fprintf(stderr, "Line %d: %s\n", lno,
2647 strerror(res));
2648 return (res);
2649 }
2650
2651 cp = cmdbuf;
2652 cmd_complete = 0;
2653 }
2654
2655 /* Flush any buffered data */
2656 commit(1);
2657
2658 return (res);
2659 }
2660
2661
2662 static void
terminal_help(void)2663 terminal_help(void)
2664 {
2665
2666 printf(
2667 " ~> send file\n"
2668 " ~b change baudrate\n"
2669 " ~r reprogram / reload "
2670 "the FPGA\n"
2671 " ~# send a BREAK signal\n"
2672 " ~d enter f32c debugger\n"
2673 " ~. exit from ujprog\n"
2674 " ~? get this summary\n"
2675 );
2676 }
2677
2678
2679 static void
usage(void)2680 usage(void)
2681 {
2682
2683 printf("Usage: ujprog [option(s)] [bitstream_file]\n\n");
2684
2685 printf(" Valid options:\n");
2686 #ifdef USE_PPI
2687 printf(" -c CABLE Select USB (default) or PPI JTAG CABLE\n");
2688 #endif
2689 printf(" -p PORT Select USB JTAG / UART PORT (default is 0)\n");
2690 #ifdef WIN32
2691 printf(" -P COM Select COM port (valid only with -t or -a)\n");
2692 #else
2693 printf(" -P TTY Select TTY port (valid only with -t or -a)\n");
2694 #endif
2695 printf(" -j TARGET Select bitstream TARGET as SRAM (default)"
2696 " or FLASH\n");
2697 printf(" -f ADDR Start writing to SPI flash at ADDR, "
2698 "optional with -j flash\n");
2699 printf(" -s FILE Convert bitstream to SVF FILE and exit\n");
2700 printf(" -r Reload FPGA configuration from"
2701 " FLASH\n");
2702 printf(" -t Enter terminal emulation mode after"
2703 " completing JTAG operations\n");
2704 printf(" -b SPEED Set baudrate to SPEED (300 to 3000000"
2705 " bauds)\n");
2706 printf(" -e FILE Send and execute a f32c (MIPS/RISCV) binary "
2707 "FILE\n");
2708 printf(" -x SPEED Set binary transfer speed, optional with -e\n");
2709 printf(" -a FILE Send a raw FILE\n");
2710 printf(" -d debug (verbose)\n");
2711 printf(" -D DELAY Delay transmission of each byte by"
2712 " DELAY ms\n");
2713 printf(" -q Suppress messages\n");
2714
2715 if (terminal) {
2716 printf("\n Terminal emulation mode commands:\n");
2717 terminal_help();
2718 }
2719 #ifndef WIN32
2720 printf("\n");
2721 #endif
2722 }
2723
2724
2725 static int
gets1(char * cp,int size)2726 gets1(char *cp, int size)
2727 {
2728 char *lp, *end;
2729 char c;
2730 int error = 0;
2731
2732 lp = cp;
2733 end = cp + size - 1;
2734 for (;;) {
2735 #ifdef WIN32
2736 c = getch() & 0177;
2737 #else
2738 while (read(0, &c, 1) < 0)
2739 ms_sleep(10);
2740 #endif
2741 switch (c) {
2742 case 3: /* CTRL + C */
2743 error = -1;
2744 case '\n':
2745 case '\r':
2746 printf("\n");
2747 *lp = '\0';
2748 return (error);
2749 case '\b':
2750 case '\177':
2751 if (lp > cp) {
2752 printf("%c \b", c);
2753 fflush(stdout);
2754 lp--;
2755 }
2756 continue;
2757 case '\0':
2758 continue;
2759 default:
2760 if (lp < end) {
2761 printf("%c", c);
2762 fflush(stdout);
2763 *lp++ = c;
2764 }
2765 }
2766 }
2767 }
2768
2769
2770 static int
prog(char * fname,int target,int debug)2771 prog(char *fname, int target, int debug)
2772 {
2773 int res, c, tstart, tend;
2774
2775 tstart = ms_uptime();
2776 last_ledblink_ms = tstart;
2777
2778 /* Move TAP into RESET state. */
2779 set_port_mode(PORT_MODE_ASYNC);
2780 set_state(RESET);
2781
2782 commit(1);
2783
2784 c = strlen(fname) - 4;
2785 if (c < 0) {
2786 usage();
2787 exit(EXIT_FAILURE);
2788 }
2789 if (strcasecmp(&fname[c], ".jed") == 0)
2790 res = exec_jedec_file(fname, target, debug);
2791 else if (strcasecmp(&fname[c], ".bit") == 0 ||
2792 (strcasecmp(&fname[c], ".img") == 0 && target == JED_TGT_FLASH))
2793 res = exec_bit_file(fname, target, debug);
2794 else if (strcasecmp(&fname[c], ".svf") == 0)
2795 res = exec_svf_file(fname, debug);
2796 else
2797 res = -1;
2798
2799 /* Leave TAP in RESET state. */
2800 set_port_mode(PORT_MODE_ASYNC);
2801 set_state(IDLE);
2802 set_state(RESET);
2803 commit(1);
2804
2805 tend = ms_uptime();
2806 if (res == 0) {
2807 if (!quiet) {
2808 fprintf(stderr, "\rProgramming: 100%% ");
2809 fprintf(stderr, "\nCompleted in %.2f seconds.\n",
2810 (tend - tstart) / 1000.0);
2811 }
2812 } else
2813 fprintf(stderr, "\nFailed.\n");
2814
2815 return (res);
2816 }
2817
2818
2819 #if 0
2820 static void
2821 reload_xp2_flash(int debug)
2822 {
2823 char buf[128];
2824 char *c;
2825
2826 if (!quiet)
2827 printf("Reconfiguring FPGA...\n");
2828 last_ledblink_ms = ms_uptime();
2829 need_led_blink = 0;
2830
2831 /* Move TAP into RESET state. */
2832 set_port_mode(PORT_MODE_SYNC);
2833 set_state(IDLE);
2834 set_state(RESET);
2835 commit(1);
2836
2837 /* Reset sequence */
2838 c = buf;
2839 c += sprintf(c, "RUNTEST IDLE 30 TCK;\n");
2840 *c++ = 0;
2841 c += sprintf(c, "SIR 8 TDI (1E);\n");
2842 *c++ = 0;
2843 c += sprintf(c, "SIR 8 TDI (23);\n");
2844 *c++ = 0;
2845 c += sprintf(c, "!\n");
2846 exec_svf_mem(buf, 4, debug);
2847
2848 /* Leave TAP in RESET state. */
2849 set_state(IDLE);
2850 set_state(RESET);
2851 commit(1);
2852 }
2853 #endif
2854
2855
2856 static int
async_read_block(int len)2857 async_read_block(int len)
2858 {
2859 int res, got = 0, backoff = 0, backoff_lim = 5;
2860 int i;
2861 #if defined(__FreeBSD__) || defined(__linux__)
2862 if (cable_hw == CABLE_HW_COM)
2863 backoff_lim = 10;
2864 #endif
2865 do {
2866 if (cable_hw == CABLE_HW_USB) {
2867 #ifdef WIN32
2868 DWORD ev_stat, avail;
2869 FT_GetStatus(ftHandle, &avail, &ev_stat, &ev_stat);
2870 if (avail > len - got)
2871 avail = len - got;
2872 if (avail)
2873 FT_Read(ftHandle, &rxbuf[got], avail,
2874 (DWORD *) &res);
2875 else
2876 res = 0;
2877 #else
2878 res = ftdi_read_data(&fc, &rxbuf[got], len - got);
2879 #endif
2880 } else {
2881 #ifdef WIN32
2882 DWORD n;
2883 n = len - got;
2884 if (n > 32)
2885 n = 32;
2886 ReadFile(com_port, &rxbuf[got], n,
2887 (DWORD *) &res, NULL);
2888 #else
2889 res = read(com_port, &rxbuf[got], len - got);
2890 if (res == -1)
2891 res = 0;
2892 #endif
2893 }
2894 if (res > 0) {
2895 got += res;
2896 backoff = 0;
2897 } else {
2898 backoff++;
2899 ms_sleep(backoff * 4);
2900 }
2901 } while (got < len && backoff < backoff_lim);
2902 if(global_debug)
2903 {
2904 fprintf(stderr, "<");
2905 for(i = 0; i < got; i++)
2906 fprintf(stderr, " %02x", rxbuf[i]);
2907 fprintf(stderr, "\n");
2908 }
2909 return (got);
2910 }
2911
2912
2913 static int
async_send_block(int len)2914 async_send_block(int len)
2915 {
2916 int sent;
2917 int i;
2918
2919 if (cable_hw == CABLE_HW_USB) {
2920 #ifdef WIN32
2921 FT_Write(ftHandle, txbuf, len, (DWORD *) &sent);
2922 #else
2923 sent = ftdi_write_data(&fc, txbuf, len);
2924 #endif
2925 } else {
2926 #ifdef WIN32
2927 WriteFile(com_port, txbuf, len, (DWORD *) &sent, NULL);
2928 #else
2929 fcntl(com_port, F_SETFL, 0);
2930 sent = write(com_port, txbuf, len);
2931 tcdrain(com_port); // flush data to hardware
2932 fcntl(com_port, F_SETFL, O_NONBLOCK);
2933 #endif
2934 }
2935 if(global_debug)
2936 {
2937 fprintf(stderr, ">");
2938 for(i = 0; i < sent && i < 20; i++)
2939 fprintf(stderr, " %02x", txbuf[i]);
2940 if(sent >= 20)
2941 fprintf(stderr, "...");
2942 fprintf(stderr, "\n");
2943 }
2944 if (sent == len)
2945 return (0);
2946 else
2947 return (1);
2948 }
2949
2950
2951 static void
async_send_uint8(uint32_t data)2952 async_send_uint8(uint32_t data)
2953 {
2954
2955 txbuf[0] = data;
2956 async_send_block(1);
2957 }
2958
2959
2960 static void
async_send_uint32(uint32_t data)2961 async_send_uint32(uint32_t data)
2962 {
2963 int i;
2964
2965 for (i = 0; i < 4; i++) {
2966 txbuf[i] = (data >> 24);
2967 data <<= 8;
2968 }
2969 async_send_block(4);
2970 }
2971
2972
2973 static int
async_set_baudrate(int speed)2974 async_set_baudrate(int speed)
2975 {
2976
2977 if (cable_hw == CABLE_HW_USB) {
2978 #ifdef WIN32
2979 FT_SetBaudRate(ftHandle, speed);
2980 #else
2981 ftdi_set_baudrate(&fc, speed);
2982 #endif
2983 } else {
2984 #ifdef WIN32
2985 if (GetCommState(com_port, &tty) == 0) {
2986 fprintf(stderr, "%s is not a COM port\n", com_name);
2987 exit(EXIT_FAILURE);
2988 }
2989 tty.BaudRate = speed;
2990 tty.StopBits = 0;
2991 tty.Parity = 0;
2992 tty.ByteSize = 8;
2993 if (SetCommState(com_port, &tty) == 0) {
2994 fprintf(stderr, "Can't set baudrate to %d\n", speed);
2995 exit(EXIT_FAILURE);
2996 }
2997 #else
2998 cfsetspeed(&tty, speed);
2999 if (tcsetattr(com_port, TCSAFLUSH, &tty) != 0) {
3000 fprintf(stderr, "Can't set baudrate to %d\n", speed);
3001 exit(EXIT_FAILURE);
3002 }
3003 #endif
3004 }
3005 return (0);
3006 }
3007
3008
3009 static void
txfile(void)3010 txfile(void)
3011 {
3012 int tx_cnt, i, infile, res;
3013 int crc_retry;
3014 int tx_retry, tx_success;
3015 uint32_t rx_crc, local_crc, crc_i;
3016 uint32_t base, bootaddr;
3017 FILE *fd;
3018 uint8_t hdrbuf[16];
3019
3020 if (tx_binary) {
3021 fd = fopen(txfname, "r");
3022 if (fd == NULL) {
3023 fprintf(stderr, "%s: cannot open\n", txfname);
3024 return;
3025 }
3026 i = fread(hdrbuf, 1, 16, fd);
3027 fseek(fd, 0, SEEK_END);
3028 // len = ftell(fd);
3029 fseek(fd, 0, SEEK_SET);
3030 fclose(fd);
3031 if (i != 16) {
3032 fprintf(stderr, "%s: short read\n", txfname);
3033 return;
3034 }
3035 if (hdrbuf[2] == 0x10 && hdrbuf[3] == 0x3c &&
3036 hdrbuf[6] == 0x10 && hdrbuf[7] == 0x26 &&
3037 hdrbuf[10] == 0x11 && hdrbuf[11] == 0x3c &&
3038 hdrbuf[14] == 0x31 && hdrbuf[7] == 0x26) {
3039 /* MIPS, little-endian cookie found */
3040 base = (hdrbuf[1] << 24) + (hdrbuf[0] << 16)
3041 + (hdrbuf[5] << 8) + hdrbuf[4];
3042 if (!quiet)
3043 printf("MIPS little-endian");
3044 } else if (hdrbuf[2] == 0x10 && hdrbuf[3] == 0x3c &&
3045 hdrbuf[6] == 0x10 && hdrbuf[7] == 0x26 &&
3046 hdrbuf[10] == 0x11 && hdrbuf[11] == 0x3c) {
3047 /* MIPS, big-endian cookie found */
3048 /* XXX fixme */
3049 fprintf(stderr, "%s: MIPS, big-endian UNSUPPORTED\n",
3050 txfname);
3051 return;
3052 } else if ((hdrbuf[1] & 0xf) == 1 && hdrbuf[0] == 0x97 &&
3053 hdrbuf[4] == 0x93 && hdrbuf[5] == 0x81) {
3054 /* RISC-V, little-endian cookie found */
3055 /* XXX hardcoded load address - fixme */
3056 base = 0x400;
3057 if (!quiet)
3058 printf("RISC-V (PIC)");
3059 } else {
3060 fprintf(stderr,
3061 "invalid file type, missing header cookie\n");
3062 return;
3063 }
3064 bootaddr = base;
3065 if (!quiet)
3066 printf(" binary, loading at 0x%08x, "
3067 "TX speed %d bauds\n", base, xbauds);
3068 }
3069
3070 infile = open(txfname,
3071 #ifdef WIN32
3072 O_RDONLY | O_BINARY
3073 #else
3074 O_RDONLY
3075 #endif
3076 );
3077 if (infile < 0) {
3078 fprintf(stderr, "%s: cannot open\n", txfname);
3079 return;
3080 }
3081
3082 async_set_baudrate(bauds);
3083 if (cable_hw == CABLE_HW_USB) {
3084 set_port_mode(PORT_MODE_UART);
3085 #ifdef WIN32
3086 FT_SetDataCharacteristics(ftHandle, FT_BITS_8, FT_STOP_BITS_1,
3087 FT_PARITY_NONE);
3088 FT_SetFlowControl(ftHandle, FT_FLOW_NONE, 0, 0);
3089 do {} while (FT_StopInTask(ftHandle) != FT_OK);
3090 ms_sleep(50);
3091 FT_Purge(ftHandle, FT_PURGE_RX);
3092 do {} while (FT_RestartInTask(ftHandle) != FT_OK);
3093 #else
3094 ftdi_set_line_property(&fc, BITS_8, STOP_BIT_1, NONE);
3095 ftdi_setflowctrl(&fc, SIO_DISABLE_FLOW_CTRL);
3096 ftdi_usb_purge_buffers(&fc);
3097 ms_sleep(50);
3098 #endif
3099 }
3100
3101 /* Send a space mark to break into SIO loader prompt */
3102 async_send_uint8(' ');
3103
3104 /* Wait for f32c ROM to catch up */
3105 if (tx_binary)
3106 ms_sleep(200);
3107 else
3108 ms_sleep(100);
3109
3110 /* Prune any stale data from rx buffer */
3111 async_read_block(2048);
3112
3113 if (tx_binary) {
3114 /* Start of binary transfer marker */
3115 async_send_uint8(255);
3116
3117 async_send_uint8(0x80); /* CMD: set base */
3118 async_send_uint32(xbauds);
3119 async_send_uint8(0xb0); /* CMD: set baudrate */
3120 ms_sleep(50);
3121 async_set_baudrate(xbauds);
3122 }
3123
3124 i = bauds / 300;
3125 if (bauds < 4800)
3126 i = 16;
3127 if (txfu_ms)
3128 i = 1;
3129 if (tx_binary)
3130 i = 8192;
3131 do {
3132 if (!quiet) {
3133 printf("%c ", statc[blinker_phase]);
3134 printf("\rSending %s: ", txfname);
3135 fflush(stdout);
3136 blinker_phase = (blinker_phase + 1) & 0x3;
3137 }
3138 res = read(infile, &txbuf[8192], i);
3139 if (!tx_binary && txfu_ms)
3140 ms_sleep(txfu_ms);
3141 if (res <= 0) {
3142 tx_cnt = 0;
3143 } else
3144 tx_cnt = res;
3145
3146 if (tx_cnt == 0)
3147 break;
3148
3149 if (tx_binary) {
3150 tx_success = 0;
3151 for(tx_retry = 0; tx_retry < 4 && tx_success == 0; tx_retry++)
3152 {
3153 async_send_uint8(0x80); /* CMD: set base */
3154 async_send_uint32(tx_cnt);
3155 async_send_uint8(0x90); /* CMD: len = base */
3156
3157 async_send_uint8(0x80); /* CMD: set base */
3158 async_send_uint32(base);
3159
3160 async_send_uint8(0xa0); /* CMD: Write block */
3161 local_crc = 0;
3162 for (crc_i = 0; crc_i < tx_cnt; crc_i++) {
3163 local_crc =
3164 (local_crc >> 31) | (local_crc << 1);
3165 txbuf[crc_i] = txbuf[crc_i + 8192];
3166 local_crc += txbuf[crc_i];
3167 }
3168 #if 0
3169 if(1) // intentionally damage tx packet to test CRC
3170 {
3171 // srandom(time(NULL)); // randomize seed, each run will be different
3172 if( (rand() % 256) > 100 ) // error probability 100/256
3173 txbuf[rand() % tx_cnt] = rand() % 0xFF; // error byte at random place
3174 }
3175 #endif
3176 if (async_send_block(tx_cnt)) {
3177 fprintf(stderr, "Block sending failed!\n");
3178 tx_cnt = -1;
3179 continue;
3180 }
3181 if(txfu_ms > 0)
3182 ms_sleep(txfu_ms);
3183 async_send_uint8(0x81); // read checksum
3184 res = 0;
3185 for(crc_retry = 4; crc_retry > 0 && res != 4; ms_sleep(10), crc_retry--)
3186 {
3187 res = async_read_block(4);
3188 if(crc_retry == 2 && res != 4)
3189 async_send_uint8(0x81); // try again to read checksum
3190 }
3191 if(res != 4)
3192 {
3193 fprintf(stderr, "Checksum not received: "
3194 "got %d bytes, should be 4 (0x%08X)\n", res, local_crc);
3195 continue;
3196 }
3197 rx_crc = rxbuf[0] << 24;
3198 rx_crc += rxbuf[1] << 16;
3199 rx_crc += rxbuf[2] << 8;
3200 rx_crc += rxbuf[3];
3201 if (rx_crc != local_crc) {
3202 fprintf(stderr, "CRC error: "
3203 "got 0x%08x, should be 0x%08x\n",
3204 rx_crc, local_crc);
3205 continue;
3206 }
3207 else
3208 {
3209 tx_success = 1; // checksum ok
3210 tx_retry = 0; // reset number of retries
3211 }
3212 }
3213 if(tx_success == 0)
3214 {
3215 tx_cnt = -1; // give up, no more retries retries
3216 break;
3217 }
3218 } else {
3219 memcpy(txbuf, &txbuf[8192], tx_cnt);
3220 if (async_send_block(tx_cnt)) {
3221 fprintf(stderr, "Block sending failed!\n");
3222 tx_cnt = -1;
3223 break;
3224 }
3225 tx_success = 1;
3226 }
3227 if(tx_success)
3228 base += tx_cnt;
3229 } while (tx_cnt > 0);
3230
3231
3232 if (tx_cnt >= 0 && !quiet)
3233 printf("done.\n");
3234 close(infile);
3235 fflush(stdout);
3236
3237 if (tx_success == 0)
3238 fprintf(stderr, "TX error at %08x\n", base);
3239 else if (tx_binary) {
3240 async_send_uint8(0x80); /* CMD: set base */
3241 async_send_uint32(bauds);
3242 async_send_uint8(0xb0); /* CMD: set baudrate */
3243 ms_sleep(50);
3244 async_set_baudrate(bauds);
3245
3246 async_send_uint8(0x80); /* CMD: set base */
3247 async_send_uint32(bootaddr);
3248 async_send_uint8(0xb1); /* CMD: jump to base */
3249 }
3250 }
3251
3252
3253 static void
genbrk(void)3254 genbrk(void)
3255 {
3256
3257 if (cable_hw == CABLE_HW_USB) {
3258 #ifdef WIN32
3259 FT_SetBreakOn(ftHandle);
3260 ms_sleep(BREAK_MS);
3261 FT_SetBreakOff(ftHandle);
3262 #else
3263 ftdi_set_line_property2(&fc, BITS_8, STOP_BIT_1, NONE,
3264 BREAK_ON);
3265 ms_sleep(BREAK_MS);
3266 ftdi_set_line_property2(&fc, BITS_8, STOP_BIT_1, NONE,
3267 BREAK_OFF);
3268 #endif
3269 } else {
3270 #ifdef WIN32
3271 EscapeCommFunction(com_port, SETBREAK);
3272 ms_sleep(BREAK_MS);
3273 EscapeCommFunction(com_port, CLRBREAK);
3274 #else
3275 ioctl(com_port, TIOCSBRK, NULL);
3276 ms_sleep(BREAK_MS);
3277 ioctl(com_port, TIOCCBRK, NULL);
3278 #endif
3279 }
3280 ms_sleep(20);
3281 }
3282
3283
3284 static const char *riscv_reg_names[] = {
3285 "zr", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
3286 "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
3287 "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
3288 "s8", "s9", "sA", "sB", "t3", "t4", "t5", "t6"
3289 };
3290
3291 static const char *mips_reg_names[] = {
3292 "zr", "at", "v0", "v1", "a0", "a1", "a2", "a3",
3293 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
3294 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
3295 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
3296 };
3297
3298
3299 static int deb_seqn;
3300 static int deb_big_endian;
3301 static int deb_riscv;
3302
3303
3304 static void
deb_print_reg(int off)3305 deb_print_reg(int off)
3306 {
3307 int i;
3308
3309 for (i = 0; i < 4; i++)
3310 printf("%02x", rxbuf[off * 4 + (3 - i)]);
3311 }
3312
3313
3314 static int
deb_get_seqn()3315 deb_get_seqn()
3316 {
3317 int i;
3318
3319 i = async_read_block(1);
3320 if (i == 0) {
3321 printf("Error: got no sequence number, "
3322 "debugger disfunctional!\n");
3323 return (1);
3324 }
3325 if (rxbuf[0] != ((deb_seqn + 1) & 0xff)) {
3326 printf("Error: bad sequence number: "
3327 "got %d, should have %d\n", rxbuf[0],
3328 (deb_seqn + 1) & 0xff);
3329 return (1);
3330 }
3331 deb_seqn = rxbuf[0];
3332 return (0);
3333 }
3334
3335
3336 #define BREAKPOINTS 2
3337
3338 static int
deb_print_breakpoints(void)3339 deb_print_breakpoints(void)
3340 {
3341 int i, enabled, trapped;
3342
3343 async_send_uint8(0xa1); /* DEB_CMD_BREAKPOINT_RD */
3344 async_send_uint8(0); /* start at breakpoint #0 */
3345 async_send_uint8(BREAKPOINTS - 1);/* fetch values */
3346 deb_get_seqn();
3347 i = async_read_block(BREAKPOINTS * 4);
3348 if (i != BREAKPOINTS * 4) {
3349 printf("\nError: short read "
3350 "(%d instead of %d)\n", i, BREAKPOINTS * 4);
3351 return (-1);
3352 }
3353
3354 for (i = 0; i < BREAKPOINTS; i++) {
3355 enabled = rxbuf[i * 4] & 1;
3356 trapped = rxbuf[i * 4] & 2;
3357 rxbuf[i * 4] &= ~3;
3358 printf("breakpoint #%d: ", i);
3359 if (enabled) {
3360 deb_print_reg(i);
3361 if (trapped)
3362 printf(" (trapped)");
3363 printf("\n");
3364 } else
3365 printf("disabled\n");
3366 }
3367
3368 return (0);
3369 }
3370
3371
3372 static int
deb_print_registers(void)3373 deb_print_registers(void)
3374 {
3375 int r, c, i;
3376
3377 async_send_uint8(0xa0); /* DEB_CMD_REG_RD */
3378 async_send_uint8(0); /* start at reg #0 */
3379 async_send_uint8(63); /* fetch 64 values */
3380 deb_get_seqn();
3381 i = async_read_block(64 * 4);
3382 if (i != 64 * 4) {
3383 printf("\nError: short read "
3384 "(%d instead of %d)\n", i, 64 * 4);
3385 return (-1);
3386 }
3387
3388 for (r = 0; r < 8; r++) {
3389 for (c = 0; c < 4; c++) {
3390 if (r + 8 * c < 10)
3391 printf(" ");
3392 if (deb_riscv)
3393 printf("x%d (%s): ", r + 8 * c,
3394 riscv_reg_names[r + 8 * c]);
3395 else
3396 printf("$%d (%s): ", r + 8 * c,
3397 mips_reg_names[r + 8 * c]);
3398 deb_print_reg(r + 8 * c);
3399 if (c != 3)
3400 printf(" ");
3401 }
3402 printf("\n");
3403 }
3404 printf("\n");
3405
3406 printf(" HI: ");
3407 deb_print_reg(32);
3408 printf(" LO: ");
3409 deb_print_reg(33);
3410 printf(" SR: ");
3411 deb_print_reg(34);
3412 printf(" CS: ");
3413 deb_print_reg(35);
3414 printf(" EPC: ");
3415 deb_print_reg(36);
3416 printf(" EB: ");
3417 deb_print_reg(37);
3418 printf("\n");
3419
3420 printf("\n");
3421 printf(" IF A: ");
3422 deb_print_reg(40);
3423 printf(" ID A: ");
3424 deb_print_reg(42);
3425 printf(" EX A: ");
3426 deb_print_reg(44);
3427 printf(" MA A: ");
3428 deb_print_reg(46);
3429 printf(" WB A: ");
3430 deb_print_reg(48);
3431 printf("\n");
3432
3433 printf(" IF I: ");
3434 deb_print_reg(41);
3435 printf(" ID I: ");
3436 deb_print_reg(43);
3437 printf(" EX I: ");
3438 deb_print_reg(45);
3439 printf(" MA I: ");
3440 deb_print_reg(47);
3441 printf(" WB I: ");
3442 deb_print_reg(49);
3443 printf("\n");
3444
3445 printf("\n");
3446 printf(" Count: ");
3447 deb_print_reg(38);
3448 printf(" Exec: ");
3449 deb_print_reg(52);
3450 printf(" Branch: ");
3451 deb_print_reg(53);
3452 printf(" Mispred: ");
3453 deb_print_reg(54);
3454 printf("\n");
3455
3456 return (0);
3457 }
3458
3459
3460 static void
debug_help(void)3461 debug_help(void)
3462 {
3463
3464 printf(
3465 " r show registers\n"
3466 " R show registers until a key is pressed\n"
3467 " s execute a single clock cycle\n"
3468 " s N execute at most N clock cycles\n"
3469 " c continue execution\n"
3470 " b show breakpoints\n"
3471 " b N deactivate breakpoint N\n"
3472 " b N,A set breakpoint N at address A\n"
3473 " . exit from debugger\n"
3474 " h get this summary\n"
3475 " ? get this summary\n"
3476 );
3477 }
3478
3479
3480 static void
debug_cmd(void)3481 debug_cmd(void)
3482 {
3483 char cmdbuf[256];
3484 int i, j, c, r;
3485 #ifdef WIN32
3486 HANDLE cons_out = GetStdHandle(STD_OUTPUT_HANDLE);
3487 CONSOLE_SCREEN_BUFFER_INFO screen_info;
3488 #endif
3489
3490 /* Enable debugger */
3491 printf("\n*** Entering debug mode ***\n");
3492 async_send_uint8(0x9d);
3493 async_send_uint8(0xed);
3494
3495 /* Flush read buffer */
3496 async_read_block(BUFLEN_MAX);
3497
3498 /* Fetch initial sequence number and config register */
3499 async_send_uint8(0xa0); /* DEB_CMD_REG_RD */
3500 async_send_uint8(55); /* start at reg #55 */
3501 async_send_uint8(0); /* fetch 1 value */
3502 i = async_read_block(1);
3503 if (i == 0) {
3504 printf("Error: got no sequence number\n");
3505 printf("Debugger disfunctional, exiting.\n");
3506 return;
3507 }
3508 deb_seqn = rxbuf[0];
3509 i = async_read_block(4);
3510 if (i != 4) {
3511 printf("\nError: short read (%d instead of %d)\n", i, 4);
3512 printf("Debugger disfunctional, exiting.\n");
3513 return;
3514 }
3515 printf("Detected ");
3516 if (rxbuf[1] & 0x80) {
3517 printf("big-endian ");
3518 deb_big_endian = 1;
3519 } else {
3520 printf("little-endian ");
3521 deb_big_endian = 0;
3522 }
3523 if (rxbuf[1] & 0x40) {
3524 printf("f32c/riscv");
3525 deb_riscv = 1;
3526 } else {
3527 printf("f32c/mips");
3528 deb_riscv = 0;
3529 }
3530 printf(" core, clk ticks at %f MHz.\n", 1.0 *
3531 (((rxbuf[3] & 0xf) << 8) + rxbuf[2]) / ((rxbuf[3] >> 5) + 1));
3532
3533 do {
3534 printf("db> ");
3535 fflush(stdout);
3536 gets1(cmdbuf, sizeof(cmdbuf));
3537 for (i = 0; cmdbuf[i] != 0 ; i++)
3538 if (cmdbuf[i] != ' ' && cmdbuf[i] != 9)
3539 break;
3540 switch (cmdbuf[i]) {
3541 case 's': /* single step */
3542 c = atoi(&cmdbuf[i + 1]);
3543 if (c < 1)
3544 c = 1;
3545 async_send_uint8(0xef); /* DEB_CMD_CLK_STEP */
3546 async_send_uint32(0); /* disable clk when done */
3547 async_send_uint32(c); /* how many cycles */
3548 deb_get_seqn();
3549 printf("Single-stepping %d cycle(s)...\n", c);
3550 /* XXX ugly hack, wait for cycles to pass... */
3551 ms_sleep(c / 50000);
3552 deb_print_registers();
3553 break;
3554 case 'b': /* set / clear breakpoints */
3555 i++;
3556 while (cmdbuf[i] == ' ' || cmdbuf[i] == 8)
3557 i++;
3558 if (cmdbuf[i] == 0) {
3559 deb_print_breakpoints();
3560 break;
3561 }
3562 j = i;
3563 while (isnumber(cmdbuf[j]))
3564 j++;
3565 r = atoi(&cmdbuf[i]);
3566 i = j;
3567 while (cmdbuf[i] == ' ' || cmdbuf[i] == 8 ||
3568 cmdbuf[i] == ',')
3569 i++;
3570 c = strtoul(&cmdbuf[i], NULL, 16);
3571 c &= ~3; /* Word align */
3572 if (cmdbuf[i] != 0)
3573 c |= 1; /* Set breakpoint enable flag */
3574 async_send_uint8(0xe1); /* DEB_CMD_BREAKPOINT_WR */
3575 async_send_uint32(r); /* dst reg */
3576 async_send_uint32(c); /* value */
3577 deb_get_seqn();
3578 break;
3579 case 'c': /* continue */
3580 async_send_uint8(0xef); /* DEB_CMD_CLK_STEP */
3581 async_send_uint32(1); /* enable clk */
3582 async_send_uint32(0); /* don't wait */
3583 deb_get_seqn();
3584 break;
3585 case 'r': /* print registers */
3586 deb_print_registers();
3587 break;
3588 case 'R': /* continuously print registers */
3589 do {
3590 if (deb_print_registers() != 0)
3591 break;
3592 #ifdef WIN32
3593 if (kbhit()) {
3594 c = getch();
3595 #else
3596 if (read(0, &c, 1) > 0) {
3597 #endif
3598 break;
3599 }
3600 #ifdef WIN32
3601 GetConsoleScreenBufferInfo(cons_out,
3602 &screen_info);
3603 screen_info.dwCursorPosition.X = 0;
3604 screen_info.dwCursorPosition.Y -= 15;
3605 SetConsoleCursorPosition(cons_out,
3606 screen_info.dwCursorPosition);
3607 #else
3608 printf("\r\033[15A");
3609 #endif
3610 } while (1);
3611 break;
3612 case 'q':
3613 cmdbuf[i] = '.';
3614 break;
3615 case '.':
3616 case 0:
3617 break;
3618 case 'h':
3619 case '?':
3620 debug_help();
3621 break;
3622 default:
3623 printf("Unknown command\n");
3624 break;
3625 }
3626 } while (cmdbuf[i] != '.');
3627
3628 /* Exit debugger */
3629 printf("*** Exiting debug mode ***\n");
3630 async_send_uint8(0x9d);
3631 async_send_uint8(0xdd);
3632 async_read_block(1);
3633 }
3634
3635
3636 static int
3637 term_emul(void)
3638 {
3639 #ifdef WIN32
3640 DWORD saved_cons_mode;
3641 DWORD rx_cnt, tx_cnt, ev_stat, sent;
3642 HANDLE cons_in = GetStdHandle(STD_INPUT_HANDLE);
3643 HANDLE cons_out = GetStdHandle(STD_OUTPUT_HANDLE);
3644 CONSOLE_CURSOR_INFO cursor_info;
3645 CONSOLE_SCREEN_BUFFER_INFO screen_info;
3646 COORD cursor_pos, saved_cursor_pos;
3647 int color0, cons_color;
3648 int rx_esc_seqn = 0;
3649 int tx_esc_seqn = 0;
3650 int esc_arg, esc_arg0;
3651 int prev_char = 0;
3652 char *keystr;
3653 char vt100buf[20];
3654 #else
3655 int rx_cnt, tx_cnt, sent;
3656 #endif
3657 int key_phase = 1; /* 0 .. normal; 1 .. CR; 2 .. CR + ~ */
3658 int c, res;
3659 int infile = -1;
3660 int sleep_t = 0;
3661 char argbuf[256];
3662 int i;
3663
3664 #ifdef WIN32
3665 if (cable_hw == CABLE_HW_USB) {
3666 FT_SetLatencyTimer(ftHandle, 20);
3667 FT_SetBaudRate(ftHandle, bauds);
3668 FT_SetDataCharacteristics(ftHandle, FT_BITS_8, FT_STOP_BITS_1,
3669 FT_PARITY_NONE);
3670 FT_SetFlowControl(ftHandle, FT_FLOW_NONE, 0, 0);
3671 if (port_mode != PORT_MODE_UART) {
3672 set_port_mode(PORT_MODE_UART);
3673 do {} while (FT_StopInTask(ftHandle) != FT_OK);
3674 ms_sleep(50);
3675 FT_Purge(ftHandle, FT_PURGE_RX);
3676 do {} while (FT_RestartInTask(ftHandle) != FT_OK);
3677 }
3678 }
3679
3680 /* Disable CTRL-C, XON/XOFF etc. processing on console input. */
3681 GetConsoleMode(cons_in, &saved_cons_mode);
3682 SetConsoleMode(cons_in, 0x40); /* ENABLE_QUICK_EDIT_MODE */
3683 GetConsoleScreenBufferInfo(cons_out, &screen_info);
3684 color0 = screen_info.wAttributes;
3685 color0 = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
3686 cursor_info.bVisible = 1;
3687 cursor_info.dwSize = 100;
3688 SetConsoleCursorInfo(cons_out, &cursor_info);
3689 SetConsoleTextAttribute(cons_out, color0);
3690 #else
3691 if (cable_hw == CABLE_HW_USB) {
3692 if (port_mode != PORT_MODE_UART) {
3693 set_port_mode(PORT_MODE_UART);
3694 ftdi_usb_purge_buffers(&fc);
3695 }
3696 ftdi_set_latency_timer(&fc, 20);
3697 ftdi_set_baudrate(&fc, bauds);
3698 ftdi_set_line_property(&fc, BITS_8, STOP_BIT_1, NONE);
3699 ftdi_setflowctrl(&fc, SIO_DISABLE_FLOW_CTRL);
3700 }
3701
3702 /* Disable CTRL-C, XON/XOFF etc. processing on console input. */
3703 fcntl(0, F_SETFL, O_NONBLOCK);
3704 system("stty -echo -isig -icanon -iexten -ixon -ixoff -icrnl");
3705 #endif
3706
3707 printf("Terminal emulation mode, using %d bauds\n", bauds);
3708 printf("Press ENTER, ~, ? for help\n");
3709
3710 do {
3711 tx_cnt = 0;
3712 if (infile > 0) {
3713 i = bauds / 300;
3714 if (bauds < 4800)
3715 i = 16;
3716 res = read(infile, txbuf, i);
3717 if (res <= 0) {
3718 close(infile);
3719 infile = -1;
3720 tx_cnt = 0;
3721 } else
3722 tx_cnt = res;
3723 #ifdef WIN32
3724 if (kbhit()) {
3725 c = getch();
3726 #else
3727 if (read(0, &c, 1) > 0) {
3728 #endif
3729 if (c == 3) {
3730 close(infile);
3731 infile = -1;
3732 tx_cnt = 0;
3733 printf("\nTransfer interrupted!\n\n");
3734 }
3735 }
3736 } else
3737 #ifdef WIN32
3738 while (kbhit()) {
3739 c = getch();
3740 txbuf[tx_cnt] = c;
3741 #else
3742 while (read(0, &txbuf[tx_cnt], 1) > 0) {
3743 c = txbuf[tx_cnt];
3744 #endif
3745 #ifdef WIN32
3746 /*
3747 * Translate cursor / function keys to vt100 sequences.
3748 */
3749 if (c == 224) {
3750 tx_esc_seqn = 1; /* Cursor keys */
3751 continue;
3752 }
3753 if (c == 0) {
3754 tx_esc_seqn = 2; /* FN keys */
3755 continue;
3756 }
3757 if (tx_esc_seqn == 1) {
3758 keystr = "";
3759 switch (c) {
3760 case 75: /* cursor left */
3761 keystr = "\x1b[D";
3762 break;
3763 case 77: /* cursor right */
3764 keystr = "\x1b[C";
3765 break;
3766 case 72: /* cursor up */
3767 keystr = "\x1b[A";
3768 break;
3769 case 80: /* cursor down */
3770 keystr = "\x1b[B";
3771 break;
3772 case 82: /* INS */
3773 keystr = "\x1b[2\x7e";
3774 break;
3775 case 83: /* DEL */
3776 keystr = "\x1b[3\x7e";
3777 break;
3778 case 73: /* PgUP */
3779 break;
3780 case 81: /* PgDOWN */
3781 break;
3782 case 71: /* Home */
3783 keystr = "\x1b[H";
3784 break;
3785 case 79: /* End */
3786 keystr = "\x1b[F";
3787 break;
3788 default:
3789 break;
3790 }
3791 tx_cnt += sprintf(&txbuf[tx_cnt], "%s", keystr);
3792 tx_esc_seqn = 0;
3793 continue;
3794 }
3795 if (tx_esc_seqn == 2) {
3796 /* Ignore FN keys for now */
3797 tx_esc_seqn = 0;
3798 continue;
3799 }
3800 #endif
3801
3802 /*
3803 * Catch and process ~ escape sequences.
3804 */
3805 if (key_phase == 2) {
3806 switch (c) {
3807 case '?':
3808 printf("~?\n");
3809 terminal_help();
3810 key_phase = 0;
3811 continue;
3812 case '#':
3813 genbrk();
3814 key_phase = 0;
3815 continue;
3816 case 'r':
3817 reload = 1;
3818 res = 0;
3819 goto done;
3820 case '.':
3821 res = 1;
3822 goto done;
3823 case 'b':
3824 printf("~>New baudrate? ");
3825 fflush(stdout);
3826 gets1(argbuf, sizeof(argbuf));
3827 c = atoi(argbuf);
3828 if (c > 0 &&
3829 cable_hw == CABLE_HW_USB) {
3830 #ifdef WIN32
3831 res = FT_SetBaudRate(ftHandle,
3832 c);
3833 if (res == FT_OK) {
3834 #else
3835 res = ftdi_set_baudrate(&fc,
3836 c);
3837 if (res == 0) {
3838 #endif
3839 bauds = c;
3840 printf("new"
3841 " baudrate: %d\n",
3842 bauds);
3843 } else
3844 printf("%d: invalid"
3845 " baudrate\n", c);
3846 }
3847 key_phase = 0;
3848 continue;
3849 case '>':
3850 printf("~>Local file name? ");
3851 fflush(stdout);
3852 gets1(argbuf, sizeof(argbuf));
3853 infile = open(argbuf,
3854 #ifdef WIN32
3855 O_RDONLY | O_BINARY
3856 #else
3857 O_RDONLY
3858 #endif
3859 );
3860 if (infile < 0)
3861 printf("%s: cannot open\n",
3862 argbuf);
3863 key_phase = 0;
3864 continue;
3865 case 'd':
3866 debug_cmd();
3867 key_phase = 0;
3868 continue;
3869 default:
3870 if (c != '~') {
3871 txbuf[tx_cnt] = '~';
3872 tx_cnt++;
3873 txbuf[tx_cnt] = c;
3874 }
3875 key_phase = 0;
3876 break;
3877 }
3878 }
3879 if (key_phase == 1 && c == '~') {
3880 key_phase = 2;
3881 continue;
3882 }
3883 if (c == 13)
3884 key_phase = 1;
3885 else
3886 key_phase = 0;
3887 tx_cnt++;
3888 if (tx_cnt >= 16)
3889 break;
3890 }
3891 if (tx_cnt) {
3892 if (cable_hw == CABLE_HW_USB) {
3893 #ifdef WIN32
3894 FT_Write(ftHandle, txbuf, tx_cnt, &sent);
3895 #else
3896 sent = ftdi_write_data(&fc, txbuf, tx_cnt);
3897 #endif
3898 } else {/* cable_hw == CABLE_HW_COM */
3899 #ifdef WIN32
3900 WriteFile(com_port, txbuf, tx_cnt,
3901 (DWORD *) &sent, NULL);
3902 #else
3903 fcntl(com_port, F_SETFL, 0);
3904 sent = write(com_port, txbuf, tx_cnt);
3905 fcntl(com_port, F_SETFL, O_NONBLOCK);
3906 #endif
3907 }
3908 if (sent != tx_cnt) {
3909 res = 1;
3910 goto done;
3911 }
3912 }
3913
3914 #ifdef WIN32
3915 if (cable_hw == CABLE_HW_USB) {
3916 FT_GetStatus(ftHandle, &rx_cnt, &ev_stat, &ev_stat);
3917 if (rx_cnt > BUFLEN_MAX)
3918 rx_cnt = BUFLEN_MAX;
3919 if (rx_cnt)
3920 FT_Read(ftHandle, txbuf, rx_cnt, &rx_cnt);
3921 } else {
3922 rx_cnt = 32;
3923 ReadFile(com_port, txbuf, rx_cnt,
3924 (DWORD *) &rx_cnt, NULL);
3925 }
3926 #else
3927 rx_cnt = 1;
3928 if (cable_hw == CABLE_HW_USB) {
3929 if (rx_cnt < fc.readbuffer_remaining)
3930 rx_cnt = fc.readbuffer_remaining;
3931 if (rx_cnt > BUFLEN_MAX)
3932 rx_cnt = BUFLEN_MAX;
3933 rx_cnt = ftdi_read_data(&fc, txbuf, rx_cnt);
3934 } else {
3935 rx_cnt = read(com_port, txbuf, rx_cnt);
3936 if (rx_cnt == -1)
3937 rx_cnt = 0;
3938 }
3939 #endif
3940 if (rx_cnt) {
3941 if (rx_cnt < 0) {
3942 res = 1;
3943 goto done;
3944 }
3945 #ifdef WIN32
3946 for (i = 0; i < rx_cnt; i++) {
3947 c = txbuf[i];
3948 /*
3949 * Interpret selected VT-100 control sequences
3950 */
3951 if (c == 27) {
3952 prev_char = 27;
3953 continue;
3954 }
3955 if (prev_char == 27 && c == '[') {
3956 rx_esc_seqn = 1;
3957 esc_arg = 0;
3958 esc_arg0 = 0;
3959 continue;
3960 }
3961 if (rx_esc_seqn) {
3962 if (c >= '0' && c <= '9') {
3963 esc_arg = esc_arg * 10 +
3964 c - '0';
3965 continue;
3966 }
3967 if (c == ';') {
3968 esc_arg0 = esc_arg;
3969 esc_arg = 0;
3970 continue;
3971 }
3972 switch (c) {
3973 case 's': /* Save cursor position */
3974 break;
3975 case 'u': /* Restore cursor position */
3976 break;
3977 case 'n': /* Query cursor position */
3978 if (esc_arg != 6)
3979 break;
3980 break;
3981 GetConsoleScreenBufferInfo(
3982 cons_out, &screen_info);
3983 c = sprintf(vt100buf,
3984 "\x1b[%d;%dR",
3985 screen_info.dwCursorPosition.Y
3986 - screen_info.srWindow.Top,
3987 screen_info.dwCursorPosition.X
3988 - screen_info.srWindow.Left);
3989 FT_Write(ftHandle, vt100buf,
3990 c, &sent);
3991 break;
3992 case 'C': /* Set cursor hpos */
3993 break;
3994 case 'H': /* Cursor home */
3995 break;
3996 case 'A': /* Cursor up */
3997 break;
3998 case 'K': /* Erase to end of line */
3999 break;
4000 case 'J': /* Clear screen */
4001 GetConsoleScreenBufferInfo(
4002 cons_out, &screen_info);
4003 cursor_pos.X =
4004 screen_info.srWindow.Left;
4005 cursor_pos.Y =
4006 screen_info.srWindow.Top;
4007 FillConsoleOutputCharacter(
4008 cons_out, ' ',
4009 (screen_info.srWindow.Bottom
4010 - screen_info.srWindow.Top) *
4011 (screen_info.srWindow.Right
4012 - screen_info.srWindow.Left),
4013 cursor_pos, &sent);
4014 SetConsoleCursorPosition(
4015 cons_out, cursor_pos);
4016 break;
4017 case 'm': /* Set char attribute */
4018 cons_color = color0;
4019 if (esc_arg == 1 ||
4020 esc_arg == 4) {
4021 cons_color |=
4022 FOREGROUND_RED;
4023 }
4024 SetConsoleTextAttribute(
4025 cons_out, cons_color);
4026 break;
4027 default:
4028 break;
4029 }
4030 rx_esc_seqn = 0;
4031 continue;
4032 }
4033 rx_esc_seqn = 0;
4034 fwrite(&c, 1, 1, stdout);
4035 }
4036 #else
4037 fwrite(txbuf, 1, rx_cnt, stdout);
4038 #endif
4039 fflush(stdout);
4040 }
4041 if (tx_cnt == 0 && rx_cnt == 0) {
4042 ms_sleep(sleep_t);
4043 if (sleep_t < 5)
4044 sleep_t++;
4045 } else
4046 sleep_t = 0;
4047 } while (1);
4048
4049 done:
4050 printf("\n");
4051
4052 /* Restore special key processing on console input. */
4053 #ifdef WIN32
4054 SetConsoleMode(cons_in, saved_cons_mode);
4055 cursor_info.bVisible = 1;
4056 cursor_info.dwSize = 20;
4057 SetConsoleCursorInfo(cons_out, &cursor_info);
4058 FT_SetLatencyTimer(ftHandle, 1);
4059 FT_SetBaudRate(ftHandle, USB_BAUDS);
4060 #else
4061 system("stty echo isig icanon iexten ixon ixoff icrnl");
4062 ftdi_set_latency_timer(&fc, 1);
4063 ftdi_set_baudrate(&fc, USB_BAUDS);
4064 #endif
4065
4066 return (res);
4067 }
4068
4069
4070 int
4071 main(int argc, char *argv[])
4072 {
4073 int res = EXIT_FAILURE;
4074 int jed_target = JED_TGT_SRAM;
4075 int debug = 0;
4076 int c;
4077 #ifdef WIN32
4078 int had_terminal = 0;
4079 COMMTIMEOUTS com_to;
4080 #endif
4081
4082 #ifndef USE_PPI
4083 #define OPTS "qtdj:b:p:x:p:P:a:e:f:D:rs:"
4084 #else
4085 #define OPTS "qtdj:b:p:x:p:P:a:e:f:D:rs:c:"
4086 #endif
4087 while ((c = getopt(argc, argv, OPTS)) != -1) {
4088 switch (c) {
4089 case 'a':
4090 txfname = optarg;
4091 tx_binary = 0;
4092 break;
4093 case 'b':
4094 bauds = atoi(optarg);
4095 break;
4096 case 'x':
4097 xbauds = atoi(optarg);
4098 break;
4099 #ifdef USE_PPI
4100 case 'c':
4101 if (strcasecmp(optarg, "usb") == 0)
4102 cable_hw = CABLE_HW_USB;
4103 else if (strcasecmp(optarg, "ppi") == 0)
4104 cable_hw = CABLE_HW_PPI;
4105 else {
4106 usage();
4107 exit(EXIT_FAILURE);
4108 }
4109 break;
4110 #endif
4111 case 'd':
4112 debug = 1;
4113 global_debug = 1;
4114 break;
4115 case 'D':
4116 txfu_ms = atoi(optarg);
4117 break;
4118 case 'e':
4119 txfname = optarg;
4120 tx_binary = 1;
4121 break;
4122 case 'j':
4123 if (strcasecmp(optarg, "sram") == 0)
4124 jed_target = JED_TGT_SRAM;
4125 else if (strcasecmp(optarg, "flash") == 0)
4126 jed_target = JED_TGT_FLASH;
4127 else {
4128 usage();
4129 exit(EXIT_FAILURE);
4130 }
4131 break;
4132 case 'f':
4133 if (optarg[0] == '0' && optarg[1] == 'x')
4134 sscanf(&optarg[2], "%x", &spi_addr);
4135 else if (isdigit(*optarg))
4136 spi_addr = atoi(optarg);
4137 else {
4138 printf("Invalid address format\n");
4139 exit(EXIT_FAILURE);
4140 }
4141 if ((spi_addr & (SPI_SECTOR_SIZE - 1)) != 0) {
4142 printf("SPI address must be a multiple of %d\n",
4143 SPI_SECTOR_SIZE);
4144 exit(EXIT_FAILURE);
4145 }
4146 break;
4147 case 'p':
4148 port_index = atoi(optarg);
4149 break;
4150 case 'P':
4151 com_name = optarg;
4152 cable_hw = CABLE_HW_COM;
4153 break;
4154 case 'q':
4155 quiet = 1;
4156 break;
4157 case 'r':
4158 reload = 1;
4159 break;
4160 case 's':
4161 svf_name = optarg;
4162 break;
4163 case 't':
4164 terminal = 1;
4165 #ifdef WIN32
4166 had_terminal = 1;
4167 #endif
4168 break;
4169 case '?':
4170 default:
4171 usage();
4172 exit(EXIT_FAILURE);
4173 }
4174 }
4175 argc -= optind;
4176 argv += optind;
4177
4178 #ifdef WIN32
4179 if (terminal) {
4180 system("color 0a");
4181 system("cls");
4182 }
4183 #endif
4184
4185 if (!quiet)
4186 printf("%s (built %s %s)\n", verstr, __DATE__, __TIME__);
4187
4188 if (svf_name) {
4189 if (terminal || reload || txfname || com_name || argc == 0) {
4190 usage();
4191 exit(EXIT_FAILURE);
4192 }
4193 res = exec_bit_file(argv[0], jed_target, debug);
4194 return(res);
4195 }
4196
4197 if (argc == 0 && terminal == 0 && txfname == NULL && reload == 0) {
4198 usage();
4199 exit(EXIT_FAILURE);
4200 }
4201
4202 if (com_name && terminal == 0 && txfname == NULL && reload == 0) {
4203 fprintf(stderr, "error: "
4204 "option -P must be used with -r, -t or -a\n");
4205 exit(EXIT_FAILURE);
4206 }
4207
4208 if (com_name && cable_hw != CABLE_HW_COM) {
4209 fprintf(stderr, "error: "
4210 "options -P and -c are mutualy exclusive\n");
4211 exit(EXIT_FAILURE);
4212 }
4213
4214 if (spi_addr && jed_target != JED_TGT_FLASH) {
4215 fprintf(stderr, "error: "
4216 "-f may be specified only with -j flash\n");
4217 exit(EXIT_FAILURE);
4218 }
4219
4220 switch (cable_hw) {
4221 case CABLE_HW_UNKNOWN:
4222 case CABLE_HW_USB:
4223 res = setup_usb();
4224 if (res == 0)
4225 cable_hw = CABLE_HW_USB;
4226 if (cable_hw == CABLE_HW_USB) {
4227 if (xbauds == 0)
4228 xbauds = 3000000;
4229 break;
4230 }
4231 #ifdef USE_PPI
4232 case CABLE_HW_PPI:
4233 res = setup_ppi();
4234 #endif
4235 break;
4236 case CABLE_HW_COM:
4237 if (xbauds == 0)
4238 xbauds = bauds;
4239 #ifdef WIN32
4240 sprintf(txbuf, "\\\\.\\%s", com_name);
4241 com_port = CreateFile(txbuf, GENERIC_READ | GENERIC_WRITE,
4242 0, NULL, OPEN_EXISTING, 0, NULL);
4243 if (com_port == INVALID_HANDLE_VALUE) {
4244 fprintf(stderr, "Can't open %s\n", com_name);
4245 exit(EXIT_FAILURE);
4246 }
4247 async_set_baudrate(bauds);
4248 if (GetCommTimeouts(com_port, &com_to) == 0) {
4249 fprintf(stderr, "Can't configure %s\n", com_port);
4250 exit(EXIT_FAILURE);
4251 }
4252 com_to.ReadIntervalTimeout = 1;
4253 com_to.ReadTotalTimeoutConstant = 1;
4254 com_to.ReadTotalTimeoutMultiplier = 1;
4255 SetCommTimeouts(com_port, &com_to);
4256 res = 0;
4257 #else
4258 com_port = open(com_name, O_RDWR);
4259 if (com_port < 0 || tcgetattr(com_port, &tty)) {
4260 fprintf(stderr, "Can't open %s\n", com_name);
4261 exit(EXIT_FAILURE);
4262 }
4263 tty.c_cflag &= ~(CSIZE|PARENB);
4264 tty.c_cflag |= CS8;
4265 tty.c_cflag |= CLOCAL;
4266 tty.c_cflag &= ~CRTSCTS;
4267 tty.c_iflag &= ~(ISTRIP|ICRNL);
4268 tty.c_iflag &= ~(IXON|IXOFF);
4269 tty.c_oflag &= ~OPOST;
4270 tty.c_lflag &= ~(ICANON|ISIG|IEXTEN|ECHO);
4271 tty.c_cc[VMIN] = 1;
4272 tty.c_cc[VTIME] = 0;
4273 async_set_baudrate(bauds);
4274 res = fcntl(com_port, F_SETFL, O_NONBLOCK);
4275 #if defined(__FreeBSD__) || defined(__linux__)
4276 /* XXX w/o this a BREAK won't be sent properly on FreeBSD ?!?*/
4277 ms_sleep(300);
4278 #endif
4279 #endif /* !WIN32 */
4280 default:
4281 /* can't happen, shut up gcc warnings */
4282 break;
4283 }
4284
4285 if (res) {
4286 fprintf(stderr, "Cannot find JTAG cable.\n");
4287 exit(EXIT_FAILURE);
4288 }
4289
4290 if (!quiet && cable_hw != CABLE_HW_COM) {
4291 #ifndef WIN32
4292 if (cable_hw == CABLE_HW_USB)
4293 printf("Using USB cable: %s\n", hmp->cable_path);
4294 else
4295 #ifdef USE_PPI
4296 printf("Using parallel port JTAG cable.\n");
4297 #else
4298 printf("Parallel port JTAG cable not supported!\n");
4299 #endif
4300 #endif /* !WIN32 */
4301 }
4302
4303 do {
4304 if (reload) {
4305 genbrk();
4306 reload = 0;
4307 }
4308 if (argc)
4309 prog(argv[0], jed_target, debug);
4310 jed_target = JED_TGT_SRAM; /* for subsequent prog() calls */
4311 if (txfname)
4312 txfile();
4313 } while (terminal && term_emul() == 0);
4314
4315 #ifdef WIN32
4316 if (had_terminal)
4317 system("color");
4318 #endif
4319
4320 if (cable_hw == CABLE_HW_COM) {
4321 #ifdef WIN32
4322 CloseHandle(com_port);
4323 #else
4324 close(com_port);
4325 #endif
4326 } else if (cable_hw == CABLE_HW_USB) {
4327 ms_sleep(1); // small delay for f32c to start
4328 shutdown_usb();
4329 }
4330 #ifdef USE_PPI
4331 else
4332 shutdown_ppi();
4333 #endif
4334
4335 return (res);
4336 }
4337