Re: Unwanted auto-assertion of DTR & RTS on serial port open

From: Warner Losh <imp_at_bsdimp.com>
Date: Thu, 26 May 2022 13:57:24 UTC
On Tue, May 24, 2022 at 4:47 PM Mychaela Falconia <
mychaela.falconia@gmail.com> wrote:

> Hi Warner,
>
> Thank you for the very useful reply directly addressing the key points!
>
> > The .init device node exists to open the device to do initialization
> without
> > line wiggle.
> > [...]
> > So absent direct observations to the contrary, I'd say that opening
> > the .init device will do what's desired here.
>
> Sounds like good news - but I am also going to test it myself on
> actual hardware, i.e., I'll go through the learning curve of
> installing FreeBSD on a spare laptop.  For the test setup, my current
> plan is to connect a USB cable from the FreeBSD machine to an FT2232D
> breakout board, see if ttyU* and cuaU* devices appear as I would
> expect, then connect an oscilloscope probe to DTR/RTS (first one, then
> the other), set the scope to trigger on a falling edge (set the
> trigger level to 2.0 V, the most common Vih spec for 3.3V logic) and
> verify that no unwanted falls happen on either control signal.  Does
> anyone see any problems with this plan?
>

That should work.


> Also if someone is opening a non-modem (no dial-in or dial-out
> concepts) serial port for the purpose of talking to non-modem gear
> (think industrial instrumentation, whatever), would it be more
> "proper" to use ttyXX or cuaXX?  On Linux there is only one ttyUSBx
> for each port, but with FreeBSD there is a choice - hence I'd like to
> know which one is more philosophically proper.
>

In the BSD world, ttyXX is for the data device. cuaXX is the 'Callout Unit'
which
selects a different 'ready' protocol appropriate for outgoing calls and
used to
dial out to another system.


> > despite the fact that the device uses conventions that are
> > not RS-232 standard conventions
>
> But what's the alternative?  On my target GSM device I have one full
> 8-wire UART channel, another separate UART channel that is only TxD &
> RxD, and two non-serial control lines which I would like to be able to
> trigger from the connected host computer.  My current solution covers
> all of these interfaces with a single FT2232D chip.  Someone could say
> that I should replace this FT2232D with FT4232H (4 UART channels
> instead of 2, and they don't make a 4-channel version in non-H), and
> use each of the 2 extra UART channels just for its DTR (or RTS)
> output, so that its control output can be independently wiggled by
> opening that separate "serial" port.  But this solution would have
> negatives for both power efficiency and developer-user convenience:
>

* Power: FT2232D eats about 30 mA, 'H' chips (FT2232H and FT4232H) eat
> about 70 mA; both would be coming from the same USB VBUS.
>
> * Convenience: it just so happens that the second UART channel on my
> GSM device (the one that's data leads only) is the debug/development
> interface, hence it naturally groups together with the two boot control
> signals I have overlapped onto its otherwise unused DTR & RTS.  My
> command line tools already make use of this grouping, operating on a
> single /dev/ttyUSBx port for both UART communication and boot control.
> Having two more /dev/ttyUSBx devices that aren't UART channels at all,
> but exist only so that opening one or the other will cause one or the
> other boot control signal to be asserted, would be no less ugly than
> my current "crime" of violating RS-232 canons.
>

You are using the device in a non-standard way, so you have to flag
that non-standard use, or you need to jump through crazy hoops like
you are saying.

There's still a lot of gear in the field that uses more than three wires
to talk to actual hardware devices for industrial control. Changing the
default would break these users when they upgrade. Adding the flag is
trivial for any setup.


> > (though most of them are somewhat
> > dated, I'll admit, given the near total lack of modems today).
>
> But my GSM device is in fact a modem - or rather a cellphone handset
> with built-in modem functionality.  Those two separate UART channels I
> just referred to?  The first 8-wire full UART presents the good old AT
> command interface, you could dial out CSD calls through it, whereas
> the second UART channel (the one with repurposed DTR & RTS) is the
> special one that is totally un-modem-like.  So there you have it: a
> very traditional modem serial channel *and* and a very un-modem-like
> UART on the two channels behind the same USB device...
>

So you have a UART that you are using as a GPIO port, which you'll
need to flag. There's no real standard for that, hence the need for
special support for each OS.


> > It's hard to
> > support both legacy devices and innovative devices without breaking
> > somebody by default, and there's not been a ground-swell to change
> > the defaults as of yet so it's rather favored the archaic traditions out
> > of inertia.
>
> Oh, I am *not* asking you or Linux maintainers or anyone else to
> change any defaults!  The default is pretty much unchangeable at this
> point and I am totally fine with this fact of life - instead I was
> merely asking to make it possible to have a special override for
> custom devices like mine.  You as in FreeBSD have finally got it right,
> it seems - my deepest gratitude!  But Linux kernel maintainers are
> still refusing to budge, hence I am gearing up for another round of
> battle with them.
>

Given past discussions, and the legacy devices that must be support,
I suspect a great deal of frustration in your future.


> Needless to say, going to battle against Linux kernel maintainers is
> no trivial matter, hence I need to gather all of my ammo first.  I
> will need to personally test and verify that the feature works
> correctly in FreeBSD, and assuming that it does work, then present
> this evidence to Linux stonewallers.
>
> Also while I have your attention: what's the procedure for adding
> support for non-standard USB VID:PID device IDs to the uftdi driver in
> FreeBSD?  I got a block of USB IDs officially allocated to me by FTDI,
> and I am programming the FT2232D EEPROM on my boards with a custom USB
> ID specifically to prevent special-feature-lacking drivers (those that
> lack the ability to suppress auto-assertion of DTR & RTs on open) from
> binding to it.  Because Linux does not have a feature like CNO_RTSDTR
> in FreeBSD, and more fundamentally, it lacks the .init devices that
> constitute a prerequisite for this feature addition, my idea has been
> to use the custom USB device ID as the controlling mechanism for the
> special feature.  The ftdi_sio driver in Linux has a table of supported
> device IDs (a long and always growing table, naturally), and this table
> allows associating special "quirks" with particular device IDs.  Hence
> using such a device quirk seemed most natural to me, and this solution
> is the one I use personally on my own system, with my own local patch.
>

We have similar quirks in FreeBSD. However,  there's some layering issues
that might make it hard to implement that quirk. So we'd need to see the
proposed changes to see how acceptable things would be.


> When I start shipping FC Venus development boards and later complete
> end user phones with this circuit in them, they will ship with the
> USB device ID set to 0403:7152 instead of FTDI-generic 0403:6010.  For
> as long as those obstinent Linux gatekeepers^Wmaintainers keep refusing
> my patch adding quirked support for this new USB ID, it would be better
> for unpatched Linux to not recognize my device at all, than "support"
> it in a broken manner with any open of the second UART driving a hard
> reset.
>
> But for FreeBSD, given that your OS is better in this regard and
> already has the necessary fundamental feature, what should we do here?
> At the minimum, we would need to teach FreeBSD uftdi driver that
> 0403:7152 is a USB device it should bind to, and that it's actually an
> FT2232D, unless the driver already figures out the latter part on its
> own like the Linux driver does.  But would it also be possible to
> teach the uftdi driver in FreeBSD about the special quirk?  In other
> words, would it be possible to teach the uftdi driver that if it sees
> USB ID 0403:7152, then for Channel B (but not for Channel A!) it
> should automatically set the CNO_RTSDTR flag - or is it too much to
> ask for?
>

I'd have to see how it was implemented... There's a number of different ways
this could be done. Using the second serial channel as a GPIO device might
also be an option that's less invasive and ultimately easier to implement.

Warner


> CeDeROM <cederom@tlen.pl> wrote:
>
> > some devices use those lines to power
> > (i.e. Metex Multimeters) and it would be nice to set them to constant
> > 0 (that results in high voltage output on the pins right?) :-)
>
> The mapping is:
>
> logically negated  = RS-232 -12V = LVCMOS high
> logically asserted = RS-232 +12V = LVCMOS low
>
> The LVCMOS column refers to the interface between the UART chip and
> the RS-232 level shifter, or between the USB-serial chip and the end
> application as more common nowadays.
>
> > I have question: if the option is CNO_RTSDTR then application switch
> > could be also -nortsdtr not -rtsdtr ? With -rtsdtr switch I would
> > think this option is enabled. With -nortsdtr I am sure this option is
> > disabled :-)
>
> Given the unavoidable problem of negatives and the desire to avoid
> making it even worse with double negatives, the folks who implemented
> this recent feature addition in FreeBSD settled for a somewhat
> inverted sense between the underlying termios flag and stty front end:
>
> stty rtsdtr means CNO_RTSDTR flag is NOT set (default)
> stty -rtsdtr means CNO_RTSDTR flag is SET (opposite of default)
>
> M~
>