Android Subsurface mobile issues with pelagic data cable downloads

Bill Perry bill at billandterrie.com
Tue Sep 11 20:04:06 PDT 2018


Ok,

So I'm reviving this thread as I'm back to trying to investigate what is going on as I really want
to use Subsurface with my Atmos AI.

Here is a brief summary for those not following along.
Subsurface mobile cannot download an Aeris Atmos AI using a Pelagic download cable.
(Subsurface desktop on linux has no issues)
A year ago, I found some coding issues in libdivecomputer that were causing some of the issues
and managed to get it working but not all the time.
There were (and still are) some issues with the low level data cable initialization for this type of data cable
The RTS line is not being handle correctly - it is easily fixed and resolves part of the issue to allow retries of the
initialization to properly work.

The other issue back then was that the serial_ftdi_read() function serial_ftdi.c was broken with respect to timeouts
which meant timeouts could be much MUCH longer than expected - so long that the divecomputer could timeout and turn off.

Fastforward to today and lots has changed, including a change to using "iostream" stuff rather than directly calling the serial code.
I tested the latest Subsurface Mobile code on a Galaxy 4 and a Galaxy S 7.
Downloads work on the S4 - but only once (this is due to the RTS handling issue) until the app is restarted and the cable is pulled.
Downloads fail on the S7.

I created a h/w test jig that I can use to get better visibility what the USB host is doing with the FTDI cable.

First a bit of background reminder.
The Pelagic data cable is not just a FTDI chip with its output signals hooked up to the pins on the dive computer.
There is a PIC processor that sits between the FTDI chip and the dive computer and processes messages from the host
and talks to the dive computer. The host does not directly talk to the dive computer.
There are different versions of this data cable that have different physical pin interfaces to the dive computers
and the PIC internally can have different f/w in it. Some cables run at different baud rates between the FTDI chip and
and the PIC.

The data cable I'm using is an Oceanic part #4.9600 that runs at 9600 baud.
The RTS signal is used to reset the PIC. The libdivecomputer is not handling the RTS signal in a robust way
that allows recovery and restarting from all conditions. This does create some issues - it is easily fixed.

My h/w test jig consists of standard FTDI cable along with an Arduino and a logic analyzer to measure things in real time.
The cable is the "official" FTDI cable directly from FTDI that uses the 6 pin header with RTS & CTS pins.
The cable is hooked up to an Arduino that has been programmed to mimick the PIC microcontroller that is inside the data cable.
This allows seeing the low level signal control and timing.

A bit more background. When talking to the Pelagic data cable, you must first initialized the PIC then you can talk to the PIC
which can query the dive computer. There are some specific timings that need to be honored in order for the
PIC initialization to work properly / reliably. If they are not followed, the data cable will appear to be "deaf".

Here is what I noticed today. When using the real data cable and the Atmos AI dive computer,
the dive computer never enters download mode on the Galaxy S7 but works correctly on the S4.

I hooked up my test jig and one issue became obvious.
After you un-reset the PIC by lowering RTS, you should wait 100ms (that is what the original Aeris s/w did). (libedivecomputer has a 100ms delay in the code)
if you don't wait long enough the PIC will mis the initial command and you can never talk further with it.
It will appear to be deaf and will not answer - not even NAK any messages.

For the Atmos AI this delay can be seen in oceanic_vtpro_device_open() in the file oceanic_vtpro.c

>     // Set the RTS line.
>     status = dc_iostream_set_rts (device->iostream, 1);
>     if (status != DC_STATUS_SUCCESS) {
>         ERROR (context, "Failed to set the RTS line.");
>         goto error_free;
>     }
>
>     // Give the interface 100 ms to settle and draw power up.
>     dc_iostream_sleep (device->iostream, device->protocol == MOD ? 100 : 1000);
>
>     // Make sure everything is in a sane state.
>     dc_iostream_purge (device->iostream, DC_DIRECTION_ALL);
>
>     // Initialize the data cable (MOD mode).
>     status = oceanic_vtpro_init (device);

In looking at analyzer shots here is the timing for desktop, S4, and S7
From the time RTS changes state to the first bit of the first byte of the initialization message.
Desktop linux: 101ms (which is correct)
Galaxy S4: 2.5ms (which is not nearly long enough)
Galaxy S7: 650us (which is way too short and explains why it does not work on the S7 as the PIC never sees the initial command)

It appears that delays used by libdivecomputer on Android - at least on the Samsung devices not working based
on the analyzer shots are likely not doing any delay.
So depending the data cable (some cables for other computers run at 38400 vs 9600 and have faster PICs in them) and the speed
of the phone and what is going on inside the phone, the connection may not ever work.
Surprisingly the short 2.5ms delay that is happening on the S4 seems to work, instead of the intended 100ms delay.

My guess is that this issue affects more than just this dive computer and this data cable which may explain some of the
"hit and miss" issues with FTDI cables and Subsurface mobile.

I haven't fully traced down the iostream to see where the dc_iostream_sleep() function eventually goes,
but I think calls down into posix_serial.c dc_serial_sleep()

> static dc_status_t
> dc_serial_sleep (dc_iostream_t *abstract, unsigned int timeout)
> {
>     struct timespec ts;
>     ts.tv_sec  = (timeout / 1000);
>     ts.tv_nsec = (timeout % 1000) * 1000000;
>
>     while (nanosleep (&ts, &ts) != 0) {
>         int errcode = errno;
>         if (errcode != EINTR ) {
>             SYSERROR (abstract->context, errcode);
>             return syserror (errcode);
>         }
>     }
>
>     return DC_STATUS_SUCCESS;
> }

There are better ways to handle the while loop to ensure that the proper delay is always met.

Whatever the case, dc_serial_sleep() as called by libdivecomputer is not working on Android at least on the Samsung galaxy S4 running 4.4.4 and Galaxy S7 running 8.0.0
which not allowing the PIC to be initialized which means that the Atmos AI can't be downloaded.

I will need some help again getting a working build environment to be able to build the app and test the fixes.

--- bill





-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3996 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.subsurface-divelog.org/pipermail/subsurface/attachments/20180911/bfffe014/attachment-0001.bin>


More information about the subsurface mailing list