diff --git a/ftdijtag.cpp b/ftdijtag.cpp index 1852510..d69861a 100644 --- a/ftdijtag.cpp +++ b/ftdijtag.cpp @@ -42,6 +42,24 @@ using namespace std; * - 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, unsigned char interface, uint32_t clkHZ): FTDIpp_MPSSE(cable.vid, cable.pid, interface, clkHZ), diff --git a/ftdijtag.hpp b/ftdijtag.hpp index e5760aa..da4327c 100644 --- a/ftdijtag.hpp +++ b/ftdijtag.hpp @@ -9,6 +9,8 @@ class FtdiJtag : public FTDIpp_MPSSE { public: //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(); diff --git a/ftdipp_mpsse.cpp b/ftdipp_mpsse.cpp index 2e3a0fa..96ae201 100644 --- a/ftdipp_mpsse.cpp +++ b/ftdipp_mpsse.cpp @@ -1,6 +1,13 @@ -#include +#include #include +#include +#include +#include +#include +#include + +#include #include #include "ftdipp_mpsse.hpp" @@ -16,11 +23,31 @@ using namespace std; #define display(...) do {}while(0) #endif -FTDIpp_MPSSE::FTDIpp_MPSSE(int vid, int pid, unsigned char interface, - uint32_t clkHZ):_vid(vid), _pid(pid), _interface(interface), -_clkHZ(clkHZ), _buffer_size(2*32768), _num(0), _verbose(false) +FTDIpp_MPSSE::FTDIpp_MPSSE(const string &dev, unsigned char interface, + uint32_t clkHZ):_vid(0), _pid(0), _bus(-1), _addr(-1), _product(""), + _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); if (!_buffer) { @@ -32,23 +59,30 @@ _clkHZ(clkHZ), _buffer_size(2*32768), _num(0), _verbose(false) FTDIpp_MPSSE::~FTDIpp_MPSSE() { ftdi_set_bitmode(_ftdi, 0, BITMODE_RESET); + ftdi_usb_reset(_ftdi); close_device(); free(_buffer); } -void FTDIpp_MPSSE::open_device(unsigned int vid, unsigned int pid, - unsigned char interface, unsigned int baudrate) +void FTDIpp_MPSSE::open_device(unsigned int baudrate) { int ret; + + printf("try to open %x %x %d %d\n", _vid, _pid, _bus, _addr); + _ftdi = ftdi_new(); if (_ftdi == NULL) { cout << "open_device: failed to initialize ftdi" << endl; throw std::exception(); } - ftdi_set_interface(_ftdi, (ftdi_interface)interface); - if ((ret = ftdi_usb_open_desc(_ftdi, vid, pid, NULL, NULL)) < 0) { + ftdi_set_interface(_ftdi, (ftdi_interface)_interface); + 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", ret, ftdi_get_error_string(_ftdi)); ftdi_free(_ftdi); @@ -64,7 +98,7 @@ void FTDIpp_MPSSE::open_device(unsigned int vid, unsigned int pid, /* cf. ftdi.c same function */ void FTDIpp_MPSSE::ftdi_usb_close_internal () { - libusb_close (_ftdi->usb_dev); + libusb_close(_ftdi->usb_dev); _ftdi->usb_dev = NULL; } @@ -73,10 +107,12 @@ int FTDIpp_MPSSE::close_device() int rtn; if (_ftdi == NULL) return EXIT_FAILURE; + + /* purge FTDI */ ftdi_usb_purge_rx_buffer(_ftdi); ftdi_usb_purge_tx_buffer(_ftdi); - /*ftdi_usb_close(h->ftdi); + /* * repompe de la fonction et des suivantes */ if (_ftdi->usb_dev != NULL) { @@ -259,3 +295,94 @@ int FTDIpp_MPSSE::mpsse_read(unsigned char *rx_buff, int len) } while (len > 0); 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; +} diff --git a/ftdipp_mpsse.hpp b/ftdipp_mpsse.hpp index 03a6c0d..3e1b0df 100644 --- a/ftdipp_mpsse.hpp +++ b/ftdipp_mpsse.hpp @@ -1,9 +1,11 @@ #ifndef _FTDIPP_MPSSE_H #define _FTDIPP_MPSSE_H #include +#include class FTDIpp_MPSSE { 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(); @@ -24,8 +26,7 @@ class FTDIpp_MPSSE { int pid() {return _pid;} protected: - void open_device(unsigned int vid, unsigned int pid, - unsigned char interface, unsigned int baudrate); + void open_device(unsigned int baudrate); void ftdi_usb_close_internal(); int close_device(); int mpsse_write(); @@ -33,10 +34,15 @@ class FTDIpp_MPSSE { int mpsse_store(unsigned char c); int mpsse_store(unsigned char *c, int len); 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: int _vid; int _pid; + int _bus; + int _addr; + char _product[64]; unsigned char _interface; int _clkHZ; int _buffer_size;