diff --git a/libztex.c b/libztex.c index 3440d22d..a73130fa 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) {