Commit bed6a9c436dccb561b9766aaa15e21e32511785d

Con Kolivas 2014-01-05T23:00:45

Basic import of libbitfury functions from nanofury branch

diff --git a/driver-bitfury.c b/driver-bitfury.c
index 3678aa1..0384be1 100644
--- a/driver-bitfury.c
+++ b/driver-bitfury.c
@@ -290,58 +290,6 @@ static void nf1_close(struct cgpu_info *bitfury)
 	mcp2210_set_gpio_settings(bitfury, mcp);
 }
 
-static void spi_clear_buf(struct bitfury_info *info)
-{
-	info->spibufsz = 0;
-}
-
-static void spi_add_buf(struct bitfury_info *info, const void *buf, const int sz)
-{
-	if (unlikely(info->spibufsz + sz > NF1_SPIBUF_SIZE)) {
-		applog(LOG_WARNING, "SPI bufsize overflow!");
-		return;
-	}
-	memcpy(&info->spibuf[info->spibufsz], buf, sz);
-	info->spibufsz += sz;
-}
-
-static void spi_add_break(struct bitfury_info *info)
-{
-	spi_add_buf(info, "\x4", 1);
-}
-
-static void spi_add_buf_reverse(struct bitfury_info *info, const char *buf, const int sz)
-{
-	int i;
-
-	for (i = 0; i < sz; i++) { // Reverse bit order in each byte!
-		unsigned char p = buf[i];
-
-		p = ((p & 0xaa) >> 1) | ((p & 0x55) << 1);
-		p = ((p & 0xcc) >> 2) | ((p & 0x33) << 2);
-		p = ((p & 0xf0) >> 4) | ((p & 0x0f) << 4);
-		info->spibuf[info->spibufsz + i] = p;
-	}
-	info->spibufsz += sz;
-}
-
-static void spi_add_data(struct bitfury_info *info, uint16_t addr, const void *buf, int len)
-{
-	unsigned char otmp[3];
-
-	if (len < 4 || len > 128) {
-		applog(LOG_WARNING, "Can't add SPI data size %d", len);
-		return;
-	}
-	len /= 4; /* Strip */
-	otmp[0] = (len - 1) | 0xE0;
-	otmp[1] = addr >> 8;
-	otmp[2] = addr & 0xFF;
-	spi_add_buf(info, otmp, 3);
-	len *= 4;
-	spi_add_buf_reverse(info, buf, len);
-}
-
 /* Configuration registers - control oscillators and such stuff. PROGRAMMED when
  * magic number matches, UNPROGRAMMED (default) otherwise */
 static void nf1_config_reg(struct bitfury_info *info, int cfgreg, int ena)
@@ -411,68 +359,8 @@ static void nf1_send_init(struct bitfury_info *info)
 	spi_add_data(info, 0x3000, atrvec, 19 * 4);
 }
 
-// Bit-banging reset... Each 3 reset cycles reset first chip in chain
-static bool nf1_spi_reset(struct cgpu_info *bitfury, struct bitfury_info *info)
-{
-	struct mcp_settings *mcp = &info->mcp;
-	int r;
-
-	// SCK_OVRRIDE
-	mcp->value.pin[NF1_PIN_SCK_OVR] = MCP2210_GPIO_PIN_HIGH;
-	mcp->direction.pin[NF1_PIN_SCK_OVR] = MCP2210_GPIO_OUTPUT;
-	if (!mcp2210_set_gpio_settings(bitfury, mcp))
-		return false;
-
-	for (r = 0; r < 16; ++r) {
-		char buf[1] = {0x81}; // will send this waveform: - _ _ _ _ _ _ -
-		unsigned int length = 1;
-
-		if (!mcp2210_spi_transfer(bitfury, buf, &length))
-			return false;
-	}
-
-	mcp->direction.pin[NF1_PIN_SCK_OVR] = MCP2210_GPIO_INPUT;
-	if (!mcp2210_set_gpio_settings(bitfury, mcp))
-		return false;
-	if (!mcp2210_get_gpio_pinval(bitfury, NF1_PIN_SCK_OVR, &r))
-		return false;
-
-	return true;
-}
-
-static bool nf1_spi_txrx(struct cgpu_info *bitfury, struct bitfury_info *info)
-{
-	unsigned int length, sendrcv;
-	int offset = 0, roffset = 0;
-
-	if (!nf1_spi_reset(bitfury, info))
-		return false;
-	length = info->spibufsz;
-	applog(LOG_DEBUG, "%s %d: SPI sending %u bytes", bitfury->drv->name, bitfury->device_id,
-	       length);
-	while (length > MCP2210_TRANSFER_MAX) {
-		sendrcv = MCP2210_TRANSFER_MAX;
-		if (!mcp2210_spi_transfer(bitfury, info->spibuf + offset, &sendrcv))
-			return false;
-		if (sendrcv != MCP2210_TRANSFER_MAX) {
-			applog(LOG_DEBUG, "%s %d: Send/Receive size mismatch sent %d received %d",
-			       bitfury->drv->name, bitfury->device_id, MCP2210_TRANSFER_MAX, sendrcv);
-		}
-		length -= MCP2210_TRANSFER_MAX;
-		offset += MCP2210_TRANSFER_MAX;
-		roffset += sendrcv;
-	}
-	sendrcv = length;
-	if (!mcp2210_spi_transfer(bitfury, info->spibuf + offset, &sendrcv))
-		return false;
-	if (sendrcv != length) {
-		applog(LOG_WARNING, "%s %d: Send/Receive size mismatch sent %d received %d",
-		       bitfury->drv->name, bitfury->device_id, length, sendrcv);
-	}
-	roffset += sendrcv;
-	info->spibufsz = roffset;
-	return true;
-}
+#define nf1_spi_reset(bitfury, info) (spi_reset(bitfury, info))
+#define nf1_spi_txrx(bitfury, info) (spi_txrx(bitfury, info))
 
 static bool nf1_reinit(struct cgpu_info *bitfury, struct bitfury_info *info)
 {
diff --git a/driver-bitfury.h b/driver-bitfury.h
index 2621e50..7fc8a2f 100644
--- a/driver-bitfury.h
+++ b/driver-bitfury.h
@@ -31,6 +31,15 @@ extern int opt_bxf_temp_target;
 
 #define NF1_SPIBUF_SIZE 16384
 
+struct bitfury_payload {
+	unsigned char midstate[32];
+	unsigned int junk[8];
+	unsigned m7;
+	unsigned ntime;
+	unsigned nbits;
+	unsigned nnonce;
+};
+
 struct bitfury_info {
 	struct cgpu_info *base_cgpu;
 	struct thr_info *thr;
@@ -71,6 +80,13 @@ struct bitfury_info {
 	char spibuf[NF1_SPIBUF_SIZE];
 	unsigned int spibufsz;
 	int osc6_bits;
+	struct bitfury_payload payload;
+	struct bitfury_payload opayload;
+	unsigned newbuf[20];
+	unsigned oldbuf[20];
+	int job_switched;
+	unsigned int results[16];
+	int results_n;
 };
 
 #endif /* BITFURY_H */
diff --git a/libbitfury.c b/libbitfury.c
index 1d42090..fb7e876 100644
--- a/libbitfury.c
+++ b/libbitfury.c
@@ -13,6 +13,8 @@
 #include "libbitfury.h"
 #include "sha2.h"
 
+#define BITFURY_REFRESH_DELAY 100
+
 void ms3steps(uint32_t *p)
 {
 	uint32_t a, b, c, d, e, f, g, h, new_e, new_a;
@@ -145,3 +147,171 @@ void bitfury_work_to_payload(struct bitfury_payload *p, struct work *w)
 	applog(LOG_INFO, "INFO nonc: %08x bitfury_scanHash MS0: %08x, ", p->nnonce, ((unsigned int *)w->midstate)[0]);
 	applog(LOG_INFO, "INFO merkle[7]: %08x, ntime: %08x, nbits: %08x", p->m7, p->ntime, p->nbits);
 }
+
+void spi_clear_buf(struct bitfury_info *info)
+{
+	info->spibufsz = 0;
+}
+
+void spi_add_buf(struct bitfury_info *info, const void *buf, const int sz)
+{
+	if (unlikely(info->spibufsz + sz > NF1_SPIBUF_SIZE)) {
+		applog(LOG_WARNING, "SPI bufsize overflow!");
+		return;
+	}
+	memcpy(&info->spibuf[info->spibufsz], buf, sz);
+	info->spibufsz += sz;
+}
+
+void spi_add_break(struct bitfury_info *info)
+{
+	spi_add_buf(info, "\x4", 1);
+}
+
+static void spi_add_buf_reverse(struct bitfury_info *info, const char *buf, const int sz)
+{
+	int i;
+
+	for (i = 0; i < sz; i++) { // Reverse bit order in each byte!
+		unsigned char p = buf[i];
+
+		p = ((p & 0xaa) >> 1) | ((p & 0x55) << 1);
+		p = ((p & 0xcc) >> 2) | ((p & 0x33) << 2);
+		p = ((p & 0xf0) >> 4) | ((p & 0x0f) << 4);
+		info->spibuf[info->spibufsz + i] = p;
+	}
+	info->spibufsz += sz;
+}
+
+void spi_add_data(struct bitfury_info *info, uint16_t addr, const void *buf, int len)
+{
+	unsigned char otmp[3];
+
+	if (len < 4 || len > 128) {
+		applog(LOG_WARNING, "Can't add SPI data size %d", len);
+		return;
+	}
+	len /= 4; /* Strip */
+	otmp[0] = (len - 1) | 0xE0;
+	otmp[1] = addr >> 8;
+	otmp[2] = addr & 0xFF;
+	spi_add_buf(info, otmp, 3);
+	len *= 4;
+	spi_add_buf_reverse(info, buf, len);
+}
+
+// Bit-banging reset... Each 3 reset cycles reset first chip in chain
+bool spi_reset(struct cgpu_info *bitfury, struct bitfury_info *info)
+{
+	struct mcp_settings *mcp = &info->mcp;
+	int r;
+
+	// SCK_OVRRIDE
+	mcp->value.pin[NF1_PIN_SCK_OVR] = MCP2210_GPIO_PIN_HIGH;
+	mcp->direction.pin[NF1_PIN_SCK_OVR] = MCP2210_GPIO_OUTPUT;
+	if (!mcp2210_set_gpio_settings(bitfury, mcp))
+		return false;
+
+	for (r = 0; r < 16; ++r) {
+		char buf[1] = {0x81}; // will send this waveform: - _ _ _ _ _ _ -
+		unsigned int length = 1;
+
+		if (!mcp2210_spi_transfer(bitfury, buf, &length))
+			return false;
+	}
+
+	mcp->direction.pin[NF1_PIN_SCK_OVR] = MCP2210_GPIO_INPUT;
+	if (!mcp2210_set_gpio_settings(bitfury, mcp))
+		return false;
+	if (!mcp2210_get_gpio_pinval(bitfury, NF1_PIN_SCK_OVR, &r))
+		return false;
+
+	return true;
+}
+
+bool spi_txrx(struct cgpu_info *bitfury, struct bitfury_info *info)
+{
+	unsigned int length, sendrcv;
+	int offset = 0, roffset = 0;
+
+	if (!spi_reset(bitfury, info))
+		return false;
+	length = info->spibufsz;
+	applog(LOG_DEBUG, "%s %d: SPI sending %u bytes", bitfury->drv->name, bitfury->device_id,
+	       length);
+	while (length > MCP2210_TRANSFER_MAX) {
+		sendrcv = MCP2210_TRANSFER_MAX;
+		if (!mcp2210_spi_transfer(bitfury, info->spibuf + offset, &sendrcv))
+			return false;
+		if (sendrcv != MCP2210_TRANSFER_MAX) {
+			applog(LOG_DEBUG, "%s %d: Send/Receive size mismatch sent %d received %d",
+			       bitfury->drv->name, bitfury->device_id, MCP2210_TRANSFER_MAX, sendrcv);
+		}
+		length -= MCP2210_TRANSFER_MAX;
+		offset += MCP2210_TRANSFER_MAX;
+		roffset += sendrcv;
+	}
+	sendrcv = length;
+	if (!mcp2210_spi_transfer(bitfury, info->spibuf + offset, &sendrcv))
+		return false;
+	if (sendrcv != length) {
+		applog(LOG_WARNING, "%s %d: Send/Receive size mismatch sent %d received %d",
+		       bitfury->drv->name, bitfury->device_id, length, sendrcv);
+	}
+	roffset += sendrcv;
+	info->spibufsz = roffset;
+	return true;
+}
+
+void libbitfury_sendHashData(struct cgpu_info *bf)
+{
+	struct bitfury_info *info = bf->device_data;
+	static unsigned second_run;
+	unsigned *newbuf = info->newbuf;
+	unsigned *oldbuf = info->oldbuf;
+	struct bitfury_payload *p = &(info->payload);
+	struct bitfury_payload *op = &(info->opayload);
+
+	/* Programming next value */
+	memcpy(atrvec, p, 20 * 4);
+	ms3steps(atrvec);
+
+	spi_clear_buf(info);
+	spi_add_break(info);
+	spi_add_data(info, 0x3000, (void*)&atrvec[0], 19 * 4);
+	spi_txrx(bf, info);
+
+	memcpy(newbuf, info->spibuf + 4, 17 * 4);
+
+	info->job_switched = newbuf[16] != oldbuf[16];
+
+	if (second_run && info->job_switched) {
+		int i;
+		int results_num = 0;
+		unsigned *results = info->results;
+
+		for (i = 0; i < 16; i++) {
+			if (oldbuf[i] != newbuf[i]) {
+				unsigned pn; //possible nonce
+				unsigned int s = 0; //TODO zero may be solution
+
+				pn = decnonce(newbuf[i]);
+				s |= rehash(op->midstate, op->m7, op->ntime, op->nbits, pn) ? pn : 0;
+				s |= rehash(op->midstate, op->m7, op->ntime, op->nbits, pn-0x400000) ? pn - 0x400000 : 0;
+				s |= rehash(op->midstate, op->m7, op->ntime, op->nbits, pn-0x800000) ? pn - 0x800000 : 0;
+				s |= rehash(op->midstate, op->m7, op->ntime, op->nbits, pn+0x2800000)? pn + 0x2800000 : 0;
+				s |= rehash(op->midstate, op->m7, op->ntime, op->nbits, pn+0x2C00000)? pn + 0x2C00000 : 0;
+				s |= rehash(op->midstate, op->m7, op->ntime, op->nbits, pn+0x400000) ? pn + 0x400000 : 0;
+				if (s)
+					results[results_num++] = bswap_32(s);
+			}
+		}
+		info->results_n = results_num;
+
+		memcpy(op, p, sizeof(struct bitfury_payload));
+		memcpy(oldbuf, newbuf, 17 * 4);
+	}
+
+	cgsleep_ms(BITFURY_REFRESH_DELAY);
+	second_run = 1;
+}
diff --git a/libbitfury.h b/libbitfury.h
index 562b942..377b3dd 100644
--- a/libbitfury.h
+++ b/libbitfury.h
@@ -9,16 +9,16 @@
 
 #ifndef LIBBITFURY_H
 #define LIBBITFURY_H
-struct bitfury_payload {
-	unsigned char midstate[32];
-	unsigned int junk[8];
-	unsigned m7;
-	unsigned ntime;
-	unsigned nbits;
-	unsigned nnonce;
-};
+#include "miner.h"
+#include "driver-bitfury.h"
 
 void ms3steps(uint32_t *p);
 uint32_t decnonce(uint32_t in);
+void spi_clear_buf(struct bitfury_info *info);
+void spi_add_buf(struct bitfury_info *info, const void *buf, const int sz);
+void spi_add_break(struct bitfury_info *info);
+void spi_add_data(struct bitfury_info *info, uint16_t addr, const void *buf, int len);
+bool spi_reset(struct cgpu_info *bitfury, struct bitfury_info *info);
+bool spi_txrx(struct cgpu_info *bitfury, struct bitfury_info *info);
 
 #endif /* LIBBITFURY_H */