Merge pull request #51 from martin2250/master
add ftdi serial number argument
This commit is contained in:
commit
1a952f466a
46
README.md
46
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 <gwenhael.goavec-merou@trabucayre.com>.
|
||||
```
|
||||
To have complete help
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
20
src/jtag.cpp
20
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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
16
src/main.cpp
16
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<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)",
|
||||
|
|
|
|||
Loading…
Reference in New Issue