Add support for the INTR protocol variant.
There are two variants of the vtpro communication protocol: the existing MOD variant and the new INTR variant. The main difference is in the initialization sequence, with two completely different response packets: MOD--OK_V2.00 INTR-OK_V1.11 The INTR variant does not appear to return useful information in the version packet.
This commit is contained in:
parent
b41ecd0c15
commit
5824254cf5
@ -40,10 +40,16 @@
|
|||||||
#define NAK 0xA5
|
#define NAK 0xA5
|
||||||
#define END 0x51
|
#define END 0x51
|
||||||
|
|
||||||
|
typedef enum oceanic_vtpro_protocol_t {
|
||||||
|
MOD,
|
||||||
|
INTR,
|
||||||
|
} oceanic_vtpro_protocol_t;
|
||||||
|
|
||||||
typedef struct oceanic_vtpro_device_t {
|
typedef struct oceanic_vtpro_device_t {
|
||||||
oceanic_common_device_t base;
|
oceanic_common_device_t base;
|
||||||
dc_serial_t *port;
|
dc_serial_t *port;
|
||||||
unsigned int model;
|
unsigned int model;
|
||||||
|
oceanic_vtpro_protocol_t protocol;
|
||||||
} oceanic_vtpro_device_t;
|
} oceanic_vtpro_device_t;
|
||||||
|
|
||||||
static dc_status_t oceanic_vtpro_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size);
|
static dc_status_t oceanic_vtpro_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size);
|
||||||
@ -179,8 +185,10 @@ oceanic_vtpro_init (oceanic_vtpro_device_t *device)
|
|||||||
dc_device_t *abstract = (dc_device_t *) device;
|
dc_device_t *abstract = (dc_device_t *) device;
|
||||||
|
|
||||||
// Send the command to the dive computer.
|
// Send the command to the dive computer.
|
||||||
unsigned char command[2] = {0xAA, 0x00};
|
unsigned char command[2][2] = {
|
||||||
status = dc_serial_write (device->port, command, sizeof (command), NULL);
|
{0xAA, 0x00},
|
||||||
|
{0x20, 0x00}};
|
||||||
|
status = dc_serial_write (device->port, command[device->protocol], sizeof (command[device->protocol]), NULL);
|
||||||
if (status != DC_STATUS_SUCCESS) {
|
if (status != DC_STATUS_SUCCESS) {
|
||||||
ERROR (abstract->context, "Failed to send the command.");
|
ERROR (abstract->context, "Failed to send the command.");
|
||||||
return status;
|
return status;
|
||||||
@ -195,10 +203,10 @@ oceanic_vtpro_init (oceanic_vtpro_device_t *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify the answer.
|
// Verify the answer.
|
||||||
const unsigned char response[13] = {
|
const unsigned char response[2][13] = {
|
||||||
0x4D, 0x4F, 0x44, 0x2D, 0x2D, 0x4F, 0x4B,
|
{0x4D, 0x4F, 0x44, 0x2D, 0x2D, 0x4F, 0x4B, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x30},
|
||||||
0x5F, 0x56, 0x32, 0x2E, 0x30, 0x30};
|
{0x49, 0x4E, 0x54, 0x52, 0x2D, 0x4F, 0x4B, 0x5F, 0x56, 0x31, 0x2E, 0x31, 0x31}};
|
||||||
if (memcmp (answer, response, sizeof (response)) != 0) {
|
if (memcmp (answer, response[device->protocol], sizeof (response[device->protocol])) != 0) {
|
||||||
ERROR (abstract->context, "Unexpected answer byte(s).");
|
ERROR (abstract->context, "Unexpected answer byte(s).");
|
||||||
return DC_STATUS_PROTOCOL;
|
return DC_STATUS_PROTOCOL;
|
||||||
}
|
}
|
||||||
@ -287,6 +295,7 @@ oceanic_vtpro_device_open2 (dc_device_t **out, dc_context_t *context, const char
|
|||||||
// Set the default values.
|
// Set the default values.
|
||||||
device->port = NULL;
|
device->port = NULL;
|
||||||
device->model = model;
|
device->model = model;
|
||||||
|
device->protocol = MOD;
|
||||||
|
|
||||||
// Open the device.
|
// Open the device.
|
||||||
status = dc_serial_open (&device->port, context, name);
|
status = dc_serial_open (&device->port, context, name);
|
||||||
@ -324,7 +333,7 @@ oceanic_vtpro_device_open2 (dc_device_t **out, dc_context_t *context, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Give the interface 100 ms to settle and draw power up.
|
// Give the interface 100 ms to settle and draw power up.
|
||||||
dc_serial_sleep (device->port, 100);
|
dc_serial_sleep (device->port, device->protocol == MOD ? 100 : 1000);
|
||||||
|
|
||||||
// Make sure everything is in a sane state.
|
// Make sure everything is in a sane state.
|
||||||
dc_serial_purge (device->port, DC_DIRECTION_ALL);
|
dc_serial_purge (device->port, DC_DIRECTION_ALL);
|
||||||
@ -444,32 +453,36 @@ oceanic_vtpro_device_version (dc_device_t *abstract, unsigned char data[], unsig
|
|||||||
return DC_STATUS_PROTOCOL;
|
return DC_STATUS_PROTOCOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain the device identification string. This string is
|
if (device->protocol == MOD) {
|
||||||
// split over two packets, but we join both parts again.
|
// Obtain the device identification string. This string is
|
||||||
|
// split over two packets, but we join both parts again.
|
||||||
|
for (unsigned int i = 0; i < 2; ++i) {
|
||||||
|
unsigned char command[4] = {0x72, 0x03, i * 0x10, 0x00};
|
||||||
|
unsigned char answer[PAGESIZE / 2 + 2] = {0};
|
||||||
|
rc = oceanic_vtpro_transfer (device, command, sizeof (command), answer, sizeof (answer));
|
||||||
|
if (rc != DC_STATUS_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 2; ++i) {
|
// Verify the checksum of the answer.
|
||||||
unsigned char command[4] = {0x72, 0x03, i * 0x10, 0x00};
|
unsigned char crc = answer[PAGESIZE / 2];
|
||||||
unsigned char answer[PAGESIZE / 2 + 2] = {0};
|
unsigned char ccrc = checksum_add_uint4 (answer, PAGESIZE / 2, 0x00);
|
||||||
rc = oceanic_vtpro_transfer (device, command, sizeof (command), answer, sizeof (answer));
|
if (crc != ccrc) {
|
||||||
if (rc != DC_STATUS_SUCCESS)
|
ERROR (abstract->context, "Unexpected answer checksum.");
|
||||||
return rc;
|
return DC_STATUS_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
// Verify the checksum of the answer.
|
// Verify the last byte of the answer.
|
||||||
unsigned char crc = answer[PAGESIZE / 2];
|
if (answer[PAGESIZE / 2 + 1] != END) {
|
||||||
unsigned char ccrc = checksum_add_uint4 (answer, PAGESIZE / 2, 0x00);
|
ERROR (abstract->context, "Unexpected answer byte.");
|
||||||
if (crc != ccrc) {
|
return DC_STATUS_PROTOCOL;
|
||||||
ERROR (abstract->context, "Unexpected answer checksum.");
|
}
|
||||||
return DC_STATUS_PROTOCOL;
|
|
||||||
|
// Append the answer to the output buffer.
|
||||||
|
memcpy (data + i * PAGESIZE / 2, answer, PAGESIZE / 2);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// Verify the last byte of the answer.
|
// Return an empty device identification string.
|
||||||
if (answer[PAGESIZE / 2 + 1] != END) {
|
memset (data, 0x00, PAGESIZE);
|
||||||
ERROR (abstract->context, "Unexpected answer byte.");
|
|
||||||
return DC_STATUS_PROTOCOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the answer to the output buffer.
|
|
||||||
memcpy (data + i * PAGESIZE / 2, answer, PAGESIZE / 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user