Browse Source

Merge branch 'hashfast' into bfgminer

Luke Dashjr 12 years ago
parent
commit
0722cb33ac
1 changed files with 84 additions and 0 deletions
  1. 84 0
      driver-hashfast.c

+ 84 - 0
driver-hashfast.c

@@ -33,6 +33,7 @@ BFG_REGISTER_DRIVER(hashfast_ums_drv)
 #define HASHFAST_HEADER_SIZE 8
 #define HASHFAST_HEADER_SIZE 8
 #define HASHFAST_MAX_DATA 0x3fc
 #define HASHFAST_MAX_DATA 0x3fc
 #define HASHFAST_HASH_SIZE (0x20 + 0xc + 4 + 4 + 2 + 1 + 1)
 #define HASHFAST_HASH_SIZE (0x20 + 0xc + 4 + 4 + 2 + 1 + 1)
+#define HASHFAST_MAX_VOLTAGES 4
 
 
 enum hashfast_opcode {
 enum hashfast_opcode {
 	HFOP_NULL          =    0,
 	HFOP_NULL          =    0,
@@ -71,6 +72,26 @@ enum hashfast_opcode {
 
 
 typedef unsigned long hashfast_isn_t;
 typedef unsigned long hashfast_isn_t;
 
 
+static inline
+float hashfast_temperature_conv(const uint8_t * const data)
+{
+	// Temperature is 12-bit fraction ranging between -61.5 C and ~178.5 C
+	uint32_t tempdata = ((uint32_t)data[1] << 8) | data[0];
+	tempdata &= 0xfff;
+	tempdata *= 240;
+	tempdata -= 251904;  // 61.5 * 4096
+	float temp = tempdata;
+	temp /= 4096.;
+	return temp;
+}
+
+static inline
+float hashfast_voltage_conv(const uint8_t vdata)
+{
+	// Voltage is 8-bit fraction ranging between 0 V and ~1.2 V
+	return (float)vdata / 256. * 1.2;
+}
+
 struct hashfast_parsed_msg {
 struct hashfast_parsed_msg {
 	uint8_t opcode;
 	uint8_t opcode;
 	uint8_t chipaddr;
 	uint8_t chipaddr;
@@ -257,6 +278,7 @@ struct hashfast_dev_state {
 struct hashfast_chip_state {
 struct hashfast_chip_state {
 	struct cgpu_info **coreprocs;
 	struct cgpu_info **coreprocs;
 	hashfast_isn_t last_isn;
 	hashfast_isn_t last_isn;
+	float voltages[HASHFAST_MAX_VOLTAGES];
 };
 };
 
 
 struct hashfast_core_state {
 struct hashfast_core_state {
@@ -514,6 +536,9 @@ bool hashfast_poll_msg(struct thr_info * const master_thr)
 			}
 			}
 			struct hashfast_chip_state * const chipstate = &devstate->chipstates[msg.chipaddr];
 			struct hashfast_chip_state * const chipstate = &devstate->chipstates[msg.chipaddr];
 			hashfast_isn_t isn = hashfast_get_isn(chipstate, msg.hdata);
 			hashfast_isn_t isn = hashfast_get_isn(chipstate, msg.hdata);
+			const float temp = hashfast_temperature_conv(&msg.data[0]);
+			for (int i = 0; i < HASHFAST_MAX_VOLTAGES; ++i)
+				chipstate->voltages[i] = hashfast_voltage_conv(msg.data[2 + i]);
 			int cores_uptodate, cores_active, cores_pending, cores_transitioned;
 			int cores_uptodate, cores_active, cores_pending, cores_transitioned;
 			cores_uptodate = cores_active = cores_pending = cores_transitioned = 0;
 			cores_uptodate = cores_active = cores_pending = cores_transitioned = 0;
 			for (int i = 0; i < devstate->cores_per_chip; ++i, (proc = proc->next_proc))
 			for (int i = 0; i < devstate->cores_per_chip; ++i, (proc = proc->next_proc))
@@ -525,6 +550,8 @@ bool hashfast_poll_msg(struct thr_info * const master_thr)
 				const bool has_pending = bits & 2;
 				const bool has_pending = bits & 2;
 				bool try_transition = true;
 				bool try_transition = true;
 				
 				
+				proc->temp = temp;
+				
 				if (cs->last_isn <= isn)
 				if (cs->last_isn <= isn)
 					++cores_uptodate;
 					++cores_uptodate;
 				else
 				else
@@ -576,6 +603,57 @@ void hashfast_poll(struct thr_info * const master_thr)
 	timer_set_delay_from_now(&master_thr->tv_poll, 100000);
 	timer_set_delay_from_now(&master_thr->tv_poll, 100000);
 }
 }
 
 
+static
+struct api_data *hashfast_api_stats(struct cgpu_info * const proc)
+{
+	struct hashfast_dev_state * const devstate = proc->device_data;
+	struct thr_info * const thr = proc->thr[0];
+	struct hashfast_core_state * const cs = thr->cgpu_data;
+	struct hashfast_chip_state * const chipstate = &devstate->chipstates[cs->chipaddr];
+	struct api_data *root = NULL;
+	char key[] = "VoltageNN";
+	
+	for (int i = 0; i < HASHFAST_MAX_VOLTAGES; ++i)
+	{
+		snprintf(&key[7], 3, "%d", i);
+		if (chipstate->voltages[i])
+			root = api_add_volts(root, key, &chipstate->voltages[i], false);
+	}
+	
+	return root;
+}
+
+#ifdef HAVE_CURSES
+static
+void hashfast_wlogprint_status(struct cgpu_info * const proc)
+{
+	struct hashfast_dev_state * const devstate = proc->device_data;
+	struct thr_info * const thr = proc->thr[0];
+	struct hashfast_core_state * const cs = thr->cgpu_data;
+	struct hashfast_chip_state * const chipstate = &devstate->chipstates[cs->chipaddr];
+	
+	{
+		// -> "NNN.xxx / NNN.xxx / NNN.xxx"
+		size_t sz = (HASHFAST_MAX_VOLTAGES * 10) + 1;
+		char buf[sz];
+		char *s = buf;
+		int rv = 0;
+		for (int i = 0; i < HASHFAST_MAX_VOLTAGES; ++i)
+		{
+			const float voltage = chipstate->voltages[i];
+			if (!voltage)
+				continue;
+			_SNP("%.3f / ", voltage);
+		}
+		if (rv >= 3 && s[-2] == '/')
+		{
+			s[-3] = '\0';
+			wlogprint("Voltages: %s\n", buf);
+		}
+	}
+}
+#endif
+
 struct device_drv hashfast_ums_drv = {
 struct device_drv hashfast_ums_drv = {
 	.dname = "hashfast_ums",
 	.dname = "hashfast_ums",
 	.name = "HFA",
 	.name = "HFA",
@@ -589,4 +667,10 @@ struct device_drv hashfast_ums_drv = {
 	.queue_append = hashfast_queue_append,
 	.queue_append = hashfast_queue_append,
 	.queue_flush = hashfast_queue_flush,
 	.queue_flush = hashfast_queue_flush,
 	.poll = hashfast_poll,
 	.poll = hashfast_poll,
+	
+	.get_api_stats = hashfast_api_stats,
+	
+#ifdef HAVE_CURSES
+	.proc_wlogprint_status = hashfast_wlogprint_status,
+#endif
 };
 };