Commit e869b43ba44f9c332247190b6d6472deaf909a05

Kano 2014-01-24T21:15:15

Add bab-options

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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
diff --git a/ASIC-README b/ASIC-README
index b206d43..5857e2a 100644
--- a/ASIC-README
+++ b/ASIC-README
@@ -40,7 +40,7 @@ BlackArrow Bitfury devices
 BlackArrow Bitfury devices need the --enable-bab option when compiling cgminer.
 
 The current BlackArrow Bitfury devices are similar to the Bitfury GPIO mining
-boards and come up as BaB. There are no options available for them.
+boards, with both V1 and V2 controllers, and come up as BaB.
 
 
 BITFURY devices
@@ -129,6 +129,7 @@ ASIC SPECIFIC COMMANDS
 --avalon-freq <arg> Set frequency range for avalon-auto, single value or range
 --avalon-options <arg> Set avalon options baud:miners:asic:timeout:freq:tech
 --avalon-temp <arg> Set avalon target temperature (default: 50)
+--bab-options <arg> Set BaB options max:def:min:up:down:hz:delay:trf
 --bflsc-overheat <arg> Set overheat temperature where BFLSC devices throttle, 0 to disable (default: 90)
 --bitburner-fury-options <arg> Override avalon-options for BitBurner Fury boards baud:miners:asic:timeout:freq
 --bitburner-fury-voltage <arg> Set BitBurner Fury core voltage, in millivolts
@@ -344,6 +345,28 @@ ext recommends a clock of 80 to 230, with a default of 200
 voltage must be one of 650, 750, 850 or 950 with a default of 850
 
 
+BlackArrow Bitfury devices
+
+--bab-options <arg> Set BaB options Max:Def:Min:Up:Down:Hz:Delay:Trf
+
+Any option left blank or starting with 'd' will use the default setting
+If there are not enough options, then the remaining will be left at their
+defailt value
+
+Max:Def:Min are the chip speed limits to allow ranging from 52 to 57
+
+Up:Down are the HW error % used to tune the chip speed
+Up means if the HW error % is less than up over a 5 minute period,
+then increase the chip speed
+Down means if the HW error % is greater than down over 5 minutes,
+then decrease the chip speed
+
+Hz is the SPI clock speed to use
+
+Delay is the us delay used between bytes for the SPI I/O - default 0
+
+Trf is the us delay used between sends for the SPI I/O - default 0
+
 ---
 
 This code is provided entirely free of charge by the programmer in his spare
diff --git a/README b/README
index a5c955e..8c8fc62 100644
--- a/README
+++ b/README
@@ -218,6 +218,7 @@ ASIC only options:
 --avalon-cutoff <arg> Set avalon overheat cut off temperature (default: 60)
 --avalon-options <arg> Set avalon options baud:miners:asic:timeout:freq:tech
 --avalon-temp <arg> Set avalon target temperature (default: 50)
+--bab-options <arg> Set BaB options max:def:min:up:down:hz:delay:trf
 --bflsc-overheat <arg> Set overheat temperature where BFLSC devices throttle, 0 to disable (default: 90)
 --bitburner-fury-options <arg> Override avalon-options for BitBurner Fury boards baud:miners:asic:timeout:freq
 --bitburner-fury-voltage <arg> Set BitBurner Fury core voltage, in millivolts
diff --git a/cgminer.c b/cgminer.c
index 9ae57f0..d847bb9 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -174,6 +174,7 @@ char *opt_klondike_options = NULL;
 #ifdef USE_DRILLBIT
 char *opt_drillbit_options = NULL;
 #endif
+char *opt_bab_options = NULL;
 #ifdef USE_USBUTILS
 char *opt_usb_select = NULL;
 int opt_usbdump = -1;
@@ -1063,6 +1064,15 @@ static char *set_drillbit_options(const char *arg)
 }
 #endif
 
+#ifdef USE_BAB
+static char *set_bab_options(const char *arg)
+{
+	opt_set_charp(arg, &opt_bab_options);
+
+	return NULL;
+}
+#endif
+
 #ifdef USE_USBUTILS
 static char *set_usb_select(const char *arg)
 {
@@ -1230,6 +1240,11 @@ static struct opt_table opt_config_table[] = {
                      set_drillbit_options, NULL, NULL,
                      "Set drillbit options <int|ext>:clock[:clock_divider][:voltage]"),
 #endif
+#ifdef USE_BAB
+	OPT_WITH_ARG("--bab-options",
+		     set_bab_options, NULL, NULL,
+		     "Set bab options max:def:min:up:down:hz:delay:trf"),
+#endif
 	OPT_WITHOUT_ARG("--load-balance",
 		     set_loadbalance, &pool_strategy,
 		     "Change multipool strategy from failover to quota based balance"),
@@ -4393,12 +4408,14 @@ void write_config(FILE *fcfg)
 		fprintf(fcfg, ",\n\"icarus-timing\" : \"%s\"", json_escape(opt_icarus_timing));
 #ifdef USE_KLONDIKE
 	if (opt_klondike_options)
-		fprintf(fcfg, ",\n\"klondike-options\" : \"%s\"", json_escape(opt_icarus_options));
+		fprintf(fcfg, ",\n\"klondike-options\" : \"%s\"", json_escape(opt_klondike_options));
 #endif
 #ifdef USE_DRILLBIT
         if (opt_drillbit_options)
                 fprintf(fcfg, ",\n\"drillbit-options\" : \"%s\"", json_escape(opt_drillbit_options));
 #endif
+	if (opt_bab_options)
+		fprintf(fcfg, ",\n\"bab-options\" : \"%s\"", json_escape(opt_bab_options));
 #ifdef USE_USBUTILS
 	if (opt_usb_select)
 		fprintf(fcfg, ",\n\"usb\" : \"%s\"", json_escape(opt_usb_select));
diff --git a/driver-bab.c b/driver-bab.c
index 9fc3357..e0b54c6 100644
--- a/driver-bab.c
+++ b/driver-bab.c
@@ -17,6 +17,7 @@
 #include "sha2.h"
 #include "libbitfury.h"
 #include "klist.h"
+#include <ctype.h>
 
 /*
  * Tested on RPi running both Raspbian and Arch
@@ -39,9 +40,13 @@ static void bab_detect(__maybe_unused bool hotplug)
 #define BAB_SPI_BUS 0
 #define BAB_SPI_CHIP 0
 
-#define BAB_SPI_SPEED 96000
+//#define BAB_SPI_SPEED 96000
+#define BAB_SPI_SPEED 1000000
 #define BAB_SPI_BUFSIZ 1024
 
+#define BAB_DELAY_USECS 0
+#define BAB_TRF_DELAY 0
+
 #define BAB_ADDR(_n) (*((babinfo->gpio) + (_n)))
 
 #define BAB_INP_GPIO(_n) BAB_ADDR((_n) / 10) &= (~(7 << (((_n) % 10) * 3)))
@@ -356,13 +361,6 @@ struct bab_info {
 	struct bab_work_reply chip_results[BAB_MAXCHIPS];
 	struct bab_work_reply chip_prev[BAB_MAXCHIPS];
 
-	uint8_t max_speed;
-	uint8_t def_speed;
-	uint8_t min_speed;
-
-	float tune_up;
-	float tune_down;
-
 	uint8_t chip_fast[BAB_MAXCHIPS];
 	uint8_t chip_conf[BAB_MAXCHIPS];
 	uint8_t old_fast[BAB_MAXCHIPS];
@@ -461,6 +459,16 @@ struct bab_info {
 	bool dead_msg[BAB_MAXCHIPS];
 #endif
 
+	// bab-options (in order)
+	uint8_t max_speed;
+	uint8_t def_speed;
+	uint8_t min_speed;
+	double tune_up;
+	double tune_down;
+	uint32_t speed_hz;
+	uint16_t delay_usecs;
+	uint64_t trf_delay;
+
 	struct timeval last_did;
 
 	bool initialised;
@@ -609,8 +617,8 @@ static bool _bab_txrx(struct cgpu_info *babcgpu, struct bab_info *babinfo, K_ITE
 	siz = (uint32_t)(DATAS(item)->siz);
 
 	memset(&tran, 0, sizeof(tran));
-	tran.delay_usecs = 0;
-	tran.speed_hz = BAB_SPI_SPEED;
+	tran.speed_hz = babinfo->speed_hz;
+	tran.delay_usecs = babinfo->delay_usecs;
 
 	i = 0;
 	pos = 0;
@@ -694,6 +702,9 @@ static bool _bab_txrx(struct cgpu_info *babcgpu, struct bab_info *babinfo, K_ITE
 		wbuf += tran.len;
 		rbuf += tran.len;
 		pos += tran.len;
+
+		if (siz > 0 && babinfo->trf_delay > 0)
+			cgsleep_us(babinfo->trf_delay);
 	}
 	cgtime(&(DATAS(item)->work_start));
 	mutex_lock(&(babinfo->did_lock));
@@ -1026,6 +1037,9 @@ static bool bab_init_gpio(struct cgpu_info *babcgpu, struct bab_info *babinfo, i
 	int i, err, memfd, data;
 	char buf[64];
 
+	bab_ioc[4].value = (int)(babinfo->speed_hz);
+	bab_ioc[5].value = (int)(babinfo->speed_hz);
+
 	for (i = 0; bab_modules[i]; i++) {
 		snprintf(buf, sizeof(buf), "modprobe %s", bab_modules[i]);
 		err = system(buf);
@@ -1171,6 +1185,148 @@ static void bab_init_chips(struct cgpu_info *babcgpu, struct bab_info *babinfo)
 	memcpy(babinfo->old_fast, babinfo->chip_fast, sizeof(babinfo->old_fast));
 }
 
+static char *bab_options[] = {
+	"MaxSpeed",
+	"DefaultSpeed",
+	"MinSpeed",
+	"TuneUp",
+	"TuneDown",
+	"SPISpeed",
+	"SPIDelayuS",
+	"TransferDelayuS"
+};
+
+#define INVOP " Invalid Option "
+
+static void bab_get_options(struct cgpu_info *babcgpu, struct bab_info *babinfo)
+{
+	char *ptr, *colon;
+	int which, val;
+	double fval;
+	long lval;
+
+	if (opt_bab_options == NULL)
+		return;
+
+	which = 0;
+	ptr = opt_bab_options;
+	while (ptr && *ptr) {
+		colon = strchr(ptr, ':');
+		if (colon)
+			*(colon++) = '\0';
+
+		switch (which) {
+			case 0:
+				if (*ptr && tolower(*ptr) != 'd') {
+					val = atoi(ptr);
+					if (!isdigit(*ptr) || val < BAB_MINSPEED || val > BAB_MAXSPEED) {
+						quit(1, "%s"INVOP"%s '%s' must be %d <= %s <= %d",
+							babcgpu->drv->dname,
+							bab_options[which],
+							ptr, BAB_MINSPEED,
+							bab_options[which],
+							BAB_MAXSPEED);
+					}
+					babinfo->max_speed = (uint8_t)val;
+				}
+				break;
+			case 1:
+				if (*ptr && tolower(*ptr) != 'd') {
+					val = atoi(ptr);
+					if (!isdigit(*ptr) || val < BAB_MINSPEED || val > babinfo->max_speed) {
+						quit(1, "%s"INVOP"%s '%s' must be %d <= %s <= %d",
+							babcgpu->drv->dname,
+							bab_options[which],
+							ptr, BAB_MINSPEED,
+							bab_options[which],
+							babinfo->max_speed);
+					}
+					babinfo->def_speed = (uint8_t)val;
+				}
+				break;
+			case 2:
+				if (*ptr && tolower(*ptr) != 'd') {
+					val = atoi(ptr);
+					if (!isdigit(*ptr) || val < BAB_MINSPEED || val > babinfo->def_speed) {
+						quit(1, "%s"INVOP"%s '%s' must be %d <= %s <= %d",
+							babcgpu->drv->dname,
+							bab_options[which],
+							ptr, BAB_MINSPEED,
+							bab_options[which],
+							babinfo->def_speed);
+					}
+					babinfo->min_speed = (uint8_t)val;
+				}
+				break;
+			case 3:
+				if (*ptr && tolower(*ptr) != 'd') {
+					fval = atof(ptr);
+					if (!isdigit(*ptr) || fval < 0.0 || fval > 100.0) {
+						quit(1, "%s"INVOP"%s '%s' must be 0.0 <= %s <= 100.0",
+							babcgpu->drv->dname,
+							bab_options[which], ptr,
+							bab_options[which]);
+					}
+					babinfo->tune_up = fval;
+				}
+				break;
+			case 4:
+				if (*ptr && tolower(*ptr) != 'd') {
+					fval = atof(ptr);
+					if (!isdigit(*ptr) || fval < 0.0 || fval > 100.0) {
+						quit(1, "%s"INVOP"%s '%s' must be %f <= %s <= 100.0",
+							babcgpu->drv->dname,
+							bab_options[which],
+							ptr, babinfo->tune_up,
+							bab_options[which]);
+					}
+					babinfo->tune_down = fval;
+				}
+				break;
+			case 5:
+				if (*ptr && tolower(*ptr) != 'd') {
+					val = atoi(ptr);
+					if (!isdigit(*ptr) || val < 10000 || val > 10000000) {
+						quit(1, "%s"INVOP"%s '%s' must be 10,000 <= %s <= 10,000,000",
+							babcgpu->drv->dname,
+							bab_options[which], ptr,
+							bab_options[which]);
+					}
+					babinfo->speed_hz = (uint32_t)val;
+				}
+				break;
+			case 6:
+				if (*ptr && tolower(*ptr) != 'd') {
+					val = atoi(ptr);
+					if (!isdigit(*ptr) || val < 0 || val > 65535) {
+						quit(1, "%s"INVOP"%s '%s' must be 0 <= %s <= 65535",
+							babcgpu->drv->dname,
+							bab_options[which], ptr,
+							bab_options[which]);
+					}
+					babinfo->delay_usecs = (uint16_t)val;
+				}
+				break;
+			case 7:
+				if (*ptr && tolower(*ptr) != 'd') {
+					lval = atol(ptr);
+					if (!isdigit(*ptr) || lval < 0) {
+						quit(1, "%s"INVOP"%s '%s' must be %s >= 0",
+							babcgpu->drv->dname,
+							bab_options[which], ptr,
+							bab_options[which]);
+					}
+					babinfo->trf_delay = (uint64_t)lval;
+				}
+				break;
+			default:
+				break;
+		}
+		ptr = colon;
+		which++;
+	}
+}
+
 static void bab_detect(bool hotplug)
 {
 	struct cgpu_info *babcgpu = NULL;
@@ -1200,7 +1356,11 @@ static void bab_detect(bool hotplug)
 	babinfo->tune_up = BAB_TUNEUP;
 	babinfo->tune_down = BAB_TUNEDOWN;
 
-	// TODO: get --bab-options
+	babinfo->speed_hz = BAB_SPI_SPEED;
+	babinfo->delay_usecs = BAB_DELAY_USECS;
+	babinfo->trf_delay = BAB_TRF_DELAY;
+
+	bab_get_options(babcgpu, babinfo);
 
 	for (i = 0; i < BAB_MAXCHIPS; i++) {
 		babinfo->chip_conf[i] = BAB_DEFCONF;
@@ -1429,7 +1589,7 @@ static void process_history(struct cgpu_info *babcgpu, int chip, struct timeval 
 	struct bab_info *babinfo = (struct bab_info *)(babcgpu->device_data);
 	uint64_t good_nonces, bad_nonces;
 	uint8_t chip_fast;
-	float tune;
+	double tune;
 	K_ITEM *item;
 	int i;
 
@@ -1525,7 +1685,7 @@ static void process_history(struct cgpu_info *babcgpu, int chip, struct timeval 
 		if (babinfo->bad_fast[chip] <= chip_fast)
 			babinfo->bad_fast[chip] = chip_fast + 1;
 
-		tune = (float)bad_nonces / (float)(good_nonces + bad_nonces) * 100.0;
+		tune = (double)bad_nonces / (double)(good_nonces + bad_nonces) * 100.0;
 
 		// Tune it down if error rate is too high
 		if (tune >= babinfo->tune_down) {
@@ -2492,6 +2652,20 @@ static struct api_data *bab_api_stats(struct cgpu_info *babcgpu)
 	root = api_add_double(root, "Send Min", &(babinfo->send_min), true);
 	root = api_add_double(root, "Send Max", &(babinfo->send_max), true);
 
+	i = (int)(babinfo->max_speed);
+	root = api_add_int(root, bab_options[0], &i, true);
+	i = (int)(babinfo->def_speed);
+	root = api_add_int(root, bab_options[1], &i, true);
+	i = (int)(babinfo->min_speed);
+	root = api_add_int(root, bab_options[2], &i, true);
+	root = api_add_double(root, bab_options[3], &(babinfo->tune_up), true);
+	root = api_add_double(root, bab_options[4], &(babinfo->tune_down), true);
+	i = (int)(babinfo->speed_hz);
+	root = api_add_int(root, bab_options[5], &i, true);
+	i = (int)(babinfo->delay_usecs);
+	root = api_add_int(root, bab_options[6], &i, true);
+	root = api_add_uint64(root, bab_options[7], &(babinfo->trf_delay), true);
+
 	return root;
 }
 
diff --git a/miner.h b/miner.h
index 08b1fa0..3e5ff36 100644
--- a/miner.h
+++ b/miner.h
@@ -959,6 +959,9 @@ extern char *opt_klondike_options;
 #ifdef USE_DRILLBIT
 extern char *opt_drillbit_options;
 #endif
+#ifdef USE_BAB
+extern char *opt_bab_options;
+#endif
 #ifdef USE_USBUTILS
 extern char *opt_usb_select;
 extern int opt_usbdump;