Browse Source

x6500: Bare minimum detection-only X6500 support via libusb

Luke Dashjr 13 years ago
parent
commit
55623b7ae9
6 changed files with 289 additions and 3 deletions
  1. 6 0
      Makefile.am
  2. 29 2
      configure.ac
  3. 66 0
      driver-x6500.c
  4. 146 0
      ft232r.c
  5. 21 0
      ft232r.h
  6. 21 1
      miner.c

+ 6 - 0
Makefile.am

@@ -114,6 +114,12 @@ bitstreamsdir = $(bindir)/bitstreams
 dist_bitstreams_DATA = bitstreams/*
 endif
 
+if HAS_X6500
+bfgminer_SOURCES += driver-x6500.c ft232r.c
+bitstreamsdir = $(bindir)/bitstreams
+dist_bitstreams_DATA = bitstreams/*
+endif
+
 if HAS_ZTEX
 bfgminer_SOURCES += driver-ztex.c libztex.c libztex.h
 bitstreamsdir = $(bindir)/bitstreams

+ 29 - 2
configure.ac

@@ -197,6 +197,25 @@ AC_CHECK_LIB(usb-1.0, libusb_init,
 	[libusb=no]
 )
 
+AC_ARG_ENABLE([x6500],
+	[AC_HELP_STRING([--disable-x6500],[Compile support for X6500 (default if libusb)])],
+	[x6500=$enableval],
+	[x6500=auto]
+	)
+if test "x$x6500$libusb" = xyesno; then
+	AC_MSG_ERROR([Could not find libusb, required for X6500 support])
+elif test "x$x6500" = xauto; then
+	x6500="$libusb"
+	if test "x$libusb" = xno; then
+		AC_MSG_WARN([Could not find libusb, required for X6500 support])
+		x6500warn=yes
+	fi
+fi
+if test "x$x6500" = xyes; then
+	AC_DEFINE([USE_X6500], [1], [Defined to 1 if X6500 support is wanted])
+fi
+AM_CONDITIONAL([HAS_X6500], [test x$x6500 = xyes])
+
 AC_ARG_ENABLE([ztex],
 	[AC_HELP_STRING([--disable-ztex],[Compile support for Ztex (default if libusb)])],
 	[ztex=$enableval],
@@ -291,8 +310,8 @@ fi
 AC_CONFIG_SUBDIRS([libblkmaker])
 
 AM_CONDITIONAL([NEED_LIBBLKMAKER], [true])
-AM_CONDITIONAL([NEED_DYNCLOCK], [test x$icarus$modminer$ztex != xnonono])
-AM_CONDITIONAL([NEED_FPGAUTILS], [test x$icarus$bitforce$modminer$ztex != xnononono])
+AM_CONDITIONAL([NEED_DYNCLOCK], [test x$icarus$modminer$x6500$ztex != xnonono])
+AM_CONDITIONAL([NEED_FPGAUTILS], [test x$icarus$bitforce$modminer$x6500$ztex != xnononono])
 AM_CONDITIONAL([HAS_SCRYPT], [test x$scrypt = xyes])
 AM_CONDITIONAL([HAVE_CURSES], [test x$curses = xyes])
 AM_CONDITIONAL([HAVE_CYGWIN], [test x$have_cygwin = xtrue])
@@ -484,6 +503,14 @@ else
 	echo "  ModMiner.FPGAs.......: Disabled"
 fi
 
+if test "x$x6500" = xyes; then
+	echo "  X6500.FPGAs..........: Enabled"
+elif test "x$ztexwarn" = xyes; then
+	echo "  X6500.FPGAs..........: Disabled (libusb not found)"
+else
+	echo "  X6500.FPGAs..........: Disabled"
+fi
+
 if test "x$ztex" = xyes; then
 	echo "  Ztex.FPGAs...........: Enabled"
 elif test "x$ztexwarn" = xyes; then

+ 66 - 0
driver-x6500.c

@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012 Luke Dashjr
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.  See COPYING for more details.
+ */
+
+#include <libusb-1.0/libusb.h>
+
+#include "dynclock.h"
+#include "logging.h"
+#include "miner.h"
+#include "fpgautils.h"
+#include "ft232r.h"
+
+#define X6500_USB_PRODUCT "X6500 FPGA Miner"
+#define X6500_BITSTREAM_FILENAME "fpgaminer_top_fixed7_197MHz.bit"
+#define X6500_BISTREAM_USERID "\2\4$B"
+#define X6500_MINIMUM_CLOCK    2
+#define X6500_DEFAULT_CLOCK  200
+#define X6500_MAXIMUM_CLOCK  210
+
+struct device_api x6500_api;
+
+static bool x6500_foundusb(libusb_device *dev, const char *product, const char *serial)
+{
+	struct cgpu_info *x6500;
+	x6500 = calloc(1, sizeof(*x6500));
+	x6500->api = &x6500_api;
+	mutex_init(&x6500->device_mutex);
+	x6500->device_path = strdup(serial);
+	x6500->device_fd = -1;
+	x6500->deven = DEV_ENABLED;
+	x6500->threads = 2;
+	x6500->name = strdup(product);
+	x6500->cutofftemp = 85;
+	x6500->cgpu_data = dev;
+
+	return add_cgpu(x6500);
+}
+
+static bool x6500_detect_one(const char *serial)
+{
+	return ft232r_detect(X6500_USB_PRODUCT, serial, x6500_foundusb);
+}
+
+static int x6500_detect_auto()
+{
+	return ft232r_detect(X6500_USB_PRODUCT, NULL, x6500_foundusb);
+}
+
+static void x6500_detect()
+{
+	serial_detect_auto(&x6500_api, x6500_detect_one, x6500_detect_auto);
+}
+
+struct device_api x6500_api = {
+	.dname = "x6500",
+	.name = "XBS",
+	.api_detect = x6500_detect,
+// 	.thread_init = x6500_fpga_init,
+// 	.scanhash = x6500_fpga_scanhash,
+// 	.thread_shutdown = x6500_fpga_shutdown,
+};

+ 146 - 0
ft232r.c

@@ -0,0 +1,146 @@
+/*
+ * Copyright 2012 Luke Dashjr
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.  See COPYING for more details.
+ */
+
+#include <libusb-1.0/libusb.h>
+
+#include "fpgautils.h"
+#include "ft232r.h"
+#include "logging.h"
+#include "miner.h"
+
+#define FT232R_IDVENDOR   0x0403
+#define FT232R_IDPRODUCT  0x6001
+
+struct ft232r_device_info {
+	libusb_device *libusb_dev;
+	char *product;
+	char *serial;
+};
+
+static struct ft232r_device_info **ft232r_devinfo_list;
+
+void ft232r_scan_free()
+{
+	if (!ft232r_devinfo_list)
+		return;
+
+	struct ft232r_device_info *info;
+
+	for (struct ft232r_device_info **infop = ft232r_devinfo_list; (info = *infop); ++infop) {
+		libusb_unref_device(info->libusb_dev);
+		free(info->product);
+		free(info->serial);
+		free(info);
+	}
+	free(ft232r_devinfo_list);
+	ft232r_devinfo_list = NULL;
+}
+
+void ft232r_scan()
+{
+	ssize_t n, i, found = 0;
+	libusb_device **list;
+	struct libusb_device_descriptor desc;
+	libusb_device_handle *handle;
+	struct ft232r_device_info *info;
+	int err;
+	unsigned char buf[0x100];
+
+	ft232r_scan_free();
+
+	n = libusb_get_device_list(NULL, &list);
+	if (unlikely(n < 0)) {
+		applog(LOG_ERR, "ft232r scan: Error getting USB device list: %s", libusb_error_name(n));
+		ft232r_devinfo_list = calloc(1, sizeof(struct ft232r_device_info *));
+		return;
+	}
+
+	ft232r_devinfo_list = malloc(sizeof(struct ft232r_device_info *) * (n + 1));
+
+	for (i = 0; i < n; ++i) {
+		err = libusb_get_device_descriptor(list[i], &desc);
+		if (unlikely(err)) {
+			applog(LOG_ERR, "ft232r scan: Error getting device descriptor: %s", libusb_error_name(err));
+			continue;
+		}
+		if (!(desc.idVendor == FT232R_IDVENDOR && desc.idProduct == FT232R_IDPRODUCT))
+			continue;
+
+		err = libusb_open(list[i], &handle);
+		if (unlikely(err)) {
+			applog(LOG_ERR, "ft232r scan: Error opening device: %s", libusb_error_name(err));
+			continue;
+		}
+
+		n = libusb_get_string_descriptor_ascii(handle, desc.iProduct, buf, sizeof(buf)-1);
+		if (unlikely(n < 0)) {
+			libusb_close(handle);
+			applog(LOG_ERR, "ft232r scan: Error getting iProduct string: %s", libusb_error_name(n));
+			continue;
+		}
+		buf[n] = '\0';
+		info = malloc(sizeof(struct ft232r_device_info));
+		info->product = strdup((char*)buf);
+
+		n = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, buf, sizeof(buf)-1);
+		libusb_close(handle);
+		if (unlikely(n < 0)) {
+			applog(LOG_ERR, "ft232r scan: Error getting iSerialNumber string: %s", libusb_error_name(n));
+			n = 0;
+		}
+		buf[n] = '\0';
+		info->serial = strdup((char*)buf);
+		info->libusb_dev = libusb_ref_device(list[i]);
+		ft232r_devinfo_list[found++] = info;
+
+		applog(LOG_DEBUG, "ft232r scan: Found \"%s\" serial \"%s\"", info->product, info->serial);
+	}
+
+	ft232r_devinfo_list[found] = NULL;
+	libusb_free_device_list(list, 1);
+}
+
+int ft232r_detect(const char *product_needle, const char *serial, foundusb_func_t cb)
+{
+	struct ft232r_device_info *info;
+	int found = 0;
+
+	for (struct ft232r_device_info **infop = ft232r_devinfo_list; (info = *infop); ++infop) {
+		if (!strstr(info->product, product_needle))
+			continue;
+		if (serial && strcmp(serial, info->serial))
+			continue;
+		if (!info->libusb_dev)
+			continue;
+		if (!cb(info->libusb_dev, info->product, info->serial))
+			continue;
+		info->libusb_dev = NULL;
+		++found;
+	}
+
+	return found;
+}
+
+#if 0
+int main() {
+	libusb_init(NULL);
+	ft232r_scan();
+	ft232r_scan_free();
+	libusb_exit(NULL);
+}
+void applog(int prio, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vprintf(fmt, ap);
+	puts("");
+	va_end(ap);
+}
+#endif

+ 21 - 0
ft232r.h

@@ -0,0 +1,21 @@
+/*
+ * Copyright 2012 Luke Dashjr
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.  See COPYING for more details.
+ */
+
+#ifndef BFGMINER_FT232R_H
+#define BFGMINER_FT232R_H
+
+#include <libusb-1.0/libusb.h>
+
+typedef bool(*foundusb_func_t)(libusb_device *, const char *product, const char *serial);
+
+extern void ft232r_scan();
+extern void ft232r_scan_free();
+extern int ft232r_detect(const char *product_needle, const char *serial, foundusb_func_t);
+
+#endif

+ 21 - 1
miner.c

@@ -55,6 +55,10 @@
 #include "driver-opencl.h"
 #include "bench_block.h"
 
+#ifdef USE_X6500
+#include "ft232r.h"
+#endif
+
 #if defined(unix)
 	#include <errno.h>
 	#include <fcntl.h>
@@ -68,7 +72,7 @@
 #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_MODMINER)
 #	define USE_FPGA
 #	define USE_FPGA_SERIAL
-#elif defined(USE_ZTEX)
+#elif defined(USE_ZTEX) || defined(USE_X6500)
 #	define USE_FPGA
 #endif
 
@@ -6367,6 +6371,10 @@ extern struct device_api icarus_api;
 extern struct device_api modminer_api;
 #endif
 
+#ifdef USE_X6500
+extern struct device_api x6500_api;
+#endif
+
 #ifdef USE_ZTEX
 extern struct device_api ztex_api;
 #endif
@@ -6450,6 +6458,9 @@ int main(int argc, char *argv[])
 #ifdef HAVE_LIBUSB
         libusb_init(NULL);
 #endif
+#ifdef USE_X6500
+	ft232r_scan();
+#endif
 
 	mutex_init(&hash_lock);
 	mutex_init(&qd_lock);
@@ -6654,6 +6665,11 @@ int main(int argc, char *argv[])
 		modminer_api.api_detect();
 #endif
 
+#ifdef USE_X6500
+	if (!opt_scrypt)
+		x6500_api.api_detect();
+#endif
+
 #ifdef USE_ZTEX
 	if (!opt_scrypt)
 		ztex_api.api_detect();
@@ -6663,6 +6679,10 @@ int main(int argc, char *argv[])
 	cpu_api.api_detect();
 #endif
 
+#ifdef USE_X6500
+	ft232r_scan_free();
+#endif
+
 	for (i = 0; i < total_devices; ++i)
 		if (!devices[i]->devtype)
 			devices[i]->devtype = "PGA";