diff options
Diffstat (limited to 'fpga/xilinx/programmer/dependencies/libxsvf/xsvftool-xpcu.src/xsvftool-xpcu.c')
-rw-r--r-- | fpga/xilinx/programmer/dependencies/libxsvf/xsvftool-xpcu.src/xsvftool-xpcu.c | 720 |
1 files changed, 720 insertions, 0 deletions
diff --git a/fpga/xilinx/programmer/dependencies/libxsvf/xsvftool-xpcu.src/xsvftool-xpcu.c b/fpga/xilinx/programmer/dependencies/libxsvf/xsvftool-xpcu.src/xsvftool-xpcu.c new file mode 100644 index 0000000..b76e2d8 --- /dev/null +++ b/fpga/xilinx/programmer/dependencies/libxsvf/xsvftool-xpcu.src/xsvftool-xpcu.c @@ -0,0 +1,720 @@ +/* + * xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB + * + * Copyright (C) 2011 RIEGL Research ForschungsGmbH + * Copyright (C) 2011 Clifford Wolf <clifford@clifford.at> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <sys/time.h> + +#include "libxsvf.h" +#include "fx2usb-interface.h" + +#include "filedata.h" + +char *correct_cksum = +#include "hardware_cksum_c.inc" +; + +#define UNUSED __attribute__((unused)) + +/**** BEGIN: http://svn.clifford.at/tools/trunk/examples/check.h ****/ + +// This is to not confuse the VIM syntax highlighting +#define CHECK_VAL_OPEN ( +#define CHECK_VAL_CLOSE ) + +#define CHECK(result, check) \ + CHECK_VAL_OPEN{ \ + typeof(result) _R = (result); \ + if (!(_R check)) { \ + fprintf(stderr, "Error from '%s' (%d %s) in %s:%d.\n", \ + #result, (int)_R, #check, __FILE__, __LINE__); \ + fprintf(stderr, "ERRNO(%d): %s\n", errno, strerror(errno)); \ + abort(); \ + } \ + _R; \ + }CHECK_VAL_CLOSE + +#define CHECK_PTR(result, check) \ + CHECK_VAL_OPEN{ \ + typeof(result) _R = (result); \ + if (!(_R check)) { \ + fprintf(stderr, "Error from '%s' (%p %s) in %s:%d.\n", \ + #result, (void*)_R, #check, __FILE__, __LINE__); \ + fprintf(stderr, "ERRNO(%d): %s\n", errno, strerror(errno)); \ + abort(); \ + } \ + _R; \ + }CHECK_VAL_CLOSE + +/**** END: http://svn.clifford.at/tools/trunk/examples/check.h ****/ + +FILE *file_fp = NULL; + +int usb_vendor_id = 0; +int usb_device_id = 0; +char *usb_device_file = NULL; + +int mode_frequency = 6000; +int mode_async_check = 0; +int mode_internal_cpld = 0; +int mode_8bit_per_cycle = 0; +int mode_hex_rmask = 0; + +usb_dev_handle *fx2usb; +int internal_jtag_scan_test = 0; + +int sync_count; +int tck_cycle_count; +int blocks_without_sync; + +int tdo_check_period_100; +int tdo_check_thisperiod; + +int rmask_bits = 0, rmask_bytes = 0; +unsigned char *rmask_data = NULL; + +/* This constant are used to determine when the error status should be synced. + * Syncinc to often would slow things down, syncinc not often enough might cause + * errors beeing reported by far to late. + */ +#define FORCE_SYNC_AFTER_N_BLOCKS 100 +#define FORCE_SYNC_MIN_PERIOD 10000 +#define FORCE_SYNC_INIT_PERIOD 100000 + +// send larger junks to USB stack and let the kernel split it up +// #define MAXBUF() (mode_internal_cpld ? 50 : mode_8bit_per_cycle ? 500 : 1000) +#define MAXBUF() (mode_internal_cpld ? 50 : 4000) + +unsigned char fx2usb_retbuf[65]; +int fx2usb_retlen; + +unsigned char commandbuf[4096]; +int commandbuf_len; + +static void shrink_8bit_to_4bit() +{ + int i; + if ((commandbuf_len & 1) != 0) + commandbuf[commandbuf_len++] = 0; + for (i = 0; i<commandbuf_len; i++) { + if ((i & 1) == 0) + commandbuf[i >> 1] = (commandbuf[i >> 1] & 0xf0) | commandbuf[i]; + else + commandbuf[i >> 1] = (commandbuf[i >> 1] & 0x0f) | (commandbuf[i] << 4); + } + commandbuf_len = commandbuf_len >> 1; +} + +void fx2usb_command(const char *cmd) +{ + // fprintf(stderr, "Sending FX2USB Command: '%s' => ", cmd); + fx2usb_send_chunk(fx2usb, 1, cmd, strlen(cmd)); + fx2usb_recv_chunk(fx2usb, 1, fx2usb_retbuf, sizeof(fx2usb_retbuf)-1, &fx2usb_retlen); + fx2usb_retbuf[fx2usb_retlen] = 0; + // fprintf(stderr, "'%s'\n", fx2usb_retbuf); + + if (strchr((char*)fx2usb_retbuf, '!') != NULL) { + fprintf(stderr, "Internal ERROR in communication with probe: '%s' => '%s'\n", cmd, fx2usb_retbuf); + abort(); + } +} + +static int xpcu_set_frequency(struct libxsvf_host *h UNUSED, int v); +static int xpcu_pulse_tck(struct libxsvf_host *h UNUSED, int tms, int tdi, int tdo, int rmask UNUSED, int sync); + +static int xpcu_setup(struct libxsvf_host *h UNUSED) +{ + sync_count = 0; + blocks_without_sync = 0; + commandbuf_len = 0; + fx2usb_command("R"); + + if (!mode_internal_cpld) { + fx2usb_command("B1"); + } + + if (mode_frequency) + xpcu_set_frequency(h, mode_frequency * 1000); + + tdo_check_period_100 = FORCE_SYNC_INIT_PERIOD * 100; + tdo_check_thisperiod = 0; + + return 0; +} + +static int xpcu_shutdown(struct libxsvf_host *h UNUSED) +{ + int rc = 0; + if (commandbuf_len != 0) { + fprintf(stderr, "Found %d unsynced commands in command buffer on interface shutdown!\n", commandbuf_len); + commandbuf_len = 0; + rc = -1; + } + fx2usb_command("S"); + if (fx2usb_retbuf[mode_internal_cpld ? 1 : 0] == '1') { + fprintf(stderr, "Found pending errors in interface status on shutdown!\n"); + rc = -1; + } + fx2usb_command("R"); + return rc; +} + +static void xpcu_udelay(struct libxsvf_host *h UNUSED, long usecs, int tms, long num_tck) +{ + struct timeval tv1, tv2; + long rem_usecs; + + if (mode_internal_cpld) + { + if (!mode_8bit_per_cycle) + shrink_8bit_to_4bit(); + unsigned char tempbuf[64]; + tempbuf[0] = 'J'; + memcpy(tempbuf+1, commandbuf, commandbuf_len); + fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1); + + fx2usb_command("P"); + commandbuf_len = 0; + } + else + { + sync_count = 0x08 | ((sync_count+1) & 0x0f); + commandbuf[commandbuf_len++] = 0x01; + commandbuf[commandbuf_len++] = sync_count; + if (!mode_8bit_per_cycle) + shrink_8bit_to_4bit(); + fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len); + commandbuf_len = 0; + + char cmd[3]; + snprintf(cmd, 3, "W%x", sync_count); + fx2usb_command(cmd); + } + + gettimeofday(&tv1, NULL); + + while (num_tck > 0) { + xpcu_pulse_tck(h, tms, 0, -1, 0, 0); + num_tck--; + } + + if (mode_internal_cpld) + { + if (!mode_8bit_per_cycle) + shrink_8bit_to_4bit(); + unsigned char tempbuf[64]; + tempbuf[0] = 'J'; + memcpy(tempbuf+1, commandbuf, commandbuf_len); + fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1); + + fx2usb_command("P"); + commandbuf_len = 0; + } + else + { + sync_count = 0x08 | ((sync_count+1) & 0x0f); + commandbuf[commandbuf_len++] = 0x01; + commandbuf[commandbuf_len++] = sync_count; + if (!mode_8bit_per_cycle) + shrink_8bit_to_4bit(); + fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len); + commandbuf_len = 0; + + char cmd[3]; + snprintf(cmd, 3, "W%x", sync_count); + fx2usb_command(cmd); + } + + while (usecs > 0) { + gettimeofday(&tv2, NULL); + rem_usecs = usecs - ((tv2.tv_sec - tv1.tv_sec)*1000000 + (tv2.tv_usec - tv1.tv_usec)); + if (rem_usecs <= 0) + break; + usleep(rem_usecs); + } +} + +static int xpcu_getbyte(struct libxsvf_host *h UNUSED) +{ + return fgetc(file_fp); +} + +static int xpcu_pulse_tck(struct libxsvf_host *h UNUSED, int tms, int tdi, int tdo, int rmask, int sync) +{ + int dummy_sync = 0; + + tck_cycle_count++; + + if (tdo >= 0) { + commandbuf[commandbuf_len++] = 0x08 | ((tdo & 1) << 2) | ((tms & 1) << 1) | ((tdi & 1) << 0); + tdo_check_period_100 = (tdo_check_period_100 * 99) / 100 + tdo_check_thisperiod; + tdo_check_thisperiod = 0; + } else { + commandbuf[commandbuf_len++] = 0x04 | ((tms & 1) << 1) | ((tdi & 1) << 0); + } + + if (mode_async_check == 0) + { + if (!sync && tdo >= 0 && (blocks_without_sync > FORCE_SYNC_AFTER_N_BLOCKS || tdo_check_period_100 > FORCE_SYNC_MIN_PERIOD)) + sync = 1; + if (!sync && !mode_internal_cpld && blocks_without_sync > 10*FORCE_SYNC_AFTER_N_BLOCKS && commandbuf_len >= (MAXBUF() - 10)) + dummy_sync = 1; + } + + if (rmask && !sync) + dummy_sync = 1; + + if ((dummy_sync || sync) && !mode_internal_cpld) { + sync_count = 0x08 | ((sync_count+1) & 0x0f); + commandbuf[commandbuf_len++] = 0x01; + commandbuf[commandbuf_len++] = sync_count; + } + + if (commandbuf_len >= (MAXBUF() - 4) || sync || dummy_sync) { + if (!mode_8bit_per_cycle) + shrink_8bit_to_4bit(); + if (mode_internal_cpld) { + unsigned char tempbuf[64]; + tempbuf[0] = 'J'; + memcpy(tempbuf+1, commandbuf, commandbuf_len); + fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1); + } else { + fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len); + } + blocks_without_sync++; + commandbuf_len = 0; + } + + if ((sync || dummy_sync) && !mode_internal_cpld) { + char cmd[3]; + snprintf(cmd, 3, "W%x", sync_count); + fx2usb_command(cmd); + } + + if (sync) { + fx2usb_command("S"); + blocks_without_sync = 0; + } + + if (dummy_sync) { + fx2usb_command("P"); + blocks_without_sync = 0; + } + + if (rmask) { + if (rmask_bits >= 8*rmask_bytes) { + int old_rmask_bytes = rmask_bytes; + rmask_bytes = rmask_bytes ? rmask_bytes*2 : 64; + rmask_data = realloc(rmask_data, rmask_bytes); + memset(rmask_data + old_rmask_bytes, 0, rmask_bytes-old_rmask_bytes); + } + if (fx2usb_retbuf[mode_internal_cpld ? 5 : 4] == '1') + rmask_data[rmask_bits/8] |= 1 << (rmask_bits%8); + rmask_bits++; + } + + if (sync) { + if (fx2usb_retbuf[mode_internal_cpld ? 1 : 0] == '1') + return -1; + return fx2usb_retbuf[mode_internal_cpld ? 5 : 4] == '1'; + } + return tdo < 0 ? 1 : tdo; +} + +static int xpcu_sync(struct libxsvf_host *h UNUSED) +{ + if (!mode_internal_cpld) { + sync_count = 0x08 | ((sync_count+1) & 0x0f); + commandbuf[commandbuf_len++] = 0x01; + commandbuf[commandbuf_len++] = sync_count; + } + + if (!mode_8bit_per_cycle) + shrink_8bit_to_4bit(); + if (mode_internal_cpld) { + unsigned char tempbuf[64]; + tempbuf[0] = 'J'; + memcpy(tempbuf+1, commandbuf, commandbuf_len); + fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1); + } else { + fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len); + } + commandbuf_len = 0; + + if (!mode_internal_cpld) { + char cmd[3]; + snprintf(cmd, 3, "W%x", sync_count); + fx2usb_command(cmd); + } + + fx2usb_command("S"); + blocks_without_sync = 0; + if (fx2usb_retbuf[mode_internal_cpld ? 1 : 0] == '1') + return -1; + + return 0; +} + +static int xpcu_set_frequency(struct libxsvf_host *h UNUSED, int v) +{ + int freq = 24000000, delay = 0; + + if (mode_internal_cpld) + return 0; + + if (!mode_internal_cpld) { + sync_count = 0x08 | ((sync_count+1) & 0x0f); + commandbuf[commandbuf_len++] = 0x01; + commandbuf[commandbuf_len++] = sync_count; + } + + if (!mode_8bit_per_cycle) + shrink_8bit_to_4bit(); + if (mode_internal_cpld) { + unsigned char tempbuf[64]; + tempbuf[0] = 'J'; + memcpy(tempbuf+1, commandbuf, commandbuf_len); + fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1); + } else { + fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len); + } + commandbuf_len = 0; + + if (!mode_internal_cpld) { + char cmd[3]; + snprintf(cmd, 3, "W%x", sync_count); + fx2usb_command(cmd); + } + + while (delay < 250 && v < freq) { + delay++; + freq = 48000000 / (2*delay + 2); + } + + if (v < freq) + fprintf(stderr, "Requested FREQUENCY %dHz is to low! Using minimum value %dHz instead.\n", v, freq); + else if (v-freq > 10) + fprintf(stderr, "Requested FREQUENCY is %dHz. Using %dHz (24MHz/%d) instead.\n", v, freq, delay+1); + + char cmd[4]; + snprintf(cmd, 4, "T%02x", delay); + fx2usb_command(cmd); + + mode_8bit_per_cycle = delay != 0; + + if (!mode_internal_cpld) + { + sync_count = 0x08 | ((sync_count+1) & 0x0f); + commandbuf[commandbuf_len++] = 0x01; + commandbuf[commandbuf_len++] = sync_count; + if (!mode_8bit_per_cycle) + shrink_8bit_to_4bit(); + fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len); + commandbuf_len = 0; + + char cmd[3]; + snprintf(cmd, 3, "W%x", sync_count); + fx2usb_command(cmd); + } + + return 0; +} + +static void xpcu_report_tapstate(struct libxsvf_host *h UNUSED) +{ + // fprintf(stderr, "[%s]\n", libxsvf_state2str(h->tap_state)); +} + +static void xpcu_report_device(struct libxsvf_host *h UNUSED, unsigned long idcode) +{ + if (internal_jtag_scan_test != 0) { + // CPLD should be: idcode=0x16d4a093, revision=0x1, part=0x6d4a, manufactor=0x049 + if (((idcode >> 12) & 0xffff) == 0x6d4a && ((idcode >> 1) & 0x7ff) == 0x049) + internal_jtag_scan_test += 1; + else + internal_jtag_scan_test += 2; + } else { + printf("idcode=0x%08lx, revision=0x%01lx, part=0x%04lx, manufactor=0x%03lx\n", idcode, + (idcode >> 28) & 0xf, (idcode >> 12) & 0xffff, (idcode >> 1) & 0x7ff); + } +} + +static void xpcu_report_status(struct libxsvf_host *h UNUSED, const char *message UNUSED) +{ + // fprintf(stderr, "[STATUS] %s\n", message); +} + +static void xpcu_report_error(struct libxsvf_host *h UNUSED, const char *file, int line, const char *message) +{ + fprintf(stderr, "[%s:%d] %s\n", file, line, message); +} + +static void *xpcu_realloc(struct libxsvf_host *h UNUSED, void *ptr, int size, enum libxsvf_mem which UNUSED) +{ + return realloc(ptr, size); +} + +static struct libxsvf_host h = { + .udelay = xpcu_udelay, + .setup = xpcu_setup, + .shutdown = xpcu_shutdown, + .getbyte = xpcu_getbyte, + .pulse_tck = xpcu_pulse_tck, + .sync = xpcu_sync, + .set_frequency = xpcu_set_frequency, + .report_tapstate = xpcu_report_tapstate, + .report_device = xpcu_report_device, + .report_status = xpcu_report_status, + .report_error = xpcu_report_error, + .realloc = xpcu_realloc +}; + +const char *progname; + +static void help() +{ + fprintf(stderr, "\n"); + fprintf(stderr, "A JTAG SVF/XSVF Player based on libxsvf for the Xilinx Platform Cable USB\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "xsvftool-xpcu, part of Lib(X)SVF (http://www.clifford.at/libxsvf/).\n"); + fprintf(stderr, "Copyright (C) 2011 RIEGL Research ForschungsGmbH\n"); + fprintf(stderr, "Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>\n"); + fprintf(stderr, "Lib(X)SVF is free software licensed under the ISC license.\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: %s [ -L | -B ] [ -d <vendor>:<device> | -D <device_file> ] [ -f kHz ] [ -A ] [ -P ]\n", progname); + fprintf(stderr, " %*s { -E | -p | -s svf-file | -x xsvf-file | -c } ...\n", (int)strlen(progname), ""); + fprintf(stderr, "\n"); + fprintf(stderr, " -L, -B\n"); + fprintf(stderr, " Print RMASK bits as hex value (little or big endian)\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -d <vendor>:<device>\n"); + fprintf(stderr, " Open the device with this USB vendor and device ID.\n"); + fprintf(stderr, " (default: 03fd:000d and 04b4:8613\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -D <device_file>\n"); + fprintf(stderr, " Open this USB device (usually something like /dev/bus/usb/012/345)\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -f kHz\n"); + fprintf(stderr, " Run probe with the specified frequency (default=6000, max=24000)\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -A\n"); + fprintf(stderr, " Use full asynchonous error checking\n"); + fprintf(stderr, " (very fast but error reporting might be delayed)\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -P\n"); + fprintf(stderr, " Use CPLD on probe as target device\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -p\n"); + fprintf(stderr, " Force (re-)programming the CPLD on the probe\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -E\n"); + fprintf(stderr, " Erase the CPLD on the probe\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -s svf-file\n"); + fprintf(stderr, " Play the specified SVF file\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -x xsvf-file\n"); + fprintf(stderr, " Play the specified XSVF file\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -c\n"); + fprintf(stderr, " List devices in JTAG chain\n"); + fprintf(stderr, "\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + int rc = 0; + int gotaction = 0; + int opt, i, j; + + int done_initialization = 0; + + progname = argc >= 1 ? argv[0] : "xsvftool-xpcu"; + while ((opt = getopt(argc, argv, "LBd:D:f:APpEs:x:c")) != -1) + { + if (!done_initialization && (opt == 'p' || opt == 'E' || opt == 's' || opt == 'x' || opt == 'c')) + { + usb_init(); + usb_find_busses(); + usb_find_devices(); + + fx2usb = fx2usb_open(usb_vendor_id, usb_device_id, usb_device_file); + if (fx2usb == NULL) { + fprintf(stderr, "Failed to find or open USB device!\n"); + exit(1); + } + CHECK(fx2usb_claim(fx2usb), == 0); + + FILE *ihexf = CHECK_PTR(fmemopen(firmware_ihx, sizeof(firmware_ihx), "r"), != NULL); + CHECK(fx2usb_upload_ihex(fx2usb, ihexf), == 0); + CHECK(fclose(ihexf), == 0); + + i = mode_internal_cpld; + mode_internal_cpld = 1; + internal_jtag_scan_test = 1; + libxsvf_play(&h, LIBXSVF_MODE_SCAN); + + if (internal_jtag_scan_test != 2) { + fprintf(stderr, "Probe (device %s on bus %s) failed internal JTAG scan test!\n", + usb_device(fx2usb)->filename, usb_device(fx2usb)->bus->dirname); + exit(1); + } + mode_internal_cpld = i; + internal_jtag_scan_test = 0; + + fprintf(stderr, "Connected to probe (device %s on bus %s) and passed internal JTAG scan test.\n", + usb_device(fx2usb)->filename, usb_device(fx2usb)->bus->dirname); + + if (opt != 'p' && opt != 'E' && !mode_internal_cpld) { + fx2usb_command("C"); + if (memcmp(correct_cksum, fx2usb_retbuf, 6)) { + fprintf(stderr, "Mismatch in CPLD checksum (is=%.6s, should=%s): reprogramming CPLD on probe..\n", + fx2usb_retbuf, correct_cksum); + i = mode_internal_cpld; + mode_internal_cpld = 1; + file_fp = CHECK_PTR(fmemopen(hardware_svf, sizeof(hardware_svf), "r"), != NULL); + libxsvf_play(&h, LIBXSVF_MODE_SVF); + mode_internal_cpld = i; + fclose(file_fp); + } + } + + done_initialization = 1; + } + + switch (opt) + { + case 'L': + mode_hex_rmask = 1; + break; + case 'B': + mode_hex_rmask = 2; + break; + case 'd': + if (usb_vendor_id || usb_device_id || usb_device_file || fx2usb) + help(); + if (sscanf(optarg, "%x:%x", &usb_vendor_id, &usb_device_id) != 2) + help(); + break; + case 'D': + if (usb_vendor_id || usb_device_id || usb_device_file || fx2usb) + help(); + usb_device_file = strdup(optarg); + break; + case 'f': + mode_frequency = atoi(optarg); + break; + case 'P': + mode_internal_cpld = 1; + break; + case 'A': + mode_async_check = 1; + break; + case 'p': + case 'E': + gotaction = 1; + i = mode_internal_cpld; + mode_internal_cpld = 1; + if (opt == 'p') { + file_fp = CHECK_PTR(fmemopen(hardware_svf, sizeof(hardware_svf), "r"), != NULL); + fprintf(stderr, "(Re-)programming CPLD on the probe..\n"); + } else { + file_fp = CHECK_PTR(fmemopen(erasecpld_svf, sizeof(erasecpld_svf), "r"), != NULL); + fprintf(stderr, "Erasing CPLD on the probe..\n"); + } + libxsvf_play(&h, LIBXSVF_MODE_SVF); + mode_internal_cpld = i; + fclose(file_fp); + break; + case 'x': + case 's': + gotaction = 1; + if (!strcmp(optarg, "-")) + file_fp = stdin; + else + file_fp = fopen(optarg, "rb"); + if (file_fp == NULL) { + fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno)); + rc = 1; + break; + } + fprintf(stderr, "Playing %s file `%s'..\n", opt == 's' ? "SVF" : "XSVF", optarg); + if (libxsvf_play(&h, opt == 's' ? LIBXSVF_MODE_SVF : LIBXSVF_MODE_XSVF) < 0) { + fprintf(stderr, "Error while playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg); + rc = 1; + } + if (strcmp(optarg, "-")) + fclose(file_fp); + break; + case 'c': + gotaction = 1; + fprintf(stderr, "Scanning JTAG chain..\n"); + if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) { + fprintf(stderr, "Error while scanning JTAG chain.\n"); + rc = 1; + } + break; + default: + help(); + break; + } + } + + if (!gotaction) + help(); + + if (rmask_bits > 0) { + fprintf(stderr, "Total number of rmask bits acquired: %d\n", rmask_bits); + if (mode_hex_rmask) { + printf("0x"); + for (i = 0; i < rmask_bits; i += 4) { + int val = 0; + for (j = i; j < i + 4; j++) { + int pos = mode_hex_rmask > 1 ? j : rmask_bits - j - 1; + val = (val << 1) | (rmask_data[pos/8] & (1 << (pos%8)) ? 1 : 0); + } + printf("%x", val); + } + } else { + for (i = 0; i < rmask_bits; i++) + putchar((rmask_data[i / 8] & (1 << (i % 8))) != 0 ? '1' : '0'); + } + putchar('\n'); + } + + if (done_initialization) { + fx2usb_command("X"); + fx2usb_release(fx2usb); + usb_close(fx2usb); + } + + fprintf(stderr, "Total number of JTAG clock cycles performed: %d\n", tck_cycle_count); + if (rc == 0) + fprintf(stderr, "READY.\n"); + else + fprintf(stderr, "TERMINATED WITH ERROR(s)! (see above)\n"); + + return rc; +} + |