From a833992ed6e4efc6f1864cc890c9daa77d909704 Mon Sep 17 00:00:00 2001 From: Janice Date: Mon, 11 Dec 2017 13:33:59 -0800 Subject: [PATCH] Add support for the Mares Quad Air --- src/descriptor.c | 1 + src/mares_iconhd.c | 13 ++++++++++++- src/mares_iconhd_parser.c | 27 ++++++++++++++++++--------- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index c68ef1f..bdd5e60 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -249,6 +249,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Mares", "Puck Pro", DC_FAMILY_MARES_ICONHD , 0x18}, {"Mares", "Nemo Wide 2", DC_FAMILY_MARES_ICONHD , 0x19}, {"Mares", "Puck 2", DC_FAMILY_MARES_ICONHD , 0x1F}, + {"Mares", "Quad Air", DC_FAMILY_MARES_ICONHD , 0x23}, {"Mares", "Quad", DC_FAMILY_MARES_ICONHD , 0x29}, /* Heinrichs Weikamp */ {"Heinrichs Weikamp", "OSTC", DC_FAMILY_HW_OSTC, 0}, diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index 990f466..9a9a351 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -42,6 +42,7 @@ #define PUCKPRO 0x18 #define NEMOWIDE2 0x19 #define PUCK2 0x1F +#define QUADAIR 0x23 #define QUAD 0x29 #define ACK 0xAA @@ -127,6 +128,7 @@ mares_iconhd_get_model (mares_iconhd_device_t *device) {"Puck Pro", PUCKPRO}, {"Nemo Wide 2", NEMOWIDE2}, {"Puck 2", PUCK2}, + {"Quad Air", QUADAIR}, {"Quad", QUAD}, }; @@ -299,6 +301,10 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * device->layout = &mares_nemowide2_layout; device->packetsize = 256; break; + case QUADAIR: + device->layout = &mares_iconhdnet_layout; + device->packetsize = 256; + break; case ICONHDNET: device->layout = &mares_iconhdnet_layout; device->packetsize = 4096; @@ -463,6 +469,8 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, unsigned int header = 0x5C; if (model == ICONHDNET) header = 0x80; + else if (model == QUADAIR) + header = 0x84; else if (model == SMART) header = 4; // Type and number of samples only! else if (model == SMARTAPNEA) @@ -545,6 +553,9 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, if (model == ICONHDNET) { headersize = 0x80; samplesize = 12; + } else if (model == QUADAIR) { + headersize = 0x84; + samplesize = 12; } else if (model == SMART) { if (mode == FREEDIVE) { headersize = 0x2E; @@ -577,7 +588,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) { + if (model == ICONHDNET || model == QUADAIR) { nbytes += (nsamples / 4) * 8; } else if (model == SMARTAPNEA) { unsigned int settings = array_uint16_le (buffer + offset - headersize + 0x1C); diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 76324f3..0c48a22 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -34,6 +34,7 @@ #define SMARTAPNEA 0x010010 #define ICONHD 0x14 #define ICONHDNET 0x15 +#define QUADAIR 0x23 #define NGASMIXES 3 #define NTANKS NGASMIXES @@ -91,6 +92,8 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser) unsigned int header = 0x5C; if (parser->model == ICONHDNET) header = 0x80; + else if (parser->model == QUADAIR) + header = 0x84; else if (parser->model == SMART) header = 4; // Type and number of samples only! else if (parser->model == SMARTAPNEA) @@ -126,6 +129,9 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser) if (parser->model == ICONHDNET) { headersize = 0x80; samplesize = 12; + } else if (parser->model == QUADAIR) { + headersize = 0x84; + samplesize = 12; } else if (parser->model == SMART) { if (mode == FREEDIVE) { headersize = 0x2E; @@ -175,7 +181,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) { + if (parser->model == ICONHDNET || parser->model == QUADAIR) { nbytes += (nsamples / 4) * 8; } else if (parser->model == SMARTAPNEA) { unsigned int divetime = array_uint32_le (p + 0x24); @@ -209,10 +215,11 @@ mares_iconhd_parser_cache (mares_iconhd_parser_t *parser) // Tanks unsigned int ntanks = 0; - if (parser->model == ICONHDNET) { + if (parser->model == ICONHDNET || parser->model == QUADAIR) { + unsigned int tankoffset = (parser->model == ICONHDNET) ? 0x58 : 0x5C; while (ntanks < NTANKS) { - unsigned int beginpressure = array_uint16_le (p + 0x58 + ntanks * 4 + 0); - unsigned int endpressure = array_uint16_le (p + 0x58 + ntanks * 4 + 2); + unsigned int beginpressure = array_uint16_le (p + tankoffset + ntanks * 4 + 0); + unsigned int endpressure = array_uint16_le (p + tankoffset + ntanks * 4 + 2); if (beginpressure == 0 && (endpressure == 0 || endpressure == 36000)) break; ntanks++; @@ -352,6 +359,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi } unsigned int volume = 0, workpressure = 0; + unsigned int tankoffset = 0; dc_gasmix_t *gasmix = (dc_gasmix_t *) value; dc_tank_t *tank = (dc_tank_t *) value; @@ -394,8 +402,9 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi *((unsigned int *) value) = parser->ntanks; break; case DC_FIELD_TANK: - volume = array_uint16_le (p + 0x64 + flags * 8 + 0); - workpressure = array_uint16_le (p + 0x64 + flags * 8 + 2); + tankoffset = (parser->model == ICONHDNET) ? 0x58 : 0x5C; + volume = array_uint16_le (p + tankoffset + 0x0C + flags * 8 + 0); + workpressure = array_uint16_le (p + tankoffset + 0x0C + flags * 8 + 2); if (parser->settings & 0x0100) { tank->type = DC_TANKVOLUME_METRIC; tank->volume = volume; @@ -408,8 +417,8 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi tank->volume /= workpressure * PSI / ATM; tank->workpressure = workpressure * PSI / BAR; } - tank->beginpressure = array_uint16_le (p + 0x58 + flags * 4 + 0) / 100.0; - tank->endpressure = array_uint16_le (p + 0x58 + flags * 4 + 2) / 100.0; + tank->beginpressure = array_uint16_le (p + tankoffset + flags * 4 + 0) / 100.0; + tank->endpressure = array_uint16_le (p + tankoffset + flags * 4 + 2) / 100.0; if (flags < parser->ngasmixes) { tank->gasmix = flags; } else { @@ -602,7 +611,7 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t nsamples++; // Some extra data. - if (parser->model == ICONHDNET && (nsamples % 4) == 0) { + if ((parser->model == ICONHDNET || parser->model == QUADAIR) && (nsamples % 4) == 0) { // Pressure (1/100 bar). unsigned int pressure = array_uint16_le(data + offset); if (gasmix < parser->ntanks) {