Support for LinkUSB via libftdi
Johan Ström <johan <at> stromnet.se>
2014-06-22 21:09:50 GMT
I've previously mentioned my work on LinkUSB performance improvements
, and my goal to write a libftdi based implementation. The
client-timings are generally cut about 2.5 times, depending on
operation. A temp sensor is read in ~50ms instead of ~123ms.
I now have some code which works fine, I'm running this with my LinkUSB
1.5 on FreeBSD 9.2, performing temperature readings of 24 mixed
temperature sensors, and 4 DS2406's. The temperature is read every 30
seconds, and I (try to) scan for alarm ever 0.3 seconds. In other words,
pretty heavy load. This has been running for a few days without any
Some background (partly recap from earlier thread, but some new facts,
and also repeating here to keep it gathered):
This might be seen as "micro-optimization", not really useful if you
have a small net with few sensors. However, with a couple of DS2406's
wired as inputs, I want as low reaction time as possible. This is quite
a big step towards that goal. Other optimizations I'm doing is of course
simultaneous conversions and using alarms etc, but that's another story.
It all started with the random outages I wrote about in the other
thread, in which I got some tips on the LinkUSB's different baudmodes.
While looking into this, I also noticed that my DS2480B-based lab net
performed much faster than the LinkUSB-based net. After some digging I
found a few areas which could be improved.
It boils down to mainly two things:
* The FTDI FT232R (USB<->RS232) chip which the LinkUSB utilizes, does
not perform well with low amounts of data. The 64byte data buffer is by
default flushed every 16ms, or when full. Most OWFS operations does not
produce those amounts of data, so every transaction was delayed up to
16ms. This has been mitigated by changing the FTDi chip timer to 1ms,
and this is also the main reason libftdi is used. (FTDI docs calls this
the "latency timer")
* The LinkUSB operated at 9600bps by default. Every sent byte on the
1-wire bus is transmitted hex encoded, so 2 bytes is used for every
single wire-byte. The DS2480B uses raw bytes, thus the LinkUSB yielded
half the speed. This has been mitigated by using 19200bps instead of
9600bps. Higher speed (38400) is not usable, since it overruns the
1-Wire bus unless we take special care of rate-limiting. Could maybe be
used to speed up the search functionality..
A third thing I made some experiments on was the fact that OFWS jumps in
and out of "byte" mode. However, trying to setting this mode explicitly
and going in/out from it only when it was actually required, yielded
worse timings in the end (with the above fixes applied).. Most likely
since these changes where made in separate writes, taking up all the
time which could potentially be gained. This experiment was ditched.
I also noticed that there was some issues with using the BREAK condition
to reset my device. The manual says a BREAK condition should be able to
reset the device. I'm communicating with iButtonLink regarding this, and
they are looking in to it, believing I've found a bug.
Today I actually noticed that sending a break DOES work, but only when
inside "b" mode (sending bytes to the wire). To be strict, the manual
actually only talks about break support in the sections regarding the
different data modes.. So might actually be working as intended.
Anyway, one brute force way of resetting would thus be to send "b", then
break, then re-probe at 9600bps.. But I'll wait for further response
from their developers before doing anything with this.
The changes adds the following:
* A LIBFTDI configure option: if not auto-detected/forced-yes, all ftdi
related code is dropped out using similar conditionals as for example
the W1 code.
* A new device arg: --linkusb=<serial> which tells owfs to use libftdi
to find a specific USB device with that serial.
* Improved performance, if using the new device arg. Some examples:
Reading a DS18S20 temperature (12bit, after simultaneous conversion. 9
- Old LINK code: 123ms
(- Old LINK code with FTDI latency timer externally set to 1ms: 75ms)
- New LinkUSB FTDI code: 51ms
For the DS18B20 the improvement is actually even better, a separate
commit is already merged into master , and without that fix the
DS18B20 took 250ms.
Reading DS18*20 /power data (1 byte response):
- Old LINK code: 100ms
- New LinkUSB FTDI code: 43ms
The code is available in a branch on my fork:
The changes can roughly be summarized:
* A new file ow_ftdi.c has been added, implementing a new com_type ct_ftdi
* ow_com* has been altered to support ct_ftdi in addition to ct_serial
* ow_link.c is mostly untouched, with exception for the Link detection
code which now tries to detect a link device using multiple baud rates.
For old link mode, this should not introduce any changes at all, except
that it now has a chance to find devices configured for >9600bps.
* ow_arg changes to support new arg
To check this out locally, use:
git clone https://stromnet <at> git.code.sf.net/u/stromnet/owfs owfs-stromnet
git checkout ftdi-linkusb
Then follow the regular build-from-source commands as indicated in README.
Anyhow, I hope someone else finds these improvements interesting, and is
willing to spend some time reviewing the changes, and also to do some
testing with different OS'es and different Link12/Link45/LinkUSB
versions (I only have a LinkUSB v1.5).
Ultimately my hope is of course that this makes it into the master branch.
I do have one thing on the todo list, and that is auto-detection.
Currently you have to explicitly specify a LinkUSB FTDI serial number
(Linux: lsusb, FreeBSD: usbconfig). This is not very optimal. However,
at least my device uses the standard FTDI Vendor/product ID. This means
I cannot distinguish a random FTDI-based RS232-adapter and a LinkUSB,
without actually talking to the device. This can of course be done, but
I'm not sure it's "acceptable" to start writing to every FTDI adapter
How is this solved with other auto-detected devices?
Looking forward to any and all feedback! :)
HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration