eblot / pyftdi

FTDI device driver written in pure Python
Other
509 stars 213 forks source link

How to connect two of the same devices #123

Closed mikegant closed 5 years ago

mikegant commented 5 years ago

Hello,

This is more likely an issue with the user (me) than with your fine software. I am using pyftdi on an old netbook with bunsenlabs distribution of Linux which is Debian based. I am trying to attach two identical devices to this computer and while I can communicate with one of the devices, I cannot figure out how to communicate with both. The device is an FT4232H and there is one on each two separate hardware boards.

First off, I have set the udev rules like so for these devices:

SUBSYSTEM=="usb", ATTR{serial}=="012D0L6R" ATTR{idVendor}=="1514", ATTR{idProduct}=="2008", GROUP="plugdev", MODE="0666", SYMLINK+="RTG4_FP1" SUBSYSTEM=="usb", ATTR{serial}=="002SDNR4" ATTR{idVendor}=="1514", ATTR{idProduct}=="2008", GROUP="plugdev", MODE="0666", SYMLINK+="RTG4_FP2"

I don't think the SYMLINK setting is strictly necessary but I have it for now.

Next, in my python script I have the following:

Ftdi.add_custom_vendor(0x1514, 'RTG4') Ftdi.add_custom_product(0x1514, 0x2008, 'UART')

ser_f0=pyftdi.serialext.serial_for_url('ftdi://RTG4:UART:012D0L6R/3') ser_f1=pyftdi.serialext.serial_for_url('ftdi://RTG4:UART:002SDNR4/1')

I can communicate with device assigned to 'ser_f0' but not with the device assigned to 'ser_f1'. I have tried all values 1-4 for the interface parameter in the URL and none of them work. I would expect it to be different from ser_f0 but I did try with both set to 3.

Here is some additional info.

First dmesg output when the two are plugged in:

usb 1-3: new high-speed USB device number 22 using ehci-pci usb 1-3: New USB device found, idVendor=1514, idProduct=2008 usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-3: Product: Embedded FlashPro5 usb 1-3: Manufacturer: Microsemi usb 1-3: SerialNumber: 012D0L6R ftdi_sio 1-3:1.2: FTDI USB Serial Device converter detected usb 1-3: Detected FT4232H usb 1-3: FTDI USB Serial Device converter now attached to ttyUSB1

and,

usb 1-1: new high-speed USB device number 21 using ehci-pci usb 1-1: New USB device found, idVendor=1514, idProduct=2008 usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-1: Product: Embedded FlashPro5 usb 1-1: Manufacturer: Microsemi usb 1-1: SerialNumber: 002SDNR4 ftdi_sio 1-1:1.2: FTDI USB Serial Device converter detected usb 1-1: Detected FT4232H usb 1-1: FTDI USB Serial Device converter now attached to ttyUSB0

And here is the output of lsusb:

Bus 001 Device 034: ID 1514:2008 Actel Bus 001 Device 032: ID 1514:2008 Actel

I hope that what I want to do is possible.

Thank you, Mike

eblot commented 5 years ago

Hi,

I never gave a try to a custom VID/PID + serial number + multiple devices (I do not have this combination at hand).

Using two FTDI4232H, your current setup means that you expect to connect a serial device to:

Is that correct?

Your udev rules are a bit complex, you may want to try something easier first (then make it more specific if you need to), i.e.

# both devices are of the same kind
SUBSYSTEM=="usb", ATTR{idVendor}=="1514", ATTR{idProduct}=="2008", GROUP="plugdev", MODE="0664"

Do not forget to either unplug/replug all devices after updating the udev rules file, or execute

sudo udevadm control --reload-rules && sudo udevadm trigger

to reload the udev configuration.

Try to enumerate the devices, opening the special URL ftdi:///? - you can use serialext/tests/pyterm.py for example.

What does this report?

mikegant commented 5 years ago

Thank you so much for the quick reply! I would love to get this solved, (if possible) today.

I think my statement about using a different interface number in the URL may have been confusing. Additionally, I may be incorrect stating that the interface number needs to be different. I reviewed the data sheet for the device and it has 4 ports, A, B, C, and D. I am assuming those correspond to the interface numbers 1-4 in your driver. The two pieces of hardware are the same so in both cases the serial port is connected to the C port or interface 3. Does that seem right to you? If that is the case, then I think I need some way in the udev rules or ftdi URL to distinguish one from the other.

Your first suggestion to simplify my rules. I removed the SYMLINK command and serial number attribute so I have just the one rule:

SUBSYSTEM=="usb", ATTR{idVendor}=="1514", ATTR{idProduct}=="2008", GROUP="plugdev", MODE="0666"

I kept the same ftdi URL (with the serial number) and set both interfaces to 3. Works for ser_f0 but not ser_f1.

Next, I removed the serial number from the ftdi URL in my python script and when I run the script the result is this:

Traceback (most recent call last): File "/home/mike/.local/lib/python3.5/site-packages/pyftdi/serialext/protocol_ftdi.py", line 52, in open device = Ftdi.create_from_url(self.port) File "/home/mike/.local/lib/python3.5/site-packages/pyftdi/ftdi.py", line 296, in create_from_url device.open_from_url(url) File "/home/mike/.local/lib/python3.5/site-packages/pyftdi/ftdi.py", line 397, in open_from_url vendor, product, index, serial, interface = self.get_identifiers(url) File "/home/mike/.local/lib/python3.5/site-packages/pyftdi/ftdi.py", line 309, in get_identifiers cls.SCHEME, cls.VENDOR_IDS, cls.PRODUCT_IDS, cls.DEFAULT_VENDOR) File "/home/mike/.local/lib/python3.5/site-packages/pyftdi/usbtools.py", line 369, in parse_url len(candidates)) pyftdi.usbtools.UsbToolsError: 2 USB devices match URL

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "console.py", line 3, in from utils import File "/home/mike/srio_scripts/utils.py", line 3, in from rtg4_srio_pkg import File "/home/mike/srio_scripts/rtg4_srio_pkg.py", line 128, in ser_f0=pyftdi.serialext.serial_for_url('ftdi://0x1514:0x2008/3') File "/home/mike/.local/lib/python3.5/site-packages/serial/init.py", line 88, in serial_for_url instance.open() File "/home/mike/.local/lib/python3.5/site-packages/pyftdi/serialext/protocol_ftdi.py", line 55, in open (self.portstr, str(ex))) serial.serialutil.SerialException: Unable to open USB port ftdi://0x1514:0x2008/3: 2 USB devices match URL

So, this tells me I need some way to distinguish the two devices and the only way I know of is the serial number.

Here's the output of ftdi:///?:

Available interfaces: ftdi://RTG4:UART:002SDNR4/1 (Embedded FlashPro5) ftdi://RTG4:UART:002SDNR4/2 (Embedded FlashPro5) ftdi://RTG4:UART:002SDNR4/3 (Embedded FlashPro5) ftdi://RTG4:UART:002SDNR4/4 (Embedded FlashPro5) ftdi://RTG4:UART:012D0L6R/1 (Embedded FlashPro5) ftdi://RTG4:UART:012D0L6R/2 (Embedded FlashPro5) ftdi://RTG4:UART:012D0L6R/3 (Embedded FlashPro5) ftdi://RTG4:UART:012D0L6R/4 (Embedded FlashPro5)

I have not been using python for very long but I have experience with other scripting languages. If there is something that I can change in the driver code. I am more than happy to do it.

Thanks, Mike

eblot commented 5 years ago

The two pieces of hardware are the same so in both cases the serial port is connected to the C port or interface 3. Does that seem right to you? Yes.

If that is the case, then I think I need some way in the udev rules

udev rules only gives permissions to access a device from userland for specific users, it does not map or configure anything for the FTDI devices. The rules you wrote just tell udev that any user belonging to the group "plugdev" has permissions to communicate with 1514:2008 usb devices. Nothing more.

ftdi URL to distinguish one from the other.

That is achieved through the serial number.

To open a serial port to the 3rd port of the first FT4232H, use

ftdi://RTG4:UART:002SDNR4/3

To open a serial port to the 3rd port of the second FT4232H, use

ftdi://RTG4:UART:012D0L6R/3 

HTH.

mikegant commented 5 years ago

That is exactly what I'm doing.

I get a response from the hardware for the interface with serial number 012D0L6R but I don't get a response from the device with serial number 002SDNR4.

eblot commented 5 years ago

If you unplug the first FT4232H device, can you communicate with the second one (w/o changing the URL)?

mikegant commented 5 years ago

Update.

It's working!! I cycled power on both devices and it started working. I think all my changes put the one device in a wierd state and the power cycle cleared it up. After the power cycle both are working. Thanks for your help!

Now, I have one more question :). The interface number 4 is connected to some discrete controls (no comm protocol) on my devices. I didn't see how to control these signals with your driver. I could flail about and see if I can figure it out but I was hoping you could give me some pointers.

eblot commented 5 years ago

Great.

When you say "discrete controls", do you mean pure GPIOs or something a bit more complex (I2C, SPI, ...)?

You can use the GPIO bitbang mode, although I am not sure it is supported on port 3&4 which are UART-only (but bitbang mode is even simpler).

If you need to use a real bus (I2C, SPI), you need to connect them to either port 1 or 2.

Check out the doc for example about GPIO and the other modes: http://eblot.github.io/pyftdi/api/index.html or for GPIO-only: http://eblot.github.io/pyftdi/api/gpio.html

mikegant commented 5 years ago

Great! I'll take a look at the links. Scanned them once but I will take a closer look.

Thanks again for your help! You have made my job a whole lot easier! And thanks for writing this software, too!

Have a good day.

eblot commented 5 years ago

Thanks!