debrouxl / tilibs

TILP (formerly GtkTiLink) can transfer data between Texas Instruments graphing calculators and a computer. It works with all link cables (parallel, serial, Black/Gray/Silver/Direct Link) and it supports the TI-Z80 series (73..86), the TI-eZ80 series (83PCE, 84+CE), the TI-68k series (89, 92, 92+, V200, 89T) and the Nspire series (Nspire Clickpad / Touchpad / CX, both CAS and non-CAS)
http://lpg.ticalc.org/prj_tilp
63 stars 23 forks source link

Add support for GrayLink over USB to serial #53

Open jherning opened 3 years ago

jherning commented 3 years ago

I have several offical TI graylink cables that work fine in TILP 1.18 on Linux using cheap serial-to-usb adapters, but since /dev/ttysX is hardcoded I have to simlink to /dev/ttyUSBX. I know the blacklink/$4 cables probably won't work, but can't we have support for a custom serial port device name in Linux/etc.?

p.s. I was also thinking of making the $4 serial cable to see what would happen...

debrouxl commented 3 years ago

Normally, we already do have such support for the GrayLink, thanks to ticables_cable_set_device() in libticables/trunk/src/link_xxx.cc which delegates to gry_set_device() in libticables/trunk/src/linux/link_gry.cc when the GrayLink is selected. This set_device operation needs to be called between the prepare and the open operations. However, it's not exposed through TILP.

Most USB/DB9 and USB/DB25 adapters are known to be unable to provide proper operation for a BlackLink/$4 cable or a $5 cable, because they simply do not provide direct read and write access to the wire state (bit banging), which the protocol used by TI requires. That said, maybe some of your adapters can do that and we can add them to a compatibility list of sorts. My adapter supposedly does, but I have no working BlackLink or known working $4 cable.

jherning commented 3 years ago

Thank you for the fast response, Lionel! I'm not an experienced contributor and wasn't sure if this was the right place to post -- I guess this is a TILP feature request then?

If anyone's interested, I will put together a $4 serial link and see what happens with the converter -- it might take me a little while to get the parts. From what I can find online some people have luck using cheap pl2303 (or fake pl2303) converters to program microcontrollers via bit-banging, so blacklink cables might actually work. Perhaps drivers have improved.

jherning commented 3 years ago

I was able to acquire a BlackLink cable in addition to my GrayLink. I then tested both setups with TILP 1.18 on Linux and three different USB to serial cables with symlink from /dev/ttyS3. I also wrote a Python script to bit-bang the BlackLink properly using /dev/ttyUSBx and take a screenshot. Here are the results using a HW2 TI-89:

USB-to-Serial identifying in Linux as pl2303:

USB-to-Serial identifying in Linux as ch341-uart:

USB-to-Serial identifying in Linux as FTDI ft232rl:

Now, whether or not these adapters work is also probably influenced by driver support and the actual hardware design, but I think the FTDI adapter can probably support ALL known serial links (Gray, Black, $4).

debrouxl commented 3 years ago

I'm getting back to working a bit on libti*. Thanks for your tests :)

Could you post the full terminal output of TILP for your FTDI ft232rl - TILP/symlink tests ? I'd like to determine where the failure occurs. At least, libticables correctly uses stat() to cause symlink dereference instead of lstat(), and likewise, access() dereferences symlinks. Thanks in advance.

jherning commented 3 years ago

Below is what I tried that works with the pl2303 but not the ft232r. I might not be doing the symlinks right, but it really does work with the pl2303 using the same procedure. I can even just swap adapters after this and it will work to just fire up TiLP.

:~$ sudo chmod 666 /dev/ttyUSB0 :~$ sudo rm /dev/ttyS3 :~$ sudo ln -s /dev/ttyUSB0 /dev/ttyS3 :~$ sudo chmod 666 /dev/ttyS3 :~$ tilp --calc=v200 --cable=GrayLink --port=4 TiLP2 - Version 1.18, (C) 1999-2008 Romain Lievin THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY PLEASE READ THE DOCUMENTATION FOR DETAILS tilp-INFO: 07:08:58.278: setlocale: en_US.UTF-8 tilp-INFO: 07:08:58.278: bindtextdomain: /usr/share/locale/ tilp-INFO: 07:08:58.278: textdomain: tilp2 ticables-INFO: 07:08:58.279: ticables library version 1.3.5 ticables-INFO: 07:08:58.279: setlocale: en_US.UTF-8 ticables-INFO: 07:08:58.279: bindtextdomain: /usr/share/locale ticables-INFO: 07:08:58.279: textdomain: tilp2 ticables-INFO: 07:08:58.279: kernel: 5.4.0-77-generic tifiles-INFO: 07:08:58.283: tifiles library version 1.1.7 tifiles-INFO: 07:08:58.283: setlocale: en_US.UTF-8 tifiles-INFO: 07:08:58.283: bindtextdomain: /usr/share/locale tifiles-INFO: 07:08:58.283: textdomain: tilp2 ticalcs-INFO: 07:08:58.283: ticalcs library version 1.1.9 ticalcs-INFO: 07:08:58.283: setlocale: en_US.UTF-8 ticalcs-INFO: 07:08:58.283: bindtextdomain: /usr/share/locale ticalcs-INFO: 07:08:58.283: textdomain: tilp2 ticables-INFO: 07:08:58.283: Check for libusb support: ticables-INFO: 07:08:58.283: usb support: available. ticables-INFO: 07:08:58.283: Check for libusb usability: ticables-INFO: 07:08:58.283: usb filesystem (/dev/bus/usb/): mounted tilp-INFO: 07:08:58.283: Opening cable GrayLink on port #4 to communicate with calculator V200 ticables-INFO: 07:08:58.283: Check for tty support: ticables-INFO: 07:08:58.283: tty support: available. ticables-INFO: 07:08:58.283: Check for tty usability: ticables-INFO: 07:08:58.283: node /dev/ttyS3: exists ticables-INFO: 07:08:58.283: node /dev/ttyS3: accessible ticables-INFO: 07:08:58.283: is useable: no tilp-INFO: 07:08:58.283: Msg: unable to use serial (/dev/ttySx) device. Cause: the /dev/ttySx node doesn't exist or you don't have required permissions. How to grant permission to devices to the user depends on the distribution, it may involve adding the user to a group such as 'dialout' or 'uucp'. This can be done by editing /etc/group and add the username after the ':'. Example: dialout:x:20:romain

tilp-INFO: 07:09:00.284: Msg: attempting to use a cable which has not been open before. Cause: Internal error.

(tilp:4915): GLib-GIO-DEBUG: 07:09:00.398: _g_io_module_get_default: Found default implementation gvfs (GDaemonVfs) for ‘gio-vfs’

On Sat, Jul 10, 2021 at 4:36 AM Lionel Debroux @.***> wrote:

I'm getting back to working a bit on libti*. Thanks for your tests :)

Could you post the full terminal output of TILP for your FTDI ft232rl - TILP/symlink tests ? I'd like to determine where the failure occurs. At least, libticables correctly uses stat() to cause symlink dereference instead of lstat(), and likewise, access() dereferences symlinks. Thanks in advance.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/debrouxl/tilibs/issues/53#issuecomment-877597369, or unsubscribe https://github.com/notifications/unsubscribe-auth/AT57AN25UGOCIQDQ4MMDODDTXABAXANCNFSM44BXDGKQ .

debrouxl commented 3 years ago

Interesting. In https://github.com/debrouxl/tilibs/blob/master/libticables/trunk/src/linux/detect.cc , this means that the call to ioctl() succeeded, but that the serial port type is unknown or maximal.

I'm tempted to turn the check on the value of the ioctl() call, and the check on the serial port type, into non-fatal errors, and see what happens.

debrouxl commented 3 years ago

I've just done that on the experimental2 branch: https://github.com/debrouxl/tilibs/blob/experimental2/libticables/trunk/src/linux/detect.cc .

jherning commented 3 years ago

I recompiled using the install_tilp.sh script, checking out experimental2. While the TILP compile failed (probably my fault), tilibs compiled and installed first, so I was able to test this:

debrouxl commented 3 years ago

Great, thanks for your tests :) I suppose I could fast-track the relevant commit to the master branch, unless it creates too many rebase conflicts in the PO files.

Don't worry about the speed reported by TILP, or the fact that the build of tilp_and_gfm from the experimental2 branch failed. I simply need to add support for using separate branches for tilibs and tilp_and_gfm to the install script.

BTW: if you're using libti source code as a source of information for the Python code you mentioned and you distribute that Python code, then AFAICT, you need to use the same license as libti, namely GPLv2+. This is the second main reason why I do not maintain, let alone expand, the linkguide: that kind of perpetually incomplete text documentation works around preserving the important "contributing back to the common pool of code" aspect of open source. The weak open source licenses such as BSD/MIT/X11 do not enforce that reciprocity. Only the source code of libti* contains the information another implementation needs to go beyond a certain level of accuracy or completeness of the file formats, protocols, and quirks.

jherning commented 3 years ago

It's up to you on the priority -- I'm not sure how many others out there are like me, trying to use the old cables.

I did just release the evolved Python code under MIT license on my github. It's not a TILP derivative, though, as my only experience with the source is trying to build this experimental version through the script. I had been away from doing much programming, so I decided a Python linking program would be a fun challenge. I naively thought the LG would be "everything I needed to know," but did run into a number of errors. It sounds like I used a similar approach, mentioning them in the source code (although I did try to maintain a separate LG errata file). My focus is just the 68k calcs, and I was able to get things mostly working -- I think. File format testing was actually done against TI Graph Link running through WINE, although I should probably check TILP compatibility now that I have a working version! Check it out if you like, and let me know what you think!

I did discover some things I thought were interesting that you probably already know about: e.g. the later 68k calcs respond as if they're a 92 when you ping them as such (I use this to autodetect calculator type), and the Gray cable seems to send an extra byte to the computer when it times out. If you're interested I could polish up my errata and share either publicly or privately with you.

jherning commented 3 years ago

On your patch: If the symlink does not exist, I get a segmentation fault. This might now happen to a user who has set the wrong link settings:

tilp-INFO: 20:15:13.704: Opening cable GrayLink on port #1 to communicate with calculator TI89

(tilp:28755): ticables-CRITICAL **: 20:15:13.704: ticables_get_model(NULL)

(tilp:28755): ticables-CRITICAL **: 20:15:13.704: ticables_get_port(NULL) ticables-INFO: 20:15:13.704: Check for tty support: ticables-INFO: 20:15:13.704: tty support: available. ticables-INFO: 20:15:13.704: Check for tty usability: ticables-INFO: 20:15:13.705: node /dev/ttyS0: exists ticables-INFO: 20:15:13.705: node /dev/ttyS0: accessible ticables-INFO: 20:15:13.705: is usable: yes

(tilp:28755): ticables-WARNING **: 20:15:13.705: Serial port has unknown type 0

(tilp:28755): ticables-WARNING **: 20:15:13.705: NOTE: proceeding nevertheless, in an attempt to help usage of libticables with some USB/RS232 adapters, though most do not work at all for the purposes of TI's protocol ticalcs-INFO: 20:15:13.705: Cable GrayLink port #1 attached Segmentation fault (core dumped)

debrouxl commented 3 years ago

Oops. Could you start TILP through gdb and obtain a backtrace ? You're probably familiar with the procedure, but if not: gdb tilp, then run, then bt after the program has crashed, then Ctrl+D to exit. Thanks in advance :)

jherning commented 3 years ago

It's been a while since I've used gdb, but it came back to me! Here is what I'm getting. This is after a reboot, so there are no symlinks and nothing is connected (but /dev/ttyS3 does exist in its usual state):

:~$ gdb tilp GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: http://www.gnu.org/software/gdb/bugs/. Find the GDB manual and other documentation resources online at: http://www.gnu.org/software/gdb/documentation/.

For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from tilp... (gdb) run Starting program: /usr/bin/tilp [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". TiLP2 - Version 1.19, (C) 1999-2008 Romain Lievin THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY PLEASE READ THE DOCUMENTATION FOR DETAILS tilp-INFO: 10:31:32.192: setlocale: en_US.UTF-8 tilp-INFO: 10:31:32.192: bindtextdomain: /usr/share/locale/ tilp-INFO: 10:31:32.192: textdomain: tilp2 ticables-INFO: 10:31:32.192: ticables library version 1.3.6 ticables-INFO: 10:31:32.192: setlocale: en_US.UTF-8 ticables-INFO: 10:31:32.192: bindtextdomain: /usr/share/locale ticables-INFO: 10:31:32.192: textdomain: tilp2 ticables-INFO: 10:31:32.192: kernel: 5.4.0-80-generic [New Thread 0x7ffff3ed3700 (LWP 5885)] tifiles-INFO: 10:31:32.199: tifiles library version 1.1.8 tifiles-INFO: 10:31:32.199: setlocale: en_US.UTF-8 tifiles-INFO: 10:31:32.199: bindtextdomain: /usr/share/locale tifiles-INFO: 10:31:32.199: textdomain: tilp2 ticalcs-INFO: 10:31:32.199: ticalcs library version 1.1.10 ticalcs-INFO: 10:31:32.199: setlocale: en_US.UTF-8 ticalcs-INFO: 10:31:32.199: bindtextdomain: /usr/share/locale ticalcs-INFO: 10:31:32.199: textdomain: tilp2 ticables-INFO: 10:31:32.199: Check for libusb support: ticables-INFO: 10:31:32.199: usb support: available. ticables-INFO: 10:31:32.200: Check for libusb usability: ticables-INFO: 10:31:32.200: usb filesystem (/dev/bus/usb/): mounted tilp-INFO: 10:31:32.200: Opening cable GrayLink on port #4 to communicate with calculator TI89

(tilp:5881): ticables-CRITICAL **: 10:31:32.200: ticables_get_model(NULL)

(tilp:5881): ticables-CRITICAL **: 10:31:32.200: ticables_get_port(NULL) ticables-INFO: 10:31:32.200: Check for tty support: ticables-INFO: 10:31:32.200: tty support: available. ticables-INFO: 10:31:32.200: Check for tty usability: ticables-INFO: 10:31:32.200: node /dev/ttyS3: exists ticables-INFO: 10:31:32.200: node /dev/ttyS3: accessible ticables-INFO: 10:31:32.200: is usable: yes

(tilp:5881): ticables-WARNING **: 10:31:32.200: Serial port has unknown type 0

(tilp:5881): ticables-WARNING **: 10:31:32.200: NOTE: proceeding nevertheless, in an attempt to help usage of libticables with some USB/RS232 adapters, though most do not work at all for the purposes of TI's protocol ticalcs-INFO: 10:31:32.200: Cable GrayLink port #4 attached tilp-INFO: 10:31:34.200: Msg: attempting to use a cable which has not been open before. Cause: Internal error. System: Input/output error (errno = 5)

[New Thread 0x7ffff2cb1700 (LWP 5887)] [New Thread 0x7ffff24b0700 (LWP 5888)] (tilp:5881): GLib-GIO-DEBUG: 10:31:34.355: _g_io_module_get_default: Found default implementation gvfs (GDaemonVfs) for ‘gio-vfs’

Thread 1 "tilp" received signal SIGSEGV, Segmentation fault. 0x00007ffff77ea64d in g_utf8_validate () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 (gdb) bt

0 0x00007ffff77ea64d in g_utf8_validate ()

at /lib/x86_64-linux-gnu/libglib-2.0.so.0

1 0x00007ffff779497e in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0

2 0x00007ffff779581f in g_locale_to_utf8 ()

at /lib/x86_64-linux-gnu/libglib-2.0.so.0

3 0x00005555555668fc in tilp_err (errcode=0) at tilp_error.c:85

4 0x0000555555562804 in main (argc=, argv=)

at main.c:181

(gdb) quit

debrouxl commented 3 years ago

At least, the error is not in libticables. I feared that there could be a side effect from going forward with adapters which don't have the properties liked by the code. Looks like tilp_err passing weird stuff, probably a nullptr error string (variable s) to g_locale_to_utf8 - which probably means that the other functions didn't produce an error string.