From 567d854edf4be00096445508e44da0481907db4a Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Sun, 26 Feb 2023 10:10:46 +0100 Subject: [PATCH] efinix: fix JTAG: detect family, fix irlen for titanium, add support for bit file, hex file can't be used with titanium --- src/efinix.cpp | 41 +++++++++++++++++++++++++++++++++-------- src/efinix.hpp | 8 ++++++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/efinix.cpp b/src/efinix.cpp index 6caa3f7..4627b30 100644 --- a/src/efinix.cpp +++ b/src/efinix.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include "display.hpp" @@ -17,6 +18,7 @@ #include "device.hpp" #include "ftdiJtagMPSSE.hpp" #include "jtag.hpp" +#include "part.hpp" #include "progressBar.hpp" #include "rawParser.hpp" #include "spiFlash.hpp" @@ -27,7 +29,8 @@ Efinix::Efinix(FtdiSpi* spi, const std::string &filename, uint16_t oe_pin, bool verify, int8_t verbose): Device(NULL, filename, file_type, verify, verbose), _ftdi_jtag(NULL), - _rst_pin(rst_pin), _done_pin(done_pin), _cs_pin(0), _oe_pin(oe_pin) + _rst_pin(rst_pin), _done_pin(done_pin), _cs_pin(0), _oe_pin(oe_pin), + _fpga_family(UNKNOWN_FAMILY), _irlen(0) { _spi = spi; _spi->gpio_set_input(_done_pin); @@ -40,10 +43,28 @@ Efinix::Efinix(Jtag* jtag, const std::string &filename, bool verify, int8_t verbose): Device(jtag, filename, file_type, verify, verbose), _spi(NULL), _rst_pin(0), _done_pin(0), _cs_pin(0), - _oe_pin(0) + _oe_pin(0), _fpga_family(UNKNOWN_FAMILY), _irlen(0) { _ftdi_jtag = reinterpret_cast(jtag->get_ll_class()); + /* detect FPGA type (Trion or Titanium) */ + + uint32_t idcode = _jtag->get_target_device_id(); + std::string family = fpga_list[idcode].family; + if (family == "Titanium") { + if (_file_extension == "hex") { + throw std::runtime_error("Error: loading hex file is not allowed " + "for Titanium devices"); + } + _fpga_family = TITANIUM_FAMILY; + } else if (family == "Trion") { + _fpga_family = TRION_FAMILY; + } else { + throw std::runtime_error("Error: unknown family " + family); + } + /* get irlen value from model */ + _irlen = fpga_list[idcode].irlength; + /* WA: before using JTAG, device must restart with cs low * but cs and rst for xyloni are connected to interfaceA (ie SPI) * TODO: some boards have cs, reset and done in both interface @@ -112,7 +133,7 @@ void Efinix::program(unsigned int offset, bool unprotect_flash) ConfigBitstreamParser *bit; try { - if (_file_extension == "hex") { + if (_file_extension == "hex" || _file_extension == "bit") { bit = new EfinixHexParser(_filename); } else { if (offset == 0 && _spi) { @@ -222,13 +243,15 @@ void Efinix::programSPI(unsigned int offset, uint8_t *data, int length, #define IDCODE 0x03 #define PROGRAM 0x04 #define ENTERUSER 0x07 -#define IRLENGTH 4 void Efinix::programJTAG(uint8_t *data, int length) { int xfer_len = 512, tx_end; uint8_t tx[512]; + if (_fpga_family == TITANIUM_FAMILY) + _jtag->set_state(Jtag::RUN_TEST_IDLE); + if(_spi) { /* trion has to be reseted with cs low */ _spi->gpio_clear(_oe_pin | _cs_pin | _rst_pin); @@ -239,6 +262,8 @@ void Efinix::programJTAG(uint8_t *data, int length) usleep(50000); } + if (_fpga_family == TITANIUM_FAMILY) + _jtag->set_state(Jtag::TEST_LOGIC_RESET); /* force run_test_idle state */ _jtag->set_state(Jtag::RUN_TEST_IDLE); usleep(100000); @@ -246,8 +271,8 @@ void Efinix::programJTAG(uint8_t *data, int length) /* send PROGRAM state and stay in SHIFT_DR until * full configuration data has been sent */ - _jtag->shiftIR(PROGRAM, IRLENGTH, Jtag::EXIT1_IR); - _jtag->shiftIR(PROGRAM, IRLENGTH, Jtag::EXIT1_IR); // T20 fix + _jtag->shiftIR(PROGRAM, _irlen, Jtag::EXIT1_IR); + _jtag->shiftIR(PROGRAM, _irlen, Jtag::EXIT1_IR); // T20 fix ProgressBar progress("Load SRAM", length, 50, _quiet); @@ -269,9 +294,9 @@ void Efinix::programJTAG(uint8_t *data, int length) usleep(10000); - _jtag->shiftIR(ENTERUSER, IRLENGTH, Jtag::EXIT1_IR); + _jtag->shiftIR(ENTERUSER, _irlen, Jtag::EXIT1_IR); memset(tx, 0, 512); _jtag->shiftDR(tx, NULL, 100); - _jtag->shiftIR(IDCODE, IRLENGTH); + _jtag->shiftIR(IDCODE, _irlen); } diff --git a/src/efinix.hpp b/src/efinix.hpp index eae590e..7f71aae 100644 --- a/src/efinix.hpp +++ b/src/efinix.hpp @@ -39,6 +39,12 @@ class Efinix: public Device { void reset() override; private: + /* list of efinix family devices */ + enum efinix_family_t { + TITANIUM_FAMILY = 0, + TRION_FAMILY, + UNKNOWN_FAMILY = 999 + }; void programSPI(unsigned int offset, uint8_t *data, int length, bool unprotect_flash); void programJTAG(uint8_t *data, int length); @@ -48,6 +54,8 @@ class Efinix: public Device { uint16_t _done_pin; uint16_t _cs_pin; uint16_t _oe_pin; + efinix_family_t _fpga_family; + int _irlen; }; #endif // SRC_EFINIX_HPP_