Browse Source

Merge branch 'metabank' into bitfury

Conflicts:
	Makefile.am
	driver-bitfury.c
Luke Dashjr 12 years ago
parent
commit
860b9aab57
9 changed files with 317 additions and 26 deletions
  1. 1 1
      Makefile.am
  2. 183 0
      driver-bfsb.c
  3. 41 15
      driver-bitfury.c
  4. 3 0
      driver-metabank.c
  5. 51 4
      libbitfury.c
  6. 1 0
      libbitfury.h
  7. 2 0
      miner.c
  8. 32 6
      spidevc.c
  9. 3 0
      spidevc.h

+ 1 - 1
Makefile.am

@@ -211,7 +211,7 @@ bfgminer_SOURCES += driver-ztex.c libztex.c libztex.h
 endif
 endif
 
 
 if HAS_BITFURY
 if HAS_BITFURY
-bfgminer_SOURCES += driver-bitfury.c driver-bitfury.h libbitfury.c libbitfury.h spidevc.h spidevc.c driver-metabank.c tm_i2c.h tm_i2c.c
+bfgminer_SOURCES += driver-bitfury.c driver-bitfury.h libbitfury.c libbitfury.h spidevc.h spidevc.c driver-metabank.c tm_i2c.h tm_i2c.c driver-bfsb.c
 
 
 if HAS_LITTLEFURY
 if HAS_LITTLEFURY
 bfgminer_SOURCES += driver-littlefury.c
 bfgminer_SOURCES += driver-littlefury.c

+ 183 - 0
driver-bfsb.c

@@ -0,0 +1,183 @@
+/*
+ * Copyright 2013 bitfury
+ * Copyright 2013 legkodymov
+ * Copyright 2013 Luke Dashjr
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include "deviceapi.h"
+#include "libbitfury.h"
+#include "spidevc.h"
+
+
+struct device_drv bfsb_drv;
+
+static
+bool bfsb_spi_txrx(struct spi_port *port)
+{
+	struct cgpu_info * const proc = port->cgpu;
+	struct bitfury_device * const bitfury = proc->device_data;
+	spi_bfsb_select_bank(bitfury->slot);
+	const bool rv = sys_spi_txrx(port);
+
+	return rv;
+}
+
+static
+struct bitfury_device **bfsb_detect_chips(int *out_count) {
+	struct bitfury_device **devicelist, *bitfury;
+	struct spi_port *port;
+	int n = 0;
+	int i, j;
+	bool slot_on[32];
+	struct timespec t1, t2;
+	struct bitfury_device dummy_bitfury;
+	struct cgpu_info dummy_cgpu;
+	int max_devices = 100;
+
+
+	devicelist = malloc(max_devices * sizeof(*devicelist));
+	dummy_cgpu.device_data = &dummy_bitfury;
+	
+	clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t1);
+	for (i = 0; i < 4; i++) {
+		slot_on[i] = 1;
+	}
+
+	for (i = 0; i < 32; i++) {
+		if (slot_on[i]) {
+			int chip_n;
+			
+			port = malloc(sizeof(*port));
+			*port = *sys_spi;
+			port->cgpu = &dummy_cgpu;
+			port->txrx = bfsb_spi_txrx;
+			port->speed = 625000;
+			dummy_bitfury.slot = i;
+			
+			chip_n = libbitfury_detectChips1(port);
+			if (chip_n)
+			{
+				applog(LOG_WARNING, "BITFURY slot %d: %d chips detected", i, chip_n);
+				for (j = 0; j < chip_n; ++j)
+				{
+					if (unlikely(n >= max_devices))
+					{
+						max_devices *= 2;
+						devicelist = realloc(devicelist, max_devices * sizeof(*devicelist));
+					}
+					devicelist[n] = bitfury = malloc(sizeof(*bitfury));
+					*bitfury = (struct bitfury_device){
+						.spi = port,
+						.slot = i,
+						.fasync = j,
+					};
+					n++;
+				}
+			}
+			else
+				free(port);
+		}
+	}
+
+	clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t2);
+
+	*out_count = n;
+	return devicelist;
+}
+
+static
+int bfsb_autodetect()
+{
+	RUNONCE(0);
+	
+	int chip_n;
+	struct cgpu_info *bitfury_info;
+
+	bitfury_info = calloc(1, sizeof(struct cgpu_info));
+	bitfury_info->drv = &bfsb_drv;
+	bitfury_info->threads = 1;
+
+	applog(LOG_INFO, "INFO: bitfury_detect");
+	spi_init();
+	if (!sys_spi)
+		return 0;
+	bitfury_info->device_data = bfsb_detect_chips(&chip_n);
+	if (!chip_n) {
+		applog(LOG_WARNING, "No Bitfury chips detected!");
+		return 0;
+	} else {
+		applog(LOG_WARNING, "BITFURY: %d chips detected!", chip_n);
+	}
+
+	bitfury_info->procs = chip_n;
+	add_cgpu(bitfury_info);
+	
+	return 1;
+}
+
+static void bfsb_detect(void)
+{
+	noserial_detect_manual(&bfsb_drv, bfsb_autodetect);
+}
+
+extern bool bitfury_prepare(struct thr_info *);
+
+static
+bool bfsb_init(struct thr_info *thr)
+{
+	struct bitfury_device **devicelist = thr->cgpu->device_data;
+	struct cgpu_info *proc;
+	struct bitfury_device *bitfury;
+	
+	for (proc = thr->cgpu; proc; proc = proc->next_proc)
+	{
+		bitfury = devicelist[proc->proc_id];
+		proc->device_data = bitfury;
+		bitfury->spi->cgpu = proc;
+	}
+	
+	free(devicelist);
+	
+	return true;
+}
+
+extern int64_t bitfury_scanHash(struct thr_info *);
+extern void bitfury_shutdown(struct thr_info *);
+
+static void bfsb_shutdown(struct thr_info *thr)
+{
+	bitfury_shutdown(thr);
+	spi_bfsb_select_bank(-1);
+}
+
+struct device_drv bfsb_drv = {
+	.dname = "bitfurystrikesback",
+	.name = "BSB",
+	.drv_detect = bfsb_detect,
+	
+	.minerloop = hash_queued_work,
+	.thread_prepare = bitfury_prepare,
+	.thread_init = bfsb_init,
+	.scanwork = bitfury_scanHash,
+	.thread_shutdown = bfsb_shutdown,
+};

+ 41 - 15
driver-bitfury.c

@@ -33,6 +33,7 @@
 #include "spidevc.h"
 #include "spidevc.h"
 
 
 #define GOLDEN_BACKLOG 5
 #define GOLDEN_BACKLOG 5
+#define LINE_LEN 2048
 
 
 struct device_drv bitfury_drv;
 struct device_drv bitfury_drv;
 
 
@@ -177,6 +178,29 @@ bool bitfury_init(struct thr_info *thr)
 	return true;
 	return true;
 }
 }
 
 
+static
+bool bitfury_queue_full(struct cgpu_info *cgpu)
+{
+	struct cgpu_info *proc;
+	struct bitfury_device *bitfury;
+	
+	for (proc = cgpu; proc; proc = proc->next_proc)
+	{
+		bitfury = proc->device_data;
+		
+		if (bitfury->work)
+			continue;
+		
+		bitfury->work = get_queued(cgpu);
+		if (!bitfury->work)
+			return false;
+		
+		work_to_payload(&bitfury->payload, bitfury->work);
+	}
+	
+	return true;
+}
+
 int64_t bitfury_scanHash(struct thr_info *thr)
 int64_t bitfury_scanHash(struct thr_info *thr)
 {
 {
 	struct cgpu_info * const cgpu = thr->cgpu;
 	struct cgpu_info * const cgpu = thr->cgpu;
@@ -185,11 +209,14 @@ int64_t bitfury_scanHash(struct thr_info *thr)
 	struct thr_info *pthr;
 	struct thr_info *pthr;
 	struct bitfury_device *bitfury;
 	struct bitfury_device *bitfury;
 	struct timeval now;
 	struct timeval now;
-	char line[2048];
+	char line[LINE_LEN];
 	int short_stat = 10;
 	int short_stat = 10;
 	int long_stat = 1800;
 	int long_stat = 1800;
 	int i;
 	int i;
 
 
+	if (!bitfury_queue_full(cgpu))
+		return 0;
+	
 	for (proc = cgpu; proc; proc = proc->next_proc)
 	for (proc = cgpu; proc; proc = proc->next_proc)
 	{
 	{
 		const int chip = proc->proc_id;
 		const int chip = proc->proc_id;
@@ -197,13 +224,6 @@ int64_t bitfury_scanHash(struct thr_info *thr)
 		bitfury = proc->device_data;
 		bitfury = proc->device_data;
 		
 		
 		bitfury->job_switched = 0;
 		bitfury->job_switched = 0;
-		if(!bitfury->work) {
-			bitfury->work = get_queued(thr->cgpu);
-			if (bitfury->work == NULL)
-				return 0;
-			work_to_payload(&bitfury->payload, bitfury->work);
-		}
-		
 		payload_to_atrvec(bitfury->atrvec, &bitfury->payload);
 		payload_to_atrvec(bitfury->atrvec, &bitfury->payload);
 		libbitfury_sendHashData1(chip, bitfury, pthr);
 		libbitfury_sendHashData1(chip, bitfury, pthr);
 	}
 	}
@@ -260,10 +280,11 @@ int64_t bitfury_scanHash(struct thr_info *thr)
 
 
 	if (now.tv_sec - sds->short_out_t > short_stat) {
 	if (now.tv_sec - sds->short_out_t > short_stat) {
 		int shares_first = 0, shares_last = 0, shares_total = 0;
 		int shares_first = 0, shares_last = 0, shares_total = 0;
-		char stat_lines[32][256] = {{0}};
+		char stat_lines[32][LINE_LEN] = {{0}};
 		int len, k;
 		int len, k;
 		double gh[32][8] = {{0}};
 		double gh[32][8] = {{0}};
 		double ghsum = 0, gh1h = 0, gh2h = 0;
 		double ghsum = 0, gh1h = 0, gh2h = 0;
+		unsigned strange_counter = 0;
 
 
 		for (proc = cgpu; proc; proc = proc->next_proc)
 		for (proc = cgpu; proc; proc = proc->next_proc)
 		{
 		{
@@ -275,9 +296,9 @@ int64_t bitfury_scanHash(struct thr_info *thr)
 			len = strlen(stat_lines[bitfury->slot]);
 			len = strlen(stat_lines[bitfury->slot]);
 			ghash = shares_to_ghashes(shares_found, short_stat);
 			ghash = shares_to_ghashes(shares_found, short_stat);
 			gh[bitfury->slot][chip & 0x07] = ghash;
 			gh[bitfury->slot][chip & 0x07] = ghash;
-			snprintf(stat_lines[bitfury->slot] + len, 256 - len, "%.1f-%3.0f ", ghash, bitfury->mhz);
+			snprintf(stat_lines[bitfury->slot] + len, LINE_LEN - len, "%.1f-%3.0f ", ghash, bitfury->mhz);
 
 
-			if(sds->short_out_t && ghash < 1.0) {
+			if(sds->short_out_t && ghash < 0.5) {
 				applog(LOG_WARNING, "Chip_id %d FREQ CHANGE", chip);
 				applog(LOG_WARNING, "Chip_id %d FREQ CHANGE", chip);
 				send_freq(bitfury->spi, bitfury->slot, bitfury->fasync, bitfury->osc6_bits - 1);
 				send_freq(bitfury->spi, bitfury->slot, bitfury->fasync, bitfury->osc6_bits - 1);
 				cgsleep_ms(1);
 				cgsleep_ms(1);
@@ -286,9 +307,13 @@ int64_t bitfury_scanHash(struct thr_info *thr)
 			shares_total += shares_found;
 			shares_total += shares_found;
 			shares_first += chip < 4 ? shares_found : 0;
 			shares_first += chip < 4 ? shares_found : 0;
 			shares_last += chip > 3 ? shares_found : 0;
 			shares_last += chip > 3 ? shares_found : 0;
+			strange_counter += bitfury->strange_counter;
+			bitfury->strange_counter = 0;
 		}
 		}
 		sprintf(line, "vvvvwww SHORT stat %ds: wwwvvvv", short_stat);
 		sprintf(line, "vvvvwww SHORT stat %ds: wwwvvvv", short_stat);
 		applog(LOG_WARNING, "%s", line);
 		applog(LOG_WARNING, "%s", line);
+		sprintf(line, "stranges: %u", strange_counter);
+		applog(LOG_WARNING, "%s", line);
 		for(i = 0; i < 32; i++)
 		for(i = 0; i < 32; i++)
 			if(strlen(stat_lines[i])) {
 			if(strlen(stat_lines[i])) {
 				len = strlen(stat_lines[i]);
 				len = strlen(stat_lines[i]);
@@ -300,7 +325,7 @@ int64_t bitfury_scanHash(struct thr_info *thr)
 					gh2h += gh[i][k+4];
 					gh2h += gh[i][k+4];
 					ghsum += gh[i][k] + gh[i][k+4];
 					ghsum += gh[i][k] + gh[i][k+4];
 				}
 				}
-				snprintf(stat_lines[i] + len, 256 - len, "- %2.1f + %2.1f = %2.1f slot %i ", gh1h, gh2h, ghsum, i);
+				snprintf(stat_lines[i] + len, LINE_LEN - len, "- %2.1f + %2.1f = %2.1f slot %i ", gh1h, gh2h, ghsum, i);
 				applog(LOG_WARNING, "%s", stat_lines[i]);
 				applog(LOG_WARNING, "%s", stat_lines[i]);
 			}
 			}
 		sds->short_out_t = now.tv_sec;
 		sds->short_out_t = now.tv_sec;
@@ -308,7 +333,7 @@ int64_t bitfury_scanHash(struct thr_info *thr)
 
 
 	if (now.tv_sec - sds->long_out_t > long_stat) {
 	if (now.tv_sec - sds->long_out_t > long_stat) {
 		int shares_first = 0, shares_last = 0, shares_total = 0;
 		int shares_first = 0, shares_last = 0, shares_total = 0;
-		char stat_lines[32][256] = {{0}};
+		char stat_lines[32][LINE_LEN] = {{0}};
 		int len, k;
 		int len, k;
 		double gh[32][8] = {{0}};
 		double gh[32][8] = {{0}};
 		double ghsum = 0, gh1h = 0, gh2h = 0;
 		double ghsum = 0, gh1h = 0, gh2h = 0;
@@ -323,7 +348,7 @@ int64_t bitfury_scanHash(struct thr_info *thr)
 			len = strlen(stat_lines[bitfury->slot]);
 			len = strlen(stat_lines[bitfury->slot]);
 			ghash = shares_to_ghashes(shares_found, long_stat);
 			ghash = shares_to_ghashes(shares_found, long_stat);
 			gh[bitfury->slot][chip & 0x07] = ghash;
 			gh[bitfury->slot][chip & 0x07] = ghash;
-			snprintf(stat_lines[bitfury->slot] + len, 256 - len, "%.1f-%3.0f ", ghash, bitfury->mhz);
+			snprintf(stat_lines[bitfury->slot] + len, LINE_LEN - len, "%.1f-%3.0f ", ghash, bitfury->mhz);
 
 
 			shares_total += shares_found;
 			shares_total += shares_found;
 			shares_first += chip < 4 ? shares_found : 0;
 			shares_first += chip < 4 ? shares_found : 0;
@@ -342,7 +367,7 @@ int64_t bitfury_scanHash(struct thr_info *thr)
 					gh2h += gh[i][k+4];
 					gh2h += gh[i][k+4];
 					ghsum += gh[i][k] + gh[i][k+4];
 					ghsum += gh[i][k] + gh[i][k+4];
 				}
 				}
-				snprintf(stat_lines[i] + len, 256 - len, "- %2.1f + %2.1f = %2.1f slot %i ", gh1h, gh2h, ghsum, i);
+				snprintf(stat_lines[i] + len, LINE_LEN - len, "- %2.1f + %2.1f = %2.1f slot %i ", gh1h, gh2h, ghsum, i);
 				applog(LOG_WARNING, "%s", stat_lines[i]);
 				applog(LOG_WARNING, "%s", stat_lines[i]);
 			}
 			}
 		sds->long_out_t = now.tv_sec;
 		sds->long_out_t = now.tv_sec;
@@ -523,6 +548,7 @@ struct device_drv bitfury_drv = {
 	.drv_detect = bitfury_detect,
 	.drv_detect = bitfury_detect,
 	.thread_prepare = bitfury_prepare,
 	.thread_prepare = bitfury_prepare,
 	.thread_init = bitfury_init,
 	.thread_init = bitfury_init,
+	.queue_full = bitfury_queue_full,
 	.scanwork = bitfury_scanHash,
 	.scanwork = bitfury_scanHash,
 	.thread_shutdown = bitfury_shutdown,
 	.thread_shutdown = bitfury_shutdown,
 	.minerloop = hash_queued_work,
 	.minerloop = hash_queued_work,

+ 3 - 0
driver-metabank.c

@@ -65,6 +65,9 @@ struct bitfury_device **metabank_detect_chips(int *out_count) {
 	devicelist = malloc(max_devices * sizeof(*devicelist));
 	devicelist = malloc(max_devices * sizeof(*devicelist));
 	dummy_cgpu.device_data = &dummy_bitfury;
 	dummy_cgpu.device_data = &dummy_bitfury;
 	
 	
+	for (i = 0; i < 32; i++) {
+		slot_on[i] = 0;
+	}
 	clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t1);
 	clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t1);
 	for (i = 0; i < 32; i++) {
 	for (i = 0; i < 32; i++) {
 		int slot_detected = tm_i2c_detect(i) != -1;
 		int slot_detected = tm_i2c_detect(i) != -1;

+ 51 - 4
libbitfury.c

@@ -221,6 +221,17 @@ int get_counter(unsigned int *newbuf, unsigned int *oldbuf) {
 	return 0;
 	return 0;
 }
 }
 
 
+int get_diff(unsigned int *newbuf, unsigned int *oldbuf) {
+		int j;
+		unsigned counter = 0;
+		for(j = 0; j < 16; j++) {
+				if (newbuf[j] != oldbuf[j]) {
+						counter++;
+				}
+		}
+		return counter;
+}
+
 int detect_chip(struct spi_port *port, int chip_n) {
 int detect_chip(struct spi_port *port, int chip_n) {
 	/* Test vectors to calculate (using address-translated loads) */
 	/* Test vectors to calculate (using address-translated loads) */
 	unsigned atrvec[] = {
 	unsigned atrvec[] = {
@@ -418,6 +429,7 @@ void libbitfury_sendHashData1(int chip_id, struct bitfury_device *d, struct thr_
 	struct timespec time;
 	struct timespec time;
 	int smart = 0;
 	int smart = 0;
 	int chip = d->fasync;
 	int chip = d->fasync;
+	int buf_diff;
 
 
 	clock_gettime(CLOCK_REALTIME, &(time));
 	clock_gettime(CLOCK_REALTIME, &(time));
 
 
@@ -431,6 +443,7 @@ void libbitfury_sendHashData1(int chip_id, struct bitfury_device *d, struct thr_
 	if (d_time.tv_sec < 0 && (d->req2_done || !smart)) {
 	if (d_time.tv_sec < 0 && (d->req2_done || !smart)) {
 		d->otimer1 = d->timer1;
 		d->otimer1 = d->timer1;
 		d->timer1 = time;
 		d->timer1 = time;
+		d->ocounter1 = d->counter1;
 		/* Programming next value */
 		/* Programming next value */
 		spi_clear_buf(port);
 		spi_clear_buf(port);
 		spi_emit_break(port);
 		spi_emit_break(port);
@@ -443,6 +456,29 @@ void libbitfury_sendHashData1(int chip_id, struct bitfury_device *d, struct thr_
 		d_time = t_diff(time, d->predict1);
 		d_time = t_diff(time, d->predict1);
 		spi_txrx(port);
 		spi_txrx(port);
 		memcpy(newbuf, spi_getrxbuf(port)+4 + chip, 17*4);
 		memcpy(newbuf, spi_getrxbuf(port)+4 + chip, 17*4);
+		d->counter1 = get_counter(newbuf, oldbuf);
+		buf_diff = get_diff(newbuf, oldbuf);
+		if (buf_diff > 4 || (d->counter1 > 0 && d->counter1 < 0x00400000 / 2)) {
+			if (buf_diff > 4) {
+#ifdef BITFURY_SENDHASHDATA_DEBUG
+				applog(LOG_DEBUG, "AAA        chip_id: %d, buf_diff: %d, counter: %08x", chip_id, buf_diff, d->counter1);
+#endif
+				payload_to_atrvec(&d->atrvec[0], p);
+				spi_clear_buf(port);
+				spi_emit_break(port);
+				spi_emit_fasync(port, chip);
+				spi_emit_data(port, 0x3000, &d->atrvec[0], 19*4);
+				clock_gettime(CLOCK_REALTIME, &(time));
+				d_time = t_diff(time, d->predict1);
+				spi_txrx(port);
+				memcpy(newbuf, spi_getrxbuf(port)+4 + chip, 17*4);
+				buf_diff = get_diff(newbuf, oldbuf);
+				d->counter1 = get_counter(newbuf, oldbuf);
+#ifdef BITFURY_SENDHASHDATA_DEBUG
+				applog(LOG_DEBUG, "AAA _222__ chip_id: %d, buf_diff: %d, counter: %08x", chip_id, buf_diff, d->counter1);
+#endif
+			}
+		}
 
 
 		d->job_switched = newbuf[16] != oldbuf[16];
 		d->job_switched = newbuf[16] != oldbuf[16];
 
 
@@ -486,6 +522,7 @@ void libbitfury_sendHashData1(int chip_id, struct bitfury_device *d, struct thr_
 				}
 				}
 				if (!found) {
 				if (!found) {
 					inc_hw_errors2(thr, NULL, &pn);
 					inc_hw_errors2(thr, NULL, &pn);
+					d->strange_counter++;
 				}
 				}
 			}
 			}
 		}
 		}
@@ -496,7 +533,6 @@ void libbitfury_sendHashData1(int chip_id, struct bitfury_device *d, struct thr_
 		} else {
 		} else {
 			d_time = t_diff(d->otimer1, d->timer1);
 			d_time = t_diff(d->otimer1, d->timer1);
 		}
 		}
-		d->ocounter1 = d->counter1;
 		d->counter1 = get_counter(newbuf, oldbuf);
 		d->counter1 = get_counter(newbuf, oldbuf);
 		if (d->counter2 || !smart) {
 		if (d->counter2 || !smart) {
 			int shift;
 			int shift;
@@ -509,7 +545,9 @@ void libbitfury_sendHashData1(int chip_id, struct bitfury_device *d, struct thr_
 			long long unsigned delta;
 			long long unsigned delta;
 			struct timespec t_delta;
 			struct timespec t_delta;
 			double mhz;
 			double mhz;
+#ifdef BITFURY_SENDHASHDATA_DEBUG
 			int ccase;
 			int ccase;
+#endif
 
 
 			shift = 800000;
 			shift = 800000;
 			if (smart) {
 			if (smart) {
@@ -517,10 +555,14 @@ void libbitfury_sendHashData1(int chip_id, struct bitfury_device *d, struct thr_
 			} else {
 			} else {
 				if (d->counter1 > (0x00400000 - shift * 2) && d->ocounter1 > (0x00400000 - shift)) {
 				if (d->counter1 > (0x00400000 - shift * 2) && d->ocounter1 > (0x00400000 - shift)) {
 					cycles = 0x00400000 - d->ocounter1 + d->counter1; // + 0x003FFFFF;
 					cycles = 0x00400000 - d->ocounter1 + d->counter1; // + 0x003FFFFF;
+#ifdef BITFURY_SENDHASHDATA_DEBUG
 					ccase = 1;
 					ccase = 1;
+#endif
 				} else {
 				} else {
-					cycles = d->counter1 - d->ocounter1;
+					cycles = d->counter1 > d->ocounter1 ? d->counter1 - d->ocounter1 : 0x00400000 - d->ocounter1 + d->counter1;
+#ifdef BITFURY_SENDHASHDATA_DEBUG
 					ccase = 2;
 					ccase = 2;
+#endif
 				}
 				}
 			}
 			}
 			req1_cycles = 0x003FFFFF - d->counter1;
 			req1_cycles = 0x003FFFFF - d->counter1;
@@ -528,10 +570,15 @@ void libbitfury_sendHashData1(int chip_id, struct bitfury_device *d, struct thr_
 			ns = (double)period / (double)(cycles);
 			ns = (double)period / (double)(cycles);
 			mhz = 1.0 / ns * 65.0 * 1000.0;
 			mhz = 1.0 / ns * 65.0 * 1000.0;
 
 
-			if (d->counter1 > 0 && d->counter1 < 0x001FFFFF)
-				applog(LOG_DEBUG, "AAA chip_id %2d: %llu ms, req1_cycles: %08u,  counter1: %08d, ocounter1: %08d, counter2: %08d, cycles: %08d, ns: %.2f, mhz: %.2f ", chip_id, period / 1000000ULL, req1_cycles, d->counter1, d->ocounter1, d->counter2, cycles, ns, mhz);
+#ifdef BITFURY_SENDHASHDATA_DEBUG
+			if (d->counter1 > 0 && d->counter1 < 0x001FFFFF) {
+				applog(LOG_DEBUG, "//AAA chip_id %2d: %llu ms, req1_cycles: %08u,  counter1: %08d, ocounter1: %08d, counter2: %08d, cycles: %08d, ns: %.2f, mhz: %.2f ", chip_id, period / 1000000ULL, req1_cycles, d->counter1, d->ocounter1, d->counter2, cycles, ns, mhz);
+			}
+#endif
 			if (ns > 2000.0 || ns < 20) {
 			if (ns > 2000.0 || ns < 20) {
+#ifdef BITFURY_SENDHASHDATA_DEBUG
 				applog(LOG_DEBUG, "AAA %d!Stupid ns chip_id %2d: %llu ms, req1_cycles: %08u,  counter1: %08d, ocounter1: %08d, counter2: %08d, cycles: %08d, ns: %.2f, mhz: %.2f ", ccase, chip_id, period / 1000000ULL, req1_cycles, d->counter1, d->ocounter1, d->counter2, cycles, ns, mhz);
 				applog(LOG_DEBUG, "AAA %d!Stupid ns chip_id %2d: %llu ms, req1_cycles: %08u,  counter1: %08d, ocounter1: %08d, counter2: %08d, cycles: %08d, ns: %.2f, mhz: %.2f ", ccase, chip_id, period / 1000000ULL, req1_cycles, d->counter1, d->ocounter1, d->counter2, cycles, ns, mhz);
+#endif
 				ns = 200.0;
 				ns = 200.0;
 			} else {
 			} else {
 				d->ns = ns;
 				d->ns = ns;

+ 1 - 0
libbitfury.h

@@ -52,6 +52,7 @@ struct bitfury_device {
 	double ns;
 	double ns;
 	unsigned slot;
 	unsigned slot;
 	unsigned fasync;
 	unsigned fasync;
+	unsigned strange_counter;
 	bool second_run;
 	bool second_run;
 	
 	
 	time_t short_out_t;
 	time_t short_out_t;

+ 2 - 0
miner.c

@@ -9390,6 +9390,7 @@ extern struct device_drv ztex_drv;
 #ifdef USE_BITFURY
 #ifdef USE_BITFURY
 extern struct device_drv bitfury_drv;
 extern struct device_drv bitfury_drv;
 extern struct device_drv metabank_drv;
 extern struct device_drv metabank_drv;
+extern struct device_drv bfsb_drv;
 #endif
 #endif
 
 
 static int cgminer_id_count = 0;
 static int cgminer_id_count = 0;
@@ -9500,6 +9501,7 @@ void drv_detect_all()
 	{
 	{
 		bitfury_drv.drv_detect();
 		bitfury_drv.drv_detect();
 		metabank_drv.drv_detect();
 		metabank_drv.drv_detect();
+		bfsb_drv.drv_detect();
 	}
 	}
 #endif
 #endif
 
 

+ 32 - 6
spidevc.c

@@ -90,14 +90,14 @@ void spi_init(void)
 
 
 // Bit-banging reset, to reset more chips in chain - toggle for longer period... Each 3 reset cycles reset first chip in chain
 // Bit-banging reset, to reset more chips in chain - toggle for longer period... Each 3 reset cycles reset first chip in chain
 static
 static
-void spi_reset(void)
+int spi_reset(int a)
 {
 {
 	int i,j;
 	int i,j;
-	int a = 1234, len = 2;
+	int len = 8;
 	INP_GPIO(10); OUT_GPIO(10);
 	INP_GPIO(10); OUT_GPIO(10);
 	INP_GPIO(11); OUT_GPIO(11);
 	INP_GPIO(11); OUT_GPIO(11);
 	GPIO_SET = 1 << 11; // Set SCK
 	GPIO_SET = 1 << 11; // Set SCK
-	for (i = 0; i < 16; i++) { // On standard settings this unoptimized code produces 1 Mhz freq.
+	for (i = 0; i < 32; i++) { // On standard settings this unoptimized code produces 1 Mhz freq.
 		GPIO_SET = 1 << 10;
 		GPIO_SET = 1 << 10;
 		for (j = 0; j < len; j++) {
 		for (j = 0; j < len; j++) {
 			a *= a;
 			a *= a;
@@ -115,6 +115,8 @@ void spi_reset(void)
 	SET_GPIO_ALT(11,0);
 	SET_GPIO_ALT(11,0);
 	INP_GPIO(9);
 	INP_GPIO(9);
 	SET_GPIO_ALT(9,0);
 	SET_GPIO_ALT(9,0);
+
+	return a;
 }
 }
 
 
 #define BAILOUT(s)  do{  \
 #define BAILOUT(s)  do{  \
@@ -133,9 +135,11 @@ bool sys_spi_txrx(struct spi_port *port)
 	struct spi_ioc_transfer tr[16];
 	struct spi_ioc_transfer tr[16];
 
 
 	memset(&tr,0,sizeof(tr));
 	memset(&tr,0,sizeof(tr));
-	mode = 0; bits = 8; speed = 2000000;
+	mode = 0; bits = 8; speed = 4000000;
+	if (port->speed)
+		speed = port->speed;
 
 
-	spi_reset();
+	spi_reset(1234);
 	fd = open("/dev/spidev0.0", O_RDWR);
 	fd = open("/dev/spidev0.0", O_RDWR);
 	if (fd < 0) {
 	if (fd < 0) {
 		perror("Unable to open SPI device");
 		perror("Unable to open SPI device");
@@ -183,7 +187,7 @@ bool sys_spi_txrx(struct spi_port *port)
         }
         }
 
 
 	close(fd);
 	close(fd);
-	spi_reset();
+	spi_reset(4321);
 
 
 	return true;
 	return true;
 }
 }
@@ -252,3 +256,25 @@ void spi_emit_data(struct spi_port *port, uint16_t addr, const void *buf, size_t
 	spi_emit_buf(port, otmp, 3);
 	spi_emit_buf(port, otmp, 3);
 	spi_emit_buf_reverse(port, buf, len*4);
 	spi_emit_buf_reverse(port, buf, len*4);
 }
 }
+void spi_bfsb_select_bank(int bank)
+{
+	static int last_bank = -2;
+	if (bank == last_bank)
+		return;
+	const int banks[4]={18,23,24,25}; // GPIO connected to OE of level shifters
+	int i;
+	for(i=0;i<4;i++)
+	{
+		INP_GPIO(banks[i]);
+		OUT_GPIO(banks[i]);
+		if(i==bank)
+		{
+			GPIO_SET = 1 << banks[i]; // enable bank
+		} 
+		else
+		{
+			GPIO_CLR = 1 << banks[i];// disable bank
+		}
+	}
+	last_bank = bank;
+}

+ 3 - 0
spidevc.h

@@ -20,6 +20,7 @@ struct spi_port {
 	struct cgpu_info *cgpu;
 	struct cgpu_info *cgpu;
 	const char *repr;
 	const char *repr;
 	int logprio;
 	int logprio;
+	int speed;
 };
 };
 
 
 extern struct spi_port *sys_spi;
 extern struct spi_port *sys_spi;
@@ -71,4 +72,6 @@ bool spi_txrx(struct spi_port *port)
 
 
 extern bool sys_spi_txrx(struct spi_port *);
 extern bool sys_spi_txrx(struct spi_port *);
 
 
+void spi_bfsb_select_bank(int bank);
+
 #endif
 #endif