On 2014-03-12 11:47, Jef Driesen wrote:
I no longer believe this is a half-duplex problem. The interface has three wires, so that's probably GND, TX and RX. In that case there shouldn't be any problem with starting a read before the write has finished. It would just take a bit longer before the read receives its data. With the Suunto's there were only two wires, which makes the timing of switching between read and write a lot more critical. The Suunto's also need the toggling of the RTS line, which is not the case for the Oceanics.
Hamish already confirmed that if he adds a small delay before the write, then everything starts to work fine. I don't have a good explanation for this. I get the impression that without the extra delay we are sending the next command too fast. Maybe the dive computer is still busy processing the previous command? But it has already send the response to the previous command (because we have already processed it), so I have absolutely no idea what it could be doing. Also why does it need this delay on Linux but not on Windows? Is the Windows driver maybe slower to send out the data, and this extra delay happens to be just enough to make it work?
If you look at the error handling, you'll see that there is already a 100ms delay before sending the command again. Since the second attempt is usually successful, that's another indication that the problem is read->write turnaround rather than the write->read.
Just a thought, but maybe one or more bytes of the command get lost somehow when trying to send too fast? If the dive computer gets no bytes at all, it also doesn't reply and we get a timeout. If only the first few bytes get lost, the dive computer will see an incomplete command and will respond with a NAK to indicate it can't process the request. That would explain the two type of errors (timeout or nak) we get, but then the next question is of course how these bytes disappear?
I just remember something that could matter here. If you look at the commands that are being send, they all end with a 0x00 byte that doesn't really serve any purpose afaik. When I originally reverse engineered the protocol, that byte was send by the Oceanic application, and I just duplicated that. But I now recall that I think I've seen that newer versions of there software no longer do this. Maybe this extra byte is what is causing us trouble now?
Imagine the dive computer expects a 3 byte read command (e.g. B1XXXX). It will first receive the command type 0xB1, and then expect two more bytes for that command. Than it has everything to process the request and send back the response. But if we send that extra 0x00 byte it will probably try to process that as the next command type. This is likely a non-existing type and the device will probably just ignore it. But that might take just enough time to prevent the next command from being received correctly.
I think that's something worth trying. Hamish, can you try without that last 0x00 byte? And maybe also try Oceanlog on Windows and capture the communication to double check whether they send this extra 0x00 byte or not.
The procedure on how to setup Portmon is described here:
http://www.libdivecomputer.org/contribute.html#protocol
Unfortunately you'll need a 32bit Windows version to run Portmon. If you use some other capture application that's of course fine too. Portmon is just convenient because it's freeware and the output is easy to parse with scripts.
Jef