|
|
@@ -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) {
|