Merge branch 'release-0.3'
Integrate the bugfixes from the stable branch.
This commit is contained in:
commit
ee8b4e36ad
@ -245,7 +245,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
|
||||
"OLF", "PO2", "airtime", "rgbm", "heading", "tissue level warning",
|
||||
"gaschange2"};
|
||||
static const char *decostop[] = {
|
||||
"ndl", "deco", "deep", "safety"};
|
||||
"ndl", "safety", "deco", "deep"};
|
||||
|
||||
sample_data_t *sampledata = (sample_data_t *) userdata;
|
||||
|
||||
|
||||
@ -124,6 +124,9 @@ cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const cha
|
||||
return DC_STATUS_IO;
|
||||
}
|
||||
|
||||
serial_sleep (device->port, 100);
|
||||
serial_flush (device->port, SERIAL_QUEUE_BOTH);
|
||||
|
||||
*out = (dc_device_t *) device;
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -268,6 +271,13 @@ cressi_leonardo_device_foreach (dc_device_t *abstract, dc_dive_callback_t callba
|
||||
return rc;
|
||||
}
|
||||
|
||||
unsigned char *data = dc_buffer_get_data (buffer);
|
||||
dc_event_devinfo_t devinfo;
|
||||
devinfo.model = 0;
|
||||
devinfo.firmware = 0;
|
||||
devinfo.serial = array_uint32_le (data + 1);
|
||||
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
|
||||
|
||||
rc = cressi_leonardo_extract_dives (abstract, dc_buffer_get_data (buffer),
|
||||
dc_buffer_get_size (buffer), callback, userdata);
|
||||
|
||||
@ -328,7 +338,7 @@ cressi_leonardo_extract_dives (dc_device_t *abstract, const unsigned char data[]
|
||||
if (header < RB_PROFILE_BEGIN || header + 2 > RB_PROFILE_END ||
|
||||
footer < RB_PROFILE_BEGIN || footer + 2 > RB_PROFILE_END)
|
||||
{
|
||||
ERROR (abstract->context, "Invalid ringbuffer pointer detected.");
|
||||
ERROR (context, "Invalid ringbuffer pointer detected.");
|
||||
free (buffer);
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
@ -337,7 +347,7 @@ cressi_leonardo_extract_dives (dc_device_t *abstract, const unsigned char data[]
|
||||
unsigned int header2 = array_uint16_le (data + footer);
|
||||
unsigned int footer2 = array_uint16_le (data + header);
|
||||
if (header2 != header || footer2 != footer) {
|
||||
ERROR (abstract->context, "Invalid ringbuffer pointer detected.");
|
||||
ERROR (context, "Invalid ringbuffer pointer detected.");
|
||||
free (buffer);
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
|
||||
@ -76,20 +76,33 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"Suunto", "D4i", DC_FAMILY_SUUNTO_D9, 0x19},
|
||||
{"Suunto", "D6i", DC_FAMILY_SUUNTO_D9, 0x1A},
|
||||
{"Suunto", "D9tx", DC_FAMILY_SUUNTO_D9, 0x1B},
|
||||
{"Suunto", "DX", DC_FAMILY_SUUNTO_D9, 0x1C},
|
||||
/* Uwatec Aladin */
|
||||
{"Uwatec", "Aladin", DC_FAMILY_UWATEC_ALADIN, 0},
|
||||
{"Uwatec", "Aladin Air Twin", DC_FAMILY_UWATEC_ALADIN, 0x1C},
|
||||
{"Uwatec", "Aladin Sport Plus", DC_FAMILY_UWATEC_ALADIN, 0x3E},
|
||||
{"Uwatec", "Aladin Pro", DC_FAMILY_UWATEC_ALADIN, 0x3F},
|
||||
{"Uwatec", "Aladin Air Z", DC_FAMILY_UWATEC_ALADIN, 0x44},
|
||||
{"Uwatec", "Aladin Air Z O2", DC_FAMILY_UWATEC_ALADIN, 0xA4},
|
||||
{"Uwatec", "Aladin Air Z Nitrox", DC_FAMILY_UWATEC_ALADIN, 0xF4},
|
||||
{"Uwatec", "Aladin Pro Ultra", DC_FAMILY_UWATEC_ALADIN, 0xFF},
|
||||
/* Uwatec Memomouse */
|
||||
{"Uwatec", "Memomouse", DC_FAMILY_UWATEC_MEMOMOUSE, 0},
|
||||
/* Uwatec Smart */
|
||||
#ifdef HAVE_IRDA
|
||||
{"Uwatec", "Smart Pro", DC_FAMILY_UWATEC_SMART, 0x10},
|
||||
{"Uwatec", "Galileo", DC_FAMILY_UWATEC_SMART, 0x11},
|
||||
{"Uwatec", "Galileo Sol", DC_FAMILY_UWATEC_SMART, 0x11},
|
||||
{"Uwatec", "Galileo Luna", DC_FAMILY_UWATEC_SMART, 0x11},
|
||||
{"Uwatec", "Galileo Terra", DC_FAMILY_UWATEC_SMART, 0x11},
|
||||
{"Uwatec", "Aladin Tec", DC_FAMILY_UWATEC_SMART, 0x12},
|
||||
{"Uwatec", "Aladin Prime", DC_FAMILY_UWATEC_SMART, 0x12},
|
||||
{"Uwatec", "Aladin Tec 2G", DC_FAMILY_UWATEC_SMART, 0x13},
|
||||
{"Uwatec", "Aladin 2G", DC_FAMILY_UWATEC_SMART, 0x13},
|
||||
{"Subgear","XP-10", DC_FAMILY_UWATEC_SMART, 0x13},
|
||||
{"Uwatec", "Smart Com", DC_FAMILY_UWATEC_SMART, 0x14},
|
||||
{"Uwatec", "Smart Tec", DC_FAMILY_UWATEC_SMART, 0x18},
|
||||
{"Uwatec", "Galileo Trimix",DC_FAMILY_UWATEC_SMART, 0x19},
|
||||
{"Uwatec", "Smart Z", DC_FAMILY_UWATEC_SMART, 0x1C},
|
||||
{"Subgear","XP Air", DC_FAMILY_UWATEC_SMART, 0x1C},
|
||||
#endif
|
||||
/* Reefnet */
|
||||
{"Reefnet", "Sensus", DC_FAMILY_REEFNET_SENSUS, 1},
|
||||
@ -97,10 +110,12 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"Reefnet", "Sensus Ultra", DC_FAMILY_REEFNET_SENSUSULTRA, 3},
|
||||
/* Oceanic VT Pro */
|
||||
{"Oceanic", "Versa Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4155},
|
||||
{"Aeris", "Atmos 2", DC_FAMILY_OCEANIC_VTPRO, 0x4158},
|
||||
{"Oceanic", "Pro Plus 2", DC_FAMILY_OCEANIC_VTPRO, 0x4159},
|
||||
{"Aeris", "Atmos AI", DC_FAMILY_OCEANIC_VTPRO, 0x4244},
|
||||
{"Oceanic", "VT Pro", DC_FAMILY_OCEANIC_VTPRO, 0x4245},
|
||||
{"Sherwood", "Wisdom", DC_FAMILY_OCEANIC_VTPRO, 0x4246},
|
||||
{"Aeris", "Elite", DC_FAMILY_OCEANIC_VTPRO, 0x424F},
|
||||
/* Oceanic Veo 250 */
|
||||
{"Genesis", "React Pro", DC_FAMILY_OCEANIC_VEO250, 0x4247},
|
||||
{"Oceanic", "Veo 200", DC_FAMILY_OCEANIC_VEO250, 0x424B},
|
||||
@ -123,6 +138,7 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x434E},
|
||||
{"Sherwood", "Wisdom 2", DC_FAMILY_OCEANIC_ATOM2, 0x4350},
|
||||
{"Sherwood", "Insight 2", DC_FAMILY_OCEANIC_ATOM2, 0x4353},
|
||||
{"Genesis", "React Pro White", DC_FAMILY_OCEANIC_ATOM2, 0x4354},
|
||||
{"Tusa", "Element II (IQ-750)", DC_FAMILY_OCEANIC_ATOM2, 0x4357},
|
||||
{"Oceanic", "Veo 1.0", DC_FAMILY_OCEANIC_ATOM2, 0x4358},
|
||||
{"Oceanic", "Veo 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4359},
|
||||
@ -137,14 +153,18 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"Oceanic", "Atom 3.0", DC_FAMILY_OCEANIC_ATOM2, 0x444C},
|
||||
{"Hollis", "DG03", DC_FAMILY_OCEANIC_ATOM2, 0x444D},
|
||||
{"Oceanic", "OCS", DC_FAMILY_OCEANIC_ATOM2, 0x4450},
|
||||
{"Oceanic", "OC1", DC_FAMILY_OCEANIC_ATOM2, 0x4451},
|
||||
{"Oceanic", "VT 4.1", DC_FAMILY_OCEANIC_ATOM2, 0x4452},
|
||||
{"Aeris", "Epic", DC_FAMILY_OCEANIC_ATOM2, 0x4453},
|
||||
{"Aeris", "Elite T3", DC_FAMILY_OCEANIC_ATOM2, 0x4455},
|
||||
{"Oceanic", "Atom 3.1", DC_FAMILY_OCEANIC_ATOM2, 0x4456},
|
||||
{"Aeris", "A300 AI", DC_FAMILY_OCEANIC_ATOM2, 0x4457},
|
||||
{"Sherwood", "Wisdom 3", DC_FAMILY_OCEANIC_ATOM2, 0x4458},
|
||||
{"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548},
|
||||
/* Mares Nemo */
|
||||
{"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0},
|
||||
{"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0},
|
||||
{"Mares", "Nemo Titanium",DC_FAMILY_MARES_NEMO, 0},
|
||||
{"Mares", "Nemo Excel", DC_FAMILY_MARES_NEMO, 17},
|
||||
{"Mares", "Nemo Apneist", DC_FAMILY_MARES_NEMO, 18},
|
||||
/* Mares Puck */
|
||||
|
||||
@ -152,6 +152,8 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
|
||||
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
|
||||
|
||||
unsigned int air = (p[0] & 0x02) == 0;
|
||||
|
||||
if (value) {
|
||||
switch (type) {
|
||||
case DC_FIELD_DIVETIME:
|
||||
@ -161,11 +163,27 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
*((double *) value) = array_uint16_le (p + 0x04) / 10.0;
|
||||
break;
|
||||
case DC_FIELD_GASMIX_COUNT:
|
||||
*((unsigned int *) value) = 3;
|
||||
if (air) {
|
||||
*((unsigned int *) value) = 1;
|
||||
} else {
|
||||
// Count the number of active gas mixes. The active gas
|
||||
// mixes are always first, so we stop counting as soon
|
||||
// as the first gas marked as disabled is found.
|
||||
unsigned int i = 0;
|
||||
while (i < 3) {
|
||||
if (p[0x14 + i * 4 + 1] & 0x80)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
*((unsigned int *) value) = i;
|
||||
}
|
||||
break;
|
||||
case DC_FIELD_GASMIX:
|
||||
if (air)
|
||||
gasmix->oxygen = 0.21;
|
||||
else
|
||||
gasmix->oxygen = p[0x14 + flags * 4] / 100.0;
|
||||
gasmix->helium = 0.0;
|
||||
gasmix->oxygen = p[0x14 + flags * 4] / 100.0;
|
||||
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
|
||||
break;
|
||||
default:
|
||||
|
||||
@ -89,6 +89,7 @@ static const oceanic_common_version_t oceanic_atom2b_version[] = {
|
||||
{"ELEMENT2 \0\0 512K"},
|
||||
{"OCEVEO20 \0\0 512K"},
|
||||
{"TUSAZEN \0\0 512K"},
|
||||
{"PROPLUS3 \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_atom2c_version[] = {
|
||||
@ -124,6 +125,10 @@ static const oceanic_common_version_t oceanic_veo1_version[] = {
|
||||
{"OCEVEO10 \0\0 8K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_reactpro_version[] = {
|
||||
{"REACPRO2 \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_layout_t aeris_f10_layout = {
|
||||
0x10000, /* memsize */
|
||||
0x0000, /* cf_devinfo */
|
||||
@ -241,6 +246,18 @@ static const oceanic_common_layout_t oceanic_veo1_layout = {
|
||||
0 /* pt_mode_logbook */
|
||||
};
|
||||
|
||||
static const oceanic_common_layout_t oceanic_reactpro_layout = {
|
||||
0xFFF0, /* memsize */
|
||||
0x0000, /* cf_devinfo */
|
||||
0x0040, /* cf_pointers */
|
||||
0x0400, /* rb_logbook_begin */
|
||||
0x0600, /* rb_logbook_end */
|
||||
8, /* rb_logbook_entry_size */
|
||||
0x0600, /* rb_profile_begin */
|
||||
0xFFF0, /* rb_profile_end */
|
||||
1, /* pt_mode_global */
|
||||
1 /* pt_mode_logbook */
|
||||
};
|
||||
|
||||
static dc_status_t
|
||||
oceanic_atom2_send (oceanic_atom2_device_t *device, const unsigned char command[], unsigned int csize, unsigned char ack)
|
||||
@ -418,6 +435,8 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char
|
||||
device->base.layout = &oceanic_oc1_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_veo1_version)) {
|
||||
device->base.layout = &oceanic_veo1_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_reactpro_version)) {
|
||||
device->base.layout = &oceanic_reactpro_layout;
|
||||
} else {
|
||||
device->base.layout = &oceanic_default_layout;
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#define COMPUMASK 0x4348
|
||||
#define OC1A 0x434E
|
||||
#define F10 0x434D
|
||||
#define ELEMENT2 0x4357
|
||||
#define VEO20 0x4359
|
||||
#define VEO30 0x435A
|
||||
#define ZENAIR 0x4442
|
||||
@ -51,10 +52,12 @@
|
||||
#define ATOM3 0x444C
|
||||
#define DG03 0x444D
|
||||
#define OCS 0x4450
|
||||
#define OC1C 0x4451
|
||||
#define VT41 0x4452
|
||||
#define EPICB 0x4453
|
||||
#define ATOM31 0x4456
|
||||
#define A300AI 0x4457
|
||||
#define PROPLUS3 0x4548
|
||||
|
||||
typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t;
|
||||
|
||||
@ -156,6 +159,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
|
||||
switch (parser->model) {
|
||||
case OC1A:
|
||||
case OC1B:
|
||||
case OC1C:
|
||||
case OCS:
|
||||
case VT4:
|
||||
case VT41:
|
||||
@ -262,7 +266,7 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
|
||||
if (parser->model == DATAMASK || parser->model == COMPUMASK ||
|
||||
parser->model == GEO || parser->model == GEO20 ||
|
||||
parser->model == VEO20 || parser->model == VEO30 ||
|
||||
parser->model == OCS) {
|
||||
parser->model == OCS || parser->model == PROPLUS3) {
|
||||
headersize -= PAGESIZE;
|
||||
} else if (parser->model == VT4 || parser->model == VT41) {
|
||||
headersize += PAGESIZE;
|
||||
@ -353,7 +357,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
if (parser->model == DATAMASK || parser->model == COMPUMASK ||
|
||||
parser->model == GEO || parser->model == GEO20 ||
|
||||
parser->model == VEO20 || parser->model == VEO30 ||
|
||||
parser->model == OCS) {
|
||||
parser->model == OCS || parser->model == PROPLUS3) {
|
||||
headersize -= PAGESIZE;
|
||||
} else if (parser->model == VT4 || parser->model == VT41) {
|
||||
headersize += PAGESIZE;
|
||||
@ -390,13 +394,14 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
}
|
||||
|
||||
unsigned int samplesize = PAGESIZE / 2;
|
||||
if (parser->model == OC1A || parser->model == OC1B)
|
||||
if (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C)
|
||||
samplesize = PAGESIZE;
|
||||
else if (parser->model == F10)
|
||||
samplesize = 2;
|
||||
|
||||
unsigned int have_temperature = 1, have_pressure = 1;
|
||||
if (parser->model == VEO30 || parser->model == OCS) {
|
||||
if (parser->model == VEO30 || parser->model == OCS ||
|
||||
parser->model == ELEMENT2) {
|
||||
have_pressure = 0;
|
||||
} else if (parser->model == F10) {
|
||||
have_temperature = 0;
|
||||
@ -494,11 +499,12 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
} else {
|
||||
// Temperature (°F)
|
||||
if (have_temperature) {
|
||||
if (parser->model == GEO || parser->model == ATOM1) {
|
||||
if (parser->model == GEO || parser->model == ATOM1 ||
|
||||
parser->model == ELEMENT2) {
|
||||
temperature = data[offset + 6];
|
||||
} else if (parser->model == GEO20 || parser->model == VEO20 ||
|
||||
parser->model == VEO30 || parser->model == OC1A ||
|
||||
parser->model == OC1B) {
|
||||
parser->model == OC1B || parser->model == OC1C) {
|
||||
temperature = data[offset + 3];
|
||||
} else if (parser->model == OCS) {
|
||||
temperature = data[offset + 1];
|
||||
@ -506,7 +512,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
temperature = ((data[offset + 7] & 0xF0) >> 4) | ((data[offset + 7] & 0x0C) << 2) | ((data[offset + 5] & 0x0C) << 4);
|
||||
} else {
|
||||
unsigned int sign;
|
||||
if (parser->model == DG03)
|
||||
if (parser->model == DG03 || parser->model == PROPLUS3)
|
||||
sign = (~data[offset + 5] & 0x04) >> 2;
|
||||
else if (parser->model == ATOM2 || parser->model == PROPLUS21 ||
|
||||
parser->model == EPICA || parser->model == EPICB)
|
||||
@ -524,12 +530,12 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
|
||||
// Tank Pressure (psi)
|
||||
if (have_pressure) {
|
||||
if (parser->model == OC1A || parser->model == OC1B)
|
||||
if (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C)
|
||||
pressure = (data[offset + 10] + (data[offset + 11] << 8)) & 0x0FFF;
|
||||
else if (parser->model == VT4 || parser->model == VT41||
|
||||
parser->model == ATOM3 || parser->model == ATOM31 ||
|
||||
parser->model == ZENAIR ||parser->model == A300AI ||
|
||||
parser->model == DG03)
|
||||
parser->model == DG03 || parser->model == PROPLUS3)
|
||||
pressure = (((data[offset + 0] & 0x03) << 8) + data[offset + 1]) * 5;
|
||||
else
|
||||
pressure -= data[offset + 1];
|
||||
@ -542,7 +548,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
unsigned int depth;
|
||||
if (parser->model == GEO20 || parser->model == VEO20 ||
|
||||
parser->model == VEO30 || parser->model == OC1A ||
|
||||
parser->model == OC1B)
|
||||
parser->model == OC1B || parser->model == OC1C)
|
||||
depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF;
|
||||
else if (parser->model == ATOM1)
|
||||
depth = data[offset + 3] * 16;
|
||||
|
||||
@ -31,6 +31,11 @@
|
||||
|
||||
#define ISINSTANCE(parser) dc_parser_isinstance((parser), &oceanic_veo250_parser_vtable)
|
||||
|
||||
#define REACTPRO 0x4247
|
||||
#define VEO200 0x424B
|
||||
#define VEO250 0x424C
|
||||
#define REACTPROWHITE 0x4354
|
||||
|
||||
typedef struct oceanic_veo250_parser_t oceanic_veo250_parser_t;
|
||||
|
||||
struct oceanic_veo250_parser_t {
|
||||
@ -128,8 +133,10 @@ oceanic_veo250_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *dateti
|
||||
datetime->minute = p[2];
|
||||
datetime->second = 0;
|
||||
|
||||
if (parser->model == 0x424B || parser->model == 0x424C)
|
||||
if (parser->model == VEO200 || parser->model == VEO250)
|
||||
datetime->year += 3;
|
||||
else if (parser->model == REACTPRO)
|
||||
datetime->year += 2;
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
@ -194,6 +201,7 @@ oceanic_veo250_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
|
||||
static dc_status_t
|
||||
oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
|
||||
{
|
||||
oceanic_veo250_parser_t *parser = (oceanic_veo250_parser_t *) abstract;
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int size = abstract->size;
|
||||
|
||||
@ -202,7 +210,12 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
|
||||
|
||||
unsigned int time = 0;
|
||||
unsigned int interval = 0;
|
||||
switch (data[0x27] & 0x03) {
|
||||
unsigned int interval_idx = data[0x27] & 0x03;
|
||||
if (parser->model == REACTPRO || parser->model == REACTPROWHITE) {
|
||||
interval_idx += 1;
|
||||
interval_idx %= 4;
|
||||
}
|
||||
switch (interval_idx) {
|
||||
case 0:
|
||||
interval = 2;
|
||||
break;
|
||||
@ -244,7 +257,12 @@ oceanic_veo250_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback
|
||||
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
|
||||
|
||||
// Temperature (°F)
|
||||
unsigned int temperature = data[offset + 7];
|
||||
unsigned int temperature;
|
||||
if (parser->model == REACTPRO || parser->model == REACTPROWHITE) {
|
||||
temperature = data[offset + 6];
|
||||
} else {
|
||||
temperature = data[offset + 7];
|
||||
}
|
||||
sample.temperature = (temperature - 32.0) * (5.0 / 9.0);
|
||||
if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
|
||||
|
||||
|
||||
@ -65,9 +65,11 @@ static const dc_device_vtable_t oceanic_vtpro_device_vtable = {
|
||||
|
||||
static const oceanic_common_version_t oceanic_vtpro_version[] = {
|
||||
{"VERSAPRO \0\0 256K"},
|
||||
{"ATMOSTWO \0\0 256K"},
|
||||
{"PROPLUS2 \0\0 256K"},
|
||||
{"ATMOSAIR \0\0 256K"},
|
||||
{"VTPRO r\0\0 256K"},
|
||||
{"ELITE r\0\0 256K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_wisdom_version[] = {
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
#include "parser-private.h"
|
||||
#include "device-private.h"
|
||||
|
||||
#define REACTPROWHITE 0x4354
|
||||
|
||||
dc_status_t
|
||||
dc_parser_new (dc_parser_t **out, dc_device_t *device)
|
||||
{
|
||||
@ -86,7 +88,10 @@ dc_parser_new (dc_parser_t **out, dc_device_t *device)
|
||||
rc = oceanic_veo250_parser_create (&parser, context, device->devinfo.model);
|
||||
break;
|
||||
case DC_FAMILY_OCEANIC_ATOM2:
|
||||
rc = oceanic_atom2_parser_create (&parser, context, device->devinfo.model);
|
||||
if (device->devinfo.model == REACTPROWHITE)
|
||||
rc = oceanic_veo250_parser_create (&parser, context, device->devinfo.model);
|
||||
else
|
||||
rc = oceanic_atom2_parser_create (&parser, context, device->devinfo.model);
|
||||
break;
|
||||
case DC_FAMILY_MARES_NEMO:
|
||||
case DC_FAMILY_MARES_PUCK:
|
||||
|
||||
@ -141,7 +141,7 @@ shearwater_predator_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *d
|
||||
|
||||
unsigned int ticks = array_uint32_be (data + 12);
|
||||
|
||||
if (!dc_datetime_localtime (datetime, ticks))
|
||||
if (!dc_datetime_gmtime (datetime, ticks))
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
#define D4i 0x19
|
||||
#define D6i 0x1A
|
||||
#define D9tx 0x1B
|
||||
#define DX 0x1C
|
||||
|
||||
typedef struct suunto_d9_device_t {
|
||||
suunto_common2_device_t base;
|
||||
@ -81,6 +82,14 @@ static const suunto_common2_layout_t suunto_d9tx_layout = {
|
||||
0xEBF0 /* rb_profile_end */
|
||||
};
|
||||
|
||||
static const suunto_common2_layout_t suunto_dx_layout = {
|
||||
0x10000, /* memsize */
|
||||
0x0017, /* fingerprint */
|
||||
0x0024, /* serial */
|
||||
0x019A, /* rb_profile_begin */
|
||||
0xEBF0 /* rb_profile_end */
|
||||
};
|
||||
|
||||
|
||||
static dc_status_t
|
||||
suunto_d9_device_autodetect (suunto_d9_device_t *device, unsigned int model)
|
||||
@ -93,7 +102,7 @@ suunto_d9_device_autodetect (suunto_d9_device_t *device, unsigned int model)
|
||||
|
||||
// Use the model number as a hint to speedup the detection.
|
||||
unsigned int hint = 0;
|
||||
if (model == D4i || model == D6i || model == D9tx)
|
||||
if (model == D4i || model == D6i || model == D9tx || model == DX)
|
||||
hint = 1;
|
||||
|
||||
for (unsigned int i = 0; i < C_ARRAY_SIZE(baudrates); ++i) {
|
||||
@ -188,6 +197,8 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam
|
||||
model = device->base.version[0];
|
||||
if (model == D4i || model == D6i || model == D9tx)
|
||||
device->base.layout = &suunto_d9tx_layout;
|
||||
else if (model == DX)
|
||||
device->base.layout = &suunto_dx_layout;
|
||||
else
|
||||
device->base.layout = &suunto_d9_layout;
|
||||
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
#define D4i 0x19
|
||||
#define D6i 0x1A
|
||||
#define D9tx 0x1B
|
||||
#define DX 0x1C
|
||||
|
||||
#define AIR 0
|
||||
#define NITROX 1
|
||||
@ -132,7 +133,7 @@ suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
||||
suunto_d9_parser_t *parser = (suunto_d9_parser_t*) abstract;
|
||||
|
||||
unsigned int offset = 0x11;
|
||||
if (parser->model == HELO2)
|
||||
if (parser->model == HELO2 || parser->model == DX)
|
||||
offset = 0x17;
|
||||
else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx)
|
||||
offset = 0x13;
|
||||
@ -143,7 +144,8 @@ suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
||||
const unsigned char *p = abstract->data + offset;
|
||||
|
||||
if (datetime) {
|
||||
if (parser->model == D4i || parser->model == D6i || parser->model == D9tx) {
|
||||
if (parser->model == D4i || parser->model == D6i ||
|
||||
parser->model == D9tx || parser->model == DX) {
|
||||
datetime->year = p[0] + (p[1] << 8);
|
||||
datetime->month = p[2];
|
||||
datetime->day = p[3];
|
||||
@ -189,6 +191,9 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
|
||||
} else if (parser->model == D9tx) {
|
||||
gasmix_offset = 0x87;
|
||||
gasmix_count = 8;
|
||||
} else if (parser->model == DX) {
|
||||
gasmix_offset = 0xC1;
|
||||
gasmix_count = 11;
|
||||
}
|
||||
|
||||
// Offset to the configuration data.
|
||||
@ -196,7 +201,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
|
||||
if (parser->model == D4) {
|
||||
config += 1;
|
||||
} else if (parser->model == HELO2 || parser->model == D4i ||
|
||||
parser->model == D6i || parser->model == D9tx) {
|
||||
parser->model == D6i || parser->model == D9tx ||
|
||||
parser->model == DX) {
|
||||
config = gasmix_offset + gasmix_count * 6;
|
||||
}
|
||||
if (config + 1 > size)
|
||||
@ -208,6 +214,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
|
||||
gasmodel_offset = 0x1F;
|
||||
else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx)
|
||||
gasmodel_offset = 0x1D;
|
||||
else if (parser->model == DX)
|
||||
gasmodel_offset = 0x21;
|
||||
unsigned int gasmodel = data[gasmodel_offset];
|
||||
|
||||
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
|
||||
@ -217,7 +225,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
|
||||
case DC_FIELD_DIVETIME:
|
||||
if (parser->model == D4)
|
||||
*((unsigned int *) value) = array_uint16_le (data + 0x0B);
|
||||
else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx)
|
||||
else if (parser->model == D4i || parser->model == D6i ||
|
||||
parser->model == D9tx || parser->model == DX)
|
||||
*((unsigned int *) value) = array_uint16_le (data + 0x0D);
|
||||
else if (parser->model == HELO2)
|
||||
*((unsigned int *) value) = array_uint16_le (data + 0x0D) * 60;
|
||||
@ -239,7 +248,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne
|
||||
gasmix->helium = 0.0;
|
||||
gasmix->oxygen = 0.21;
|
||||
} else if (parser->model == HELO2 || parser->model == D4i ||
|
||||
parser->model == D6i || parser->model == D9tx) {
|
||||
parser->model == D6i || parser->model == D9tx ||
|
||||
parser->model == DX) {
|
||||
gasmix->helium = data[gasmix_offset + 6 * flags + 2] / 100.0;
|
||||
gasmix->oxygen = data[gasmix_offset + 6 * flags + 1] / 100.0;
|
||||
} else {
|
||||
@ -282,6 +292,9 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
|
||||
} else if (parser->model == D9tx) {
|
||||
gasmix_offset = 0x87;
|
||||
gasmix_count = 8;
|
||||
} else if (parser->model == DX) {
|
||||
gasmix_offset = 0xC1;
|
||||
gasmix_count = 11;
|
||||
}
|
||||
|
||||
// Offset to the configuration data.
|
||||
@ -289,7 +302,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
|
||||
if (parser->model == D4) {
|
||||
config += 1;
|
||||
} else if (parser->model == HELO2 || parser->model == D4i ||
|
||||
parser->model == D6i || parser->model == D9tx) {
|
||||
parser->model == D6i || parser->model == D9tx ||
|
||||
parser->model == DX) {
|
||||
config = gasmix_offset + gasmix_count * 6;
|
||||
}
|
||||
if (config + 1 > size)
|
||||
@ -297,7 +311,7 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
|
||||
|
||||
// Number of parameters in the configuration data.
|
||||
unsigned int nparams = data[config];
|
||||
if (nparams > MAXPARAMS)
|
||||
if (nparams == 0 || nparams > MAXPARAMS)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
// Available divisor values.
|
||||
@ -340,6 +354,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
|
||||
if (parser->model == HELO2 || parser->model == D4i ||
|
||||
parser->model == D6i || parser->model == D9tx)
|
||||
interval_sample_offset = 0x1E;
|
||||
else if (parser->model == DX)
|
||||
interval_sample_offset = 0x22;
|
||||
unsigned int interval_sample = data[interval_sample_offset];
|
||||
if (interval_sample == 0)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
@ -584,7 +584,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
|
||||
break;
|
||||
case TEMPERATURE:
|
||||
if (table[id].absolute) {
|
||||
temperature = value / 2.5;
|
||||
temperature = svalue / 2.5;
|
||||
have_temperature = 1;
|
||||
} else {
|
||||
temperature += svalue / 2.5;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user