psi46 / pxar

Life is too short for perfection
15 stars 46 forks source link

Search for DTBs fails if other FTDI devices are present #454

Open BranislavRistic opened 4 years ago

BranislavRistic commented 4 years ago

We are using DTBs together with FTDI based USB-RS232 cables. While the cables are attached to the ftdi_sio driver, which provides /dev/ttyUSB nodes, the DTBs are excluded in order to be accessible by the FTDI D2XX interface.

When pxar is searching for DTBs it traverses a list of devices found by the FTDI D2XX library (which includes all FTDI devices), it tries to also get the description for the USB cables which are claimed by the ftdi_sio driver and fails (FT_ListDevices returns 'FT_ERROR(2) device not found'). At that point the search is terminated prematurely (see line 84)

https://github.com/psi46/pxar/blob/e17df08c7bbeb8472e8f56ccd2b9d69a113ccdc3/core/usb/USBInterface.libftd2xx.cc#L81-L86

This means that depending on the order of the devices listed by the FTDI library, the DTBs will be found or not. Removing line 84 and incrementing enumPos like for the successful case mitigates this issue and works in our case.

Is there a reason to terminate the search when encountering an inaccessible device?

Same statements can be found here: https://github.com/psi46/pxar/blob/e17df08c7bbeb8472e8f56ccd2b9d69a113ccdc3/core/usb/USBInterface.libftd2xx.cc#L100
https://github.com/psi46/pxar/blob/e17df08c7bbeb8472e8f56ccd2b9d69a113ccdc3/core/usb/USBInterface.libftdi.cc#L198
https://github.com/psi46/pxar/blob/e17df08c7bbeb8472e8f56ccd2b9d69a113ccdc3/core/usb/USBInterface.libftdi.cc#L232

simonspa commented 4 years ago

Probably not, back then we most likely only though of an invalid device state but not of another device.

meierb commented 4 years ago

Remark: DTB serial numbers always start with "DTB_". In this way you can identify a DTB. See also code in psi46test pixel_dtb.cpp: bool CTestboard::FindDTB(string &usbId) that lists all the connected DTBs.

Am 18.09.2019 um 12:08 schrieb Bane:

We are using DTBs together with FTDI based USB-RS232 cables. While the cables are attached to the ftdi_sio driver, which provides |/dev/ttyUSB| nodes, the DTBs are excluded in order to be accessible by the FTDI D2XX interface.

When pxar is searching for DTBs it traverses a list of devices found by the FTDI D2XX library (which includes all FTDI devices), it tries to also get the description for the USB cables which are claimed by the ftdi_sio driver and fails (FT_ListDevices returns 'FT_ERROR(2) device not found'). At that point the search is terminated prematurely (see line 84)

https://github.com/psi46/pxar/blob/e17df08c7bbeb8472e8f56ccd2b9d69a113ccdc3/core/usb/USBInterface.libftd2xx.cc#L81-L86

This means that depending on the order of the devices listed by the FTDI library, the DTBs will be found or not. Removing line 84 and incrementing |enumPos| like for the successful case mitigates this issue and works in our case.

Is there a reason to terminate the search when encountering an inaccessible device?

Same statements can be found here: https://github.com/psi46/pxar/blob/e17df08c7bbeb8472e8f56ccd2b9d69a113ccdc3/core/usb/USBInterface.libftd2xx.cc#L100 https://github.com/psi46/pxar/blob/e17df08c7bbeb8472e8f56ccd2b9d69a113ccdc3/core/usb/USBInterface.libftdi.cc#L198 https://github.com/psi46/pxar/blob/e17df08c7bbeb8472e8f56ccd2b9d69a113ccdc3/core/usb/USBInterface.libftdi.cc#L232

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/psi46/pxar/issues/454?email_source=notifications&email_token=ABGZGJFEK53JE2MTUDTR77LQKH43BA5CNFSM4IX4R4W2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HMDARWA, or mute the thread https://github.com/notifications/unsubscribe-auth/ABGZGJCOD36AC46O6HOMJX3QKH43BANCNFSM4IX4R4WQ.

--

Paul Scherrer Institut Beat Meier OFLC/006 Forschungsstrasse 111 5232 Villigen PSI Switzerland

Phone: beat.meier@psi.ch phone +41 56 3104659

BranislavRistic commented 4 years ago

Thanks for the quick reply!

@simonspa I will then prepare a PR with our changes.

@meierb Unfortunately this is the same code as above (cycling through FTDI devices via EnumNext). If you look at https://github.com/psi46/psi46test/blob/master/usb.cpp#L57-L69 it relies on FT_ListDevices returning a zero, otherwise enumCount is set to 0 and all following calls to EnumNext return immediately a false.

meierb commented 4 years ago

This is the code I meant. I use it for the wafer test. There are also other FTDI devices connected to the PC.

bool CTestboard::EnumNext(string &name) {     char s[64];     if (!usb.EnumNext(s)) return false;     name = s;     return true; }

bool CTestboard::Enum(unsigned int pos, string &name) {     char s[64];     if (!usb.Enum(s, pos)) return false;     name = s;     return true; }

bool CTestboard::FindDTB(string &usbId) {     string name;     vector devList;     unsigned int nDev;     unsigned int nr;

    try     {         if (!EnumFirst(nDev)) throw int(1);         for (nr=0; nr<nDev; nr++)         {             if (!EnumNext(name)) continue;             if (name.size() < 4) continue;             if (name.compare(0, 4, "DTB_") == 0) devList.push_back(name);         }     }     catch (int e)     {         switch (e)         {         case 1: printf("Cannot access the USB driver\n"); return false;         default: return false;         }     }

    if (devList.size() == 0)     {         printf("No DTB connected.\n");         return false;     }

    if (devList.size() == 1)     {         usbId = devList[0];         return true;     }

    // If more than 1 connected device list them     printf("\nConnected DTBs:\n");     for (nr=0; nr<devList.size(); nr++)     {         printf("%2u: %s", nr, devList[nr].c_str());         if (Open(devList[nr], false))         {             try             {                 unsigned int bid = GetBoardId();                 printf("  BID=%2u\n", bid);             }             catch (...)             {                 printf("  Not identifiable\n");             }             Close();         }         else printf(" - in use\n");     }

    printf("Please choose DTB (0-%u): ", (nDev-1));     char choice[8];     fgets(choice, 8, stdin);     sscanf (choice, "%d", &nr);     if (nr >= devList.size())     {         nr = 0;         printf("No DTB opened\n");         return false;     }

    usbId = devList[nr];     return true; }