Add lots of magic spi initialisation to nanofury.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
diff --git a/driver-bitfury.c b/driver-bitfury.c
index b59b082..37537f2 100644
--- a/driver-bitfury.c
+++ b/driver-bitfury.c
@@ -287,7 +287,92 @@ static void nf1_close(struct cgpu_info *bitfury)
mcp2210_set_gpio_pindir(bitfury, i, MCP2210_GPIO_INPUT);
}
-static bool nf1_detect_one(struct cgpu_info *bitfury, struct bitfury_info __maybe_unused *info)
+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 > MCP2210_BUFFER_LENGTH)) {
+ 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)
+{
+ static const uint8_t enaconf[4] = { 0xc1, 0x6a, 0x59, 0xe3 };
+ static const uint8_t disconf[4] = { 0, 0, 0, 0 };
+
+ if (ena)
+ spi_add_data(info, 0x7000 + cfgreg * 32, enaconf, 4);
+ else
+ spi_add_data(info, 0x7000 + cfgreg * 32, disconf, 4);
+}
+
+static void nf1_set_freq(struct bitfury_info *info)
+{
+ uint64_t freq;
+ const uint8_t *osc6 = (unsigned char *)&freq;
+
+ freq = (1ULL << info->osc6_bits) - 1ULL;
+ spi_add_data(info, 0x6000, osc6, 8); /* Program internal on-die slow oscillator frequency */
+ nf1_config_reg(info, 4, 1);
+}
+
+static void nf1_reinit(struct cgpu_info *bitfury, struct bitfury_info *info)
+{
+ spi_clear_buf(info);
+ spi_add_break(info);
+ nf1_set_freq(info);
+ //nf1_send_conf(info);
+ //nf1_send_init(info);
+ //nf1_txrx(bitfury, info);
+}
+
+static bool nf1_detect_one(struct cgpu_info *bitfury, struct bitfury_info *info)
{
unsigned int bitrate, icsv, acsv, cstdd, ldbtcsd, sdbd, bpst, spimode, length;
char buf[MCP2210_BUFFER_LENGTH];
@@ -371,6 +456,9 @@ static bool nf1_detect_one(struct cgpu_info *bitfury, struct bitfury_info __mayb
length = 1;
if (!mcp2210_spi_transfer(bitfury, buf, &length))
goto out;
+
+ info->osc6_bits = 50;
+ nf1_reinit(bitfury, info);
ret = true;
out:
if (!ret)
diff --git a/driver-bitfury.h b/driver-bitfury.h
index 0a5f99e..bf2677d 100644
--- a/driver-bitfury.h
+++ b/driver-bitfury.h
@@ -12,6 +12,7 @@
#include "miner.h"
#include "usbutils.h"
+#include "mcp2210.h"
#define BXF_CLOCK_DEFAULT 54
#define BXF_CLOCK_OFF 0
@@ -62,6 +63,11 @@ struct bitfury_info {
int filtered_hw[2]; // Hardware errors we're told about but are filtered
int job[2]; // Completed jobs we're told about
int submits[2]; // Submitted responses
+
+ /* NF1 specific data */
+ char spibuf[MCP2210_BUFFER_LENGTH];
+ int spibufsz;
+ int osc6_bits;
};
#endif /* BITFURY_H */