Heinrichs Weikamp OSTC: add extended information parsing
This adds the string field interface to the HW OSTC family, including the proper serial number handling. The deco model information was done by Anton Lundin in the original subsurface branch, and the salinity, serial number, battery voltage and desat information was added by Dirk Hohndel. Jan Mulder added the battery percentage. [ The sign-offs have been taken from the original commits in that old subsurface branch, and I'm marking Dirk as the main author because on the whole most of the lines come from him - Linus ] Signed-off-by: Anton Lundin <glance@acc.umu.se> Signed-off-by: Jan Mulder <jlmulder@xs4all.nl> Signed-off-by: Dirk Hohndel <dirk@hohndel.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
a6637442b7
commit
9a38a1ac6d
@ -36,7 +36,7 @@ dc_status_t
|
||||
hw_ostc_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
|
||||
|
||||
dc_status_t
|
||||
hw_ostc_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int hwos);
|
||||
hw_ostc_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int serial, unsigned int hwos);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ dc_status_t
|
||||
hw_ostc3_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
|
||||
|
||||
dc_status_t
|
||||
hw_ostc3_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model);
|
||||
hw_ostc3_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int serial, unsigned int model);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -20,6 +20,12 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#include "libdivecomputer/units.h"
|
||||
|
||||
@ -61,8 +67,14 @@
|
||||
#define OSTC3_APNEA 3
|
||||
#define OSTC3_PSCR 4
|
||||
|
||||
#define OSTC3_ZHL16 0
|
||||
#define OSTC3_ZHL16_GF 1
|
||||
#define OSTC4_VPM 2
|
||||
|
||||
#define OSTC4 0x3B
|
||||
|
||||
#define UNSUPPORTED 0xFFFFFFFF
|
||||
|
||||
typedef struct hw_ostc_sample_info_t {
|
||||
unsigned int type;
|
||||
unsigned int divisor;
|
||||
@ -78,7 +90,13 @@ typedef struct hw_ostc_layout_t {
|
||||
unsigned int salinity;
|
||||
unsigned int duration;
|
||||
unsigned int temperature;
|
||||
unsigned int battery;
|
||||
unsigned int desat;
|
||||
unsigned int firmware;
|
||||
unsigned int deco_info1;
|
||||
unsigned int deco_info2;
|
||||
unsigned int decomode;
|
||||
unsigned int battery_percentage;
|
||||
} hw_ostc_layout_t;
|
||||
|
||||
typedef struct hw_ostc_gasmix_t {
|
||||
@ -90,6 +108,7 @@ typedef struct hw_ostc_parser_t {
|
||||
dc_parser_t base;
|
||||
unsigned int hwos;
|
||||
unsigned int model;
|
||||
unsigned int serial;
|
||||
// Cached fields.
|
||||
unsigned int cached;
|
||||
unsigned int version;
|
||||
@ -127,7 +146,13 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc = {
|
||||
43, /* salinity */
|
||||
47, /* duration */
|
||||
13, /* temperature */
|
||||
34, /* battery volt after dive */
|
||||
17, /* desat */
|
||||
32, /* firmware */
|
||||
49, /* deco_info1 */
|
||||
50, /* deco_info1 */
|
||||
51, /* decomode */
|
||||
0, /* battery percentage TBD */
|
||||
};
|
||||
|
||||
static const hw_ostc_layout_t hw_ostc_layout_frog = {
|
||||
@ -139,7 +164,13 @@ static const hw_ostc_layout_t hw_ostc_layout_frog = {
|
||||
43, /* salinity */
|
||||
47, /* duration */
|
||||
19, /* temperature */
|
||||
34, /* battery volt after dive */
|
||||
23, /* desat */
|
||||
32, /* firmware */
|
||||
49, /* deco_info1 */
|
||||
50, /* deco_info2 */
|
||||
51, /* decomode */
|
||||
0, /* battery percentage TBD */
|
||||
};
|
||||
|
||||
static const hw_ostc_layout_t hw_ostc_layout_ostc3 = {
|
||||
@ -151,7 +182,13 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc3 = {
|
||||
70, /* salinity */
|
||||
75, /* duration */
|
||||
22, /* temperature */
|
||||
50, /* battery volt after dive */
|
||||
26, /* desat */
|
||||
48, /* firmware */
|
||||
77, /* deco_info1 */
|
||||
78, /* deco_info2 */
|
||||
79, /* decomode */
|
||||
59, /* battery percentage */
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
@ -294,7 +331,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
|
||||
}
|
||||
|
||||
static dc_status_t
|
||||
hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, unsigned int hwos, unsigned int model)
|
||||
hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, unsigned int serial, unsigned int hwos, unsigned int model)
|
||||
{
|
||||
hw_ostc_parser_t *parser = NULL;
|
||||
|
||||
@ -324,6 +361,7 @@ hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, unsign
|
||||
parser->gasmix[i].oxygen = 0;
|
||||
parser->gasmix[i].helium = 0;
|
||||
}
|
||||
parser->serial = serial;
|
||||
|
||||
*out = (dc_parser_t *) parser;
|
||||
|
||||
@ -332,15 +370,15 @@ hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, unsign
|
||||
|
||||
|
||||
dc_status_t
|
||||
hw_ostc_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int hwos)
|
||||
hw_ostc_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int serial, unsigned int hwos)
|
||||
{
|
||||
return hw_ostc_parser_create_internal (out, context, hwos, 0);
|
||||
return hw_ostc_parser_create_internal (out, context, serial, hwos, 0);
|
||||
}
|
||||
|
||||
dc_status_t
|
||||
hw_ostc3_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
|
||||
hw_ostc3_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int serial, unsigned int model)
|
||||
{
|
||||
return hw_ostc_parser_create_internal (out, context, 1, model);
|
||||
return hw_ostc_parser_create_internal (out, context, serial, 1, model);
|
||||
}
|
||||
|
||||
static dc_status_t
|
||||
@ -428,6 +466,8 @@ hw_ostc_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define BUFLEN 32
|
||||
|
||||
static dc_status_t
|
||||
hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value)
|
||||
{
|
||||
@ -452,9 +492,12 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
|
||||
|
||||
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
|
||||
dc_salinity_t *water = (dc_salinity_t *) value;
|
||||
dc_field_string_t *string = (dc_field_string_t *) value;
|
||||
|
||||
unsigned int salinity = data[layout->salinity];
|
||||
if (version == 0x23 || version == 0x24)
|
||||
salinity += 100;
|
||||
char buf[BUFLEN];
|
||||
|
||||
if (value) {
|
||||
switch (type) {
|
||||
@ -550,6 +593,79 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
break;
|
||||
case DC_FIELD_STRING:
|
||||
switch(flags) {
|
||||
case 0: /* serial */
|
||||
string->desc = "Serial";
|
||||
snprintf(buf, BUFLEN, "%u", parser->serial);
|
||||
break;
|
||||
case 1: /* battery */
|
||||
string->desc = "Battery at end";
|
||||
unsigned int percentage = (unsigned int) data[layout->battery_percentage];
|
||||
if (percentage != 0xFF && (version == 0x23 || version == 0x24)) {
|
||||
percentage = percentage>100? 100: percentage;
|
||||
snprintf(buf, BUFLEN, "%.2fV, %u%% remaining",
|
||||
array_uint16_le (data + layout->battery) / 1000.0,
|
||||
percentage);
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "%.2fV", array_uint16_le (data + layout->battery) / 1000.0);
|
||||
}
|
||||
break;
|
||||
case 2: /* desat */
|
||||
string->desc = "Desat time";
|
||||
snprintf(buf, BUFLEN, "%0u:%02u", array_uint16_le (data + layout->desat) / 60,
|
||||
array_uint16_le (data + layout->desat) % 60);
|
||||
break;
|
||||
case 3: /* firmware */
|
||||
string->desc = "FW Version";
|
||||
/* OSTC4 stores firmware as XXXX XYYY YYZZ ZZZB, -> X.Y.Z beta? */
|
||||
if (parser->model == OSTC4) {
|
||||
int firmwareOnDevice = array_uint16_le (data + layout->firmware);
|
||||
unsigned char X = 0, Y = 0, Z = 0, beta = 0;
|
||||
X = (firmwareOnDevice & 0xF800) >> 11;
|
||||
Y = (firmwareOnDevice & 0x07C0) >> 6;
|
||||
Z = (firmwareOnDevice & 0x003E) >> 1;
|
||||
beta = firmwareOnDevice & 0x0001;
|
||||
|
||||
snprintf(buf, BUFLEN, "%u.%u.%u%s\n", X, Y, Z, beta? "beta": "");
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "%0u.%02u", data[layout->firmware], data[layout->firmware + 1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: /* Deco model */
|
||||
string->desc = "Deco model";
|
||||
if (((version == 0x23 || version == 0x24) && data[layout->decomode] == OSTC3_ZHL16) ||
|
||||
(version == 0x22 && data[layout->decomode] == FROG_ZHL16) ||
|
||||
(version == 0x21 && (data[layout->decomode] == OSTC_ZHL16_OC || data[layout->decomode] == OSTC_ZHL16_CC)))
|
||||
strncpy(buf, "ZH-L16", BUFLEN);
|
||||
else if (((version == 0x23 || version == 0x24) && data[layout->decomode] == OSTC3_ZHL16_GF) ||
|
||||
(version == 0x22 && data[layout->decomode] == FROG_ZHL16_GF) ||
|
||||
(version == 0x21 && (data[layout->decomode] == OSTC_ZHL16_OC_GF || data[layout->decomode] == OSTC_ZHL16_CC_GF)))
|
||||
strncpy(buf, "ZH-L16-GF", BUFLEN);
|
||||
else if (((version == 0x24) && data[layout->decomode] == OSTC4_VPM))
|
||||
strncpy(buf, "VPM", BUFLEN);
|
||||
else
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
break;
|
||||
case 5: /* Deco model info */
|
||||
string->desc = "Deco model info";
|
||||
if (((version == 0x23 || version == 0x24) && data[layout->decomode] == OSTC3_ZHL16) ||
|
||||
(version == 0x22 && data[layout->decomode] == FROG_ZHL16) ||
|
||||
(version == 0x21 && (data[layout->decomode] == OSTC_ZHL16_OC || data[layout->decomode] == OSTC_ZHL16_CC)))
|
||||
snprintf(buf, BUFLEN, "Saturation %u, Desaturation %u", layout->deco_info1, layout->deco_info2);
|
||||
else if (((version == 0x23 || version == 0x24) && data[layout->decomode] == OSTC3_ZHL16_GF) ||
|
||||
(version == 0x22 && data[layout->decomode] == FROG_ZHL16_GF) ||
|
||||
(version == 0x21 && (data[layout->decomode] == OSTC_ZHL16_OC_GF || data[layout->decomode] == OSTC_ZHL16_CC_GF)))
|
||||
snprintf(buf, BUFLEN, "GF %u/%u", data[layout->deco_info1], data[layout->deco_info2]);
|
||||
else
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
break;
|
||||
default:
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
string->value = strdup(buf);
|
||||
break;
|
||||
default:
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -133,11 +133,11 @@ dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, dc_family_t fa
|
||||
rc = mares_iconhd_parser_create (&parser, context, model);
|
||||
break;
|
||||
case DC_FAMILY_HW_OSTC:
|
||||
rc = hw_ostc_parser_create (&parser, context, 0);
|
||||
rc = hw_ostc_parser_create (&parser, context, serial, 0);
|
||||
break;
|
||||
case DC_FAMILY_HW_FROG:
|
||||
case DC_FAMILY_HW_OSTC3:
|
||||
rc = hw_ostc3_parser_create (&parser, context, model);
|
||||
rc = hw_ostc3_parser_create (&parser, context, serial, model);
|
||||
break;
|
||||
case DC_FAMILY_CRESSI_EDY:
|
||||
case DC_FAMILY_ZEAGLE_N2ITION3:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user