Add capacity for command line --drillbit-options (modelled on klondike driver)
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
diff --git a/cgminer.c b/cgminer.c
index e8eafd0..429bee7 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -171,6 +171,9 @@ char *opt_avalon_options = NULL;
#ifdef USE_KLONDIKE
char *opt_klondike_options = NULL;
#endif
+#ifdef USE_DRILLBIT
+char *opt_drillbit_options = NULL;
+#endif
#ifdef USE_USBUTILS
char *opt_usb_select = NULL;
int opt_usbdump = -1;
@@ -1047,6 +1050,15 @@ static char *set_klondike_options(const char *arg)
}
#endif
+#ifdef USE_DRILLBIT
+static char *set_drillbit_options(const char *arg)
+{
+ opt_set_charp(arg, &opt_drillbit_options);
+
+ return NULL;
+}
+#endif
+
#ifdef USE_USBUTILS
static char *set_usb_select(const char *arg)
{
@@ -1261,6 +1273,11 @@ static struct opt_table opt_config_table[] = {
set_klondike_options, NULL, NULL,
"Set klondike options clock:temp1:temp2:fan"),
#endif
+#ifdef USE_DRILLBIT
+ OPT_WITH_ARG("--drillbit-options",
+ set_drillbit_options, NULL, NULL,
+ "Set drillbit options <int|ext>:clock[:clock_divider][:voltage]"),
+#endif
OPT_WITHOUT_ARG("--load-balance",
set_loadbalance, &pool_strategy,
"Change multipool strategy from failover to quota based balance"),
@@ -1595,6 +1612,9 @@ static char *opt_verusage_and_exit(const char *extra)
#ifdef USE_BITFURY
"bitfury "
#endif
+#ifdef USE_DRILLBIT
+ "drillbit "
+#endif
#ifdef HAVE_OPENCL
"GPU "
#endif
@@ -4528,6 +4548,10 @@ void write_config(FILE *fcfg)
if (opt_klondike_options)
fprintf(fcfg, ",\n\"klondike-options\" : \"%s\"", json_escape(opt_icarus_options));
#endif
+#ifdef USE_DRILLBIT
+ if (opt_drillbit_options)
+ fprintf(fcfg, ",\n\"drillbit-options\" : \"%s\"", json_escape(opt_drillbit_options));
+#endif
#ifdef USE_USBUTILS
if (opt_usb_select)
fprintf(fcfg, ",\n\"usb\" : \"%s\"", json_escape(opt_usb_select));
diff --git a/driver-drillbit.c b/driver-drillbit.c
index 6e92e57..6c4b8ed 100644
--- a/driver-drillbit.c
+++ b/driver-drillbit.c
@@ -60,7 +60,8 @@ typedef struct __attribute__((packed)) Identity
uint8_t num_chips;
} Identity;
-static const BoardConfig DEFAULT_CONFIG = {
+/* Comparatively modest default settings */
+static BoardConfig drillbit_config = {
core_voltage: CONFIG_CORE_085V,
use_ext_clock: 0,
int_clock_level: 40,
@@ -242,12 +243,86 @@ static void drillbit_send_config(struct cgpu_info *drillbit, const BoardConfig *
usb_read_simple_response(drillbit, 'C', C_BF_CONFIG); // TODO: verify response
}
+static bool drillbit_parse_options()
+{
+ /* Read configuration options (currently global not per-ASIC or per-board) */
+ if (opt_drillbit_options != NULL) {
+ int count, freq, clockdiv, voltage;
+ char clksrc[4];
+
+ count = sscanf(opt_drillbit_options, "%3s:%d:%d:%d",
+ clksrc, &freq, &clockdiv, &voltage);
+
+ if(count < 2) {
+ applog(LOG_ERR, "Failed to parse drillbit-options. Invalid options string: '%s'", opt_drillbit_options);
+ return false;
+ }
+
+ if(count > 2 && clockdiv != 1 && clockdiv != 2) {
+ applog(LOG_ERR, "drillbit-options: Invalid clock divider value %d. Valid values are 1 & 2.", clockdiv);
+ return false;
+ }
+ drillbit_config.clock_div2 = count > 2 && clockdiv == 2;
+
+ if(!strcmp("int",clksrc)) {
+ drillbit_config.use_ext_clock = 0;
+ if(freq < 0 || freq > 63) {
+ applog(LOG_ERR, "drillbit-options: Invalid internal oscillator level %d. Recommended range is %s for this clock divider (possible is 0-63)", freq, drillbit_config.clock_div2 ? "48-57":"30-48");
+ return false;
+ }
+ if(drillbit_config.clock_div2 && (freq < 48 || freq > 57)) {
+ applog(LOG_WARNING, "drillbit-options: Internal oscillator level %d outside recommended range 48-57.", freq);
+ }
+ if(!drillbit_config.clock_div2 && (freq < 30 || freq > 48)) {
+ applog(LOG_WARNING, "drillbit-options: Internal oscillator level %d outside recommended range 30-48.", freq);
+ }
+ drillbit_config.int_clock_level = freq;
+ }
+ else if (!strcmp("ext", clksrc)) {
+ drillbit_config.use_ext_clock = 1;
+ drillbit_config.ext_clock_freq = freq;
+ if(freq < 80 || freq > 230) {
+ applog(LOG_WARNING, "drillbit-options: Warning: recommended external clock frequencies are 80-230MHz. Value %d may produce unexpected results.", freq);
+ }
+ }
+ else {
+ applog(LOG_ERR, "drillbit-options: Invalid clock source. Valid choices are int, ext.");
+ return false;
+ }
+
+ if(count > 3) {
+ switch(voltage) {
+ case 650:
+ voltage = CONFIG_CORE_065V;
+ break;
+ case 750:
+ voltage = CONFIG_CORE_075V;
+ break;
+ case 850:
+ voltage = CONFIG_CORE_085V;
+ break;
+ case 950:
+ voltage = CONFIG_CORE_095V;
+ break;
+ default:
+ applog(LOG_ERR, "drillbit-options: Invalid core voltage %d. Valid values 650,750,850,950mV)", voltage);
+ return false;
+ }
+ drillbit_config.core_voltage = voltage;
+ }
+ }
+ return true;
+}
+
static bool drillbit_detect_one(struct libusb_device *dev, struct usb_find_devices *found)
{
struct cgpu_info *drillbit;
struct drillbit_info *info;
int i;
+ if (!drillbit_parse_options())
+ return; // Bit of a hack doing this here, should do it somewhere else
+
drillbit = usb_alloc_cgpu(&drillbit_drv, 1);
if (!usb_init(drillbit, dev, found))
@@ -287,7 +362,7 @@ static bool drillbit_detect_one(struct libusb_device *dev, struct usb_find_devic
update_usb_stats(drillbit);
- drillbit_send_config(drillbit, &DEFAULT_CONFIG);
+ drillbit_send_config(drillbit, &drillbit_config);
applog(LOG_INFO, "%s %d: Successfully initialised %s",
drillbit->drv->name, drillbit->device_id, drillbit->device_path);
@@ -376,7 +451,7 @@ static int check_for_results(struct thr_info *thr)
for(j = 0; j < result_count; j++) {
if(!usb_read_fixed_size(drillbit, &response, sizeof(WorkResult), TIMEOUT, C_BF_GETRES)) {
- applog(LOG_ERR, "Failed to read response data packet idx %d count %d", j, result_count);
+ applog(LOG_ERR, "Failed to read response data packet idx %d count 0x%x", j, result_count);
return 0;
}
@@ -526,7 +601,7 @@ static struct api_data *drillbit_api_stats(struct cgpu_info *cgpu)
return root;
}
-static void drillbit_init(struct cgpu_info *drillbit)
+static void drillbit_reinit(struct cgpu_info *drillbit)
{
drillbit_close(drillbit);
drillbit_open(drillbit);
@@ -548,7 +623,7 @@ struct device_drv drillbit_drv = {
.drv_detect = drillbit_detect,
.scanhash = drillbit_scanhash,
.get_api_stats = drillbit_api_stats,
- .reinit_device = drillbit_init,
+ .reinit_device = drillbit_reinit,
.thread_shutdown = drillbit_shutdown,
- .identify_device = drillbit_identify
+ .identify_device = drillbit_identify,
};
diff --git a/miner.h b/miner.h
index f4bbf01..576a9c9 100644
--- a/miner.h
+++ b/miner.h
@@ -1027,6 +1027,9 @@ extern char *opt_avalon_options;
#ifdef USE_KLONDIKE
extern char *opt_klondike_options;
#endif
+#ifdef USE_DRILLBIT
+extern char *opt_drillbit_options;
+#endif
#ifdef USE_USBUTILS
extern char *opt_usb_select;
extern int opt_usbdump;