Add support for the Mares Smart Air

The Smart Air uses almost the same data format as the Quad Air. Only the
4 bytes containing the dive mode and number of samples moved from the
beginning of the header to the end. This is a change adopted from the
regular Smart.
This commit is contained in:
Jef Driesen 2018-08-12 19:42:27 +02:00
parent 17b3e07398
commit ff1ee12770
3 changed files with 23 additions and 11 deletions

View File

@ -246,6 +246,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Mares", "Nemo Wide 2", DC_FAMILY_MARES_ICONHD , 0x19, DC_TRANSPORT_SERIAL, NULL},
{"Mares", "Puck 2", DC_FAMILY_MARES_ICONHD , 0x1F, DC_TRANSPORT_SERIAL, NULL},
{"Mares", "Quad Air", DC_FAMILY_MARES_ICONHD , 0x23, DC_TRANSPORT_SERIAL, NULL},
{"Mares", "Smart Air", DC_FAMILY_MARES_ICONHD , 0x24, DC_TRANSPORT_SERIAL, NULL},
{"Mares", "Quad", DC_FAMILY_MARES_ICONHD , 0x29, DC_TRANSPORT_SERIAL, NULL},
/* Heinrichs Weikamp */
{"Heinrichs Weikamp", "OSTC", DC_FAMILY_HW_OSTC, 0, DC_TRANSPORT_SERIAL, NULL},

View File

@ -42,6 +42,7 @@
#define NEMOWIDE2 0x19
#define PUCK2 0x1F
#define QUADAIR 0x23
#define SMARTAIR 0x24
#define QUAD 0x29
#define ACK 0xAA
@ -127,6 +128,7 @@ mares_iconhd_get_model (mares_iconhd_device_t *device)
{"Nemo Wide 2", NEMOWIDE2},
{"Puck 2", PUCK2},
{"Quad Air", QUADAIR},
{"Smart Air", SMARTAIR},
{"Quad", QUAD},
};
@ -293,6 +295,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_
device->packetsize = 256;
break;
case QUADAIR:
case SMARTAIR:
device->layout = &mares_iconhdnet_layout;
device->packetsize = 256;
break;
@ -442,7 +445,7 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
header = 0x80;
else if (model == QUADAIR)
header = 0x84;
else if (model == SMART)
else if (model == SMART || model == SMARTAIR)
header = 4; // Type and number of samples only!
else if (model == SMARTAPNEA)
header = 6; // Type and number of samples only!
@ -504,7 +507,7 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
// Get the number of samples in the profile data.
unsigned int type = 0, nsamples = 0;
if (model == SMART || model == SMARTAPNEA) {
if (model == SMART || model == SMARTAPNEA || model == SMARTAIR) {
type = array_uint16_le (buffer + offset - header + 2);
nsamples = array_uint16_le (buffer + offset - header + 0);
} else {
@ -541,6 +544,10 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
headersize = 0x50;
samplesize = 14;
fingerprint = 0x40;
} else if (model == SMARTAIR) {
headersize = 0x84;
samplesize = 12;
fingerprint = 2;
}
if (offset < headersize)
break;
@ -559,7 +566,7 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
// end of the ringbuffer. The current dive is incomplete (partially
// overwritten with newer data), and processing should stop.
unsigned int nbytes = 4 + headersize + nsamples * samplesize;
if (model == ICONHDNET || model == QUADAIR) {
if (model == ICONHDNET || model == QUADAIR || model == SMARTAIR) {
nbytes += (nsamples / 4) * 8;
} else if (model == SMARTAPNEA) {
unsigned int settings = array_uint16_le (buffer + offset - headersize + 0x1C);

View File

@ -35,6 +35,7 @@
#define ICONHD 0x14
#define ICONHDNET 0x15
#define QUADAIR 0x23
#define SMARTAIR 0x24
#define NGASMIXES 3
#define NTANKS NGASMIXES
@ -94,7 +95,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser)
header = 0x80;
else if (parser->model == QUADAIR)
header = 0x84;
else if (parser->model == SMART)
else if (parser->model == SMART || parser->model == SMARTAIR)
header = 4; // Type and number of samples only!
else if (parser->model == SMARTAPNEA)
header = 6; // Type and number of samples only!
@ -112,7 +113,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser)
// Get the number of samples in the profile data.
unsigned int type = 0, nsamples = 0;
if (parser->model == SMART || parser->model == SMARTAPNEA) {
if (parser->model == SMART || parser->model == SMARTAPNEA || parser->model == SMARTAIR) {
type = array_uint16_le (data + length - header + 2);
nsamples = array_uint16_le (data + length - header + 0);
} else {
@ -129,7 +130,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser)
if (parser->model == ICONHDNET) {
headersize = 0x80;
samplesize = 12;
} else if (parser->model == QUADAIR) {
} else if (parser->model == QUADAIR || parser->model == SMARTAIR) {
headersize = 0x84;
samplesize = 12;
} else if (parser->model == SMART) {
@ -151,7 +152,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser)
}
const unsigned char *p = data + length - headersize;
if (parser->model != SMART && parser->model != SMARTAPNEA) {
if (parser->model != SMART && parser->model != SMARTAPNEA && parser->model != SMARTAIR) {
p += 4;
}
@ -181,7 +182,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser)
// Calculate the total number of bytes for this dive.
unsigned int nbytes = 4 + headersize + nsamples * samplesize;
if (parser->model == ICONHDNET || parser->model == QUADAIR) {
if (parser->model == ICONHDNET || parser->model == QUADAIR || parser->model == SMARTAIR) {
nbytes += (nsamples / 4) * 8;
} else if (parser->model == SMARTAPNEA) {
unsigned int divetime = array_uint32_le (p + 0x24);
@ -215,7 +216,7 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser)
// Tanks
unsigned int ntanks = 0;
if (parser->model == ICONHDNET || parser->model == QUADAIR) {
if (parser->model == ICONHDNET || parser->model == QUADAIR || parser->model == SMARTAIR) {
unsigned int tankoffset = (parser->model == ICONHDNET) ? 0x58 : 0x5C;
while (ntanks < NTANKS) {
unsigned int beginpressure = array_uint16_le (p + tankoffset + ntanks * 4 + 0);
@ -325,6 +326,8 @@ mares_iconhd_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime
}
} else if (parser->model == SMARTAPNEA) {
p += 0x40;
} else if (parser->model == SMARTAIR) {
p += 2;
} else {
p += 6;
}
@ -354,7 +357,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
return rc;
const unsigned char *p = abstract->data + parser->footer;
if (parser->model != SMART && parser->model != SMARTAPNEA) {
if (parser->model != SMART && parser->model != SMARTAPNEA && parser->model != SMARTAIR) {
p += 4;
}
@ -611,7 +614,8 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
nsamples++;
// Some extra data.
if ((parser->model == ICONHDNET || parser->model == QUADAIR) && (nsamples % 4) == 0) {
if ((parser->model == ICONHDNET || parser->model == QUADAIR || parser->model == SMARTAIR) &&
(nsamples % 4) == 0) {
// Pressure (1/100 bar).
unsigned int pressure = array_uint16_le(data + offset);
if (gasmix < parser->ntanks) {