Merge pull request #51 from martin2250/master

add ftdi serial number argument
This commit is contained in:
Gwenhael Goavec-Merou 2020-10-05 15:29:30 +02:00 committed by GitHub
commit 1a952f466a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 60 additions and 96 deletions

View File

@ -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 <gwenhael.goavec-merou@trabucayre.com>.
```
To have complete help

View File

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

View File

@ -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;

View File

@ -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);
}

View File

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

View File

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

View File

@ -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();

View File

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

View File

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

View File

@ -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;

View File

@ -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<string>(args->board))
("c,cable", "jtag interface", cxxopts::value<string>(args->cable))
("ftdi-serial", "FTDI chip serial number", cxxopts::value<string>(args->ftdi_serial))
("ftdi-channel", "FTDI chip channel number (channels 0-3 map to A-D)", cxxopts::value<int>(args->ftdi_channel))
#ifdef USE_UDEV
("d,device", "device to use (/dev/ttyUSBx)",