summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fpga/xilinx/programmer/svfplayer/beaglebone_black/Makefile47
-rw-r--r--fpga/xilinx/programmer/svfplayer/beaglebone_black/xsvf-bbb.c546
-rw-r--r--fpga/xilinx/programmer/svfplayer/raspberry_pi/Makefile (renamed from fpga/xilinx/programmer/svfplayer/Makefile)0
-rw-r--r--fpga/xilinx/programmer/svfplayer/raspberry_pi/xsvf-rpi.c (renamed from fpga/xilinx/programmer/svfplayer/xsvf-rpi.c)0
4 files changed, 593 insertions, 0 deletions
diff --git a/fpga/xilinx/programmer/svfplayer/beaglebone_black/Makefile b/fpga/xilinx/programmer/svfplayer/beaglebone_black/Makefile
new file mode 100644
index 0000000..5a5701e
--- /dev/null
+++ b/fpga/xilinx/programmer/svfplayer/beaglebone_black/Makefile
@@ -0,0 +1,47 @@
+# Copyright (C) 2013 Timothy Pearson
+#
+# 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.
+
+AR = ar
+RANLIB = ranlib
+CC = gcc
+
+CFLAGS += -Wall -Os -ggdb -MD
+#CFLAGS += -Wextra -Wno-unused-parameter -Werror
+
+help:
+ @echo ""
+ @echo "Usage:"
+ @echo ""
+ @echo " $(MAKE) xsvf-bbb"
+ @echo " .... build xsvf-bbb"
+ @echo ""
+ @echo " $(MAKE) all"
+ @echo " .... build everything"
+ @echo ""
+ @echo " $(MAKE) install"
+ @echo " .... install everything in /usr/"
+ @echo ""
+
+all: xsvf-bbb
+
+install: all
+ install -Dt /usr/bin/ xsvf-bbb
+
+xsvf-bbb: /usr/lib/libxsvf.a xsvf-bbb.o
+
+clean:
+ rm -f xsvf-bbb.o
+
+-include *.d
+
diff --git a/fpga/xilinx/programmer/svfplayer/beaglebone_black/xsvf-bbb.c b/fpga/xilinx/programmer/svfplayer/beaglebone_black/xsvf-bbb.c
new file mode 100644
index 0000000..3b314af
--- /dev/null
+++ b/fpga/xilinx/programmer/svfplayer/beaglebone_black/xsvf-bbb.c
@@ -0,0 +1,546 @@
+/*
+ * Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
+ *
+ * Copyright (C) 2013 Timothy Pearson <kb9vqf@pearsoncomputing.net> (Beaglebone Black)
+ * Copyright (C) 2009 RIEGL Research ForschungsGmbH
+ * Copyright (C) 2009 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.
+ *
+ */
+
+#include "libxsvf.h"
+
+#include <sys/time.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+
+/** BEGIN: Low-Level I/O Implementation **/
+
+// Beaglebone Black GPIO driver
+// TMS: P9 11 (GPIO 30)
+// TDI: P9 13 (GPIO 31)
+// TDO: P9 21 (GPIO 3)
+// TCK: P9 22 (GPIO 2)
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#define GPIO0_BASE 0x44E07000
+#define GPIO1_BASE 0x4804C000
+#define GPIO2_BASE 0x481AC000
+#define GPIO3_BASE 0x481AE000
+
+#define GPIO_SIZE 0x00000FFF
+
+// OE: 0 is output, 1 is input
+#define GPIO_OE 0x14d
+#define GPIO_IN 0x14e
+#define GPIO_OUT 0x14f
+
+#define TMS_PIN (1<<30)
+#define TDI_PIN (1<<31)
+#define TDO_PIN (1<<3)
+#define TCK_PIN (1<<2)
+
+int mem_fd;
+char *gpio_mem, *gpio_map;
+
+// I/O access
+volatile unsigned *gpio;
+
+static void io_setup(void)
+{
+ // Enable all GPIO banks
+ // Without this, access to deactivated banks (i.e. those with no clock source setup) will (logically) fail with SIGBUS
+ // Idea taken from https://groups.google.com/forum/#!msg/beagleboard/OYFp4EXawiI/Mq6s3sg14HoJ
+ system("echo 5 > /sys/class/gpio/export");
+ system("echo 65 > /sys/class/gpio/export");
+ system("echo 105 > /sys/class/gpio/export");
+
+ /* open /dev/mem */
+ if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
+ printf("can't open /dev/mem \n");
+ exit (-1);
+ }
+
+ /* mmap GPIO */
+ gpio_map = (char *)mmap(
+ 0,
+ GPIO_SIZE,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED,
+ mem_fd,
+ GPIO0_BASE
+ );
+
+ if (gpio_map == MAP_FAILED) {
+ printf("mmap error %d\n", (int)gpio_map);
+ exit (-1);
+ }
+
+ // Always use volatile pointer!
+ gpio = (volatile unsigned *)gpio_map;
+
+#if 0
+ // DEBUG ONLY
+ // Prints the contents of the memory mapped control register space
+ // Originally used to reverse engineer the register offsets #defined at the top of this file
+ int k;
+ for (k=0;k<GPIO_SIZE; k++) {
+ printf("0x%08x\t%08x\n", k, *(gpio + k));
+ }
+ fflush(stdout);
+#endif
+
+ // Get direction control register contents
+ unsigned int creg = *(gpio + GPIO_OE);
+
+ // Set outputs
+ creg = creg & (~TMS_PIN);
+ creg = creg & (~TDI_PIN);
+ creg = creg & (~TCK_PIN);
+
+ // Set inputs
+ creg = creg | TDO_PIN;
+
+ // Set new direction control register contents
+ *(gpio + GPIO_OE) = creg;
+}
+
+static void io_shutdown(void)
+{
+ // Get direction control register contents
+ unsigned int creg = *(gpio + GPIO_OE);
+
+ // Set inputs
+ creg = creg | TMS_PIN;
+ creg = creg | TDI_PIN;
+ creg = creg | TDO_PIN;
+ creg = creg | TCK_PIN;
+
+ // Set new direction control register contents
+ *(gpio + GPIO_OE) = creg;
+}
+
+static void io_tms(int val)
+{
+ if (val) {
+ *(gpio + GPIO_OUT) = *(gpio + GPIO_OUT) | TMS_PIN;
+ }
+ else {
+ *(gpio + GPIO_OUT) = *(gpio + GPIO_OUT) & (~TMS_PIN);
+ }
+}
+
+static void io_tdi(int val)
+{
+ if (val) {
+ *(gpio + GPIO_OUT) = *(gpio + GPIO_OUT) | TDI_PIN;
+ }
+ else {
+ *(gpio + GPIO_OUT) = *(gpio + GPIO_OUT) & (~TDI_PIN);
+ }
+}
+
+static void io_tck(int val)
+{
+ if (val) {
+ *(gpio + GPIO_OUT) = *(gpio + GPIO_OUT) | TCK_PIN;
+ }
+ else {
+ *(gpio + GPIO_OUT) = *(gpio + GPIO_OUT) & (~TCK_PIN);
+ }
+
+ // usleep(1);
+}
+
+static void io_sck(int val)
+{
+ /* not available */
+}
+
+static void io_trst(int val)
+{
+ /* not available */
+}
+
+static int io_tdo()
+{
+ return ((*(gpio + GPIO_IN)) & TDO_PIN) ? 1 : 0;
+}
+
+/** END: Low-Level I/O Implementation **/
+
+
+struct udata_s {
+ FILE *f;
+ int verbose;
+ int clockcount;
+ int bitcount_tdi;
+ int bitcount_tdo;
+ int retval_i;
+ int retval[256];
+};
+
+static int h_setup(struct libxsvf_host *h)
+{
+ struct udata_s *u = h->user_data;
+ if (u->verbose >= 2) {
+ fprintf(stderr, "[SETUP]\n");
+ fflush(stderr);
+ }
+ io_setup();
+ return 0;
+}
+
+static int h_shutdown(struct libxsvf_host *h)
+{
+ struct udata_s *u = h->user_data;
+ if (u->verbose >= 2) {
+ fprintf(stderr, "[SHUTDOWN]\n");
+ fflush(stderr);
+ }
+ io_shutdown();
+ return 0;
+}
+
+static void h_udelay(struct libxsvf_host *h, long usecs, int tms, long num_tck)
+{
+ struct udata_s *u = h->user_data;
+ if (u->verbose >= 3) {
+ fprintf(stderr, "[DELAY:%ld, TMS:%d, NUM_TCK:%ld]\n", usecs, tms, num_tck);
+ fflush(stderr);
+ }
+ if (num_tck > 0) {
+ struct timeval tv1, tv2;
+ gettimeofday(&tv1, NULL);
+ io_tms(tms);
+ while (num_tck > 0) {
+ io_tck(0);
+ io_tck(1);
+ num_tck--;
+ }
+ gettimeofday(&tv2, NULL);
+ if (tv2.tv_sec > tv1.tv_sec) {
+ usecs -= (1000000 - tv1.tv_usec) + (tv2.tv_sec - tv1.tv_sec - 1) * 1000000;
+ tv1.tv_usec = 0;
+ }
+ usecs -= tv2.tv_usec - tv1.tv_usec;
+ if (u->verbose >= 3) {
+ fprintf(stderr, "[DELAY_AFTER_TCK:%ld]\n", usecs > 0 ? usecs : 0);
+ fflush(stderr);
+ }
+ }
+ if (usecs > 0) {
+ usleep(usecs);
+ }
+}
+
+static int h_getbyte(struct libxsvf_host *h)
+{
+ struct udata_s *u = h->user_data;
+ return fgetc(u->f);
+}
+
+static int h_pulse_tck(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync)
+{
+ struct udata_s *u = h->user_data;
+
+ io_tms(tms);
+
+ if (tdi >= 0) {
+ u->bitcount_tdi++;
+ io_tdi(tdi);
+ }
+
+ io_tck(0);
+ io_tck(1);
+
+ int line_tdo = io_tdo();
+ int rc = line_tdo >= 0 ? line_tdo : 0;
+
+ if (rmask == 1 && u->retval_i < 256)
+ u->retval[u->retval_i++] = line_tdo;
+
+ if (tdo >= 0 && line_tdo >= 0) {
+ u->bitcount_tdo++;
+ if (tdo != line_tdo)
+ rc = -1;
+ }
+
+ if (u->verbose >= 4) {
+ fprintf(stderr, "[TMS:%d, TDI:%d, TDO_ARG:%d, TDO_LINE:%d, RMASK:%d, RC:%d]\n", tms, tdi, tdo, line_tdo, rmask, rc);
+ }
+
+ u->clockcount++;
+ return rc;
+}
+
+static void h_pulse_sck(struct libxsvf_host *h)
+{
+ struct udata_s *u = h->user_data;
+ if (u->verbose >= 4) {
+ fprintf(stderr, "[SCK]\n");
+ }
+ io_sck(0);
+ io_sck(1);
+}
+
+static void h_set_trst(struct libxsvf_host *h, int v)
+{
+ struct udata_s *u = h->user_data;
+ if (u->verbose >= 4) {
+ fprintf(stderr, "[TRST:%d]\n", v);
+ }
+ io_trst(v);
+}
+
+static int h_set_frequency(struct libxsvf_host *h, int v)
+{
+ fprintf(stderr, "WARNING: Setting JTAG clock frequency to %d ignored!\n", v);
+ return 0;
+}
+
+static void h_report_tapstate(struct libxsvf_host *h)
+{
+ struct udata_s *u = h->user_data;
+ if (u->verbose >= 3) {
+ fprintf(stderr, "[%s]\n", libxsvf_state2str(h->tap_state));
+ }
+}
+
+static void h_report_device(struct libxsvf_host *h, unsigned long idcode)
+{
+ // struct udata_s *u = h->user_data;
+ 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 h_report_status(struct libxsvf_host *h, const char *message)
+{
+ struct udata_s *u = h->user_data;
+ if (u->verbose >= 2) {
+ fprintf(stderr, "[STATUS] %s\n", message);
+ }
+}
+
+static void h_report_error(struct libxsvf_host *h, const char *file, int line, const char *message)
+{
+ fprintf(stderr, "[%s:%d] %s\n", file, line, message);
+}
+
+static int realloc_maxsize[LIBXSVF_MEM_NUM];
+
+static void *h_realloc(struct libxsvf_host *h, void *ptr, int size, enum libxsvf_mem which)
+{
+ struct udata_s *u = h->user_data;
+ if (size > realloc_maxsize[which])
+ realloc_maxsize[which] = size;
+ if (u->verbose >= 3) {
+ fprintf(stderr, "[REALLOC:%s:%d]\n", libxsvf_mem2str(which), size);
+ }
+ return realloc(ptr, size);
+}
+
+static struct udata_s u;
+
+static struct libxsvf_host h = {
+ .udelay = h_udelay,
+ .setup = h_setup,
+ .shutdown = h_shutdown,
+ .getbyte = h_getbyte,
+ .pulse_tck = h_pulse_tck,
+ .pulse_sck = h_pulse_sck,
+ .set_trst = h_set_trst,
+ .set_frequency = h_set_frequency,
+ .report_tapstate = h_report_tapstate,
+ .report_device = h_report_device,
+ .report_status = h_report_status,
+ .report_error = h_report_error,
+ .realloc = h_realloc,
+ .user_data = &u
+};
+
+const char *progname;
+
+static void copyleft()
+{
+ static int already_printed = 0;
+ if (already_printed)
+ return;
+ fprintf(stderr, "xsvftool-gpio, part of Lib(X)SVF (http://www.clifford.at/libxsvf/).\n");
+ fprintf(stderr, "Copyright (C) 2009 RIEGL Research ForschungsGmbH\n");
+ fprintf(stderr, "Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>\n");
+ fprintf(stderr, "Copyright (C) 2013 Timothy Pearson <kb9vqf@pearsoncomputing.net> (Beaglebone Black)\n");
+ fprintf(stderr, "Lib(X)SVF is free software licensed under the ISC license.\n");
+ already_printed = 1;
+}
+
+static void help()
+{
+ copyleft();
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Usage: %s [ -r funcname ] [ -v ... ] [ -L | -B ] { -s svf-file | -x xsvf-file | -c } ...\n", progname);
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -r funcname\n");
+ fprintf(stderr, " Dump C-code for pseudo-allocator based on example files\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -v, -vv, -vvv, -vvvv\n");
+ fprintf(stderr, " Verbose, more verbose and even more verbose\n");
+ 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, " -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 hex_mode = 0;
+ const char *realloc_name = NULL;
+ int opt, i, j;
+
+ progname = argc >= 1 ? argv[0] : "xvsftool";
+ while ((opt = getopt(argc, argv, "r:vLBx:s:c")) != -1)
+ {
+ switch (opt)
+ {
+ case 'r':
+ realloc_name = optarg;
+ break;
+ case 'v':
+ copyleft();
+ u.verbose++;
+ break;
+ case 'x':
+ case 's':
+ gotaction = 1;
+ if (u.verbose)
+ fprintf(stderr, "Playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
+ if (!strcmp(optarg, "-"))
+ u.f = stdin;
+ else
+ u.f = fopen(optarg, "rb");
+ if (u.f == NULL) {
+ fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno));
+ rc = 1;
+ break;
+ }
+ 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(u.f);
+ break;
+ case 'c':
+ gotaction = 1;
+ if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) {
+ fprintf(stderr, "Error while scanning JTAG chain.\n");
+ rc = 1;
+ }
+ break;
+ case 'L':
+ hex_mode = 1;
+ break;
+ case 'B':
+ hex_mode = 2;
+ break;
+ default:
+ help();
+ break;
+ }
+ }
+
+ if (!gotaction)
+ help();
+
+ if (u.verbose) {
+ fprintf(stderr, "Total number of clock cycles: %d\n", u.clockcount);
+ fprintf(stderr, "Number of significant TDI bits: %d\n", u.bitcount_tdi);
+ fprintf(stderr, "Number of significant TDO bits: %d\n", u.bitcount_tdo);
+ if (rc == 0) {
+ fprintf(stderr, "Finished without errors.\n");
+ } else {
+ fprintf(stderr, "Finished with errors!\n");
+ }
+ }
+
+ if (u.retval_i) {
+ if (hex_mode) {
+ printf("0x");
+ for (i=0; i < u.retval_i; i+=4) {
+ int val = 0;
+ for (j=i; j<i+4; j++)
+ val = val << 1 | u.retval[hex_mode > 1 ? j : u.retval_i - j - 1];
+ printf("%x", val);
+ }
+ } else {
+ printf("%d rmask bits:", u.retval_i);
+ for (i=0; i < u.retval_i; i++)
+ printf(" %d", u.retval[i]);
+ }
+ printf("\n");
+ }
+
+ if (realloc_name) {
+ int num = 0;
+ for (i = 0; i < LIBXSVF_MEM_NUM; i++) {
+ if (realloc_maxsize[i] > 0)
+ num = i+1;
+ }
+ printf("void *%s(void *h, void *ptr, int size, int which) {\n", realloc_name);
+ for (i = 0; i < num; i++) {
+ if (realloc_maxsize[i] > 0)
+ printf("\tstatic unsigned char buf_%s[%d];\n", libxsvf_mem2str(i), realloc_maxsize[i]);
+ }
+ printf("\tstatic unsigned char *buflist[%d] = {", num);
+ for (i = 0; i < num; i++) {
+ if (realloc_maxsize[i] > 0)
+ printf("%sbuf_%s", i ? ", " : " ", libxsvf_mem2str(i));
+ else
+ printf("%s(void*)0", i ? ", " : " ");
+ }
+ printf(" };\n\tstatic int sizelist[%d] = {", num);
+ for (i = 0; i < num; i++) {
+ if (realloc_maxsize[i] > 0)
+ printf("%ssizeof(buf_%s)", i ? ", " : " ", libxsvf_mem2str(i));
+ else
+ printf("%s0", i ? ", " : " ");
+ }
+ printf(" };\n");
+ printf("\treturn which < %d && size <= sizelist[which] ? buflist[which] : (void*)0;\n", num);
+ printf("};\n");
+ }
+
+ return rc;
+}
+
diff --git a/fpga/xilinx/programmer/svfplayer/Makefile b/fpga/xilinx/programmer/svfplayer/raspberry_pi/Makefile
index 176b0a3..176b0a3 100644
--- a/fpga/xilinx/programmer/svfplayer/Makefile
+++ b/fpga/xilinx/programmer/svfplayer/raspberry_pi/Makefile
diff --git a/fpga/xilinx/programmer/svfplayer/xsvf-rpi.c b/fpga/xilinx/programmer/svfplayer/raspberry_pi/xsvf-rpi.c
index 034abbc..034abbc 100644
--- a/fpga/xilinx/programmer/svfplayer/xsvf-rpi.c
+++ b/fpga/xilinx/programmer/svfplayer/raspberry_pi/xsvf-rpi.c