Merge branch 'ostc-remove-disabled-gasmixes'

This commit is contained in:
Jef Driesen 2023-08-14 10:23:55 +02:00
commit beb348dbf6

View File

@ -37,10 +37,6 @@
#define UNDEFINED 0xFFFFFFFF
#define ALL 0
#define FIXED 1
#define MANUAL 2
#define HEADER 1
#define PROFILE 2
@ -108,10 +104,12 @@ typedef struct hw_ostc_layout_t {
} hw_ostc_layout_t;
typedef struct hw_ostc_gasmix_t {
unsigned int id;
unsigned int oxygen;
unsigned int helium;
unsigned int type;
unsigned int enabled;
unsigned int active;
unsigned int diluent;
} hw_ostc_gasmix_t;
@ -126,6 +124,7 @@ typedef struct hw_ostc_parser_t {
const hw_ostc_layout_t *layout;
unsigned int ngasmixes;
unsigned int nfixed;
unsigned int ndisabled;
unsigned int initial;
unsigned int initial_setpoint;
unsigned int initial_cns;
@ -136,6 +135,8 @@ static dc_status_t hw_ostc_parser_get_datetime (dc_parser_t *abstract, dc_dateti
static dc_status_t hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
static dc_status_t hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
static dc_status_t hw_ostc_parser_internal_foreach (hw_ostc_parser_t *parser, dc_sample_callback_t callback, void *userdata);
static const dc_parser_vtable_t hw_ostc_parser_vtable = {
sizeof(hw_ostc_parser_t),
DC_FAMILY_HW_OSTC,
@ -194,15 +195,10 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc3 = {
};
static unsigned int
hw_ostc_find_gasmix (hw_ostc_parser_t *parser, unsigned int o2, unsigned int he, unsigned int dil, unsigned int type)
hw_ostc_find_gasmix_manual (hw_ostc_parser_t *parser, unsigned int o2, unsigned int he, unsigned int dil)
{
unsigned int offset = 0;
unsigned int offset = parser->nfixed - parser->ndisabled;
unsigned int count = parser->ngasmixes;
if (type == FIXED) {
count = parser->nfixed;
} else if (type == MANUAL) {
offset = parser->nfixed;
}
unsigned int i = offset;
while (i < count) {
@ -214,6 +210,22 @@ hw_ostc_find_gasmix (hw_ostc_parser_t *parser, unsigned int o2, unsigned int he,
return i;
}
static unsigned int
hw_ostc_find_gasmix_fixed (hw_ostc_parser_t *parser, unsigned int id)
{
unsigned int offset = 0;
unsigned int count = parser->nfixed - parser->ndisabled;
unsigned int i = offset;
while (i < count) {
if (id == parser->gasmix[i].id)
break;
i++;
}
return i;
}
static unsigned int
hw_ostc_is_ccr (unsigned int divemode, unsigned int version)
{
@ -295,19 +307,23 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
initial = data[31];
}
for (unsigned int i = 0; i < ngasmixes; ++i) {
gasmix[i].id = i + 1;
gasmix[i].oxygen = data[25 + 2 * i];
gasmix[i].helium = 0;
gasmix[i].type = 0;
gasmix[i].enabled = 1;
gasmix[i].active = 0;
gasmix[i].diluent = 0;
}
} else if (version == 0x23 || version == 0x24) {
ngasmixes = 5;
for (unsigned int i = 0; i < ngasmixes; ++i) {
gasmix[i].id = i + 1;
gasmix[i].oxygen = data[28 + 4 * i + 0];
gasmix[i].helium = data[28 + 4 * i + 1];
gasmix[i].type = data[28 + 4 * i + 3];
gasmix[i].enabled = gasmix[i].type != 0;
gasmix[i].active = 0;
gasmix[i].diluent = ccr;
// Find the first gas marked as the initial gas.
if (initial == UNDEFINED && data[28 + 4 * i + 3] == 1) {
@ -326,6 +342,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
initial = data[31];
}
for (unsigned int i = 0; i < ngasmixes; ++i) {
gasmix[i].id = i + 1;
gasmix[i].oxygen = data[19 + 2 * i + 0];
gasmix[i].helium = data[19 + 2 * i + 1];
gasmix[i].type = 0;
@ -334,6 +351,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
} else {
gasmix[i].enabled = 1;
}
gasmix[i].active = 0;
gasmix[i].diluent = ccr;
}
}
@ -342,7 +360,6 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
ERROR(abstract->context, "Invalid initial gas mix.");
return DC_STATUS_DATAFORMAT;
}
initial--; /* Convert to a zero based index. */
} else {
WARNING(abstract->context, "No initial gas mix available.");
}
@ -353,6 +370,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
parser->layout = layout;
parser->ngasmixes = ngasmixes;
parser->nfixed = ngasmixes;
parser->ndisabled = 0;
parser->initial = initial;
parser->initial_setpoint = initial_setpoint;
parser->initial_cns = initial_cns;
@ -388,14 +406,17 @@ hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, const
parser->layout = NULL;
parser->ngasmixes = 0;
parser->nfixed = 0;
parser->ndisabled = 0;
parser->initial = 0;
parser->initial_setpoint = 0;
parser->initial_cns = 0;
for (unsigned int i = 0; i < NGASMIXES; ++i) {
parser->gasmix[i].id = 0;
parser->gasmix[i].oxygen = 0;
parser->gasmix[i].helium = 0;
parser->gasmix[i].type = 0;
parser->gasmix[i].enabled = 0;
parser->gasmix[i].active = 0;
parser->gasmix[i].diluent = 0;
}
@ -490,7 +511,7 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
// Cache the profile data.
if (parser->cached < PROFILE) {
rc = hw_ostc_parser_samples_foreach (abstract, NULL, NULL);
rc = hw_ostc_parser_internal_foreach (parser, NULL, NULL);
if (rc != DC_STATUS_SUCCESS)
return rc;
}
@ -678,17 +699,12 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
static dc_status_t
hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
hw_ostc_parser_internal_foreach (hw_ostc_parser_t *parser, dc_sample_callback_t callback, void *userdata)
{
hw_ostc_parser_t *parser = (hw_ostc_parser_t *) abstract;
dc_parser_t *abstract = (dc_parser_t *) parser;
const unsigned char *data = abstract->data;
unsigned int size = abstract->size;
// Cache the parser data.
dc_status_t rc = hw_ostc_parser_cache (parser);
if (rc != DC_STATUS_SUCCESS)
return rc;
unsigned int version = parser->version;
unsigned int header = parser->header;
const hw_ostc_layout_t *layout = parser->layout;
@ -794,7 +810,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
unsigned int time = 0;
unsigned int nsamples = 0;
unsigned int tank = parser->initial != UNDEFINED ? parser->initial : 0;
unsigned int tank = parser->initial != UNDEFINED ? parser->initial - 1 : 0;
unsigned int offset = header;
if (version == 0x23 || version == 0x24)
@ -811,7 +827,9 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
// Initial gas mix.
if (time == samplerate && parser->initial != UNDEFINED) {
sample.gasmix = parser->initial;
unsigned int idx = hw_ostc_find_gasmix_fixed (parser, parser->initial);
parser->gasmix[idx].active = 1;
sample.gasmix = idx;
if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
}
@ -899,16 +917,18 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
}
unsigned int o2 = data[offset];
unsigned int he = data[offset + 1];
unsigned int idx = hw_ostc_find_gasmix (parser, o2, he, ccr, MANUAL);
unsigned int idx = hw_ostc_find_gasmix_manual (parser, o2, he, ccr);
if (idx >= parser->ngasmixes) {
if (idx >= NGASMIXES) {
ERROR (abstract->context, "Maximum number of gas mixes reached.");
return DC_STATUS_NOMEMORY;
}
parser->gasmix[idx].id = 0;
parser->gasmix[idx].oxygen = o2;
parser->gasmix[idx].helium = he;
parser->gasmix[idx].type = 0;
parser->gasmix[idx].enabled = 1;
parser->gasmix[idx].active = 1;
parser->gasmix[idx].diluent = ccr;
parser->ngasmixes = idx + 1;
}
@ -925,19 +945,20 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
ERROR (abstract->context, "Buffer overflow detected!");
return DC_STATUS_DATAFORMAT;
}
unsigned int idx = data[offset];
if (parser->model == OSTC4 && ccr && idx > parser->nfixed) {
unsigned int id = data[offset];
if (parser->model == OSTC4 && ccr && id > parser->nfixed) {
// Fix the OSTC4 diluent index.
idx -= parser->nfixed;
id -= parser->nfixed;
}
if (idx < 1 || idx > parser->nfixed) {
ERROR(abstract->context, "Invalid gas mix (%u).", idx);
if (id < 1 || id > parser->nfixed) {
ERROR(abstract->context, "Invalid gas mix (%u).", id);
return DC_STATUS_DATAFORMAT;
}
idx--; /* Convert to a zero based index. */
unsigned int idx = hw_ostc_find_gasmix_fixed (parser, id);
parser->gasmix[idx].active = 1;
sample.gasmix = idx;
if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
tank = idx;
tank = id - 1;
offset++;
length--;
}
@ -964,16 +985,18 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
unsigned int o2 = data[offset];
unsigned int he = data[offset + 1];
unsigned int idx = hw_ostc_find_gasmix (parser, o2, he, 0, MANUAL);
unsigned int idx = hw_ostc_find_gasmix_manual (parser, o2, he, 0);
if (idx >= parser->ngasmixes) {
if (idx >= NGASMIXES) {
ERROR (abstract->context, "Maximum number of gas mixes reached.");
return DC_STATUS_NOMEMORY;
}
parser->gasmix[idx].id = 0;
parser->gasmix[idx].oxygen = o2;
parser->gasmix[idx].helium = he;
parser->gasmix[idx].type = 0;
parser->gasmix[idx].enabled = 1;
parser->gasmix[idx].active = 1;
parser->gasmix[idx].diluent = 0;
parser->ngasmixes = idx + 1;
}
@ -1099,16 +1122,18 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
unsigned int o2 = data[offset];
unsigned int he = data[offset + 1];
unsigned int idx = hw_ostc_find_gasmix (parser, o2, he, 0, MANUAL);
unsigned int idx = hw_ostc_find_gasmix_manual (parser, o2, he, 0);
if (idx >= parser->ngasmixes) {
if (idx >= NGASMIXES) {
ERROR (abstract->context, "Maximum number of gas mixes reached.");
return DC_STATUS_NOMEMORY;
}
parser->gasmix[idx].id = 0;
parser->gasmix[idx].oxygen = o2;
parser->gasmix[idx].helium = he;
parser->gasmix[idx].type = 0;
parser->gasmix[idx].enabled = 1;
parser->gasmix[idx].active = 1;
parser->gasmix[idx].diluent = 0;
parser->ngasmixes = idx + 1;
}
@ -1132,7 +1157,50 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
return DC_STATUS_DATAFORMAT;
}
// Remove the disabled gas mixes from the fixed gas mixes.
unsigned int ndisabled = 0, nenabled = 0;
unsigned int count = parser->nfixed - parser->ndisabled;
for (unsigned int i = 0; i < count; ++i) {
if (parser->gasmix[i].enabled || parser->gasmix[i].active) {
// Move the fixed gas mix.
parser->gasmix[nenabled] = parser->gasmix[i];
nenabled++;
} else {
ndisabled++;
}
}
// Move all the manual gas mixes.
memmove (parser->gasmix + nenabled, parser->gasmix + count,
(parser->ngasmixes - count) * sizeof (hw_ostc_gasmix_t));
memset (parser->gasmix + parser->ngasmixes - ndisabled, 0,
ndisabled * sizeof (hw_ostc_gasmix_t));
// Adjust the counts.
parser->ngasmixes -= ndisabled;
parser->ndisabled += ndisabled;
parser->cached = PROFILE;
return DC_STATUS_SUCCESS;
}
static dc_status_t
hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
{
hw_ostc_parser_t *parser = (hw_ostc_parser_t *) abstract;
// Cache the header data.
dc_status_t rc = hw_ostc_parser_cache (parser);
if (rc != DC_STATUS_SUCCESS)
return rc;
// Cache the profile data.
if (parser->cached < PROFILE) {
rc = hw_ostc_parser_internal_foreach (parser, NULL, NULL);
if (rc != DC_STATUS_SUCCESS)
return rc;
}
return hw_ostc_parser_internal_foreach (parser, callback, userdata);
}