Merge branch 'shearwater-tank-usage'

This commit is contained in:
Jef Driesen 2023-07-18 00:30:22 +02:00
commit 9cde393e5f
3 changed files with 53 additions and 21 deletions

View File

@ -404,3 +404,14 @@ signextend (unsigned int value, unsigned int nbits)
else else
return value & mask; return value & mask;
} }
unsigned int
popcount (unsigned int value)
{
unsigned int count = 0;
while (value) {
value &= value - 1;
count++;
}
return count;
}

View File

@ -126,6 +126,9 @@ dec2bcd (unsigned char value);
unsigned int unsigned int
signextend (unsigned int value, unsigned int nbits); signextend (unsigned int value, unsigned int nbits);
unsigned int
popcount (unsigned int value);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -118,6 +118,7 @@ typedef struct shearwater_predator_tank_t {
unsigned int pressure_reserve; unsigned int pressure_reserve;
unsigned int serial; unsigned int serial;
char name[2]; char name[2];
dc_usage_t usage;
} shearwater_predator_tank_t; } shearwater_predator_tank_t;
struct shearwater_predator_parser_t { struct shearwater_predator_parser_t {
@ -140,6 +141,7 @@ struct shearwater_predator_parser_t {
shearwater_predator_tank_t tank[NTANKS]; shearwater_predator_tank_t tank[NTANKS];
unsigned int tankidx[NTANKS]; unsigned int tankidx[NTANKS];
unsigned int aimode; unsigned int aimode;
unsigned int hpccr;
unsigned int calibrated; unsigned int calibrated;
double calibration[3]; double calibration[3];
unsigned int divemode; unsigned int divemode;
@ -179,6 +181,12 @@ static const dc_parser_vtable_t shearwater_petrel_parser_vtable = {
}; };
static unsigned int
shearwater_predator_is_ccr (unsigned int divemode)
{
return divemode == M_CC || divemode == M_CC2 || divemode == M_SC;
}
static unsigned int static unsigned int
shearwater_predator_find_gasmix (shearwater_predator_parser_t *parser, unsigned int o2, unsigned int he, unsigned int dil) shearwater_predator_find_gasmix (shearwater_predator_parser_t *parser, unsigned int o2, unsigned int he, unsigned int dil)
{ {
@ -248,9 +256,11 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, const
parser->tank[i].pressure_reserve = 0; parser->tank[i].pressure_reserve = 0;
parser->tank[i].serial = 0; parser->tank[i].serial = 0;
memset (parser->tank[i].name, 0, sizeof (parser->tank[i].name)); memset (parser->tank[i].name, 0, sizeof (parser->tank[i].name));
parser->tank[i].usage = DC_USAGE_NONE;
parser->tankidx[i] = i; parser->tankidx[i] = i;
} }
parser->aimode = AI_OFF; parser->aimode = AI_OFF;
parser->hpccr = 0;
parser->calibrated = 0; parser->calibrated = 0;
for (unsigned int i = 0; i < 3; ++i) { for (unsigned int i = 0; i < 3; ++i) {
parser->calibration[i] = 0.0; parser->calibration[i] = 0.0;
@ -379,6 +389,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
shearwater_predator_tank_t tank[NTANKS] = {0}; shearwater_predator_tank_t tank[NTANKS] = {0};
unsigned int o2_previous = UNDEFINED, he_previous = UNDEFINED, dil_previous = UNDEFINED; unsigned int o2_previous = UNDEFINED, he_previous = UNDEFINED, dil_previous = UNDEFINED;
unsigned int aimode = AI_OFF; unsigned int aimode = AI_OFF;
unsigned int hpccr = 0;
if (!pnf) { if (!pnf) {
for (unsigned int i = 0; i < NFIXED; ++i) { for (unsigned int i = 0; i < NFIXED; ++i) {
gasmix[i].oxygen = data[20 + i]; gasmix[i].oxygen = data[20 + i];
@ -490,8 +501,8 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
tank[id].enabled = 1; tank[id].enabled = 1;
tank[id].beginpressure = pressure; tank[id].beginpressure = pressure;
tank[id].endpressure = pressure; tank[id].endpressure = pressure;
tank[id].name[0] = i == 0 ? 'D': 'O'; tank[id].usage = i == 0 ? DC_USAGE_DILUENT : DC_USAGE_OXYGEN;
tank[id].name[1] = 0; hpccr = 1;
} }
tank[id].endpressure = pressure; tank[id].endpressure = pressure;
} }
@ -535,9 +546,17 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
if (aimode == AI_HPCCR) { if (aimode == AI_HPCCR) {
for (unsigned int i = 0; i < 2; ++i) { for (unsigned int i = 0; i < 2; ++i) {
tank[4 + i].enabled = 1; tank[4 + i].enabled = 1;
tank[4 + i].name[0] = i == 0 ? 'D': 'O'; tank[4 + i].usage = i == 0 ? DC_USAGE_DILUENT : DC_USAGE_OXYGEN;
tank[4 + i].name[1] = 0;
} }
hpccr = 1;
}
}
}
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;
} }
} }
} }
@ -659,8 +678,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
for (unsigned int i = 0; i < ngasmixes; ++i) { for (unsigned int i = 0; i < ngasmixes; ++i) {
if (gasmix[i].oxygen == 0 && gasmix[i].helium == 0) if (gasmix[i].oxygen == 0 && gasmix[i].helium == 0)
continue; continue;
if (gasmix[i].diluent && if (gasmix[i].diluent && !shearwater_predator_is_ccr (divemode))
(divemode != M_CC && divemode != M_CC2 && divemode != M_SC))
continue; continue;
parser->gasmix[parser->ngasmixes] = gasmix[i]; parser->gasmix[parser->ngasmixes] = gasmix[i];
parser->ngasmixes++; parser->ngasmixes++;
@ -677,6 +695,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
} }
} }
parser->aimode = aimode; parser->aimode = aimode;
parser->hpccr = hpccr;
parser->divemode = divemode; parser->divemode = divemode;
parser->units = data[parser->opening[0] + 8]; parser->units = data[parser->opening[0] + 8];
parser->atmospheric = array_uint16_be (data + parser->opening[1] + (parser->pnf ? 16 : 47)); parser->atmospheric = array_uint16_be (data + parser->opening[1] + (parser->pnf ? 16 : 47));
@ -741,21 +760,20 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
tank->beginpressure = parser->tank[flags].beginpressure * 2 * PSI / BAR; tank->beginpressure = parser->tank[flags].beginpressure * 2 * PSI / BAR;
tank->endpressure = parser->tank[flags].endpressure * 2 * PSI / BAR; tank->endpressure = parser->tank[flags].endpressure * 2 * PSI / BAR;
tank->gasmix = DC_GASMIX_UNKNOWN; tank->gasmix = DC_GASMIX_UNKNOWN;
switch (parser->tank[flags].name[0]) { if (shearwater_predator_is_ccr (parser->divemode) && !parser->hpccr) {
case 'S': switch (parser->tank[flags].name[0]) {
tank->usage = DC_USAGE_SIDEMOUNT; case 'O':
break; tank->usage = DC_USAGE_OXYGEN;
case 'O': break;
tank->usage = DC_USAGE_OXYGEN; case 'D':
break; tank->usage = DC_USAGE_DILUENT;
case 'D': break;
tank->usage = DC_USAGE_DILUENT; default:
break; tank->usage = DC_USAGE_NONE;
case 'T': break;
case 'B': }
default: } else {
tank->usage = DC_USAGE_NONE; tank->usage = parser->tank[flags].usage;
break;
} }
break; break;
case DC_FIELD_SALINITY: case DC_FIELD_SALINITY: