Add support for temperature display (pending firmware support)
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
diff --git a/driver-drillbit.c b/driver-drillbit.c
index 4eebe09..297b258 100644
--- a/driver-drillbit.c
+++ b/driver-drillbit.c
@@ -85,6 +85,10 @@ typedef struct
uint16_t capabilities;
} Identity;
+/* Capabilities flags known to cgminer */
+#define CAP_TEMP 1
+#define CAP_EXT_CLOCK 2
+
#define SZ_SERIALISED_IDENTITY 16
static void deserialise_identity(Identity *identity, const uint8_t *buf);
@@ -245,7 +249,7 @@ static bool drillbit_getinfo(struct cgpu_info *drillbit, struct drillbit_info *i
}
const int MIN_VERSION = 2;
- const int MAX_VERSION = 2;
+ const int MAX_VERSION = 3;
if(identity.protocol_version < MIN_VERSION) {
drvlog(LOG_ERR, "Unknown device protocol version %d.", identity.protocol_version);
return false;
@@ -255,6 +259,11 @@ static bool drillbit_getinfo(struct cgpu_info *drillbit, struct drillbit_info *i
return false;
}
+ if(identity.protocol_version == 2 && identity.num_chips == 1) {
+ // Production firmware Thumbs don't set any capability bits, so fill in the EXT_CLOCK one
+ identity.capabilities = CAP_EXT_CLOCK;
+ }
+
// load identity data into device info structure
info->version = identity.protocol_version;
if(strncmp(identity.product, "DRILLBIT", sizeof(identity.product)) == 0) {
@@ -269,9 +278,11 @@ static bool drillbit_getinfo(struct cgpu_info *drillbit, struct drillbit_info *i
}
info->serial = identity.serial;
info->num_chips = identity.num_chips;
+ info->capabilities = identity.capabilities;
drvlog(LOG_INFO, "Getinfo returned version %d, product %s serial %08x num_chips %d",
info->version, info->product, info->serial, info->num_chips);
+
drillbit_empty_buffer(drillbit);
return true;
}
@@ -322,6 +333,11 @@ static void drillbit_send_config(struct cgpu_info *drillbit)
setting->config.core_voltage, setting->config.use_ext_clock,
setting->config.int_clock_level,
setting->config.clock_div2, setting->config.ext_clock_freq);
+
+ if(setting->config.use_ext_clock && !(info->capabilities & CAP_EXT_CLOCK)) {
+ drvlog(LOG_WARNING, "Board configuration calls for external clock but this device (serial %08x) has no external clock!", info->serial);
+ }
+
cmd = 'C';
usb_write(drillbit, &cmd, 1, &amount, C_BF_REQWORK);
@@ -332,6 +348,52 @@ static void drillbit_send_config(struct cgpu_info *drillbit)
usb_read_simple_response(drillbit, 'C', C_BF_CONFIG); // TODO: verify response
}
+static void drillbit_updatetemps(struct thr_info *thr)
+{
+ struct cgpu_info *drillbit = thr->cgpu;
+ struct drillbit_info *info = drillbit->device_data;
+ char cmd;
+ int amount;
+ uint16_t temp;
+ struct timeval tv_now;
+
+ if(!(info->capabilities & CAP_TEMP))
+ return;
+
+ cgtime(&tv_now);
+ if(ms_tdiff(&tv_now, &info->tv_lasttemp) < 1000)
+ return; // Only update temps once a second
+ info->tv_lasttemp = tv_now;
+
+ cmd = 'T';
+ usb_write(drillbit, &cmd, 1, &amount, C_BF_GETTEMP);
+
+ if(!usb_read_fixed_size(drillbit, &temp, sizeof(temp), TIMEOUT, C_BF_GETTEMP)) {
+ drvlog(LOG_ERR, "Got no response to request for current temperature");
+ return;
+ }
+
+ drvlog(LOG_INFO, "Got temperature reading %d.%dC", temp/10, temp%10);
+ info->temp = temp;
+ if(temp > info->max_temp)
+ info->max_temp = temp;
+}
+
+static void drillbit_get_statline_before(char *buf, size_t bufsiz, struct cgpu_info *drillbit)
+{
+ struct drillbit_info *info = drillbit->device_data;
+
+ tailsprintf(buf, bufsiz, "%c%d", info->product[0], info->num_chips);
+
+ if((info->capabilities & CAP_TEMP) && info->temp != 0) {
+ tailsprintf(buf, bufsiz, " %d.%dC (%d.%dC)", info->temp/10, info->temp%10,
+ info->max_temp/10, info->max_temp%10);
+ }
+
+ tailsprintf(buf, bufsiz, " | ");
+}
+
+
static bool drillbit_parse_options()
{
/* Read configuration options (currently global not per-ASIC or per-board) */
@@ -722,6 +784,8 @@ static int64_t drillbit_scanwork(struct thr_info *thr)
cgtime(&info->tv_lastchipinfo);
}
+ drillbit_updatetemps(thr);
+
cascade:
drillbit_empty_buffer(drillbit);
@@ -772,6 +836,7 @@ struct device_drv drillbit_drv = {
.hash_work = &hash_driver_work,
.scanwork = drillbit_scanwork,
.get_api_stats = drillbit_api_stats,
+ .get_statline_before = drillbit_get_statline_before,
.reinit_device = drillbit_reinit,
.thread_shutdown = drillbit_shutdown,
.identify_device = drillbit_identify,
diff --git a/driver-drillbit.h b/driver-drillbit.h
index 3324700..06a7e5d 100644
--- a/driver-drillbit.h
+++ b/driver-drillbit.h
@@ -21,11 +21,15 @@ struct drillbit_chip_info;
struct drillbit_info {
struct cgpu_info *base_cgpu;
uint8_t version;
+ uint8_t num_chips;
+ uint16_t capabilities;
char product[8];
uint32_t serial;
- uint8_t num_chips;
struct drillbit_chip_info *chips;
struct timeval tv_lastchipinfo;
+ struct timeval tv_lasttemp;
+ uint16_t temp;
+ uint16_t max_temp;
};
enum drillbit_chip_state {
diff --git a/usbutils.h b/usbutils.h
index 0e152f4..4b0e6fc 100644
--- a/usbutils.h
+++ b/usbutils.h
@@ -344,6 +344,7 @@ struct cg_usb_info {
USB_ADD_COMMAND(C_BF_IDENTIFY, "BFIdentify") \
USB_ADD_COMMAND(C_BF_DETECTCHIPS, "BFDetectChips") \
USB_ADD_COMMAND(C_BF_CONFIG, "BFConfig") \
+ USB_ADD_COMMAND(C_BF_GETTEMP, "BFGetTemp") \
USB_ADD_COMMAND(C_ATMEL_RESET, "AtmelReset") \
USB_ADD_COMMAND(C_ATMEL_OPEN, "AtmelOpen") \
USB_ADD_COMMAND(C_ATMEL_INIT, "AtmelInit") \