pyftdi icon indicating copy to clipboard operation
pyftdi copied to clipboard

ftdi: preserve original latency timer on close

Open pillo79 opened this issue 6 months ago • 5 comments

Instead of resetting to the maximum latency timer when closing the device, the original latency timer value is read on open and restored on close. This ensures the performance of the FTDI device is not degraded when the device is reopened.

pillo79 avatar Jun 26 '25 06:06 pillo79

I understand the purpose, but that also means an interface is no longer open in a known state, which is quite unusual... Depending on the actual usage, this is either handy or problematic.

As get_latency_timer()/set_latency_timer() functions are public, why not keeping this peculiar features in the Ftdi client?

eblot avatar Aug 14 '25 14:08 eblot

Hello and thanks for getting back!

Some more background info: we have designed a tiny board with an FTDI usually used for standard serial comms, but whose CBUS lines are wired as GPIOs for reset and stuff. Thanks to pyftdi the GPIO shuffling was super easy :bow:, but... users complained that minicom console acted reaaaaaaalllyyyyy slow after messing with GPIOs, so I looked into the issue.

an interface is no longer open in a known state

Not sure I understand this remark. I do save the original state of the device before actually forcing it to the min value. It still has a known value while the device is open in pyftdi, it just reverts to the previous configuration on close.

why not keeping this peculiar features in the Ftdi client?

Actually, I do have a tiny wrapper that does exactly this - so it's compatible with any version of pyftdi - but I thought this fix was useful to everybody. pyftdi currently leaves the device in a different hardware configuration after opening and closing; this patch prevents this in all situations.

pillo79 avatar Aug 21 '25 15:08 pillo79

Yes, I do understand that in your specific use case(s), when you re-open a connection to the FTDI interface, you'd prefer to get the same settings that were active when you closed it.

However, while this applies well to your use case(s), it departs from how device drivers usually work (pyftdi is a device driver at user level written in Python): when a connection to a device driver is opened, it is expected that the device is in a known, initial state, which does not depend on prior usage, as you cannot predict how the device has been previously used. Keeping a specific state means that for other users, they would have to perform a list of initialization steps to revert to this known state before using the device.

Maybe this could be made clearer with an example: there may be an application that uses the same FTDI interface alternatively in both UART and SPI modes. This means the app would have to re-initialize on each device connection the latency as it would be able to predict the default one. Otherwise it would have to track itself how and when the FTDI interface has been used and depending on the last used settings, fix up the initial configuration of the device.

While keeping the last configuration may sound convenient for some use cases, it is not generally how device drivers work, i.e. users expect that two calls to open a connection to a device with the same open arguments initializes it always the same way, irrespective of how the last "user" (in this case, the app) has left it.

eblot avatar Aug 23 '25 11:08 eblot

[...] when a connection to a device driver is opened, it is expected that the device is in a known, initial state, which does not depend on prior usage, as you cannot predict how the device has been previously used.

Which is still the case: INSIDE pyftdi the latency is 1; the patch changes it back after the device is closed. My problem is in fact visible with minicom, as I said - clearly well after pyftdi has completed.

the app would have to re-initialize on each device connection the latency as it would [not] be able to predict the default one. Otherwise it would have to track itself how and when the FTDI interface has been used and depending on the last used settings, fix up the initial configuration of the device.

That is exactly my point. pyftdi is changing an FTDI-specific parameter of the chip that is initialized by Linux drivers and not generally available or understood by other (serial) users of the device. It is pyftdi that is causing other processes to work differently by changing the chip latency. Blame the Linux driver if you wish, for not setting it up on serial open, but that's debatable - they don't expect anyone to change the hardware registers behind the scenes.

I am completely confused as why you would like to keep the current behavior. Still, I hope this PR will be useful to others in my situation - basically everyone that toggles between GPIO and UART mode.

pillo79 avatar Sep 01 '25 13:09 pillo79

I think I read your patch the reverse way: I though you were restoring latencies across sessions, not restoring the original state on close (the variable name should have been enough to give me the clue). In this case, this PR is fully valid, sorry about the misunderstanding.

eblot avatar Sep 01 '25 13:09 eblot