Commit 719b0c7ceee7036dc34bd9ffb73b6d39236271d6

nelisky 2012-04-30T09:29:36

HS bitstream configuration

diff --git a/libztex.c b/libztex.c
index 3440d22..a73130f 100644
--- a/libztex.c
+++ b/libztex.c
@@ -125,6 +125,107 @@ static int libztex_getFpgaState(struct libztex_device *ztex, struct libztex_fpga
 	return 0;
 }
 
+static int libztex_configureFpgaHS(struct libztex_device *ztex, const char* firmware, bool force, char bs)
+{
+	struct libztex_fpgastate state;
+	const int transactionBytes = 65536;
+	unsigned char buf[transactionBytes], settings[2];
+	int tries, cnt, buf_p, i;
+	ssize_t pos = 0;
+	FILE *fp;
+
+	if (!libztex_checkCapability(ztex, CAPABILITY_HS_FPGA))
+		return -1;
+	libztex_getFpgaState(ztex, &state);
+	if (!force && state.fpgaConfigured) {
+		applog(LOG_INFO, "Bitstream already configured");
+		return 1;
+	}
+	cnt = libusb_control_transfer(ztex->hndl, 0xc0, 0x33, 0, 0, settings, 2, 1000);
+	if (unlikely(cnt < 0)) {
+		applog(LOG_ERR, "%s: Failed getHSFpgaSettings with err %d", ztex->repr, cnt);
+		return cnt;
+	}
+
+	libusb_claim_interface(ztex->hndl, settings[1]);
+
+	for (tries = 3; tries > 0; tries--) {
+		fp = fopen(firmware, "rb");
+		if (!fp) {
+			applog(LOG_ERR, "%s: failed to read firmware '%s'", ztex->repr, firmware);
+			return -2;
+		}
+
+		while (pos < transactionBytes && !feof(fp)) {
+			buf[pos++] = getc(fp);
+		}
+
+		if (feof(fp))
+			pos--;
+
+		if (bs != 0 && bs != 1)
+			bs = libztex_detectBitstreamBitOrder(buf, transactionBytes < pos? transactionBytes: pos);
+
+
+		if (bs == 1)
+			libztex_swapBits(buf, pos);
+	 
+		libusb_control_transfer(ztex->hndl, 0x40, 0x34, 0, 0, NULL, 0, 1000);
+		// 0x34 - initHSFPGAConfiguration
+
+		buf_p = pos;
+		while (1) {
+			i = 0;
+			while (i < buf_p) {
+				if (libusb_bulk_transfer(ztex->hndl,
+				                                  settings[0],
+				                                  &buf[i],
+				                                  buf_p - i,
+				                                  &cnt, 1000) != 0) {
+					applog(LOG_ERR, "%s: Failed send hs fpga data", ztex->repr);
+					break;
+				}
+				usleep(500);
+				i += cnt;
+			}
+			if (i < buf_p || buf_p < transactionBytes)
+				break;
+			buf_p = 0;
+			while (buf_p < transactionBytes && !feof(fp)) {
+				buf[buf_p++] = getc(fp);
+			}
+			if (feof(fp))
+				buf_p--;
+			pos += buf_p;
+			if (buf_p == 0)
+				break;
+			if (bs == 1)
+				libztex_swapBits(buf, buf_p);
+		}
+
+		libusb_control_transfer(ztex->hndl, 0x40, 0x35, 0, 0, NULL, 0, 1000);
+		// 0x35 - finishHSFPGAConfiguration
+		if (cnt >= 0)
+			tries = 0;
+
+		fclose(fp);
+
+		libztex_getFpgaState(ztex, &state);
+		if (!state.fpgaConfigured) {
+			applog(LOG_ERR, "%s: HS FPGA configuration failed: DONE pin does not go high", ztex->repr);
+			return -3;
+		}
+
+	}
+
+	libusb_release_interface(ztex->hndl, settings[1]);
+
+	usleep(200000);
+	applog(LOG_INFO, "%s: HS FPGA configuration done", ztex->repr);
+	return 0;
+
+}
+
 static int libztex_configureFpgaLS(struct libztex_device *ztex, const char* firmware, bool force, char bs)
 {
 	struct libztex_fpgastate state;
@@ -216,12 +317,15 @@ static int libztex_configureFpgaLS(struct libztex_device *ztex, const char* firm
 int libztex_configureFpga(struct libztex_device *ztex)
 {
 	char buf[256] = "bitstreams/";
+	int rv;
 
 	memset(&buf[11], 0, 245);
 	strcpy(&buf[11], ztex->bitFileName);
 	strcpy(&buf[strlen(buf)], ".bit");
-
-	return libztex_configureFpgaLS(ztex, buf, true, 2);
+	rv = libztex_configureFpgaHS(ztex, buf, true, 2); 
+	if (rv != 0)
+		rv = libztex_configureFpgaLS(ztex, buf, true, 2); 
+	return rv;
 }
 
 int libztex_numberOfFpgas(struct libztex_device *ztex) {