ftdixxx: allows to open converter with device path instead of vid and pid
This commit is contained in:
parent
98c2b64cab
commit
6569ae40fe
18
ftdijtag.cpp
18
ftdijtag.cpp
|
|
@ -42,6 +42,24 @@ using namespace std;
|
||||||
* - envoyer le dernier avec 0x4B ou 0x6B
|
* - envoyer le dernier avec 0x4B ou 0x6B
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
FtdiJtag::FtdiJtag(FTDIpp_MPSSE::mpsse_bit_config &cable, string dev,
|
||||||
|
unsigned char interface, uint32_t clkHZ):
|
||||||
|
FTDIpp_MPSSE(dev, interface, clkHZ),
|
||||||
|
_state(RUN_TEST_IDLE),
|
||||||
|
_tms_buffer_size(128), _num_tms(0),
|
||||||
|
_board_name("nope"), _verbose(false)
|
||||||
|
{
|
||||||
|
display("%x\n", cable.bit_low_val);
|
||||||
|
display("%x\n", cable.bit_low_dir);
|
||||||
|
display("%x\n", cable.bit_high_val);
|
||||||
|
display("%x\n", cable.bit_high_dir);
|
||||||
|
_verbose = false;
|
||||||
|
|
||||||
|
_tms_buffer = (unsigned char *)malloc(sizeof(unsigned char) * _tms_buffer_size);
|
||||||
|
bzero(_tms_buffer, _tms_buffer_size);
|
||||||
|
init(1, 0xfb, cable);
|
||||||
|
}
|
||||||
|
|
||||||
FtdiJtag::FtdiJtag(FTDIpp_MPSSE::mpsse_bit_config &cable,
|
FtdiJtag::FtdiJtag(FTDIpp_MPSSE::mpsse_bit_config &cable,
|
||||||
unsigned char interface, uint32_t clkHZ):
|
unsigned char interface, uint32_t clkHZ):
|
||||||
FTDIpp_MPSSE(cable.vid, cable.pid, interface, clkHZ),
|
FTDIpp_MPSSE(cable.vid, cable.pid, interface, clkHZ),
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
class FtdiJtag : public FTDIpp_MPSSE {
|
class FtdiJtag : public FTDIpp_MPSSE {
|
||||||
public:
|
public:
|
||||||
//FtdiJtag(std::string board_name, int vid, int pid, unsigned char interface, uint32_t clkHZ);
|
//FtdiJtag(std::string board_name, int vid, int pid, unsigned char interface, uint32_t clkHZ);
|
||||||
|
FtdiJtag(FTDIpp_MPSSE::mpsse_bit_config &cable, std::string dev,
|
||||||
|
unsigned char interface, uint32_t clkHZ);
|
||||||
FtdiJtag(FTDIpp_MPSSE::mpsse_bit_config &cable, unsigned char interface, uint32_t clkHZ);
|
FtdiJtag(FTDIpp_MPSSE::mpsse_bit_config &cable, unsigned char interface, uint32_t clkHZ);
|
||||||
~FtdiJtag();
|
~FtdiJtag();
|
||||||
|
|
||||||
|
|
|
||||||
149
ftdipp_mpsse.cpp
149
ftdipp_mpsse.cpp
|
|
@ -1,6 +1,13 @@
|
||||||
#include <iostream>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <libudev.h>
|
||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
|
|
||||||
#include "ftdipp_mpsse.hpp"
|
#include "ftdipp_mpsse.hpp"
|
||||||
|
|
@ -16,11 +23,31 @@ using namespace std;
|
||||||
#define display(...) do {}while(0)
|
#define display(...) do {}while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FTDIpp_MPSSE::FTDIpp_MPSSE(int vid, int pid, unsigned char interface,
|
FTDIpp_MPSSE::FTDIpp_MPSSE(const string &dev, unsigned char interface,
|
||||||
uint32_t clkHZ):_vid(vid), _pid(pid), _interface(interface),
|
uint32_t clkHZ):_vid(0), _pid(0), _bus(-1), _addr(-1), _product(""),
|
||||||
_clkHZ(clkHZ), _buffer_size(2*32768), _num(0), _verbose(false)
|
_interface(interface),
|
||||||
|
_clkHZ(clkHZ), _buffer_size(2*32768), _num(0), _verbose(false)
|
||||||
{
|
{
|
||||||
open_device(vid, pid, (unsigned char)interface, 115200);
|
if (!search_with_dev(dev)) {
|
||||||
|
cerr << "No cable found" << endl;
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
open_device(115200);
|
||||||
|
|
||||||
|
_buffer = (unsigned char *)malloc(sizeof(unsigned char) * _buffer_size);
|
||||||
|
if (!_buffer) {
|
||||||
|
cout << "_buffer malloc failed" << endl;
|
||||||
|
throw std::exception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FTDIpp_MPSSE::FTDIpp_MPSSE(int vid, int pid, unsigned char interface,
|
||||||
|
uint32_t clkHZ):_vid(vid), _pid(pid), _bus(-1), _addr(-1), _product(""),
|
||||||
|
_interface(interface),
|
||||||
|
_clkHZ(clkHZ), _buffer_size(2*32768), _num(0), _verbose(false)
|
||||||
|
{
|
||||||
|
open_device(115200);
|
||||||
|
|
||||||
_buffer = (unsigned char *)malloc(sizeof(unsigned char) * _buffer_size);
|
_buffer = (unsigned char *)malloc(sizeof(unsigned char) * _buffer_size);
|
||||||
if (!_buffer) {
|
if (!_buffer) {
|
||||||
|
|
@ -32,23 +59,30 @@ _clkHZ(clkHZ), _buffer_size(2*32768), _num(0), _verbose(false)
|
||||||
FTDIpp_MPSSE::~FTDIpp_MPSSE()
|
FTDIpp_MPSSE::~FTDIpp_MPSSE()
|
||||||
{
|
{
|
||||||
ftdi_set_bitmode(_ftdi, 0, BITMODE_RESET);
|
ftdi_set_bitmode(_ftdi, 0, BITMODE_RESET);
|
||||||
|
|
||||||
ftdi_usb_reset(_ftdi);
|
ftdi_usb_reset(_ftdi);
|
||||||
close_device();
|
close_device();
|
||||||
free(_buffer);
|
free(_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FTDIpp_MPSSE::open_device(unsigned int vid, unsigned int pid,
|
void FTDIpp_MPSSE::open_device(unsigned int baudrate)
|
||||||
unsigned char interface, unsigned int baudrate)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
printf("try to open %x %x %d %d\n", _vid, _pid, _bus, _addr);
|
||||||
|
|
||||||
_ftdi = ftdi_new();
|
_ftdi = ftdi_new();
|
||||||
if (_ftdi == NULL) {
|
if (_ftdi == NULL) {
|
||||||
cout << "open_device: failed to initialize ftdi" << endl;
|
cout << "open_device: failed to initialize ftdi" << endl;
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
ftdi_set_interface(_ftdi, (ftdi_interface)interface);
|
ftdi_set_interface(_ftdi, (ftdi_interface)_interface);
|
||||||
if ((ret = ftdi_usb_open_desc(_ftdi, vid, pid, NULL, NULL)) < 0) {
|
if (_bus == -1 or _addr == -1)
|
||||||
|
ret = ftdi_usb_open_desc(_ftdi, _vid, _pid, NULL, NULL);
|
||||||
|
else
|
||||||
|
ret = ftdi_usb_open_bus_addr(_ftdi, _bus, _addr);
|
||||||
|
if (ret < 0) {
|
||||||
fprintf(stderr, "unable to open ftdi device: %d (%s)\n",
|
fprintf(stderr, "unable to open ftdi device: %d (%s)\n",
|
||||||
ret, ftdi_get_error_string(_ftdi));
|
ret, ftdi_get_error_string(_ftdi));
|
||||||
ftdi_free(_ftdi);
|
ftdi_free(_ftdi);
|
||||||
|
|
@ -64,7 +98,7 @@ void FTDIpp_MPSSE::open_device(unsigned int vid, unsigned int pid,
|
||||||
/* cf. ftdi.c same function */
|
/* cf. ftdi.c same function */
|
||||||
void FTDIpp_MPSSE::ftdi_usb_close_internal ()
|
void FTDIpp_MPSSE::ftdi_usb_close_internal ()
|
||||||
{
|
{
|
||||||
libusb_close (_ftdi->usb_dev);
|
libusb_close(_ftdi->usb_dev);
|
||||||
_ftdi->usb_dev = NULL;
|
_ftdi->usb_dev = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,10 +107,12 @@ int FTDIpp_MPSSE::close_device()
|
||||||
int rtn;
|
int rtn;
|
||||||
if (_ftdi == NULL)
|
if (_ftdi == NULL)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
/* purge FTDI */
|
||||||
ftdi_usb_purge_rx_buffer(_ftdi);
|
ftdi_usb_purge_rx_buffer(_ftdi);
|
||||||
ftdi_usb_purge_tx_buffer(_ftdi);
|
ftdi_usb_purge_tx_buffer(_ftdi);
|
||||||
|
|
||||||
/*ftdi_usb_close(h->ftdi);
|
/*
|
||||||
* repompe de la fonction et des suivantes
|
* repompe de la fonction et des suivantes
|
||||||
*/
|
*/
|
||||||
if (_ftdi->usb_dev != NULL) {
|
if (_ftdi->usb_dev != NULL) {
|
||||||
|
|
@ -259,3 +295,94 @@ int FTDIpp_MPSSE::mpsse_read(unsigned char *rx_buff, int len)
|
||||||
} while (len > 0);
|
} while (len > 0);
|
||||||
return num_read;
|
return num_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int FTDIpp_MPSSE::udevstufftoint(const char *udevstring, int base)
|
||||||
|
{
|
||||||
|
char *endp;
|
||||||
|
int ret;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
if (udevstring == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
ret = (unsigned int)strtol(udevstring, &endp, base);
|
||||||
|
if (errno) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"udevstufftoint: Unable to parse number Error : %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
return (-2);
|
||||||
|
}
|
||||||
|
if (endp == optarg) {
|
||||||
|
fprintf(stderr, "udevstufftoint: No digits were found\n");
|
||||||
|
return (-3);
|
||||||
|
}
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FTDIpp_MPSSE::search_with_dev(const string &device)
|
||||||
|
{
|
||||||
|
struct udev *udev;
|
||||||
|
struct udev_device *dev, *usbdeviceparent;
|
||||||
|
char devtype;
|
||||||
|
|
||||||
|
struct stat statinfo;
|
||||||
|
if (stat(device.c_str(), &statinfo) < 0) {
|
||||||
|
printf("unable to stat file\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get device type */
|
||||||
|
switch (statinfo.st_mode & S_IFMT) {
|
||||||
|
case S_IFBLK:
|
||||||
|
devtype = 'b';
|
||||||
|
break;
|
||||||
|
case S_IFCHR:
|
||||||
|
devtype = 'c';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("not char or block device\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the udev object */
|
||||||
|
udev = udev_new();
|
||||||
|
if (!udev) {
|
||||||
|
printf("Can't create udev\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = udev_device_new_from_devnum(udev, devtype, statinfo.st_rdev);
|
||||||
|
|
||||||
|
if (dev == NULL) {
|
||||||
|
printf("no dev\n");
|
||||||
|
udev_device_unref(dev);
|
||||||
|
udev_unref(udev);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get closest usb device parent (we need VIP/PID) */
|
||||||
|
usbdeviceparent =
|
||||||
|
udev_device_get_parent_with_subsystem_devtype(dev, "usb",
|
||||||
|
"usb_device");
|
||||||
|
if (!usbdeviceparent) {
|
||||||
|
printf
|
||||||
|
("Unable to find parent usb device! Is this actually an USB device ?\n");
|
||||||
|
udev_device_unref(dev);
|
||||||
|
udev_unref(udev);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_bus = udevstufftoint(udev_device_get_sysattr_value(
|
||||||
|
usbdeviceparent, "busnum"), 10);
|
||||||
|
_addr = udevstufftoint(udev_device_get_sysattr_value(
|
||||||
|
usbdeviceparent, "devnum"), 10);
|
||||||
|
sprintf(_product, "%s", udev_device_get_sysattr_value(usbdeviceparent, "product"));
|
||||||
|
_vid = udevstufftoint(
|
||||||
|
udev_device_get_sysattr_value(usbdeviceparent, "idVendor"), 16);
|
||||||
|
_pid = udevstufftoint(udev_device_get_sysattr_value(
|
||||||
|
usbdeviceparent, "idProduct"), 16);
|
||||||
|
|
||||||
|
printf("vid %x pid %x bus %d addr %d product name : %s\n", _vid, _pid, _bus, _addr, _product);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
#ifndef _FTDIPP_MPSSE_H
|
#ifndef _FTDIPP_MPSSE_H
|
||||||
#define _FTDIPP_MPSSE_H
|
#define _FTDIPP_MPSSE_H
|
||||||
#include <ftdi.h>
|
#include <ftdi.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class FTDIpp_MPSSE {
|
class FTDIpp_MPSSE {
|
||||||
public:
|
public:
|
||||||
|
FTDIpp_MPSSE(const std::string &dev, unsigned char interface, uint32_t clkHZ);
|
||||||
FTDIpp_MPSSE(int vid, int pid, unsigned char interface, uint32_t clkHZ);
|
FTDIpp_MPSSE(int vid, int pid, unsigned char interface, uint32_t clkHZ);
|
||||||
~FTDIpp_MPSSE();
|
~FTDIpp_MPSSE();
|
||||||
|
|
||||||
|
|
@ -24,8 +26,7 @@ class FTDIpp_MPSSE {
|
||||||
int pid() {return _pid;}
|
int pid() {return _pid;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void open_device(unsigned int vid, unsigned int pid,
|
void open_device(unsigned int baudrate);
|
||||||
unsigned char interface, 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();
|
||||||
|
|
@ -33,10 +34,15 @@ class FTDIpp_MPSSE {
|
||||||
int mpsse_store(unsigned char c);
|
int mpsse_store(unsigned char c);
|
||||||
int mpsse_store(unsigned char *c, int len);
|
int mpsse_store(unsigned char *c, int len);
|
||||||
int mpsse_get_buffer_size() {return _buffer_size;}
|
int mpsse_get_buffer_size() {return _buffer_size;}
|
||||||
|
unsigned int udevstufftoint(const char *udevstring, int base);
|
||||||
|
bool search_with_dev(const std::string &device);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _vid;
|
int _vid;
|
||||||
int _pid;
|
int _pid;
|
||||||
|
int _bus;
|
||||||
|
int _addr;
|
||||||
|
char _product[64];
|
||||||
unsigned char _interface;
|
unsigned char _interface;
|
||||||
int _clkHZ;
|
int _clkHZ;
|
||||||
int _buffer_size;
|
int _buffer_size;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue