From 78373d827be59ade15446c74ad660580fb04de73 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 30 Jan 2023 20:06:43 +0100 Subject: [PATCH] Add support for the HP CCR tank pressure For the HP CCR mode, the O2 and diluent tank pressure was stored in the T1 and T2 tank pressure fields. Starting from log version 14 they moved to dedicated fields in the EXT sample, next to the T3 and T4 tank pressure. Thus the maximum number of tanks increased from 4 to 6. --- src/shearwater_predator_parser.c | 88 ++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index 3787d0a..d0cccb3 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -78,6 +78,10 @@ #define M_OC_REC 6 #define M_FREEDIVE 7 +#define AI_OFF 0 +#define AI_HPCCR 4 +#define AI_ON 5 + #define GF 0 #define VPMB 1 #define VPMB_GFS 2 @@ -87,7 +91,7 @@ #define IMPERIAL 1 #define NGASMIXES 10 -#define NTANKS 4 +#define NTANKS 6 #define NRECORDS 8 #define PREDATOR 2 @@ -133,6 +137,7 @@ struct shearwater_predator_parser_t { shearwater_predator_gasmix_t gasmix[NGASMIXES]; shearwater_predator_tank_t tank[NTANKS]; unsigned int tankidx[NTANKS]; + unsigned int aimode; unsigned int calibrated; double calibration[3]; unsigned int divemode; @@ -245,6 +250,7 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig memset (parser->tank[i].name, 0, sizeof (parser->tank[i].name)); parser->tankidx[i] = i; } + parser->aimode = AI_OFF; parser->calibrated = 0; for (unsigned int i = 0; i < 3; ++i) { parser->calibration[i] = 0.0; @@ -307,6 +313,7 @@ shearwater_predator_parser_set_data (dc_parser_t *abstract, const unsigned char memset (parser->tank[i].name, 0, sizeof (parser->tank[i].name)); parser->tankidx[i] = i; } + parser->aimode = AI_OFF; parser->calibrated = 0; for (unsigned int i = 0; i < 3; ++i) { parser->calibration[i] = 0.0; @@ -418,6 +425,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) shearwater_predator_gasmix_t gasmix[NGASMIXES] = {0}; shearwater_predator_tank_t tank[NTANKS] = {0}; unsigned int o2_previous = 0, he_previous = 0; + unsigned int aimode = AI_OFF; unsigned int offset = headersize; unsigned int length = size - footersize; @@ -478,14 +486,15 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) // level (0=normal, 1=critical, 2=warning), and the lower 12 // bits the tank pressure in units of 2 psi. unsigned int pressure = array_uint16_be (data + offset + pnf + idx[i]); + unsigned int id = (aimode == AI_HPCCR ? 4 : 0) + i; if (pressure < 0xFFF0) { pressure &= 0x0FFF; - if (!tank[i].active) { - tank[i].active = 1; - tank[i].beginpressure = pressure; - tank[i].endpressure = pressure; + if (!tank[id].active) { + tank[id].active = 1; + tank[id].beginpressure = pressure; + tank[id].endpressure = pressure; } - tank[i].endpressure = pressure; + tank[id].endpressure = pressure; } } } @@ -494,14 +503,33 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) if (logversion >= 13) { for (unsigned int i = 0; i < 2; ++i) { unsigned int pressure = array_uint16_be (data + offset + pnf + i * 2); + unsigned int id = 2 + i; if (pressure < 0xFFF0) { pressure &= 0x0FFF; - if (!tank[i + 2].active) { - tank[i + 2].active = 1; - tank[i + 2].beginpressure = pressure; - tank[i + 2].endpressure = pressure; + if (!tank[id].active) { + tank[id].active = 1; + tank[id].beginpressure = pressure; + tank[id].endpressure = pressure; } - tank[i + 2].endpressure = pressure; + tank[id].endpressure = pressure; + } + } + } + // Tank pressure (HP CCR) + if (logversion >= 14) { + for (unsigned int i = 0; i < 2; ++i) { + unsigned int pressure = array_uint16_be (data + offset + pnf + 4 + i * 2); + unsigned int id = 4 + i; + if (pressure) { + if (!tank[id].active) { + tank[id].active = 1; + tank[id].enabled = 1; + tank[id].beginpressure = pressure; + tank[id].endpressure = pressure; + tank[id].name[0] = i == 0 ? 'D': 'O'; + tank[id].name[1] = 0; + } + tank[id].endpressure = pressure; } } } @@ -518,18 +546,23 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) // Air integration mode if (logversion >= 7) { - unsigned int airmode = data[offset + 28]; + aimode = data[offset + 28]; if (logversion < 13) { - if (airmode == 1 || airmode == 2) { - tank[airmode - 1].enabled = 1; - } else if (airmode == 3) { + if (aimode == 1 || aimode == 2) { + tank[aimode - 1].enabled = 1; + } else if (aimode == 3) { tank[0].enabled = 1; tank[1].enabled = 1; } } - if (airmode == 4) { - tank[0].enabled = 1; - tank[1].enabled = 1; + if (logversion < 14) { + if (aimode == AI_HPCCR) { + for (unsigned int i = 0; i < 2; ++i) { + tank[4 + i].enabled = 1; + tank[4 + i].name[0] = i == 0 ? 'D': 'O'; + tank[4 + i].name[1] = 0; + } + } } } } else if (type == LOG_RECORD_OPENING_5) { @@ -659,6 +692,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) parser->tankidx[i] = UNDEFINED; } } + parser->aimode = aimode; parser->divemode = divemode; parser->units = data[parser->opening[0] + 8]; parser->atmospheric = array_uint16_be (data + parser->opening[1] + (parser->pnf ? 16 : 47)); @@ -946,9 +980,10 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal // level (0=normal, 1=critical, 2=warning), and the lower 12 // bits the tank pressure in units of 2 psi. unsigned int pressure = array_uint16_be (data + offset + pnf + idx[i]); + unsigned int id = (parser->aimode == AI_HPCCR ? 4 : 0) + i; if (pressure < 0xFFF0) { pressure &= 0x0FFF; - sample.pressure.tank = parser->tankidx[i]; + sample.pressure.tank = parser->tankidx[id]; sample.pressure.value = pressure * 2 * PSI / BAR; if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata); } @@ -971,9 +1006,22 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal if (parser->logversion >= 13) { for (unsigned int i = 0; i < 2; ++i) { unsigned int pressure = array_uint16_be (data + offset + pnf + i * 2); + unsigned int id = 2 + i; if (pressure < 0xFFF0) { pressure &= 0x0FFF; - sample.pressure.tank = parser->tankidx[i + 2]; + sample.pressure.tank = parser->tankidx[id]; + sample.pressure.value = pressure * 2 * PSI / BAR; + if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata); + } + } + } + // Tank pressure (HP CCR) + if (parser->logversion >= 14) { + for (unsigned int i = 0; i < 2; ++i) { + unsigned int pressure = array_uint16_be (data + offset + pnf + 4 + i * 2); + unsigned int id = 4 + i; + if (pressure) { + sample.pressure.tank = parser->tankidx[id]; sample.pressure.value = pressure * 2 * PSI / BAR; if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata); }