Browse Source

Bugfix: jtag: Handle ftdi-common environmental stuff properly

Luke Dashjr 13 years ago
parent
commit
c3a3bb09cb
4 changed files with 50 additions and 26 deletions
  1. 13 10
      driver-x6500.c
  2. 3 1
      ft232r.c
  3. 26 11
      jtag.c
  4. 8 4
      jtag.h

+ 13 - 10
driver-x6500.c

@@ -155,7 +155,11 @@ static bool x6500_prepare(struct thr_info *thr)
 	if (!ft232r_purge_buffers(ftdi, FTDI_PURGE_BOTH))
 		return false;
 	x6500->device_ft232r = ftdi;
-	x6500->cgpu_data = calloc(1, 1);
+	
+	struct jtag_port_a *jtag_a;
+	jtag_a = calloc(1, sizeof(*jtag_a));
+	jtag_a->ftdi = ftdi;
+	x6500->cgpu_data = jtag_a;
 	
 	return true;
 }
@@ -170,11 +174,12 @@ struct x6500_fpga_data {
 } while(0)
 
 static bool
-x6500_fpga_upload_bitstream(struct cgpu_info *x6500, struct ft232r_device_handle *ftdi)
+x6500_fpga_upload_bitstream(struct cgpu_info *x6500, struct jtag_port *jp1)
 {
 	char buf[0x100];
 	unsigned long len, flen;
 	char *pdone = (char*)&x6500->cgpu_data;
+	struct ft232r_device_handle *ftdi = jp1->a->ftdi;
 
 	FILE *f = open_xilinx_bitstream(x6500, X6500_BITSTREAM_FILENAME, &len);
 	if (!f)
@@ -186,15 +191,13 @@ x6500_fpga_upload_bitstream(struct cgpu_info *x6500, struct ft232r_device_handle
 	       x6500->api->name, x6500->device_id, x6500->device_path);
 	
 	// "Magic" jtag_port configured to access both FPGAs concurrently
-	uint8_t dummyx;
 	struct jtag_port jpt = {
-		.ftdi = ftdi,
+		.a = jp1->a,
 		.tck = 0x88,
 		.tms = 0x44,
 		.tdi = 0x22,
 		.tdo = 0x11,
 		.ignored = 0,
-		.state = &dummyx,
 	};
 	struct jtag_port *jp = &jpt;
 	uint8_t i;
@@ -222,7 +225,7 @@ x6500_fpga_upload_bitstream(struct cgpu_info *x6500, struct ft232r_device_handle
 		return false;
 	if (!ft232r_purge_buffers(ftdi, FTDI_PURGE_BOTH))
 		return false;
-	jp->async = true;
+	jp->a->async = true;
 
 	ssize_t buflen;
 	char nextstatus = 10;
@@ -245,7 +248,8 @@ x6500_fpga_upload_bitstream(struct cgpu_info *x6500, struct ft232r_device_handle
 		return false;
 	if (!ft232r_purge_buffers(ftdi, FTDI_PURGE_BOTH))
 		return false;
-	jp->async = false;
+	jp->a->async = false;
+	jp->a->bufread = 0;
 
 	jtag_write(jp, JTAG_REG_IR, "\x30", 6);  // JSTART
 	for (i=0; i<16; ++i)
@@ -276,13 +280,12 @@ static bool x6500_fpga_init(struct thr_info *thr)
 	
 	fpga = calloc(1, sizeof(*fpga));
 	jp = &fpga->jtag;
-	jp->ftdi = ftdi;
+	jp->a = x6500->cgpu_data;
 	jp->tck = pinoffset << 3;
 	jp->tms = pinoffset << 2;
 	jp->tdi = pinoffset << 1;
 	jp->tdo = pinoffset << 0;
 	jp->ignored = ~(fpga->jtag.tdo | fpga->jtag.tdi | fpga->jtag.tms | fpga->jtag.tck);
-	jp->state = x6500->cgpu_data;
 	
 	mutex_lock(&x6500->device_mutex);
 	if (!jtag_reset(jp)) {
@@ -314,7 +317,7 @@ static bool x6500_fpga_init(struct thr_info *thr)
 	if (memcmp(buf, X6500_BITSTREAM_USERID, 4)) {
 		applog(LOG_ERR, "%s %u.%u: FPGA not programmed",
 		       x6500->api->name, x6500->device_id, fpgaid);
-		if (!x6500_fpga_upload_bitstream(x6500, ftdi))
+		if (!x6500_fpga_upload_bitstream(x6500, jp))
 			return false;
 	} else
 		applog(LOG_DEBUG, "%s %u.%u: FPGA is already programmed :)",

+ 3 - 1
ft232r.c

@@ -341,8 +341,10 @@ ssize_t ft232r_read(struct ft232r_device_handle *dev, void *data, size_t count)
 	memcpy(data, ibufs, count);
 	dev->ibufLen -= count;
 	ibufsLen -= count;
-	if (ibufsLen)
+	if (ibufsLen) {
 		memmove(ibufs, &ibufs[count], ibufsLen);
+		applog(LOG_DEBUG, "ft232r_read: %u bytes extra", ibufsLen);
+	}
 	return count;
 }
 

+ 26 - 11
jtag.c

@@ -19,44 +19,59 @@
 #include "logging.h"
 #include "miner.h"
 
+//#define DEBUG_JTAG_CLOCK
+
 // NOTE: The order of tms and tdi here are inverted from LPC1343CodeBase
 bool jtag_clock(struct jtag_port *jp, bool tms, bool tdi, bool *tdo)
 {
 	unsigned char buf[3];
-	memset(buf, (*jp->state & jp->ignored)
+	memset(buf, (jp->a->state & jp->ignored)
 	          | (tms ? jp->tms : 0)
 	          | (tdi ? jp->tdi : 0), sizeof(buf));
 	buf[2] =
 	buf[1] |= jp->tck;
-	if (ft232r_write_all(jp->ftdi, buf, sizeof(buf)) != sizeof(buf))
+	if (ft232r_write_all(jp->a->ftdi, buf, sizeof(buf)) != sizeof(buf))
 		return false;
-	*jp->state = buf[2];
-	if (jp->async) {
+	jp->a->state = buf[2];
+	if (jp->a->async) {
 		if (unlikely(tdo))
 			applog(LOG_WARNING, "jtag_clock: request for tdo in async mode not possible");
+#ifdef DEBUG_JTAG_CLOCK
+		applog(LOG_DEBUG, "%p %02x tms=%d tdi=%d tdo=?async", jp, (unsigned)buf[2], (int)tms, (int)tdi);
+#endif
 		return true;
 	}
-	if (jp->bufread < 100 && !tdo) {
+	if (jp->a->bufread < 100 && !tdo) {
 		// By deferring unnecessary reads, we can avoid some USB latency
-		jp->bufread += sizeof(buf);
+		jp->a->bufread += sizeof(buf);
+#ifdef DEBUG_JTAG_CLOCK
+		applog(LOG_DEBUG, "%p %02x tms=%d tdi=%d tdo=?defer", jp, (unsigned)buf[2], (int)tms, (int)tdi);
+#endif
 		return true;
 	}
 #if 0 /* untested */
 	else if (!tdo) {
-		if (ft232r_purge_buffers(jp->ftdi, FTDI_PURGE_BOTH)) {
+		if (ft232r_purge_buffers(jp->a->ftdi, FTDI_PURGE_BOTH)) {
 			jp->bufread = 0;
+#ifdef DEBUG_JTAG_CLOCK
+		applog(LOG_DEBUG, "%p %02x tms=%d tdi=%d tdo=?purge", jp, (unsigned)buf[2], (int)tms, (int)tdi);
+#endif
 			return true;
 		}
 	}
 #endif
-	uint8_t rbufsz = jp->bufread + sizeof(buf);
-	jp->bufread = 0;
+	uint8_t rbufsz = jp->a->bufread + sizeof(buf);
+	jp->a->bufread = 0;
 	unsigned char rbuf[rbufsz];
-	if (ft232r_read_all(jp->ftdi, rbuf, rbufsz) != rbufsz)
+	if (ft232r_read_all(jp->a->ftdi, rbuf, rbufsz) != rbufsz)
 		return false;
 	if (tdo)
 		*tdo = (rbuf[rbufsz-1] & jp->tdo);
-	//applog(LOG_ERR, "%p tms=%d tdi=%d tdo=%d", jp, (int)tms, (int)tdi, (int)(bool)(buf[2]&jp->tdo));
+#ifdef DEBUG_JTAG_CLOCK
+	char *x = bin2hex(rbuf, rbufsz);
+	applog(LOG_DEBUG, "%p %02x tms=%d tdi=%d tdo=%d (%u:%s)", jp, (unsigned)rbuf[rbufsz-1], (int)tms, (int)tdi, (int)(bool)(rbuf[rbufsz-1] & jp->tdo), (unsigned)rbufsz, x);
+	free(x);
+#endif
 	return true;
 }
 

+ 8 - 4
jtag.h

@@ -5,16 +5,20 @@
 #include <stdint.h>
 #include <unistd.h>
 
-struct jtag_port {
+struct jtag_port_a {
 	struct ft232r_device_handle *ftdi;
+	uint8_t state;
+	bool async;
+	uint8_t bufread;
+};
+
+struct jtag_port {
+	struct jtag_port_a *a;
 	uint8_t tck;
 	uint8_t tms;
 	uint8_t tdi;
 	uint8_t tdo;
 	uint8_t ignored;
-	uint8_t *state;
-	bool async;
-	uint8_t bufread;
 };
 
 enum jtagreg {