From a4cd21b811bf2cf025bdfc79bd877bedbae1578d Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 6 Jul 2023 22:27:05 +0200 Subject: [PATCH] Use the GTR mode to detect sidemount tanks Firmware v84 introduced support for sidemount diving. Users can now configure the two sidemount tanks as the source for the GTR (Gas Time Remaining) estimations. We can take advantage of this feature to detect the sidemount tanks. This is more reliable than using the tank name. --- src/array.c | 11 +++++++++++ src/array.h | 3 +++ src/shearwater_predator_parser.c | 16 +++++++++++----- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/array.c b/src/array.c index 29f5faf..f47c3eb 100644 --- a/src/array.c +++ b/src/array.c @@ -404,3 +404,14 @@ signextend (unsigned int value, unsigned int nbits) else return value & mask; } + +unsigned int +popcount (unsigned int value) +{ + unsigned int count = 0; + while (value) { + value &= value - 1; + count++; + } + return count; +} diff --git a/src/array.h b/src/array.h index a6ef21e..fab1475 100644 --- a/src/array.h +++ b/src/array.h @@ -126,6 +126,9 @@ dec2bcd (unsigned char value); unsigned int signextend (unsigned int value, unsigned int nbits); +unsigned int +popcount (unsigned int value); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index d1a1cd6..2bf4e3a 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -118,6 +118,7 @@ typedef struct shearwater_predator_tank_t { unsigned int pressure_reserve; unsigned int serial; char name[2]; + dc_usage_t usage; } shearwater_predator_tank_t; struct shearwater_predator_parser_t { @@ -254,6 +255,7 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, const parser->tank[i].pressure_reserve = 0; parser->tank[i].serial = 0; memset (parser->tank[i].name, 0, sizeof (parser->tank[i].name)); + parser->tank[i].usage = DC_USAGE_NONE; parser->tankidx[i] = i; } parser->aimode = AI_OFF; @@ -547,6 +549,14 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) } } } + unsigned int gtrmode = data[offset + 29]; + if (popcount(gtrmode) >= 2) { + for (unsigned int i = 0; i < 4; ++i) { + if (gtrmode & (1 << i)) { + tank[i].usage = DC_USAGE_SIDEMOUNT; + } + } + } } else if (type == LOG_RECORD_OPENING_5) { if (logversion >= 9) { tank[0].serial = array_convert_bcd2dec (data + offset + 1, 3); @@ -759,11 +769,7 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ break; } } else { - if (parser->tank[flags].name[0] == 'S') { - tank->usage = DC_USAGE_SIDEMOUNT; - } else { - tank->usage = DC_USAGE_NONE; - } + tank->usage = parser->tank[flags].usage; } break; case DC_FIELD_SALINITY: