Bug #7563
open"Could not configure port" on Baofeng UV-5R+
0%
Description
Linux can see the cable:
esr@snark:~$ dmesg | grep tty
[ 0.000000] printk: console [tty0] enabled
[ 23.449994] usb 5-2: FTDI USB Serial Device converter now attached to ttyUSB0
Traceback:
ERROR: --- Exception Dialog: Could not configure port: (5, 'Input/output error') ---
ERROR: Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/chirp/ui/mainapp.py", line 731, in do_download
timeout=0.25)
File "/usr/lib/python2.7/dist-packages/serial/serialutil.py", line 240, in init
self.open()
File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 272, in open
self._reconfigure_port(force_update=True)
File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 326, in _reconfigure_port
raise SerialException("Could not configure port: {}".format(msg))
SerialException: Could not configure port: (5, 'Input/output error')
The correct USB device and type was selected.
It's not a permissions problem - I saw that error the first time around and added myself to dialout.
Persists with thumb pressure on the connector, so does not appear to be a connection glitch.
Updated by Dan Smith almost 5 years ago
- Status changed from New to Feedback
AFAIK, this means that python-serial was unable to effectively stty the serial device to change parameters. I've not seen this on FTDI devices (which generally are very well-behaved) but it's more common on some of the cheesier ones that are not. For the latter, it always boils down to either a bad device, or something related to the USB serial module.
As you can see from the stack trace, everything but us calling open on the serial class is in the python-serial code, so I'm pretty sure this isn't something chirp can fix.
Maybe try stty'ing /dev/ttyUSB0 with some common settings to see if that works or gives a similar error?
Updated by Eric Raymond almost 5 years ago
I mailed you a freply, but just in case...
Dan Smith wrote:
AFAIK, this means that python-serial was unable to effectively stty the serial device to change parameters.
Maybe try stty'ing /dev/ttyUSB0 with some common settings to see if that works or gives a similar error?
I was able to change the line speed with stty to 4800 and then back again without visible rrtror/
What possibilities does this leave open?
When you say "bad unit" do you mean individually defective, or thast there is a general problem with this make and model?
Updated by Dan Smith almost 5 years ago
I was able to change the line speed with stty to 4800 and then back again without visible rrtror/
Okay, that's interesting. I'm not sure which attribute python-serial is reconfiguring at the time, but you've got a path and line number from the trace, if you want to have a peek.
Looking on my system near L326, you might be hitting this:
except termios.error as msg: # if a port is nonexistent but has a /dev file, it'll fail here
which is actually an exception raised when that code is trying to read the current set of settings to decide what settings to change. The comment indicates that a device file existing but not being read/configurable is something the author has seen before.
What possibilities does this leave open?
When you say "bad unit" do you mean individually defective, or thast there is a general problem with this make and model?
I mean both. I've seen some USB-serial devices that are integrated into devices and refuse to go to baud rates other than what they're locked to for that specific device. They raise similar errors which confuses generic software that expects to be able to probe baud rates by trying several. Also, the market is flooded with illegal clones of Prolific and FTDI USB-Serial devices which often don't behave the same, and for which both manufacturers have altered their Windows drivers to reject (or brick, in the case of FTDI). These are very common on inexpensive cables for the cheap Chinese radios, even when supplied by the manufacturer.
It's definitely weird (to me) that stty can read/apply at least baudrate settings, but python-serial is failing to even read them (assuming I guessed your line of code properly). If it's failing to write them, that makes a little more sense as it applies them in a single batch, where I think stty specifically only tweaks the setting(s) you specify on the command line per invocation, and there are lots that python-serial supports.
I'll also say that this is not something I see a lot on Linux. It's fairly common on Windows because the drivers provided by the manufacturers try to reject clones. On MacOS the drivers are just terrible quality in general. For the most part, Linux will play with anyone :)
Updated by Eric Raymond almost 5 years ago
Dan Smith wrote:
I'll also say that this is not something I see a lot on Linux. It's fairly common on Windows because the drivers provided by the manufacturers try to reject clones. On MacOS the drivers are just terrible quality in general. For the most part, Linux will play with anyone :)
I know. I'm the author of GPSD. https://gpsd.gitlab.io/gpsd/
As such, I'm one of the very few people likely to have had as much experience with flaky USB devices and drivers as you - it's a besetting problem with cheap GPS USB pucks. The next thing I'm going to do is plug a USB GPS in and see if, as I expect, /dev/ttyUSB0 is accessible and I can read data off it.
OK, I plugged in a random USB GPS and ran "gpsmon /dev/ttyUSB0"/ Took about 30 seconds for the autobaud loop in my code to sync up, but I'm seeing the expected NMEA sentences scrolling by.
So the ttyUSB0 port and device does exist and software on my system can see it. (The only reason I was in doubt about this is that I got a new machine recently.) All looks correct from the system end - I think we're left with a problem either in CHIRP or the radio firmware.
How do you handle baud-rate sync? Would your code cope gracefully if Baofeng changed the default port speed on you? I ask because in GPS-land I've seen problems a bit like this arising from a simple baud mismatch.
Updated by Dan Smith almost 5 years ago
OK, I plugged in a random USB GPS and ran "gpsmon /dev/ttyUSB0"/ Took about 30 seconds for the autobaud loop in my code to sync up, but I'm seeing the expected NMEA sentences scrolling by.
Right, but this is a different USB device from the one in your cable, correct? I'm assuming you're using a cable for your radio that is USB on one end and the radio connector on the other, right? If you're using a USB-to-DE9 and regular serial cables for the radio and GPS, then this is a good data point. If not, I don't think it tells us much, other than some USB serial devices work on your system.
So the ttyUSB0 port and device does exist and software on my system can see it. (The only reason I was in doubt about this is that I got a new machine recently.)
When you unplug the device, you'll see that ttyUSB0 goes away, and then comes back when you plug something else in, and that device node is just referencing a dynamic device on the kernel side that the usb-serial module (ftdi, pl2303, etc) is creating when they discover the device is connected.
All looks correct from the system end - I think we're left with a problem either in CHIRP or the radio firmware.
Unless the USB device is actually in the radio, the radio's firmware can't really do this. If you have a USB cable with a fat USB-A shell and a two-pronged right-angle connector on the other end, the fat shell has the FTDI USB device inside, which speaks USB to the computer and RS232 (or TTL serial) to the radio. That means that the radio really only sees serial data, and there's no high-level signaling of error conditions or anything like that. The USB device is just a translator for the strings we're sending.
What happens if you try to get gpsd to talk to the radio? Is it able to open, configure, and read from that device? It won't ever see NMEA sentences of course, but it'll try and might tickle the same behavior. You could also just try minicom or something like that.
How do you handle baud-rate sync? Would your code cope gracefully if Baofeng changed the default port speed on you? I ask because in GPS-land I've seen problems a bit like this arising from a simple baud mismatch.
There is no need to probe for the baud rate on most radios (Kenwoods being the most common exception) as they're fixed in the radio and each driver in CHIRP specifies the rate needed per model. If you got a radio that wanted a different one, chirp would be sending commands at, (say) 9600 which the radio at (say) 19200 would see as garbage. Similarly, any replies would be seen by CHIRP as garbage because of the baud rate mismatch. So, no, CHIRP would not cope with that for a model we don't know to have multiple baud rate possibilities, but the failure you would see would be in actual CHIRP code where it fails to receive a suitable response from the radio. What you're seeing is python-serial trying to call set tcgetattr() or tcsetattr() on the serial device and getting an error result. These are system calls (eventually), and any error (especially EIO) that comes from calling that is generated either by the base serial line driver or the usb-serial emulation modules that sit above it.
Updated by Eric Raymond almost 5 years ago
Dan Smith wrote:
OK, I plugged in a random USB GPS and ran "gpsmon /dev/ttyUSB0"/ Took about 30 seconds for the autobaud loop in my code to sync up, but I'm seeing the expected NMEA sentences scrolling by.
Right, but this is a different USB device from the one in your cable, correct? I'm assuming you're using a cable for your radio that is USB on one end and the radio connector on the other, right? If you're using a USB-to-DE9 and regular serial cables for the radio and GPS, then this is a good data point. If not, I don't think it tells us much, other than some USB serial devices work on your system.
True. This was in tge nature of a smoke tesrt on USB-to-serial devices.
When you unplug the device, you'll see that ttyUSB0 goes away, and then comes back when you plug something else in, and that device node is just referencing a dynamic device on the kernel side that the usb-serial module (ftdi, pl2303, etc) is creating when they discover the device is connected.
Am aware of this.
Unless the USB device is actually in the radio, the radio's firmware can't really do this. If you have a USB cable with a fat USB-A shell and a two-pronged right-angle connector on the other end, the fat shell has the FTDI USB device inside, which speaks USB to the computer and RS232 (or TTL serial) to the radio. That means that the radio really only sees serial data, and there's no high-level signaling of error conditions or anything like that. The USB device is just a translator for the strings we're sending.
OK, I wasn't clear on what the two-wire link was doing. This makes it seem likely that the problem is somewhere around the FTDI chip. On GPSes I never found those to be as trouble-free as the PL2303s, so this would not astonish me, especially if it's some FTDI clone made out of Chinesium.
What happens if you try to get gpsd to talk to the radio? Is it able to open, configure, and read from that device? It won't ever see NMEA sentences of course, but it'll try and might tickle the same behavior. You could also just try minicom or something like that.
I wasn't using gpsd itself, but rather a monitor app that exists specifically to capture raw trafffic from the GPS for diagnostic purposes. Manual page here:
http://manpages.ubuntu.com/manpages/precise/man1/gpsmon.1.html
Now trying it on the Baofeng....all I get is infinite hang,
Nothing from minicom either - I set it for 9600 8N1 on /dev/ttyUSBS0, Status bar thinks it's offline.
How do you handle baud-rate sync? Would your code cope gracefully if Baofeng changed the default port speed on you? I ask because in GPS-land I've seen problems a bit like this arising from a simple baud mismatch.
There is no need to probe for the baud rate on most radios (Kenwoods being the most common exception) as they're fixed in the radio and each driver in CHIRP specifies the rate needed per model. If you got a radio that wanted a different one, chirp would be sending commands at, (say) 9600 which the radio at (say) 19200 would see as garbage. Similarly, any replies would be seen by CHIRP as garbage because of the baud rate mismatch. So, no, CHIRP would not cope with that for a model we don't know to have multiple baud rate possibilities, but the failure you would see would be in actual CHIRP code where it fails to receive a suitable response from the radio. What you're seeing is python-serial trying to call set tcgetattr() or tcsetattr() on the serial device and getting an error result. These are system calls (eventually), and any error (especially EIO) that comes from calling that is generated either by the base serial line driver or the usb-serial emulation modules that sit above it.
OK, that makes since.
Looks like the FTDI chip doesn't want to talk.
Do you have any other suggestions?
Updated by Dan Smith almost 5 years ago
Well, to be honest, I would have expected minicom or gpsmon to complain similarly to how python-serial is because the tcgetatr() (or tcsetattr()) is returning an error. So, if you want to dig further, I can point you at what chirp is asking of python-serial in the way of configuring the serial line and you can go from there.
Also, FYI, minicom will report "offline" until or unless the serial device asserts DSR, or you turn off the setting that looks at that (hardware flow off, software on might do that, but it does other things too). Reporting "offline" won't prevent it from trying to open the serial line or displaying data if it shows up. The radio isn't going to do anything unless it's asked, so no data is expected as well.
So as far as suggestions, I can try to help guide you towards replicating what we're asking of python-serial to further debug what specific thing is triggering the failure (if it's even one thing). Otherwise my suggestion would be (gasp) to try it on a windows machine to see if it seems to behave over there (I know, I know).
As much as it sucks, I try to choose DE9 serial cables for my radios and use a known-good USB-to-serial adapter as the interface just because I can swap out the "complex driver-specific black box" part of it if needed for debugging or future proofness.
Here's the only line of chirp code from your traceback:
https://chirp.danplanet.com/projects/chirp/repository/entry/chirp/ui/mainapp.py#L728
Which is something you can drop into a python REPL shell and should be able to reproduce and dig further. BAUD_RATE for yours is 9600 and HARDWARE_FLOW should be False (almost none of the radios even have the pins for it). The port arg is just the string of the serial device you're choosing (i.e. "/dev/ttyUSB0").
Updated by Eric Raymond almost 5 years ago
Sigh. It's not practical for me to do this before I'm going on the road to to deploy the radio - next Monday at the Lobby Day demonstration in VA. (I'll be eyes on the ground watching for medical emergencies or attempts to incite violence.)
Guess I'll have to program it by hand.
Updated by R D about 2 years ago
I'm posting here because #7891 was closed.
I believe this is again related to 1a86:7523 using Linux's ch341 (as in #7891)
I found other threads about problems connecting to this particular device using usb-serial:
- https://lore.kernel.org/all/YlP1poVgy0bAP3MN@hovoldconsulting.com/T/
- https://unix.stackexchange.com/questions/442743/problems-connecting-via-serial-to-usb-port-to-pcengines-apu-board-using-hl-340
- https://www.illumos.org/issues/12756
Attempts:
Enabling debugging
$ echo module ch341 +p |sudo tee /sys/kernel/debug/dynamic_debug/control
Then:
$ sudo stty -F /dev/ttyUSB0 9600 raw
I see:
usb 1-1: ch341_control_out - (9a,1312,b282) usb 1-1: ch341_control_out - (9a,2518,00c3) usb 1-1: ch341_control_out - (a4,ffff,0000) ch341-uart ttyUSB0: ch341_open - submitting interrupt urb usb 1-1: ch341_control_in - (95,0706,0000,2) usb 1-1: ch341_control_out - (a4,ff9f,0000) usb 1-1: ch341_control_out - (a4,ffff,0000) usb 1-1: ch341_read_int_callback - urb shutting down: -2
Still, nothing else and chirpw does not show anything at launch (it's not complaining either but I believe it's ignoring my /dev/ttyUSB0)
Someone managed to overcome this in https://unix.stackexchange.com/a/361199
stty -F /dev/ttyUSB0 9600 raw
but doesn't seem to work in my case.
Is there anything you would advise to further debug/invetigate and hypothetically communicate with such an adapter?
Updated by R D about 2 years ago
Adding that someone at https://forums.raspberrypi.com/viewtopic.php?t=149999 got it to work using that upstream FOSS driver at https://www.wch.cn/download/CH341SER_LINUX_ZIP.html ... from 2018 which obviously, won't compile against a 5.x kernel.
By chance, someone update this driver (https://github.com/juliagoda/CH341SER).
I believe it should work now (but I'm not sure how to confirm that the low-level serial-comm' works).
Still, chirpw (py3 branch @41a188) shows mostly greyed menu items and an empty window. When clicking "Download from Radio", it throws:
File "chirp/chirp/ui/clone.py", line 158, in __init__ self.set_alternative_button_order([gtk.RESPONSE_OK, AttributeError: 'CloneSettingsDialog' object has no attribute 'set_alternative_button_order'. Did you mean: 'set_alternative_button_order_from_array'?
Now looking for some hints to move further...