MichaelZaidman / hid-ft260

FTDI FT260 Linux kernel driver
GNU General Public License v2.0
23 stars 6 forks source link

Implement ioctl calls TIOCMBIS, TIOCMBIC, TIOCMGET and TIOCMSET #27

Open Rio6 opened 1 month ago

Rio6 commented 1 month ago

Hello, I am trying to program an ESP32 over FT260. For the most part this module works great! I am able to program the chip by manually going into the bootloader mode. But it does not work if I want to use espressif's auto reset function via DTR and RTS pins. The tool uses these 4 ioctl calls to reset the chip: TIOCMBIS, TIOCMBIC, TIOCMGET, TIOCMSET.

https://github.com/espressif/esptool/blob/master/esptool/reset.py#L77 https://github.com/pyserial/pyserial/blob/master/serial/serialposix.py#L717

which causes an OSError: [Errno 25] Inappropriate ioctl for device as it seems like they are not implemented. How easy would it be to add them into this module? Or alternatively, does this module already have an interface that allows controlling the DTR and RTS lines?

(There's another issue with pyerial's list_port implementation where it ignores hid devices from realpath /sys/class/tty/*/device/subsystem. But I think that's belongs to pyerial).

MichaelZaidman commented 1 month ago

Hi @Rio6, According to the spec, the FT260 device supports both, DTR-DSR and RTS_CTS, but only one can be enabled at a time. You are correct. The driver code does not support these flow control modes since they are rarely used nowadays. I mean to add such support when I have more time, but it never happens. Your query motivated me to look into it again.

Rio6 commented 1 month ago

I looked through the datasheet for a bit, it seems the RTS line is set automatically based on the chip's internal queue. DTR line might be similar but the wording on that one is a bit unclear.

In any case, looks like the driver will need to put those lines in GPIO mode to be able to drive them manually. I'm not sure if there's a standard in Linux that change flow control mode back to automatic - there's CRTSCTS from termio but I didn't find anything like that for DTR/DSR.

vanrein commented 1 month ago

DTR and DSR are meant to signal that "the line is open" from the side of the DTE and DCE respectively, basically because the terminal (DTR) or communications device (DSR) has powered up or enabled its serial channel.

DTR and DSR may also be used to mimic hardware flow control, but that is a bit of a hack (because it makes assumptions that the other side does not take dramatic action when it sees its peer going offline). The datasheet says that FT260 can support its side of this hack.

The code you pointed to wants to send RTS (a desire to send data from the terminal) while DTR is low (indicating that the terminal is offline). That is a hack that may or may not work on various serial ports. It is not surprising if the FT260 cannot do that because it is abnormal RS-232 behaviour.

Having said that, I am in no way voting to withhold these line signals if they are possible with this chip :-)

But you are asking for a response to generic ioctl() calls that would reconfigure the FT260. That's going to cause confusion. A reasonable approach could be after a deliberate switch of its function, perhaps with an argument to modprobe? Possible modes could be the FT260 modes, kernel-controlled DTR/DSR and generic GPIO pins, I suppose. And perhaps a bit complex?

vanrein commented 1 month ago

I looked through the datasheet for a bit, it seems the RTS line is set automatically based on the chip's internal queue.

Where did you find this? The datasheet starts off in 5.3.3 to indicate it has distinct modes, but none for both RTS/CTS and DTR/DSR, and GPIO is en entirely separate mode. These modes are pretty much what I meant with the modprobe module argument.

The datasheet mentions in 5.3.3 the RTS/CTS and DTR/DSR flow control behaviour under headers for flow control so nothing in those sections are certain in the other modes. Confusingly, nothing is being said about the lines when flow control is not in the respective modes. Especially the remark of setting DTR upon reset could describe the classical DTR/DSR behaviour as well as the handshaking with an empty buffer. Terribly poor text!

In AN394, the User Guide for FT260, these modes are indeed configured distincgly in 4.4.5, Set UART Mode. They obviously need to select one mechanism for flow control. The documentation is poor in not specifying (at least there) that the unused pins get GPIO function, except for mode 0, OFF. If GPIO is otherwise available, one wonders what the difference is between mode 0 and 4. It is quite possible that DSR and DTR are used in their traditional function ("the line is open" or "we are connected") but the documentation is... poor.

I think what @Rio6 is asking for is a driver-local variant on mode 0, where not GPIO controls these pins but the ioctl() interface. This sounds like supporting a hack that was created without observing general RS-232 behaviour (no judgement, just an observation). But it also sounds like generally supporting these pins from software, which is generally useful.

What seems to be needed to support this is

  1. A choice whether software-driven control of RTS/CTS and/or DTR/DSR should be supported in the FT260 driver (it may be more appropriate to alter the esptool software to use GPIO pins for reset)
  2. How to toggle between UART modes, and what mode to reserve for ESP32
  3. Implementation of the ioctl() interface in the indicated situation

I hope this is helpful, it's my RS-232-aware thank-you for the I2C driver :-)

Rio6 commented 4 weeks ago

Where did you find this? The datasheet starts off in 5.3.3 to indicate it has distinct modes, but none for both RTS/CTS and DTR/DSR, and GPIO is en entirely separate mode. These modes are pretty much what I meant with the modprobe module argument.

That's my interpretation from section 5.3.3. I agree with you that their text is not very well documented. The datasheet says

Thus, it should be set inactive by the FT260 when both the UART receive register and receive holding register are full.

Also, there's HID commands that sets the XON/XOFF characters. I think it is reasonable to say the chip handles the flow control by itself.

There is a chance that setting the GPIO without changing the device mode will set the lines anyways, until the next transfer resets it. I can test to see what the actual behavior is (although won't be anytime soon).

As a side note, the fact that there's a standard kernel API for setting the flow control bit programically probably means that there's at least some chips that supports this kind of usage.

In any case, I agree that what esptool is doing is a hack. If there's an easy way to control the gpio through thr serial device handle somehow, getting esptool to change shouldn't be that hard.

vanrein commented 4 weeks ago

There is a chance that setting the GPIO without changing the device mode will set the lines anyways, until the next transfer resets it. I can test to see what the actual behavior is (although won't be anytime soon).

I asked FTDI to update the datasheet. This is their job. No idea if they will, though.

When they reply, I will send an update here.

As a side note, the fact that there's a standard kernel API for setting the flow control bit programically probably means that there's at least some chips that supports this kind of usage.

Yes, that's fair. I actually fixed the message to say that too after I had posted it.

In any case, I agree that what esptool is doing is a hack. If there's an easy way to control the gpio through thr serial device handle somehow, getting esptool to change shouldn't be that hard.

We'll leave it to Michael. It hopefully helps him that we've had a little exchange.

MichaelZaidman commented 4 weeks ago

@vanrein, @Rio6 Thank you for your interest in the driver and for the serious and productive discussion. I came to the same conclusions a couple of weeks ago after I wrote, "Your query motivated me to look into it again." I believe adding such support is feasible, but since it serves a narrow niche and is somewhat of a hack, it may be challenging to get it upstream. I will look into it further when I have some free time, but that won't be soon.

vanrein commented 3 weeks ago

FTDI kindly sent me this table to my query. I don't know where they got it from, but this is missing in the datasheets we've seen so I'm sharing it here. image003 Saves us from testing and hoping the results can be reproduced :-)

Oh, and they added "We will add this description to the AN_394 User Guide for FT260." :+1:

MichaelZaidman commented 3 weeks ago

Nice summary! Though, this information can be found in the AN_394_User_Guide_for_FT260 and DS_FT260 (see the 3.3 Pin Description and GPIOs sections)

It is also implemented in the GPIO part of the driver code. Search for FT260_GPIO_UART_MODE.

image