Browse Source

x6500 dual temp sensor support

Jason Hughes 13 years ago
parent
commit
193ea4a75e
3 changed files with 131 additions and 1 deletions
  1. 106 1
      driver-x6500.c
  2. 23 0
      ft232r.c
  3. 2 0
      ft232r.h

+ 106 - 1
driver-x6500.c

@@ -178,8 +178,8 @@ struct x6500_fpga_data {
 	struct jtag_port jtag;
 	struct jtag_port jtag;
 	struct work prevwork;
 	struct work prevwork;
 	struct timeval tv_workstart;
 	struct timeval tv_workstart;
-
 	struct dclk_data dclk;
 	struct dclk_data dclk;
+	float temp;
 };
 };
 
 
 #define bailout2(...) do {  \
 #define bailout2(...) do {  \
@@ -386,10 +386,107 @@ static bool x6500_fpga_init(struct thr_info *thr)
 	return true;
 	return true;
 }
 }
 
 
+static 
+void x6500_get_temperature(struct cgpu_info *x6500)
+{
+
+	struct x6500_fpga_data *fpga = x6500->thr[0]->cgpu_data;
+	struct jtag_port *jp = &fpga->jtag;
+	struct ft232r_device_handle *ftdi = jp->a->ftdi;
+	int i, code[2];
+	bool sio[2];
+
+	code[0] = 0;
+	code[1] = 0;
+
+	ft232r_flush(ftdi);
+
+
+	if (!(ft232r_set_cbus_bits(ftdi, false, true))) return;
+	if (!(ft232r_set_cbus_bits(ftdi, true, true))) return;
+	if (!(ft232r_set_cbus_bits(ftdi, false, true))) return;
+	if (!(ft232r_set_cbus_bits(ftdi, true, true))) return;
+	if (!(ft232r_set_cbus_bits(ftdi, false, false))) return;
+
+	for (i = 16; i--; ) {
+		if (ft232r_set_cbus_bits(ftdi, true, false)) {
+			if (!(ft232r_get_cbus_bits(ftdi, &sio[0], &sio[1]))) {
+				return;
+			}
+		} else {
+			return;
+		}
+
+		code[0] |= sio[0] << i;
+		code[1] |= sio[1] << i;
+		if (!ft232r_set_cbus_bits(ftdi, false, false)) {
+			return;
+		}
+	}
+
+	if (!(ft232r_set_cbus_bits(ftdi, false, true))) {
+		return;
+	}
+	if (!(ft232r_set_cbus_bits(ftdi, true, true))) {
+		return;
+	}
+	if (!(ft232r_set_cbus_bits(ftdi, false, true))) {
+		return;
+	}
+	if (!ft232r_set_bitmode(ftdi, 0xee, 4)) {
+		return;
+	}
+	ft232r_purge_buffers(jp->a->ftdi, FTDI_PURGE_BOTH);
+	jp->a->bufread = 0;
+
+	for (i = 0; i < 2; ++i) {
+		fpga = x6500->thr[i]->cgpu_data;
+		if (code[i] == 0xffff || !code[i]) {
+			fpga->temp = 0;
+			continue;
+		}
+		if ((code[i] >> 15) & 1)
+			code[i] -= 0x10000;
+		fpga->temp = (float)(code[i] >> 2) * 0.03125f;
+		applog(LOG_DEBUG,"x6500_get_temperature: fpga[%d]->temp=%.1fC",i,fpga->temp);
+	}
+
+}
+
+static bool x6500_get_stats(struct cgpu_info *x6500)
+{
+	float hottest = 0;
+	if (x6500->deven != DEV_ENABLED) {
+		// Getting temperature more efficiently while enabled
+		// NOTE: Don't need to mess with mutex here, since the device is disabled
+		x6500_get_temperature(x6500);
+	} else {
+		mutex_lock(&x6500->device_mutex);
+		x6500_get_temperature(x6500);
+		mutex_unlock(&x6500->device_mutex);
+	}
+
+	for (int i = x6500->threads; i--; ) {
+		struct thr_info *thr = x6500->thr[i];
+		struct x6500_fpga_data *fpga = thr->cgpu_data;
+		if (!fpga)
+			continue;
+		float temp = fpga->temp;
+		if (temp > hottest)
+			hottest = temp;
+	}
+
+	x6500->temp = hottest;
+
+	return true;
+}
+
 static void
 static void
 get_x6500_statline_before(char *buf, struct cgpu_info *x6500)
 get_x6500_statline_before(char *buf, struct cgpu_info *x6500)
 {
 {
 	char info[18] = "               | ";
 	char info[18] = "               | ";
+	struct x6500_fpga_data *fpga0 = x6500->thr[0]->cgpu_data;
+	struct x6500_fpga_data *fpga1 = x6500->thr[1]->cgpu_data;
 
 
 	unsigned char pdone = *((unsigned char*)x6500->cgpu_data - 1);
 	unsigned char pdone = *((unsigned char*)x6500->cgpu_data - 1);
 	if (pdone != 101) {
 	if (pdone != 101) {
@@ -398,6 +495,12 @@ get_x6500_statline_before(char *buf, struct cgpu_info *x6500)
 		strcat(buf, info);
 		strcat(buf, info);
 		return;
 		return;
 	}
 	}
+	if (x6500->temp) {
+		sprintf(&info[1], "%.1fC/%.1fC", fpga0->temp, fpga1->temp);
+		info[strlen(info)] = ' ';
+		strcat(buf, info);
+		return;
+	}
 	strcat(buf, "               | ");
 	strcat(buf, "               | ");
 }
 }
 
 
@@ -420,6 +523,7 @@ bool x6500_start_work(struct thr_info *thr, struct work *work)
 	ft232r_flush(jp->a->ftdi);
 	ft232r_flush(jp->a->ftdi);
 
 
 	gettimeofday(&fpga->tv_workstart, NULL);
 	gettimeofday(&fpga->tv_workstart, NULL);
+	//x6500_get_temperature(x6500);
 	mutex_unlock(&x6500->device_mutex);
 	mutex_unlock(&x6500->device_mutex);
 
 
 	if (opt_debug) {
 	if (opt_debug) {
@@ -526,6 +630,7 @@ struct device_api x6500_api = {
 	.api_detect = x6500_detect,
 	.api_detect = x6500_detect,
 	.thread_prepare = x6500_prepare,
 	.thread_prepare = x6500_prepare,
 	.thread_init = x6500_fpga_init,
 	.thread_init = x6500_fpga_init,
+	.get_stats = x6500_get_stats,
 	.get_statline_before = get_x6500_statline_before,
 	.get_statline_before = get_x6500_statline_before,
 	.scanhash = x6500_scanhash,
 	.scanhash = x6500_scanhash,
 // 	.thread_shutdown = x6500_fpga_shutdown,
 // 	.thread_shutdown = x6500_fpga_shutdown,

+ 23 - 0
ft232r.c

@@ -145,6 +145,7 @@ int ft232r_detect(const char *product_needle, const char *serial, foundusb_func_
 #define FTDI_REQUEST_SET_BAUDRATE    3
 #define FTDI_REQUEST_SET_BAUDRATE    3
 #define FTDI_REQUEST_SET_BITMODE  0x0b
 #define FTDI_REQUEST_SET_BITMODE  0x0b
 #define FTDI_REQUEST_GET_PINS     0x0c
 #define FTDI_REQUEST_GET_PINS     0x0c
+#define FTDI_REQUEST_GET_BITMODE  0x0c
 
 
 #define FTDI_BAUDRATE_3M  0,0
 #define FTDI_BAUDRATE_3M  0,0
 
 
@@ -363,6 +364,28 @@ bool ft232r_get_pins(struct ft232r_device_handle *dev, uint8_t *pins)
 	return libusb_control_transfer(dev->h, FTDI_REQTYPE_IN, FTDI_REQUEST_GET_PINS, 0, FTDI_INDEX, pins, 1, FTDI_TIMEOUT) == 1;
 	return libusb_control_transfer(dev->h, FTDI_REQTYPE_IN, FTDI_REQUEST_GET_PINS, 0, FTDI_INDEX, pins, 1, FTDI_TIMEOUT) == 1;
 }
 }
 
 
+bool ft232r_get_bitmode(struct ft232r_device_handle *dev, uint8_t *out_mode)
+{
+	return libusb_control_transfer(dev->h, FTDI_REQTYPE_IN, FTDI_REQUEST_GET_BITMODE, 0, FTDI_INDEX, out_mode, 1, FTDI_TIMEOUT) == 1;
+}
+
+bool ft232r_set_cbus_bits(struct ft232r_device_handle *dev, bool sc, bool cs)
+{
+	uint8_t pin_state = (cs ? (1<<2) : 0)
+	                  | (sc ? (1<<3) : 0);
+	return ft232r_set_bitmode(dev, 0xc0 | pin_state, 0x20);
+}
+
+bool ft232r_get_cbus_bits(struct ft232r_device_handle *dev, bool *out_sio0, bool *out_sio1)
+{
+	uint8_t data;
+	if (!ft232r_get_bitmode(dev, &data))
+		return false;
+	*out_sio0 = data & 1;
+	*out_sio1 = data & 2;
+	return true;
+}
+
 #if 0
 #if 0
 int main() {
 int main() {
 	libusb_init(NULL);
 	libusb_init(NULL);

+ 2 - 0
ft232r.h

@@ -38,5 +38,7 @@ extern ssize_t ft232r_write_all(struct ft232r_device_handle *, void *data, size_
 extern ssize_t ft232r_read(struct ft232r_device_handle *, void *buf, size_t count);
 extern ssize_t ft232r_read(struct ft232r_device_handle *, void *buf, size_t count);
 extern ssize_t ft232r_read_all(struct ft232r_device_handle *, void *data, size_t count);
 extern ssize_t ft232r_read_all(struct ft232r_device_handle *, void *data, size_t count);
 extern bool ft232r_get_pins(struct ft232r_device_handle *, uint8_t *pins);
 extern bool ft232r_get_pins(struct ft232r_device_handle *, uint8_t *pins);
+extern bool ft232r_set_cbus_bits(struct ft232r_device_handle *dev, bool sc, bool cs);
+extern bool ft232r_get_cbus_bits(struct ft232r_device_handle *dev, bool *out_sio0, bool *out_sio1);
 
 
 #endif
 #endif