Commit 68e514e67717aa54ace1bc51ffab64caed2f9dff

Con Kolivas 2014-02-03T20:10:42

Add op commands necessary to control hfa fanspeeds.

diff --git a/driver-hashfast.c b/driver-hashfast.c
index 3b1c30e..52099d8 100644
--- a/driver-hashfast.c
+++ b/driver-hashfast.c
@@ -24,6 +24,9 @@ int opt_hfa_overheat = HFA_TEMP_OVERHEAT;
 int opt_hfa_target = HFA_TEMP_TARGET;
 bool opt_hfa_pll_bypass;
 bool opt_hfa_dfu_boot;
+int opt_hfa_fan_default = HFA_FAN_DEFAULT;
+int opt_hfa_fan_max = HFA_FAN_MAX;
+int opt_hfa_fan_min = HFA_FAN_MIN;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Support for the CRC's used in header (CRC-8) and packet body (CRC-32)
@@ -102,7 +105,10 @@ static const struct hfa_cmd hfa_cmds[] = {
 	{OP_USB_STATS1, "OP_USB_STATS1", C_NULL},
 	{OP_USB_GWQSTATS, "OP_USB_GWQSTATS", C_HF_GWQSTATS},
 	{OP_USB_NOTICE, "OP_USB_NOTICE", C_HF_NOTICE},
-	{OP_PING, "OP_PING", C_HF_PING}
+	{OP_PING, "OP_PING", C_HF_PING},
+	{OP_CORE_MAP, "OP_CORE_MAP", C_NULL},
+	{OP_VERSION, "OP_VERSION", C_NULL},			// 32
+	{OP_FAN, "OP_FAN", C_HF_FAN}
 };
 
 #define HF_USB_CMD_OFFSET (128 - 18)
@@ -110,28 +116,13 @@ static const struct hfa_cmd hfa_cmds[] = {
 
 /* Send an arbitrary frame, consisting of an 8 byte header and an optional
  * packet body. */
-
-static bool hfa_send_frame(struct cgpu_info *hashfast, uint8_t opcode, uint16_t hdata,
-			   uint8_t *data, int len)
+static bool __hfa_send_frame(struct cgpu_info *hashfast, uint8_t opcode, int tx_length,
+			     uint8_t *packet)
 {
-	int tx_length, ret, amount, id = hashfast->device_id;
 	struct hashfast_info *info = hashfast->device_data;
-	uint8_t packet[256];
-	struct hf_header *p = (struct hf_header *)packet;
+	int ret, amount, id = hashfast->device_id;
 	bool retried = false;
 
-	p->preamble = HF_PREAMBLE;
-	p->operation_code = hfa_cmds[opcode].cmd;
-	p->chip_address = HF_GWQ_ADDRESS;
-	p->core_address = 0;
-	p->hdata = htole16(hdata);
-	p->data_length = len / 4;
-	p->crc8 = hfa_crc8(packet);
-
-	if (len)
-		memcpy(&packet[sizeof(struct hf_header)], data, len);
-	tx_length = sizeof(struct hf_header) + len;
-
 	if (unlikely(hashfast->usbinfo.nodev))
 		return false;
 
@@ -160,6 +151,28 @@ retry:
 	return true;
 }
 
+static bool hfa_send_frame(struct cgpu_info *hashfast, uint8_t opcode, uint16_t hdata,
+			   uint8_t *data, int len)
+{
+	uint8_t packet[256];
+	struct hf_header *p = (struct hf_header *)packet;
+	int tx_length;
+
+	p->preamble = HF_PREAMBLE;
+	p->operation_code = hfa_cmds[opcode].cmd;
+	p->chip_address = HF_GWQ_ADDRESS;
+	p->core_address = 0;
+	p->hdata = htole16(hdata);
+	p->data_length = len / 4;
+	p->crc8 = hfa_crc8(packet);
+
+	if (len)
+		memcpy(&packet[sizeof(struct hf_header)], data, len);
+	tx_length = sizeof(struct hf_header) + len;
+
+	return (__hfa_send_frame(hashfast, opcode, tx_length, packet));
+}
+
 /* Send an already assembled packet, consisting of an 8 byte header which may
  * or may not be followed by a packet body. */
 
@@ -907,6 +920,9 @@ static void *hfa_read(void *arg)
 	return NULL;
 }
 
+static void hfa_set_fanspeed(struct cgpu_info *hashfast, struct hashfast_info *info,
+			     int fanspeed);
+
 static bool hfa_prepare(struct thr_info *thr)
 {
 	struct cgpu_info *hashfast = thr->cgpu;
@@ -921,6 +937,7 @@ static bool hfa_prepare(struct thr_info *thr)
 	get_datestamp(hashfast->init, sizeof(hashfast->init), &now);
 	hashfast->last_device_valid_work = time(NULL);
 	info->resets = 0;
+	hfa_set_fanspeed(hashfast, info, opt_hfa_fan_default);
 
 	return true;
 }
@@ -953,6 +970,28 @@ out:
 	return ret;
 }
 
+static void hfa_set_fanspeed(struct cgpu_info *hashfast, struct hashfast_info *info,
+			     int fanspeed)
+{
+	const uint8_t opcode = HF_USB_CMD(OP_FAN);
+	uint8_t packet[256];
+	struct hf_header *p = (struct hf_header *)packet;
+	const int tx_length = sizeof(struct hf_header);
+	uint16_t hdata;
+
+	info->fanspeed = fanspeed;
+	hdata = fanspeed * 255 / 100; // Fanspeed is in percent, hdata 0-255
+	p->preamble = HF_PREAMBLE;
+	p->operation_code = hfa_cmds[opcode].cmd;
+	p->chip_address = 0xff;
+	p->core_address = 1;
+	p->hdata = htole16(hdata);
+	p->data_length = 0;
+	p->crc8 = hfa_crc8(packet);
+
+	__hfa_send_frame(hashfast, opcode, tx_length, packet);
+}
+
 static void hfa_increase_clock(struct cgpu_info *hashfast, struct hashfast_info *info,
 			       int die)
 {
diff --git a/driver-hashfast.h b/driver-hashfast.h
index bd74824..acc89b4 100644
--- a/driver-hashfast.h
+++ b/driver-hashfast.h
@@ -22,6 +22,9 @@ int opt_hfa_overheat;
 int opt_hfa_target;
 bool opt_hfa_pll_bypass;
 bool opt_hfa_dfu_boot;
+int opt_hfa_fan_default;
+int opt_hfa_fan_max;
+int opt_hfa_fan_min;
 
 #define HASHFAST_MINER_THREADS 1
 #define HFA_CLOCK_DEFAULT 550
@@ -29,6 +32,9 @@ bool opt_hfa_dfu_boot;
 #define HFA_TEMP_OVERHEAT 90
 #define HFA_TEMP_TARGET 85
 #define HFA_TEMP_HYSTERESIS 3
+#define HFA_FAN_DEFAULT 33
+#define HFA_FAN_MAX 100
+#define HFA_FAN_MIN 0
 
 // Matching fields for hf_statistics, but large #s for local accumulation, per-die
 struct hf_long_statistics {
@@ -116,6 +122,8 @@ struct hashfast_info {
 	int resets;
 	int overheat;
 	double max_temp;
+	int last_max_temp;
+	int fanspeed;                               // Fanspeed in percent
 
 	pthread_t read_thr;
 	time_t last_restart;
diff --git a/usbutils.h b/usbutils.h
index 4c4f3d3..60e2209 100644
--- a/usbutils.h
+++ b/usbutils.h
@@ -386,6 +386,7 @@ struct cg_usb_info {
 	USB_ADD_COMMAND(C_HF_GWQSTATS, "HFGWQStats") \
 	USB_ADD_COMMAND(C_HF_NOTICE, "HFNotice") \
 	USB_ADD_COMMAND(C_HF_PING, "HFPing") \
+	USB_ADD_COMMAND(C_HF_FAN, "HFFan") \
 	USB_ADD_COMMAND(C_HF_GETHEADER, "HFGetHeader") \
 	USB_ADD_COMMAND(C_HF_GETDATA, "HFGetData") \
 	USB_ADD_COMMAND(C_HF_CLEAR_READ, "HFClearRead") \