From 88159c6fe4bac07a526e62b3c7cb83930243ec67 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 27 Oct 2014 09:38:14 +0100 Subject: [PATCH] Implement the dive mode for several devices. The new dive mode field is now supported by devices from these manufacturers: * Atomic Aquatics * Heinrichs Weikamp * Mares * Reefnet * Suunto --- src/atomics_cobalt_parser.c | 12 ++++++ src/hw_ostc_parser.c | 71 ++++++++++++++++++++++++++++++++ src/mares_iconhd_parser.c | 13 ++++++ src/mares_nemo_parser.c | 17 ++++++++ src/reefnet_sensus_parser.c | 3 ++ src/reefnet_sensuspro_parser.c | 3 ++ src/reefnet_sensusultra_parser.c | 3 ++ src/suunto_d9_parser.c | 21 ++++++++++ src/suunto_vyper_parser.c | 7 ++++ 9 files changed, 150 insertions(+) diff --git a/src/atomics_cobalt_parser.c b/src/atomics_cobalt_parser.c index f5b1044..ce17100 100644 --- a/src/atomics_cobalt_parser.c +++ b/src/atomics_cobalt_parser.c @@ -203,6 +203,18 @@ atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un tank->beginpressure = array_uint16_le(p + 6) * PSI / BAR; tank->endpressure = array_uint16_le(p + 14) * PSI / BAR; break; + case DC_FIELD_DIVEMODE: + switch(p[0x24]) { + case 0: // Open Circuit Trimix + case 2: // Open Circuit Nitrox + *((dc_divemode_t *) value) = DC_DIVEMODE_OC; + break; + case 1: // Closed Circuit + *((dc_divemode_t *) value) = DC_DIVEMODE_CC; + break; + default: + return DC_STATUS_DATAFORMAT; + } default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c index ac42219..de0cef9 100644 --- a/src/hw_ostc_parser.c +++ b/src/hw_ostc_parser.c @@ -33,6 +33,23 @@ #define MAXCONFIG 7 #define MAXGASMIX 5 +#define OSTC_ZHL16_OC 0 +#define OSTC_GAUGE 1 +#define OSTC_ZHL16_CC 2 +#define OSTC_APNEA 3 +#define OSTC_ZHL16_OC_GF 4 +#define OSTC_ZHL16_CC_GF 5 +#define OSTC_PSCR_GF 6 + +#define FROG_ZHL16 0 +#define FROG_ZHL16_GF 1 +#define FROG_APNEA 2 + +#define OSTC3_OC 0 +#define OSTC3_CC 1 +#define OSTC3_GAUGE 2 +#define OSTC3_APNEA 3 + typedef struct hw_ostc_parser_t hw_ostc_parser_t; struct hw_ostc_parser_t { @@ -323,6 +340,60 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned case DC_FIELD_TEMPERATURE_MINIMUM: *((double *) value) = (signed short) array_uint16_le (data + layout->temperature) / 10.0; break; + case DC_FIELD_DIVEMODE: + if (version == 0x21) { + switch (data[51]) { + case OSTC_APNEA: + *((dc_divemode_t *) value) = DC_DIVEMODE_FREEDIVE; + break; + case OSTC_GAUGE: + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + break; + case OSTC_ZHL16_OC: + case OSTC_ZHL16_OC_GF: + *((dc_divemode_t *) value) = DC_DIVEMODE_OC; + break; + case OSTC_ZHL16_CC: + case OSTC_ZHL16_CC_GF: + case OSTC_PSCR_GF: + *((dc_divemode_t *) value) = DC_DIVEMODE_CC; + break; + default: + return DC_STATUS_DATAFORMAT; + } + } else if (version == 0x22) { + switch (data[51]) { + case FROG_ZHL16: + case FROG_ZHL16_GF: + *((dc_divemode_t *) value) = DC_DIVEMODE_OC; + break; + case FROG_APNEA: + *((dc_divemode_t *) value) = DC_DIVEMODE_FREEDIVE; + break; + default: + return DC_STATUS_DATAFORMAT; + } + } else if (version == 0x23) { + switch (data[82]) { + case OSTC3_OC: + *((dc_divemode_t *) value) = DC_DIVEMODE_OC; + break; + case OSTC3_CC: + *((dc_divemode_t *) value) = DC_DIVEMODE_CC; + break; + case OSTC3_GAUGE: + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + break; + case OSTC3_APNEA: + *((dc_divemode_t *) value) = DC_DIVEMODE_FREEDIVE; + break; + default: + return DC_STATUS_DATAFORMAT; + } + } else { + return DC_STATUS_UNSUPPORTED; + } + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 6016e44..ccf297b 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -258,6 +258,19 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi case DC_FIELD_TEMPERATURE_MAXIMUM: *((double *) value) = (signed short) array_uint16_le (p + 0x48) / 10.0; break; + case DC_FIELD_DIVEMODE: + switch (p[0] & 0x03) { + case AIR: + case NITROX: + *((dc_divemode_t *) value) = DC_DIVEMODE_OC; + break; + case GAUGE: + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + break; + default: + return DC_STATUS_DATAFORMAT; + } + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/mares_nemo_parser.c b/src/mares_nemo_parser.c index 03a88ee..c396fea 100644 --- a/src/mares_nemo_parser.c +++ b/src/mares_nemo_parser.c @@ -261,6 +261,20 @@ mares_nemo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign case DC_FIELD_TEMPERATURE_MINIMUM: *((double *) value) = (signed char) p[53 - 11]; break; + case DC_FIELD_DIVEMODE: + switch (parser->mode) { + case AIR: + case NITROX: + *((dc_divemode_t *) value) = DC_DIVEMODE_OC; + break; + case FREEDIVE: + case GAUGE: + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + break; + default: + return DC_STATUS_DATAFORMAT; + } + break; default: return DC_STATUS_UNSUPPORTED; } @@ -283,6 +297,9 @@ mares_nemo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign case DC_FIELD_TEMPERATURE_MINIMUM: *((double *) value) = (signed char) p[28 - 11]; break; + case DC_FIELD_DIVEMODE: + *((dc_divemode_t *) value) = DC_DIVEMODE_FREEDIVE; + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/reefnet_sensus_parser.c b/src/reefnet_sensus_parser.c index cbbb5dd..9b5de72 100644 --- a/src/reefnet_sensus_parser.c +++ b/src/reefnet_sensus_parser.c @@ -211,6 +211,9 @@ reefnet_sensus_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un case DC_FIELD_GASMIX_COUNT: *((unsigned int *) value) = 0; break; + case DC_FIELD_DIVEMODE: + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/reefnet_sensuspro_parser.c b/src/reefnet_sensuspro_parser.c index 6f818e8..0f3af95 100644 --- a/src/reefnet_sensuspro_parser.c +++ b/src/reefnet_sensuspro_parser.c @@ -200,6 +200,9 @@ reefnet_sensuspro_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, case DC_FIELD_GASMIX_COUNT: *((unsigned int *) value) = 0; break; + case DC_FIELD_DIVEMODE: + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/reefnet_sensusultra_parser.c b/src/reefnet_sensusultra_parser.c index e4ed80a..1d85b06 100644 --- a/src/reefnet_sensusultra_parser.c +++ b/src/reefnet_sensusultra_parser.c @@ -201,6 +201,9 @@ reefnet_sensusultra_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ case DC_FIELD_GASMIX_COUNT: *((unsigned int *) value) = 0; break; + case DC_FIELD_DIVEMODE: + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/suunto_d9_parser.c b/src/suunto_d9_parser.c index 63c6d0c..939dab6 100644 --- a/src/suunto_d9_parser.c +++ b/src/suunto_d9_parser.c @@ -51,6 +51,7 @@ #define GAUGE 2 #define FREEDIVE 3 #define MIXED 4 +#define CCR 5 #define SAFETYSTOP (1 << 0) #define DECOSTOP (1 << 1) @@ -326,6 +327,26 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne gasmix->oxygen = parser->oxygen[flags] / 100.0; gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; + case DC_FIELD_DIVEMODE: + switch (parser->mode) { + case AIR: + case NITROX: + case MIXED: + *((dc_divemode_t *) value) = DC_DIVEMODE_OC; + break; + case GAUGE: + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + break; + case FREEDIVE: + *((dc_divemode_t *) value) = DC_DIVEMODE_FREEDIVE; + break; + case CCR: + *((dc_divemode_t *) value) = DC_DIVEMODE_CC; + break; + default: + return DC_STATUS_DATAFORMAT; + } + break; default: return DC_STATUS_UNSUPPORTED; } diff --git a/src/suunto_vyper_parser.c b/src/suunto_vyper_parser.c index f1dc6ce..15e6db6 100644 --- a/src/suunto_vyper_parser.c +++ b/src/suunto_vyper_parser.c @@ -198,6 +198,13 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi case DC_FIELD_TEMPERATURE_MINIMUM: *((double *) value) = (signed char) data[parser->marker + 1]; break; + case DC_FIELD_DIVEMODE: + if (data[4] & 0x40) { + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + } else { + *((dc_divemode_t *) value) = DC_DIVEMODE_OC; + } + break; default: return DC_STATUS_UNSUPPORTED; }