Serial-ftdi Issues
Anton Lundin
glance at acc.umu.se
Tue Aug 29 23:11:02 PDT 2017
On 29 August, 2017 - John Van Ostrand wrote:
> I'm trying to get the Cochran computers working with the FTDI library and
> serial_ftdi so I can read them on an Android biuld. I'm having two issues that
> I have to ask for advice about.
>
> 1. In serial_ftdi_read() a failed read exponentially backs off when there's a
> short read. This is causing Cochran reads to timeout about 95% of the time.
> It's as if reading too late causes lost data. Having a fixed backoff of 10ms
> works. Are there any issues if I alter this backoff tactic? It could be
> shortened to 1ms if 10ms is too long.
>
> diff --git a/core/serial_ftdi.c b/core/serial_ftdi.c
> index f8cba95..bc20ce1 100644
> --- a/core/serial_ftdi.c
> +++ b/core/serial_ftdi.c
> @@ -384,7 +384,7 @@ static dc_status_t serial_ftdi_read (dc_custom_io_t *io,
> void *data, size_t size
> if (timeout == -1)
> timeout = 10000;
>
> - int backoff = 1;
> + int backoff = 10;
> int slept = 0;
> unsigned int nbytes = 0;
> while (nbytes < size) {
> @@ -402,12 +402,11 @@ static dc_status_t serial_ftdi_read (dc_custom_io_t *io,
> void *data, size_t size
> }
> serial_ftdi_sleep (device, backoff);
> slept += backoff;
> - backoff *= 2;
> if (backoff + slept > timeout)
> backoff = timeout - slept;
> } else {
> // Reset backoff to 1 on success.
> - backoff = 1;
> + backoff = 10;
> }
>
> nbytes += n;
This is probably related to the issue Jocke sees on android:
https://github.com/Subsurface-divelog/subsurface/pull/421
I don't mind another back off algorithm, just update the comment that
says "Exponential backoff" to.
This came about when Venkatesh converted this async api to a sync api to
work with the api libdivecomputer expects.
>
> 2. It doesn't make any sense to me but setting serial break on then off is the
> trigger to the Cochran to wake up, so I need the ability to set breaks.
> Currently the code doesn't support setting breaks and is explained with the
> comment "// Not implemented in libftdi yet. Research it further."
>
> So I looked at it and it's supported with the following libftdi-1.3 function:
>
> int ftdi_set_line_property2(struct ftdi_context *ftdi, enum
> ftdi_bits_type bits,
> enum ftdi_stopbits_type sbit, enum
> ftdi_parity_type parity,
> enum ftdi_break_type break_type);
>
> To make this work seamlessly with libdivecomputer's serial function I need to
> emulate the dc_serial_set_break function. A prototype serial_ftdi_set_break
> function is there and I can change it to use ftdi_set_line_property2, which
> means I have to get the parameters bits, sbit, and parity from somewhere.
>
> There isn't a function that will read this from the device.
>
> I could create some global vars in serial_ftdi.c, initialize them with 8,1,N
> values, update them as needed. To support multiple devices concurrently it
> would have to be an array indexed by device but it's not clear what index would
> work best.
>
> I was thinking of a global variable like:
>
> struct serial_parm {
> struct ftdi_context *ftdi_ctx;
> enum ftdi_bits_type bits;
> enum ftdi_stopbits_type sbit;
> enum ftdi_parity_type parity;
> } *serial_parms = NULL;
>
> Then realloc() to add (on serial_ftdi_open) or remove (on serial_ftdi_close).
> When serial_ftdi_configure is called I can search the array and update the
> values so I can use them in serial_ftdi_set_break.
>
> Does this work or is there a better idea?
Don't do it with a global variable. There's already a ftdi_serial_t
which contains such information, so use that structure and add whatever
more needed to be in it.
Each function gets that structure as dc_custom_io_t userdata argument.
//Anton
--
Anton Lundin +46702-161604
More information about the subsurface
mailing list