From c4233c091d6b24ec75c30c9ef38676cdbc9f1dfe Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 19 Mar 2015 20:23:47 +0100 Subject: [PATCH] Send the command and read the echo byte by byte. When trying to send a command, the first attempt always fails. We receive the echo, but no data packet. A second attempt usually works, but we always get back the same data packet. That's cleary wrong. Now, when comparing the data packets with those of the Tusa application, I noticed something very interesting. When we request the first packet (page 0x0000), we get: W: 520000 R: 520000 R: 00880124056202000250002890470824...19202720002000200020002000204145 The Tusa application also request this page, but the response is completely different: W: 520000 R: 520000 R: 22182224222322092203220522112210...0000000000f021fc0000000000000045 The response we get is identical to the response that the Tusa application gets for page 0x0052: W: 520052 R: 520052 R: 00880124056202000250002890470824...19202720002000200020002000204145 The only difference here is the echo of the command. But the echo should be ignored, because it's generated by the pc interface, and not send by the dive computer. This is easily verified by the fact that we always receive an echo, even without a dive computer connected (e.g. only the pc interface). Notice how the command type (first byte) and page number (last byte) are identical (0x52) for this request! I suspect that somehow the command type ends up being interpreted as the page number. That would explain why we're always getting the same response: as far as the device is concerned we're always requesting page 0x52. This is probably also related to the fact that the device doesn't respond after the first request. It's not impossible that if the first command wasn't received correctly and we resend the command, the device receives something that contains parts of both attempts. By sending the command and reading the echo byte by byte instead of all at once, the above problem disappears. --- src/cressi_edy.c | 71 +++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/src/cressi_edy.c b/src/cressi_edy.c index 5a51090..fc1e96b 100644 --- a/src/cressi_edy.c +++ b/src/cressi_edy.c @@ -83,35 +83,45 @@ cressi_edy_packet (cressi_edy_device_t *device, const unsigned char command[], u { dc_device_t *abstract = (dc_device_t *) device; - assert (asize >= csize); - if (device_is_cancelled (abstract)) return DC_STATUS_CANCELLED; - // Send the command to the device. - int n = serial_write (device->port, command, csize); - if (n != csize) { - ERROR (abstract->context, "Failed to send the command."); - return EXITCODE (n); + for (unsigned int i = 0; i < csize; ++i) { + // Send the command to the device. + int n = serial_write (device->port, command + i, 1); + if (n != 1) { + ERROR (abstract->context, "Failed to send the command."); + return EXITCODE (n); + } + + // Receive the echo. + unsigned char echo = 0; + n = serial_read (device->port, &echo, 1); + if (n != 1) { + ERROR (abstract->context, "Failed to receive the echo."); + return EXITCODE (n); + } + + // Verify the echo. + if (command[i] != echo) { + ERROR (abstract->context, "Unexpected echo."); + return DC_STATUS_PROTOCOL; + } } - // Receive the answer of the device. - n = serial_read (device->port, answer, asize); - if (n != asize) { - ERROR (abstract->context, "Failed to receive the answer."); - return EXITCODE (n); - } + if (asize) { + // Receive the answer of the device. + int n = serial_read (device->port, answer, asize); + if (n != asize) { + ERROR (abstract->context, "Failed to receive the answer."); + return EXITCODE (n); + } - // Verify the echo. - if (memcmp (answer, command, csize) != 0) { - ERROR (abstract->context, "Unexpected echo."); - return DC_STATUS_PROTOCOL; - } - - // Verify the trailer of the packet. - if (trailer && answer[asize - 1] != 0x45) { - ERROR (abstract->context, "Unexpected answer trailer byte."); - return DC_STATUS_PROTOCOL; + // Verify the trailer of the packet. + if (trailer && answer[asize - 1] != 0x45) { + ERROR (abstract->context, "Unexpected answer trailer byte."); + return DC_STATUS_PROTOCOL; + } } return DC_STATUS_SUCCESS; @@ -142,7 +152,7 @@ static dc_status_t cressi_edy_init1 (cressi_edy_device_t *device) { unsigned char command[3] = {0x41, 0x42, 0x43}; - unsigned char answer[6] = {0}; + unsigned char answer[3] = {0}; return cressi_edy_transfer (device, command, sizeof (command), answer, sizeof (answer), 0); } @@ -152,13 +162,13 @@ static dc_status_t cressi_edy_init2 (cressi_edy_device_t *device) { unsigned char command[1] = {0x44}; - unsigned char answer[2] = {0}; + unsigned char answer[1] = {0}; dc_status_t rc = cressi_edy_transfer (device, command, sizeof (command), answer, sizeof (answer), 0); if (rc != DC_STATUS_SUCCESS) return rc; - device->model = answer[1]; + device->model = answer[0]; return DC_STATUS_SUCCESS; } @@ -168,7 +178,7 @@ static dc_status_t cressi_edy_init3 (cressi_edy_device_t *device) { unsigned char command[1] = {0x0C}; - unsigned char answer[2] = {0}; + unsigned char answer[1] = {0}; return cressi_edy_transfer (device, command, sizeof (command), answer, sizeof (answer), 1); } @@ -178,9 +188,8 @@ static dc_status_t cressi_edy_quit (cressi_edy_device_t *device) { unsigned char command[1] = {0x46}; - unsigned char answer[1] = {0}; - return cressi_edy_transfer (device, command, sizeof (command), answer, sizeof (answer), 0); + return cressi_edy_transfer (device, command, sizeof (command), NULL, 0, 0); } @@ -301,7 +310,7 @@ cressi_edy_device_read (dc_device_t *abstract, unsigned int address, unsigned ch while (nbytes < size) { // Read the package. unsigned int number = address / SZ_PAGE; - unsigned char answer[3 + SZ_PACKET + 1] = {0}; + unsigned char answer[SZ_PACKET + 1] = {0}; unsigned char command[3] = {0x52, (number >> 8) & 0xFF, // high (number ) & 0xFF}; // low @@ -309,7 +318,7 @@ cressi_edy_device_read (dc_device_t *abstract, unsigned int address, unsigned ch if (rc != DC_STATUS_SUCCESS) return rc; - memcpy (data, answer + 3, SZ_PACKET); + memcpy (data, answer, SZ_PACKET); nbytes += SZ_PACKET; address += SZ_PACKET;