diff --git a/README.md b/README.md index 949fefc..62e4b26 100644 --- a/README.md +++ b/README.md @@ -108,28 +108,34 @@ After that you need to unplug and replug your device. ```bash openFPGALoader --help Usage: openFPGALoader [OPTION...] BIT_FILE -openFPGALoader -- a program to flash cyclone10 LP FPGA +openFPGALoader -- a program to flash FPGA - -b, --board=BOARD board name, may be used instead of cable - -c, --cable=CABLE jtag interface - -d, --device=DEVICE device to use (/dev/ttyUSBx) - --ftdi-channel=CHANNEL FTDI chip channel number (channels 0-3 map to A-D) - --detect detect FPGA - --freq=FREQ jtag frequency (Hz) - -f, --write-flash write bitstream in flash (default: false, only for - Gowin and ECP5 devices) - --list-boards list all supported boards - --list-cables list all supported cables - --list-fpga list all supported FPGA - -m, --write-sram write bitstream in SRAM (default: true, only for - Gowin and ECP5 devices) - -o, --offset=OFFSET start offset in EEPROM - --pins arg pin config (only for bitbang) TDI:TDO:TCK:TMS - -r, --reset reset FPGA after operations - -v, --verbose Produce verbose output - -h, --help Give this help list - -V, --version Print program version + --bitstream arg bitstream + -b, --board arg board name, may be used instead of cable + -c, --cable arg jtag interface + --ftdi-serial arg FTDI chip serial number + --ftdi-channel arg FTDI chip channel number (channels 0-3 map to A-D) + -d, --device arg device to use (/dev/ttyUSBx) + --detect detect FPGA + --freq arg jtag frequency (Hz) + -f, --write-flash write bitstream in flash (default: false, only for + Gowin and ECP5 devices) + --list-boards list all supported boards + --list-cables list all supported cables + --list-fpga list all supported FPGA + -m, --write-sram write bitstream in SRAM (default: true, only for + Gowin and ECP5 devices) + -o, --offset arg start offset in EEPROM + --pins arg pin config (only for ft232R) TDI:TDO:TCK:TMS + -r, --reset reset FPGA after operations + -v, --verbose Produce verbose output + -h, --help Give this help list + -V, --Version Print program version +Mandatory or optional arguments to long options are also mandatory or optional +for any corresponding short options. + +Report bugs to . ``` To have complete help diff --git a/src/ftdiJtagBitbang.cpp b/src/ftdiJtagBitbang.cpp index 19ec9ab..d36728d 100644 --- a/src/ftdiJtagBitbang.cpp +++ b/src/ftdiJtagBitbang.cpp @@ -41,21 +41,14 @@ using namespace std; #endif FtdiJtagBitBang::FtdiJtagBitBang(const FTDIpp_MPSSE::mpsse_bit_config &cable, - const jtag_pins_conf_t *pin_conf, string dev, uint32_t clkHZ, bool verbose): - FTDIpp_MPSSE(cable, dev, clkHZ, verbose), _bitmode(0), _nb_bit(0), + const jtag_pins_conf_t *pin_conf, string dev, const std::string &serial, + uint32_t clkHZ, bool verbose): + FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _bitmode(0), _nb_bit(0), _curr_tms(0) { init_internal(cable, pin_conf); } -FtdiJtagBitBang::FtdiJtagBitBang(const FTDIpp_MPSSE::mpsse_bit_config &cable, - const jtag_pins_conf_t *pin_conf, uint32_t clkHZ, bool verbose): - FTDIpp_MPSSE(cable, clkHZ, verbose), - _bitmode(0), _nb_bit(0) -{ - init_internal(cable, pin_conf); -} - FtdiJtagBitBang::~FtdiJtagBitBang() { free(_in_buf); diff --git a/src/ftdiJtagBitbang.hpp b/src/ftdiJtagBitbang.hpp index 8167f41..12d1090 100644 --- a/src/ftdiJtagBitbang.hpp +++ b/src/ftdiJtagBitbang.hpp @@ -36,10 +36,8 @@ class FtdiJtagBitBang : public JtagInterface, private FTDIpp_MPSSE { public: FtdiJtagBitBang(const FTDIpp_MPSSE::mpsse_bit_config &cable, - const jtag_pins_conf_t *pin_conf, std::string dev, + const jtag_pins_conf_t *pin_conf, std::string dev, const std::string &serial, uint32_t clkHZ, bool verbose = false); - FtdiJtagBitBang(const FTDIpp_MPSSE::mpsse_bit_config &cable, - const jtag_pins_conf_t *pin_conf, uint32_t clkHZ, bool verbose); virtual ~FtdiJtagBitBang(); int setClkFreq(uint32_t clkHZ) override; diff --git a/src/ftdiJtagMPSSE.cpp b/src/ftdiJtagMPSSE.cpp index e980444..f64dd5a 100644 --- a/src/ftdiJtagMPSSE.cpp +++ b/src/ftdiJtagMPSSE.cpp @@ -41,15 +41,8 @@ using namespace std; #endif FtdiJtagMPSSE::FtdiJtagMPSSE(const FTDIpp_MPSSE::mpsse_bit_config &cable, - string dev, uint32_t clkHZ, bool verbose): - FTDIpp_MPSSE(cable, dev, clkHZ, verbose), _ch552WA(false) -{ - init_internal(cable); -} - -FtdiJtagMPSSE::FtdiJtagMPSSE(const FTDIpp_MPSSE::mpsse_bit_config &cable, - uint32_t clkHZ, bool verbose): - FTDIpp_MPSSE(cable, clkHZ, verbose), _ch552WA(false) + string dev, const string &serial, uint32_t clkHZ, bool verbose): + FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _ch552WA(false) { init_internal(cable); } diff --git a/src/ftdiJtagMPSSE.hpp b/src/ftdiJtagMPSSE.hpp index 80d64a7..d6285b3 100644 --- a/src/ftdiJtagMPSSE.hpp +++ b/src/ftdiJtagMPSSE.hpp @@ -35,9 +35,7 @@ class FtdiJtagMPSSE : public JtagInterface, private FTDIpp_MPSSE { public: FtdiJtagMPSSE(const FTDIpp_MPSSE::mpsse_bit_config &cable, std::string dev, - uint32_t clkHZ, bool verbose = false); - FtdiJtagMPSSE(const FTDIpp_MPSSE::mpsse_bit_config &cable, - uint32_t clkHZ, bool verbose); + const std::string &serial, uint32_t clkHZ, bool verbose = false); virtual ~FtdiJtagMPSSE(); int setClkFreq(uint32_t clkHZ) override { diff --git a/src/ftdipp_mpsse.cpp b/src/ftdipp_mpsse.cpp index adc7126..b9a54d6 100644 --- a/src/ftdipp_mpsse.cpp +++ b/src/ftdipp_mpsse.cpp @@ -20,7 +20,8 @@ using namespace std; do { if (_verbose) fprintf(stdout, __VA_ARGS__);}while(0) FTDIpp_MPSSE::FTDIpp_MPSSE(const mpsse_bit_config &cable, const string &dev, - uint32_t clkHZ, bool verbose):_verbose(verbose), _vid(0), + const std::string &serial, uint32_t clkHZ, bool verbose): + _verbose(verbose), _vid(0), _pid(0), _bus(-1), _addr(-1), _interface(cable.interface), _clkHZ(clkHZ), _buffer_size(2*32768), _num(0) @@ -36,24 +37,7 @@ FTDIpp_MPSSE::FTDIpp_MPSSE(const mpsse_bit_config &cable, const string &dev, _pid = cable.pid; } - open_device(115200); - _buffer_size = _ftdi->max_packet_size; - - _buffer = (unsigned char *)malloc(sizeof(unsigned char) * _buffer_size); - if (!_buffer) { - cout << "_buffer malloc failed" << endl; - throw std::exception(); - } -} - -FTDIpp_MPSSE::FTDIpp_MPSSE(const mpsse_bit_config &cable, - uint32_t clkHZ, bool verbose):_verbose(verbose), - _vid(cable.vid), _pid(cable.pid), _bus(-1), - _addr(-1), _interface(cable.interface), - _clkHZ(clkHZ), _buffer_size(2*32768), _num(0) -{ - sprintf(_product, ""); - open_device(115200); + open_device(serial, 115200); _buffer_size = _ftdi->max_packet_size; _buffer = (unsigned char *)malloc(sizeof(unsigned char) * _buffer_size); @@ -72,7 +56,7 @@ FTDIpp_MPSSE::~FTDIpp_MPSSE() free(_buffer); } -void FTDIpp_MPSSE::open_device(unsigned int baudrate) +void FTDIpp_MPSSE::open_device(const std::string &serial, unsigned int baudrate) { int ret; @@ -86,7 +70,7 @@ void FTDIpp_MPSSE::open_device(unsigned int baudrate) ftdi_set_interface(_ftdi, (ftdi_interface)_interface); if (_bus == -1 || _addr == -1) - ret = ftdi_usb_open_desc(_ftdi, _vid, _pid, NULL, NULL); + ret = ftdi_usb_open_desc(_ftdi, _vid, _pid, NULL, serial.empty() ? NULL : serial.c_str()); else #if (OLD_FTDI_VERSION == 1) ret = ftdi_usb_open_desc(_ftdi, _vid, _pid, _product, NULL); diff --git a/src/ftdipp_mpsse.hpp b/src/ftdipp_mpsse.hpp index d582e38..b4a5d5d 100644 --- a/src/ftdipp_mpsse.hpp +++ b/src/ftdipp_mpsse.hpp @@ -16,9 +16,7 @@ class FTDIpp_MPSSE { } mpsse_bit_config; FTDIpp_MPSSE(const mpsse_bit_config &cable, const std::string &dev, - uint32_t clkHZ, bool verbose = false); - FTDIpp_MPSSE(const mpsse_bit_config &cablen, - uint32_t clkHZ, bool verbose = false); + const std::string &serial, uint32_t clkHZ, bool verbose = false); ~FTDIpp_MPSSE(); int init(unsigned char latency, unsigned char bitmask_mode, unsigned char mode, @@ -30,7 +28,7 @@ class FTDIpp_MPSSE { int pid() {return _pid;} protected: - void open_device(unsigned int baudrate); + void open_device(const std::string &serial, unsigned int baudrate); void ftdi_usb_close_internal(); int close_device(); int mpsse_write(); diff --git a/src/ftdispi.cpp b/src/ftdispi.cpp index 80dbc4c..ac4ce2c 100644 --- a/src/ftdispi.cpp +++ b/src/ftdispi.cpp @@ -66,7 +66,7 @@ static FTDIpp_MPSSE::mpsse_bit_config bit_conf = FtdiSpi::FtdiSpi(int vid, int pid, unsigned char interface, uint32_t clkHZ, bool verbose): - FTDIpp_MPSSE(bit_conf, clkHZ, verbose) + FTDIpp_MPSSE(bit_conf, "", "", clkHZ, verbose) { setCSmode(SPI_CS_AUTO); setEndianness(SPI_MSB_FIRST); @@ -76,7 +76,7 @@ FtdiSpi::FtdiSpi(int vid, int pid, unsigned char interface, uint32_t clkHZ, FtdiSpi::FtdiSpi(const FTDIpp_MPSSE::mpsse_bit_config &conf, uint32_t clkHZ, bool verbose): - FTDIpp_MPSSE(conf, clkHZ, verbose) + FTDIpp_MPSSE(conf, "", "", clkHZ, verbose) { setCSmode(SPI_CS_AUTO); setEndianness(SPI_MSB_FIRST); diff --git a/src/jtag.cpp b/src/jtag.cpp index 0cf4cff..f12132e 100644 --- a/src/jtag.cpp +++ b/src/jtag.cpp @@ -67,23 +67,13 @@ using namespace std; */ Jtag::Jtag(cable_t &cable, const jtag_pins_conf_t *pin_conf, string dev, - uint32_t clkHZ, bool verbose): + const string &serial, uint32_t clkHZ, bool verbose): _verbose(verbose), _state(RUN_TEST_IDLE), _tms_buffer_size(128), _num_tms(0), _board_name("nope") { - init_internal(cable, dev, pin_conf, clkHZ); -} - -Jtag::Jtag(cable_t &cable, const jtag_pins_conf_t *pin_conf, - uint32_t clkHZ, bool verbose): - _verbose(verbose), - _state(RUN_TEST_IDLE), - _tms_buffer_size(128), _num_tms(0), - _board_name("nope") -{ - init_internal(cable, "", pin_conf, clkHZ); + init_internal(cable, dev, serial, pin_conf, clkHZ); } Jtag::~Jtag() @@ -92,7 +82,7 @@ Jtag::~Jtag() delete _jtag; } -void Jtag::init_internal(cable_t &cable, const string &dev, +void Jtag::init_internal(cable_t &cable, const string &dev, const string &serial, const jtag_pins_conf_t *pin_conf, uint32_t clkHZ) { switch (cable.type) { @@ -102,10 +92,10 @@ void Jtag::init_internal(cable_t &cable, const string &dev, case MODE_FTDI_BITBANG: if (pin_conf == NULL) throw std::exception(); - _jtag = new FtdiJtagBitBang(cable.config, pin_conf, dev, clkHZ, _verbose); + _jtag = new FtdiJtagBitBang(cable.config, pin_conf, dev, serial, clkHZ, _verbose); break; case MODE_FTDI_SERIAL: - _jtag = new FtdiJtagMPSSE(cable.config, dev, clkHZ, _verbose); + _jtag = new FtdiJtagMPSSE(cable.config, dev, serial, clkHZ, _verbose); break; case MODE_DIRTYJTAG: _jtag = new DirtyJtag(clkHZ, _verbose); diff --git a/src/jtag.hpp b/src/jtag.hpp index ec3ffc0..9f6cb7e 100644 --- a/src/jtag.hpp +++ b/src/jtag.hpp @@ -30,9 +30,7 @@ class Jtag { public: Jtag(cable_t &cable, const jtag_pins_conf_t *pin_conf, std::string dev, - uint32_t clkHZ, bool verbose = false); - Jtag(cable_t &cable, const jtag_pins_conf_t *pin_conf, - uint32_t clkHZ, bool verbose); + const std::string &serial, uint32_t clkHZ, bool verbose = false); ~Jtag(); /* maybe to update */ @@ -82,7 +80,7 @@ class Jtag { void setVerbose(bool verbose){_verbose = verbose;} private: - void init_internal(cable_t &cable, const std::string &dev, + void init_internal(cable_t &cable, const std::string &dev, const std::string &serial, const jtag_pins_conf_t *pin_conf, uint32_t clkHZ); bool _verbose; int _state; diff --git a/src/main.cpp b/src/main.cpp index 9d41234..63b80ca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,6 +44,7 @@ struct arguments { string bit_file; string device; string cable; + string ftdi_serial; int ftdi_channel; uint32_t freq; string board; @@ -66,7 +67,7 @@ int main(int argc, char **argv) jtag_pins_conf_t pins_config = {0, 0, 0, 0}; /* command line args. */ - struct arguments args = {false, false, false, 0, "", "-", "-", -1, 6000000, "-", + struct arguments args = {false, false, false, 0, "", "", "-", "", -1, 6000000, "-", false, false, false, false, false, true, false}; /* parse arguments */ try { @@ -125,13 +126,17 @@ int main(int argc, char **argv) cable.config.interface = mapping[args.ftdi_channel]; } + if (args.ftdi_serial != "-") { + if (cable.type != MODE_FTDI_SERIAL && cable.type != MODE_FTDI_BITBANG){ + printError("Error: FTDI serial param is for FTDI cables."); + return EXIT_FAILURE; + } + } + /* jtag base */ Jtag *jtag; try { - if (args.device == "-") - jtag = new Jtag(cable, &pins_config, args.freq, false); - else - jtag = new Jtag(cable, &pins_config, args.device, args.freq, false); + jtag = new Jtag(cable, &pins_config, args.device, args.ftdi_serial, args.freq, false); } catch (std::exception &e) { printError("Error: Failed to claim cable"); return EXIT_FAILURE; @@ -261,6 +266,7 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p ("b,board", "board name, may be used instead of cable", cxxopts::value(args->board)) ("c,cable", "jtag interface", cxxopts::value(args->cable)) + ("ftdi-serial", "FTDI chip serial number", cxxopts::value(args->ftdi_serial)) ("ftdi-channel", "FTDI chip channel number (channels 0-3 map to A-D)", cxxopts::value(args->ftdi_channel)) #ifdef USE_UDEV ("d,device", "device to use (/dev/ttyUSBx)",