Add support for the Mares Matrix.

The Matrix uses the same communication protocol as the Nemo Wide 2,
except that the sending the request packets with just a single write
operation doesn't seem to work. That's very surprising because it
caused no problems for the Nemo Wide 2 or the Icon HD!

The first two bytes of each request packet are probably some kind of
command type. These two bytes are answerred immediately with an ACK
byte (0xAA). Once this ACK byte has been received, the payload of the
command (if any) can be sent, and finally the response packet can be
received.

I suspect that when trying to send the entire command at once, the
device somehow doesn't receive the payload bytes correctly. Maybe it's
still busy processing those first two bytes, which causes the remainder
of the packet to get dropped? That might explain why the version
commands is not affected, because it doesn't have any payload bytes!
This commit is contained in:
Jef Driesen 2013-01-05 21:08:08 +01:00
parent 380eaadf83
commit 59bfb0f318
2 changed files with 19 additions and 5 deletions

View File

@ -150,6 +150,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Mares", "M2", DC_FAMILY_MARES_DARWIN , 0},
{"Mares", "Darwin Air", DC_FAMILY_MARES_DARWIN , 1},
/* Mares Icon HD */
{"Mares", "Matrix", DC_FAMILY_MARES_ICONHD , 0x0F},
{"Mares", "Icon HD", DC_FAMILY_MARES_ICONHD , 0x14},
{"Mares", "Icon HD Net Ready", DC_FAMILY_MARES_ICONHD , 0x15},
{"Mares", "Nemo Wide 2", DC_FAMILY_MARES_ICONHD , 0x19},

View File

@ -21,6 +21,7 @@
#include <string.h> // memcpy, memcmp
#include <stdlib.h> // malloc, free
#include <assert.h> // assert
#include <libdivecomputer/mares_iconhd.h>
@ -40,6 +41,7 @@
#define BAUDRATE 230400
#endif
#define MATRIX 0x0F
#define ICONHD 0x14
#define ICONHDNET 0x15
#define NEMOWIDE2 0x19
@ -111,9 +113,11 @@ mares_iconhd_transfer (mares_iconhd_device_t *device,
{
dc_device_t *abstract = (dc_device_t *) device;
// Send the command to the dive computer.
int n = serial_write (device->port, command, csize);
if (n != csize) {
assert (csize >= 2);
// Send the command header to the dive computer.
int n = serial_write (device->port, command, 2);
if (n != 2) {
ERROR (abstract->context, "Failed to send the command.");
return EXITCODE (n);
}
@ -132,6 +136,15 @@ mares_iconhd_transfer (mares_iconhd_device_t *device,
return DC_STATUS_PROTOCOL;
}
// Send the command payload to the dive computer.
if (csize > 2) {
n = serial_write (device->port, command + 2, csize - 2);
if (n != csize - 2) {
ERROR (abstract->context, "Failed to send the command.");
return EXITCODE (n);
}
}
unsigned int nbytes = 0;
while (nbytes < asize) {
// Set the minimum packet size.
@ -242,7 +255,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *
device->port = NULL;
memset (device->fingerprint, 0, sizeof (device->fingerprint));
memset (device->version, 0, sizeof (device->version));
if (model == NEMOWIDE2) {
if (model == NEMOWIDE2 || model == MATRIX) {
device->packetsize = SZ_PACKET;
} else {
device->packetsize = 0;
@ -257,7 +270,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *
}
// Set the serial communication protocol (256000 8N1).
if (model == NEMOWIDE2) {
if (model == NEMOWIDE2 || model == MATRIX) {
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_EVEN, 1, SERIAL_FLOWCONTROL_NONE);
} else {
rc = serial_configure (device->port, BAUDRATE, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);