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
|
```bash
|
||||||
openFPGALoader --help
|
openFPGALoader --help
|
||||||
Usage: openFPGALoader [OPTION...] BIT_FILE
|
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
|
--bitstream arg bitstream
|
||||||
-c, --cable=CABLE jtag interface
|
-b, --board arg board name, may be used instead of cable
|
||||||
-d, --device=DEVICE device to use (/dev/ttyUSBx)
|
-c, --cable arg jtag interface
|
||||||
--ftdi-channel=CHANNEL FTDI chip channel number (channels 0-3 map to A-D)
|
--ftdi-serial arg FTDI chip serial number
|
||||||
--detect detect FPGA
|
--ftdi-channel arg FTDI chip channel number (channels 0-3 map to A-D)
|
||||||
--freq=FREQ jtag frequency (Hz)
|
-d, --device arg device to use (/dev/ttyUSBx)
|
||||||
-f, --write-flash write bitstream in flash (default: false, only for
|
--detect detect FPGA
|
||||||
Gowin and ECP5 devices)
|
--freq arg jtag frequency (Hz)
|
||||||
--list-boards list all supported boards
|
-f, --write-flash write bitstream in flash (default: false, only for
|
||||||
--list-cables list all supported cables
|
Gowin and ECP5 devices)
|
||||||
--list-fpga list all supported FPGA
|
--list-boards list all supported boards
|
||||||
-m, --write-sram write bitstream in SRAM (default: true, only for
|
--list-cables list all supported cables
|
||||||
Gowin and ECP5 devices)
|
--list-fpga list all supported FPGA
|
||||||
-o, --offset=OFFSET start offset in EEPROM
|
-m, --write-sram write bitstream in SRAM (default: true, only for
|
||||||
--pins arg pin config (only for bitbang) TDI:TDO:TCK:TMS
|
Gowin and ECP5 devices)
|
||||||
-r, --reset reset FPGA after operations
|
-o, --offset arg start offset in EEPROM
|
||||||
-v, --verbose Produce verbose output
|
--pins arg pin config (only for ft232R) TDI:TDO:TCK:TMS
|
||||||
-h, --help Give this help list
|
-r, --reset reset FPGA after operations
|
||||||
-V, --version Print program version
|
-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
|
To have complete help
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,21 +41,14 @@ using namespace std;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FtdiJtagBitBang::FtdiJtagBitBang(const FTDIpp_MPSSE::mpsse_bit_config &cable,
|
FtdiJtagBitBang::FtdiJtagBitBang(const FTDIpp_MPSSE::mpsse_bit_config &cable,
|
||||||
const jtag_pins_conf_t *pin_conf, string dev, uint32_t clkHZ, bool verbose):
|
const jtag_pins_conf_t *pin_conf, string dev, const std::string &serial,
|
||||||
FTDIpp_MPSSE(cable, dev, clkHZ, verbose), _bitmode(0), _nb_bit(0),
|
uint32_t clkHZ, bool verbose):
|
||||||
|
FTDIpp_MPSSE(cable, dev, serial, clkHZ, verbose), _bitmode(0), _nb_bit(0),
|
||||||
_curr_tms(0)
|
_curr_tms(0)
|
||||||
{
|
{
|
||||||
init_internal(cable, pin_conf);
|
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()
|
FtdiJtagBitBang::~FtdiJtagBitBang()
|
||||||
{
|
{
|
||||||
free(_in_buf);
|
free(_in_buf);
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,8 @@
|
||||||
class FtdiJtagBitBang : public JtagInterface, private FTDIpp_MPSSE {
|
class FtdiJtagBitBang : public JtagInterface, private FTDIpp_MPSSE {
|
||||||
public:
|
public:
|
||||||
FtdiJtagBitBang(const FTDIpp_MPSSE::mpsse_bit_config &cable,
|
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);
|
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();
|
virtual ~FtdiJtagBitBang();
|
||||||
|
|
||||||
int setClkFreq(uint32_t clkHZ) override;
|
int setClkFreq(uint32_t clkHZ) override;
|
||||||
|
|
|
||||||
|
|
@ -41,15 +41,8 @@ using namespace std;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FtdiJtagMPSSE::FtdiJtagMPSSE(const FTDIpp_MPSSE::mpsse_bit_config &cable,
|
FtdiJtagMPSSE::FtdiJtagMPSSE(const FTDIpp_MPSSE::mpsse_bit_config &cable,
|
||||||
string dev, uint32_t clkHZ, bool verbose):
|
string dev, const string &serial, uint32_t clkHZ, bool verbose):
|
||||||
FTDIpp_MPSSE(cable, dev, clkHZ, verbose), _ch552WA(false)
|
FTDIpp_MPSSE(cable, dev, serial, 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)
|
|
||||||
{
|
{
|
||||||
init_internal(cable);
|
init_internal(cable);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,7 @@
|
||||||
class FtdiJtagMPSSE : public JtagInterface, private FTDIpp_MPSSE {
|
class FtdiJtagMPSSE : public JtagInterface, private FTDIpp_MPSSE {
|
||||||
public:
|
public:
|
||||||
FtdiJtagMPSSE(const FTDIpp_MPSSE::mpsse_bit_config &cable, std::string dev,
|
FtdiJtagMPSSE(const FTDIpp_MPSSE::mpsse_bit_config &cable, std::string dev,
|
||||||
uint32_t clkHZ, bool verbose = false);
|
const std::string &serial, uint32_t clkHZ, bool verbose = false);
|
||||||
FtdiJtagMPSSE(const FTDIpp_MPSSE::mpsse_bit_config &cable,
|
|
||||||
uint32_t clkHZ, bool verbose);
|
|
||||||
virtual ~FtdiJtagMPSSE();
|
virtual ~FtdiJtagMPSSE();
|
||||||
|
|
||||||
int setClkFreq(uint32_t clkHZ) override {
|
int setClkFreq(uint32_t clkHZ) override {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ using namespace std;
|
||||||
do { if (_verbose) fprintf(stdout, __VA_ARGS__);}while(0)
|
do { if (_verbose) fprintf(stdout, __VA_ARGS__);}while(0)
|
||||||
|
|
||||||
FTDIpp_MPSSE::FTDIpp_MPSSE(const mpsse_bit_config &cable, const string &dev,
|
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),
|
_pid(0), _bus(-1), _addr(-1),
|
||||||
_interface(cable.interface),
|
_interface(cable.interface),
|
||||||
_clkHZ(clkHZ), _buffer_size(2*32768), _num(0)
|
_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;
|
_pid = cable.pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
open_device(115200);
|
open_device(serial, 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);
|
|
||||||
_buffer_size = _ftdi->max_packet_size;
|
_buffer_size = _ftdi->max_packet_size;
|
||||||
|
|
||||||
_buffer = (unsigned char *)malloc(sizeof(unsigned char) * _buffer_size);
|
_buffer = (unsigned char *)malloc(sizeof(unsigned char) * _buffer_size);
|
||||||
|
|
@ -72,7 +56,7 @@ FTDIpp_MPSSE::~FTDIpp_MPSSE()
|
||||||
free(_buffer);
|
free(_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FTDIpp_MPSSE::open_device(unsigned int baudrate)
|
void FTDIpp_MPSSE::open_device(const std::string &serial, unsigned int baudrate)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
@ -86,7 +70,7 @@ void FTDIpp_MPSSE::open_device(unsigned int baudrate)
|
||||||
|
|
||||||
ftdi_set_interface(_ftdi, (ftdi_interface)_interface);
|
ftdi_set_interface(_ftdi, (ftdi_interface)_interface);
|
||||||
if (_bus == -1 || _addr == -1)
|
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
|
else
|
||||||
#if (OLD_FTDI_VERSION == 1)
|
#if (OLD_FTDI_VERSION == 1)
|
||||||
ret = ftdi_usb_open_desc(_ftdi, _vid, _pid, _product, NULL);
|
ret = ftdi_usb_open_desc(_ftdi, _vid, _pid, _product, NULL);
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,7 @@ class FTDIpp_MPSSE {
|
||||||
} mpsse_bit_config;
|
} mpsse_bit_config;
|
||||||
|
|
||||||
FTDIpp_MPSSE(const mpsse_bit_config &cable, const std::string &dev,
|
FTDIpp_MPSSE(const mpsse_bit_config &cable, const std::string &dev,
|
||||||
uint32_t clkHZ, bool verbose = false);
|
const std::string &serial, uint32_t clkHZ, bool verbose = false);
|
||||||
FTDIpp_MPSSE(const mpsse_bit_config &cablen,
|
|
||||||
uint32_t clkHZ, bool verbose = false);
|
|
||||||
~FTDIpp_MPSSE();
|
~FTDIpp_MPSSE();
|
||||||
|
|
||||||
int init(unsigned char latency, unsigned char bitmask_mode, unsigned char mode,
|
int init(unsigned char latency, unsigned char bitmask_mode, unsigned char mode,
|
||||||
|
|
@ -30,7 +28,7 @@ class FTDIpp_MPSSE {
|
||||||
int pid() {return _pid;}
|
int pid() {return _pid;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void open_device(unsigned int baudrate);
|
void open_device(const std::string &serial, unsigned int baudrate);
|
||||||
void ftdi_usb_close_internal();
|
void ftdi_usb_close_internal();
|
||||||
int close_device();
|
int close_device();
|
||||||
int mpsse_write();
|
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,
|
FtdiSpi::FtdiSpi(int vid, int pid, unsigned char interface, uint32_t clkHZ,
|
||||||
bool verbose):
|
bool verbose):
|
||||||
FTDIpp_MPSSE(bit_conf, clkHZ, verbose)
|
FTDIpp_MPSSE(bit_conf, "", "", clkHZ, verbose)
|
||||||
{
|
{
|
||||||
setCSmode(SPI_CS_AUTO);
|
setCSmode(SPI_CS_AUTO);
|
||||||
setEndianness(SPI_MSB_FIRST);
|
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,
|
FtdiSpi::FtdiSpi(const FTDIpp_MPSSE::mpsse_bit_config &conf, uint32_t clkHZ,
|
||||||
bool verbose):
|
bool verbose):
|
||||||
FTDIpp_MPSSE(conf, clkHZ, verbose)
|
FTDIpp_MPSSE(conf, "", "", clkHZ, verbose)
|
||||||
{
|
{
|
||||||
setCSmode(SPI_CS_AUTO);
|
setCSmode(SPI_CS_AUTO);
|
||||||
setEndianness(SPI_MSB_FIRST);
|
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,
|
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),
|
_verbose(verbose),
|
||||||
_state(RUN_TEST_IDLE),
|
_state(RUN_TEST_IDLE),
|
||||||
_tms_buffer_size(128), _num_tms(0),
|
_tms_buffer_size(128), _num_tms(0),
|
||||||
_board_name("nope")
|
_board_name("nope")
|
||||||
{
|
{
|
||||||
init_internal(cable, dev, pin_conf, clkHZ);
|
init_internal(cable, dev, serial, 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Jtag::~Jtag()
|
Jtag::~Jtag()
|
||||||
|
|
@ -92,7 +82,7 @@ Jtag::~Jtag()
|
||||||
delete _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)
|
const jtag_pins_conf_t *pin_conf, uint32_t clkHZ)
|
||||||
{
|
{
|
||||||
switch (cable.type) {
|
switch (cable.type) {
|
||||||
|
|
@ -102,10 +92,10 @@ void Jtag::init_internal(cable_t &cable, const string &dev,
|
||||||
case MODE_FTDI_BITBANG:
|
case MODE_FTDI_BITBANG:
|
||||||
if (pin_conf == NULL)
|
if (pin_conf == NULL)
|
||||||
throw std::exception();
|
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;
|
break;
|
||||||
case MODE_FTDI_SERIAL:
|
case MODE_FTDI_SERIAL:
|
||||||
_jtag = new FtdiJtagMPSSE(cable.config, dev, clkHZ, _verbose);
|
_jtag = new FtdiJtagMPSSE(cable.config, dev, serial, clkHZ, _verbose);
|
||||||
break;
|
break;
|
||||||
case MODE_DIRTYJTAG:
|
case MODE_DIRTYJTAG:
|
||||||
_jtag = new DirtyJtag(clkHZ, _verbose);
|
_jtag = new DirtyJtag(clkHZ, _verbose);
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,7 @@
|
||||||
class Jtag {
|
class Jtag {
|
||||||
public:
|
public:
|
||||||
Jtag(cable_t &cable, const jtag_pins_conf_t *pin_conf, std::string dev,
|
Jtag(cable_t &cable, const jtag_pins_conf_t *pin_conf, std::string dev,
|
||||||
uint32_t clkHZ, bool verbose = false);
|
const std::string &serial, uint32_t clkHZ, bool verbose = false);
|
||||||
Jtag(cable_t &cable, const jtag_pins_conf_t *pin_conf,
|
|
||||||
uint32_t clkHZ, bool verbose);
|
|
||||||
~Jtag();
|
~Jtag();
|
||||||
|
|
||||||
/* maybe to update */
|
/* maybe to update */
|
||||||
|
|
@ -82,7 +80,7 @@ class Jtag {
|
||||||
void setVerbose(bool verbose){_verbose = verbose;}
|
void setVerbose(bool verbose){_verbose = verbose;}
|
||||||
|
|
||||||
private:
|
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);
|
const jtag_pins_conf_t *pin_conf, uint32_t clkHZ);
|
||||||
bool _verbose;
|
bool _verbose;
|
||||||
int _state;
|
int _state;
|
||||||
|
|
|
||||||
16
src/main.cpp
16
src/main.cpp
|
|
@ -44,6 +44,7 @@ struct arguments {
|
||||||
string bit_file;
|
string bit_file;
|
||||||
string device;
|
string device;
|
||||||
string cable;
|
string cable;
|
||||||
|
string ftdi_serial;
|
||||||
int ftdi_channel;
|
int ftdi_channel;
|
||||||
uint32_t freq;
|
uint32_t freq;
|
||||||
string board;
|
string board;
|
||||||
|
|
@ -66,7 +67,7 @@ int main(int argc, char **argv)
|
||||||
jtag_pins_conf_t pins_config = {0, 0, 0, 0};
|
jtag_pins_conf_t pins_config = {0, 0, 0, 0};
|
||||||
|
|
||||||
/* command line args. */
|
/* 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};
|
false, false, false, false, false, true, false};
|
||||||
/* parse arguments */
|
/* parse arguments */
|
||||||
try {
|
try {
|
||||||
|
|
@ -125,13 +126,17 @@ int main(int argc, char **argv)
|
||||||
cable.config.interface = mapping[args.ftdi_channel];
|
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 base */
|
||||||
Jtag *jtag;
|
Jtag *jtag;
|
||||||
try {
|
try {
|
||||||
if (args.device == "-")
|
jtag = new Jtag(cable, &pins_config, args.device, args.ftdi_serial, args.freq, false);
|
||||||
jtag = new Jtag(cable, &pins_config, args.freq, false);
|
|
||||||
else
|
|
||||||
jtag = new Jtag(cable, &pins_config, args.device, args.freq, false);
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
printError("Error: Failed to claim cable");
|
printError("Error: Failed to claim cable");
|
||||||
return EXIT_FAILURE;
|
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",
|
("b,board", "board name, may be used instead of cable",
|
||||||
cxxopts::value<string>(args->board))
|
cxxopts::value<string>(args->board))
|
||||||
("c,cable", "jtag interface", cxxopts::value<string>(args->cable))
|
("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))
|
("ftdi-channel", "FTDI chip channel number (channels 0-3 map to A-D)", cxxopts::value<int>(args->ftdi_channel))
|
||||||
#ifdef USE_UDEV
|
#ifdef USE_UDEV
|
||||||
("d,device", "device to use (/dev/ttyUSBx)",
|
("d,device", "device to use (/dev/ttyUSBx)",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue