Because the user needs to initiate the transfer on the device itself, we
have to wait for an unknown amount of time. The infinite timeout works,
but causes problems if the data never arrives. By polling the serial
line, an application can at least cancel the operation.
With the knowledge of the end of profile pointer and the number of
samples, the ringbuffer can be traversed backwards and the start of the
ringbuffer doesn't have to be fixed anymore.
Especially the version commands seems to be sensitive to errors. Once
the initialization phase is over, a delay is usually not necessary, but
it should cause a noticable slowdown either because errors are supposed
to be rare.
If a logbook entry contains an invalid ringbuffer pointer, the error is
not returned immediately, but delayed until the end of the download.
With this approach we can download at least the dives before the
problematic logbook entry.
The handshaking is now automatically restarted whenever a non-fatal
error (such as a timeout or a protocol violation) is encountered.
Previously, only corrupt handshake packets where handled.
Note that this implementation will fail if the ringbuffer doesn't start
at the fixed address 0xA000. This is very likely to occur once the
ringbuffer is filled completely and the device starts to overwrite old
data.
The depth is stored with only 12 bits, which results in a maximum depth
of 99.9 meters. The remaining 4 bits are yet unknown, but one of those
bits appears to indicate a larger sample.
Since the total amount of profile data is not necessary a multiple of
the maximum packet size, the code may attempt to read outside the
ringbuffer area in some cases. Because the device supports a variable
packet size, the problem can simply be avoided by adjusting the packet
size.
As a side effect of this fix, the code will now also detect when the
profile ringbuffer is filling up faster than the logbook ringbuffer, and
the progress events are improved as well.
The Uwatec Smart stores a sample value only when it's diffent from the
previous value. While this compressed format does save some space on the
device, it is less practical for use in an application. The original
uncompressed data can easily be obtained by copying missing sample
values from the previous sample.
The implementation uses a two pass approach. In the first pass, all
sample values that are explicitly stored in the profile date are
collected. Any sample value that is not present, will automatically
retain the value from the previous sample. In the second pass, all
sample values are passed back to the application. The presence of an
absolute value is used to decide which sample types are present in the
data.
The total memory size is hardcoded again because the protocol does not
allow to retrieve the correct memory layout in advance. As long as there
is no device with a different amount of memory, that should be fine.
When trying to read the last memory page from an Oceanic Atom 2, the
device does not respond. Strangely, other compatible devices are not
affected by this problem.