Merge branch 'release-0.4'
Integrate the bugfixes from the stable branch.
This commit is contained in:
commit
56aa3b6669
@ -243,7 +243,7 @@ sample_cb (dc_sample_type_t type, dc_sample_value_t value, void *userdata)
|
||||
"none", "deco", "rbt", "ascent", "ceiling", "workload", "transmitter",
|
||||
"violation", "bookmark", "surface", "safety stop", "gaschange",
|
||||
"safety stop (voluntary)", "safety stop (mandatory)", "deepstop",
|
||||
"ceiling (safety stop)", "unknown", "divetime", "maxdepth",
|
||||
"ceiling (safety stop)", "floor", "divetime", "maxdepth",
|
||||
"OLF", "PO2", "airtime", "rgbm", "heading", "tissue level warning",
|
||||
"gaschange2"};
|
||||
static const char *decostop[] = {
|
||||
|
||||
@ -73,7 +73,7 @@ typedef enum parser_sample_event_t {
|
||||
SAMPLE_EVENT_SAFETYSTOP_MANDATORY,
|
||||
SAMPLE_EVENT_DEEPSTOP,
|
||||
SAMPLE_EVENT_CEILING_SAFETYSTOP,
|
||||
SAMPLE_EVENT_UNKNOWN,
|
||||
SAMPLE_EVENT_FLOOR,
|
||||
SAMPLE_EVENT_DIVETIME,
|
||||
SAMPLE_EVENT_MAXDEPTH,
|
||||
SAMPLE_EVENT_OLF,
|
||||
@ -87,6 +87,9 @@ typedef enum parser_sample_event_t {
|
||||
respectively the low and high part. */
|
||||
} parser_sample_event_t;
|
||||
|
||||
/* For backwards compatibility */
|
||||
#define SAMPLE_EVENT_UNKNOWN SAMPLE_EVENT_FLOOR
|
||||
|
||||
typedef enum parser_sample_flags_t {
|
||||
SAMPLE_FLAGS_NONE = 0,
|
||||
SAMPLE_FLAGS_BEGIN = (1 << 0),
|
||||
|
||||
@ -83,6 +83,9 @@ cressi_edy_transfer (cressi_edy_device_t *device, const unsigned char command[],
|
||||
|
||||
assert (asize >= csize);
|
||||
|
||||
if (device_is_cancelled (abstract))
|
||||
return DC_STATUS_CANCELLED;
|
||||
|
||||
// Flush the serial input buffer.
|
||||
int rc = serial_flush (device->port, SERIAL_QUEUE_INPUT);
|
||||
if (rc == -1) {
|
||||
|
||||
@ -162,7 +162,7 @@ cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
|
||||
dc_sample_value_t sample = {0};
|
||||
|
||||
unsigned int value = array_uint16_le (data + offset);
|
||||
unsigned int depth = value & 0x3FFF;
|
||||
unsigned int depth = value & 0x07FF;
|
||||
|
||||
// Time (seconds).
|
||||
time += interval;
|
||||
|
||||
@ -99,6 +99,7 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"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", "Aladin 2G", DC_FAMILY_UWATEC_SMART, 0x15},
|
||||
{"Uwatec", "Smart Tec", DC_FAMILY_UWATEC_SMART, 0x18},
|
||||
{"Uwatec", "Galileo Trimix",DC_FAMILY_UWATEC_SMART, 0x19},
|
||||
{"Uwatec", "Smart Z", DC_FAMILY_UWATEC_SMART, 0x1C},
|
||||
@ -163,7 +164,9 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"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},
|
||||
{"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545},
|
||||
{"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548},
|
||||
{"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B},
|
||||
/* Mares Nemo */
|
||||
{"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0},
|
||||
{"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0},
|
||||
@ -186,6 +189,7 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"Mares", "Icon HD Net Ready", DC_FAMILY_MARES_ICONHD , 0x15},
|
||||
{"Mares", "Puck Pro", DC_FAMILY_MARES_ICONHD , 0x18},
|
||||
{"Mares", "Nemo Wide 2", DC_FAMILY_MARES_ICONHD , 0x19},
|
||||
{"Mares", "Puck 2", DC_FAMILY_MARES_ICONHD , 0x1F},
|
||||
/* Heinrichs Weikamp */
|
||||
{"Heinrichs Weikamp", "OSTC", DC_FAMILY_HW_OSTC, 0},
|
||||
{"Heinrichs Weikamp", "OSTC Mk2", DC_FAMILY_HW_OSTC, 1},
|
||||
@ -201,6 +205,7 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"Zeagle", "N2iTiON3", DC_FAMILY_ZEAGLE_N2ITION3, 0},
|
||||
{"Apeks", "Quantum X", DC_FAMILY_ZEAGLE_N2ITION3, 0},
|
||||
{"Dive Rite", "NiTek Trio", DC_FAMILY_ZEAGLE_N2ITION3, 0},
|
||||
{"Scubapro", "XTender 5", DC_FAMILY_ZEAGLE_N2ITION3, 0},
|
||||
/* Atomic Aquatics Cobalt */
|
||||
#ifdef HAVE_LIBUSB
|
||||
{"Atomic Aquatics", "Cobalt", DC_FAMILY_ATOMICS_COBALT, 0},
|
||||
|
||||
@ -322,6 +322,10 @@ dc_device_close (dc_device_t *device)
|
||||
if (device->vtable->close == NULL)
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
|
||||
// Disable the cancellation callback.
|
||||
device->cancel_callback = NULL;
|
||||
device->cancel_userdata = NULL;
|
||||
|
||||
return device->vtable->close (device);
|
||||
}
|
||||
|
||||
|
||||
@ -111,6 +111,9 @@ hw_frog_transfer (hw_frog_device_t *device,
|
||||
{
|
||||
dc_device_t *abstract = (dc_device_t *) device;
|
||||
|
||||
if (device_is_cancelled (abstract))
|
||||
return DC_STATUS_CANCELLED;
|
||||
|
||||
// Send the command.
|
||||
unsigned char command[1] = {cmd};
|
||||
int n = serial_write (device->port, command, sizeof (command));
|
||||
|
||||
@ -108,6 +108,9 @@ hw_ostc3_transfer (hw_ostc3_device_t *device,
|
||||
{
|
||||
dc_device_t *abstract = (dc_device_t *) device;
|
||||
|
||||
if (device_is_cancelled (abstract))
|
||||
return DC_STATUS_CANCELLED;
|
||||
|
||||
// Send the command.
|
||||
unsigned char command[1] = {cmd};
|
||||
int n = serial_write (device->port, command, sizeof (command));
|
||||
@ -392,8 +395,13 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi
|
||||
unsigned int idx = (latest + RB_LOGBOOK_COUNT - i) % RB_LOGBOOK_COUNT;
|
||||
unsigned int offset = idx * RB_LOGBOOK_SIZE;
|
||||
|
||||
// Get the firmware version.
|
||||
unsigned int firmware = array_uint16_be (header + offset + 0x30);
|
||||
|
||||
// Calculate the profile length.
|
||||
unsigned int length = RB_LOGBOOK_SIZE + array_uint24_le (header + offset + 9) - 6;
|
||||
if (firmware >= 93)
|
||||
length += 3;
|
||||
|
||||
// Check the fingerprint data.
|
||||
if (memcmp (header + offset + 12, device->fingerprint, sizeof (device->fingerprint)) == 0)
|
||||
@ -428,8 +436,13 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi
|
||||
unsigned int idx = (latest + RB_LOGBOOK_COUNT - i) % RB_LOGBOOK_COUNT;
|
||||
unsigned int offset = idx * RB_LOGBOOK_SIZE;
|
||||
|
||||
// Get the firmware version.
|
||||
unsigned int firmware = array_uint16_be (header + offset + 0x30);
|
||||
|
||||
// Calculate the profile length.
|
||||
unsigned int length = RB_LOGBOOK_SIZE + array_uint24_le (header + offset + 9) - 6;
|
||||
if (firmware >= 93)
|
||||
length += 3;
|
||||
|
||||
// Download the dive.
|
||||
unsigned char number[1] = {idx};
|
||||
|
||||
@ -482,6 +482,8 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
|
||||
unsigned int nbits = 0;
|
||||
unsigned int events = 0;
|
||||
while (data[offset - 1] & 0x80) {
|
||||
if (nbits && version != 0x23)
|
||||
break;
|
||||
if (offset + 1 > size)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
events |= data[offset] << nbits;
|
||||
@ -594,13 +596,27 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
|
||||
}
|
||||
}
|
||||
|
||||
// SetPoint Change
|
||||
if ((events & 0x40) && (version != 0x23)) {
|
||||
if (offset + 1 > size)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
sample.setpoint = data[offset] / 100.0;
|
||||
if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
|
||||
offset++;
|
||||
if (version != 0x23) {
|
||||
// SetPoint Change
|
||||
if (events & 0x40) {
|
||||
if (offset + 1 > size)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
sample.setpoint = data[offset] / 100.0;
|
||||
if (callback) callback (DC_SAMPLE_SETPOINT, sample, userdata);
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Bailout Event
|
||||
if (events & 0x80) {
|
||||
if (offset + 2 > size)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
sample.event.type = SAMPLE_EVENT_GASCHANGE2;
|
||||
sample.event.time = 0;
|
||||
sample.event.flags = 0;
|
||||
sample.event.value = data[offset] | (data[offset + 1] << 16);
|
||||
if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
|
||||
offset += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
#define ICONHDNET 0x15
|
||||
#define PUCKPRO 0x18
|
||||
#define NEMOWIDE2 0x19
|
||||
#define PUCK2 0x1F
|
||||
|
||||
#define ACK 0xAA
|
||||
#define EOF 0xEA
|
||||
@ -89,10 +90,16 @@ static const mares_iconhd_layout_t mares_iconhd_layout = {
|
||||
0x100000, /* rb_profile_end */
|
||||
};
|
||||
|
||||
static const mares_iconhd_layout_t mares_iconhdnet_layout = {
|
||||
0x100000, /* memsize */
|
||||
0x00E000, /* rb_profile_begin */
|
||||
0x100000, /* rb_profile_end */
|
||||
};
|
||||
|
||||
static const mares_iconhd_layout_t mares_matrix_layout = {
|
||||
0x40000, /* memsize */
|
||||
0x0A000, /* rb_profile_begin */
|
||||
0x40000, /* rb_profile_end */
|
||||
0x3E000, /* rb_profile_end */
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
@ -121,6 +128,9 @@ mares_iconhd_transfer (mares_iconhd_device_t *device,
|
||||
|
||||
assert (csize >= 2);
|
||||
|
||||
if (device_is_cancelled (abstract))
|
||||
return DC_STATUS_CANCELLED;
|
||||
|
||||
// Send the command header to the dive computer.
|
||||
int n = serial_write (device->port, command, 2);
|
||||
if (n != 2) {
|
||||
@ -261,9 +271,12 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *
|
||||
device->port = NULL;
|
||||
memset (device->fingerprint, 0, sizeof (device->fingerprint));
|
||||
memset (device->version, 0, sizeof (device->version));
|
||||
if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO) {
|
||||
if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO || model == PUCK2) {
|
||||
device->layout = &mares_matrix_layout;
|
||||
device->packetsize = 64;
|
||||
} else if (model == ICONHDNET) {
|
||||
device->layout = &mares_iconhdnet_layout;
|
||||
device->packetsize = 0;
|
||||
} else {
|
||||
device->layout = &mares_iconhd_layout;
|
||||
device->packetsize = 0;
|
||||
@ -278,7 +291,7 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *
|
||||
}
|
||||
|
||||
// Set the serial communication protocol (256000 8N1).
|
||||
if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO) {
|
||||
if (model == NEMOWIDE2 || model == MATRIX || model == PUCKPRO || model == PUCK2) {
|
||||
rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_EVEN, 1, SERIAL_FLOWCONTROL_NONE);
|
||||
} else {
|
||||
rc = serial_configure (device->port, BAUDRATE, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
|
||||
|
||||
@ -55,6 +55,27 @@ static const dc_parser_vtable_t mares_iconhd_parser_vtable = {
|
||||
};
|
||||
|
||||
|
||||
/* Find how many gas mixes are in use */
|
||||
static unsigned int
|
||||
mares_iconhd_parser_count_active_gas_mixes (const unsigned char *p, unsigned int air)
|
||||
{
|
||||
if (air) {
|
||||
return 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++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dc_status_t
|
||||
mares_iconhd_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
|
||||
{
|
||||
@ -163,20 +184,7 @@ 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:
|
||||
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;
|
||||
}
|
||||
*((unsigned int *) value) = mares_iconhd_parser_count_active_gas_mixes (p, air);
|
||||
break;
|
||||
case DC_FIELD_GASMIX:
|
||||
if (air)
|
||||
@ -186,6 +194,10 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
gasmix->helium = 0.0;
|
||||
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
|
||||
break;
|
||||
case DC_FIELD_ATMOSPHERIC:
|
||||
// Pressure (1/8 millibar)
|
||||
*((double *) value) = array_uint16_le (p + 0x26) / 8000.0;
|
||||
break;
|
||||
default:
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
@ -215,6 +227,10 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
|
||||
if (abstract->size < length || length < header + 4)
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
|
||||
const unsigned char *p = abstract->data + length - header;
|
||||
|
||||
unsigned int air = (p[0] & 0x02) == 0;
|
||||
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int size = length - header;
|
||||
|
||||
@ -223,6 +239,11 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
|
||||
|
||||
unsigned int offset = 4;
|
||||
unsigned int nsamples = 0;
|
||||
|
||||
// Previous gas mix - initialize with impossible value
|
||||
unsigned int gasmix_previous = 0xFFFFFFFF;
|
||||
unsigned int ngasmixes = mares_iconhd_parser_count_active_gas_mixes (p, air);
|
||||
|
||||
while (offset + samplesize <= size) {
|
||||
dc_sample_value_t sample = {0};
|
||||
|
||||
@ -237,10 +258,28 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
|
||||
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
|
||||
|
||||
// Temperature (1/10 °C).
|
||||
unsigned int temperature = array_uint16_le (data + offset + 2);
|
||||
unsigned int temperature = array_uint16_le (data + offset + 2) & 0x0FFF;
|
||||
sample.temperature = temperature / 10.0;
|
||||
if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
|
||||
|
||||
// Current gas mix
|
||||
unsigned int gasmix = (data[offset + 3] & 0xF0) >> 4;
|
||||
if (gasmix >= ngasmixes) {
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
if (gasmix != gasmix_previous) {
|
||||
unsigned int o2 = 0;
|
||||
if (air)
|
||||
o2 = 21;
|
||||
else
|
||||
o2 = p[0x14 + gasmix * 4];
|
||||
sample.event.type = SAMPLE_EVENT_GASCHANGE;
|
||||
sample.event.time = 0;
|
||||
sample.event.value = o2;
|
||||
if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
|
||||
gasmix_previous = gasmix;
|
||||
}
|
||||
|
||||
offset += samplesize;
|
||||
nsamples++;
|
||||
|
||||
|
||||
@ -108,16 +108,27 @@ static const oceanic_common_version_t oceanic_default_version[] = {
|
||||
|
||||
static const oceanic_common_version_t tusa_zenair_version[] = {
|
||||
{"TUZENAIR \0\0 512K"},
|
||||
{"AMPHOSSW \0\0 512K"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_oc1_version[] = {
|
||||
{"OCWATCH R\0\0 1024"},
|
||||
{"OCEANVT4 \0\0 1024"},
|
||||
{"OC1WATCH \0\0 1024"},
|
||||
{"OCEATOM3 \0\0 1024"},
|
||||
{"OCSWATCH \0\0 1024"},
|
||||
{"OCEAVT41 \0\0 1024"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_oci_version[] = {
|
||||
{"OCEANOCI \0\0 1024"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_atom3_version[] = {
|
||||
{"OCEATOM3 \0\0 1024"},
|
||||
{"ATOM31 \0\0 1024"},
|
||||
};
|
||||
|
||||
static const oceanic_common_version_t oceanic_vt4_version[] = {
|
||||
{"OCEANVT4 \0\0 1024"},
|
||||
{"OCEAVT41 \0\0 1024"},
|
||||
{"AERISAIR \0\0 1024"},
|
||||
};
|
||||
|
||||
@ -234,6 +245,45 @@ static const oceanic_common_layout_t oceanic_oc1_layout = {
|
||||
1 /* pt_mode_logbook */
|
||||
};
|
||||
|
||||
static const oceanic_common_layout_t oceanic_oci_layout = {
|
||||
0x20000, /* memsize */
|
||||
0x0000, /* cf_devinfo */
|
||||
0x0040, /* cf_pointers */
|
||||
0x10C0, /* rb_logbook_begin */
|
||||
0x1400, /* rb_logbook_end */
|
||||
8, /* rb_logbook_entry_size */
|
||||
0x1400, /* rb_profile_begin */
|
||||
0x1FE00, /* rb_profile_end */
|
||||
0, /* pt_mode_global */
|
||||
1 /* pt_mode_logbook */
|
||||
};
|
||||
|
||||
static const oceanic_common_layout_t oceanic_atom3_layout = {
|
||||
0x20000, /* memsize */
|
||||
0x0000, /* cf_devinfo */
|
||||
0x0040, /* cf_pointers */
|
||||
0x0400, /* rb_logbook_begin */
|
||||
0x0A40, /* rb_logbook_end */
|
||||
8, /* rb_logbook_entry_size */
|
||||
0x0A40, /* rb_profile_begin */
|
||||
0x1FE00, /* rb_profile_end */
|
||||
0, /* pt_mode_global */
|
||||
1 /* pt_mode_logbook */
|
||||
};
|
||||
|
||||
static const oceanic_common_layout_t oceanic_vt4_layout = {
|
||||
0x20000, /* memsize */
|
||||
0x0000, /* cf_devinfo */
|
||||
0x0040, /* cf_pointers */
|
||||
0x0420, /* rb_logbook_begin */
|
||||
0x0A40, /* rb_logbook_end */
|
||||
8, /* rb_logbook_entry_size */
|
||||
0x0A40, /* rb_profile_begin */
|
||||
0x1FE00, /* rb_profile_end */
|
||||
0, /* pt_mode_global */
|
||||
1 /* pt_mode_logbook */
|
||||
};
|
||||
|
||||
static const oceanic_common_layout_t oceanic_veo1_layout = {
|
||||
0x0400, /* memsize */
|
||||
0x0000, /* cf_devinfo */
|
||||
@ -434,6 +484,12 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char
|
||||
device->base.layout = &tusa_zenair_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_oc1_version)) {
|
||||
device->base.layout = &oceanic_oc1_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_oci_version)) {
|
||||
device->base.layout = &oceanic_oci_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom3_version)) {
|
||||
device->base.layout = &oceanic_atom3_layout;
|
||||
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_vt4_version)) {
|
||||
device->base.layout = &oceanic_vt4_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)) {
|
||||
|
||||
@ -45,6 +45,7 @@
|
||||
#define VEO20 0x4359
|
||||
#define VEO30 0x435A
|
||||
#define ZENAIR 0x4442
|
||||
#define ATMOSAI2 0x4443
|
||||
#define PROPLUS21 0x4444
|
||||
#define GEO20 0x4446
|
||||
#define VT4 0x4447
|
||||
@ -57,7 +58,9 @@
|
||||
#define EPICB 0x4453
|
||||
#define ATOM31 0x4456
|
||||
#define A300AI 0x4457
|
||||
#define AMPHOS 0x4545
|
||||
#define PROPLUS3 0x4548
|
||||
#define OCI 0x454B
|
||||
|
||||
typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t;
|
||||
|
||||
@ -166,6 +169,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
|
||||
case ATOM3:
|
||||
case ATOM31:
|
||||
case A300AI:
|
||||
case OCI:
|
||||
datetime->year = ((p[5] & 0xE0) >> 5) + ((p[7] & 0xE0) >> 2) + 2000;
|
||||
datetime->month = (p[3] & 0x0F);
|
||||
datetime->day = ((p[0] & 0x80) >> 3) + ((p[3] & 0xF0) >> 4);
|
||||
@ -175,7 +179,6 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
|
||||
case VT3:
|
||||
case VEO20:
|
||||
case VEO30:
|
||||
case GEO20:
|
||||
case DG03:
|
||||
datetime->year = ((p[3] & 0xE0) >> 1) + (p[4] & 0x0F) + 2000;
|
||||
datetime->month = (p[4] & 0xF0) >> 4;
|
||||
@ -184,6 +187,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
|
||||
datetime->minute = bcd2dec (p[0]);
|
||||
break;
|
||||
case ZENAIR:
|
||||
case AMPHOS:
|
||||
datetime->year = (p[3] & 0x0F) + 2000;
|
||||
datetime->month = (p[7] & 0xF0) >> 4;
|
||||
datetime->day = ((p[3] & 0x80) >> 3) + ((p[5] & 0xF0) >> 4);
|
||||
@ -201,7 +205,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
|
||||
default:
|
||||
datetime->year = bcd2dec (((p[3] & 0xC0) >> 2) + (p[4] & 0x0F)) + 2000;
|
||||
datetime->month = (p[4] & 0xF0) >> 4;
|
||||
if (parser->model == T3)
|
||||
if (parser->model == T3 || parser->model == GEO20)
|
||||
datetime->day = p[3] & 0x3F;
|
||||
else
|
||||
datetime->day = bcd2dec (p[3] & 0x3F);
|
||||
@ -394,14 +398,15 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
}
|
||||
|
||||
unsigned int samplesize = PAGESIZE / 2;
|
||||
if (parser->model == OC1A || parser->model == OC1B || parser->model == OC1C)
|
||||
if (parser->model == OC1A || parser->model == OC1B ||
|
||||
parser->model == OC1C || parser->model == OCI)
|
||||
samplesize = PAGESIZE;
|
||||
else if (parser->model == F10)
|
||||
samplesize = 2;
|
||||
|
||||
unsigned int have_temperature = 1, have_pressure = 1;
|
||||
if (parser->model == VEO30 || parser->model == OCS ||
|
||||
parser->model == ELEMENT2) {
|
||||
parser->model == ELEMENT2 || parser->model == VEO20) {
|
||||
have_pressure = 0;
|
||||
} else if (parser->model == F10) {
|
||||
have_temperature = 0;
|
||||
@ -504,7 +509,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
temperature = data[offset + 6];
|
||||
} else if (parser->model == GEO20 || parser->model == VEO20 ||
|
||||
parser->model == VEO30 || parser->model == OC1A ||
|
||||
parser->model == OC1B || parser->model == OC1C) {
|
||||
parser->model == OC1B || parser->model == OC1C ||
|
||||
parser->model == OCI) {
|
||||
temperature = data[offset + 3];
|
||||
} else if (parser->model == OCS) {
|
||||
temperature = data[offset + 1];
|
||||
@ -515,7 +521,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
|
||||
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)
|
||||
parser->model == EPICA || parser->model == EPICB ||
|
||||
parser->model == ATMOSAI2 || parser->model == AMPHOS)
|
||||
sign = (data[offset + 0] & 0x80) >> 7;
|
||||
else
|
||||
sign = (~data[offset + 0] & 0x80) >> 7;
|
||||
@ -530,7 +537,8 @@ 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 || parser->model == OC1C)
|
||||
if (parser->model == OC1A || parser->model == OC1B ||
|
||||
parser->model == OC1C || parser->model == OCI)
|
||||
pressure = (data[offset + 10] + (data[offset + 11] << 8)) & 0x0FFF;
|
||||
else if (parser->model == VT4 || parser->model == VT41||
|
||||
parser->model == ATOM3 || parser->model == ATOM31 ||
|
||||
@ -548,7 +556,8 @@ 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 == OC1C)
|
||||
parser->model == OC1B || parser->model == OC1C ||
|
||||
parser->model == OCI)
|
||||
depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF;
|
||||
else if (parser->model == ATOM1)
|
||||
depth = data[offset + 3] * 16;
|
||||
|
||||
@ -148,6 +148,8 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned
|
||||
const unsigned char end[] = {END};
|
||||
const unsigned char esc_end[] = {ESC, ESC_END};
|
||||
const unsigned char esc_esc[] = {ESC, ESC_ESC};
|
||||
unsigned char buffer[32];
|
||||
unsigned int nbytes = 0;
|
||||
|
||||
#if 0
|
||||
// Send an initial END character to flush out any data that may have
|
||||
@ -179,15 +181,28 @@ shearwater_common_slip_write (shearwater_common_device_t *device, const unsigned
|
||||
break;
|
||||
}
|
||||
|
||||
n = serial_write (device->port, seq, len);
|
||||
if (n != len) {
|
||||
return EXITCODE(n);
|
||||
// Flush the buffer if necessary.
|
||||
if (nbytes + len + sizeof(end) > sizeof(buffer)) {
|
||||
n = serial_write (device->port, buffer, nbytes);
|
||||
if (n != nbytes) {
|
||||
return EXITCODE(n);
|
||||
}
|
||||
|
||||
nbytes = 0;
|
||||
}
|
||||
|
||||
// Append the escaped character.
|
||||
memcpy(buffer + nbytes, seq, len);
|
||||
nbytes += len;
|
||||
}
|
||||
|
||||
// Send the END character to indicate the end of the packet.
|
||||
n = serial_write (device->port, end, sizeof (end));
|
||||
if (n != sizeof (end)) {
|
||||
// Append the END character to indicate the end of the packet.
|
||||
memcpy(buffer + nbytes, end, sizeof(end));
|
||||
nbytes += sizeof(end);
|
||||
|
||||
// Flush the buffer.
|
||||
n = serial_write (device->port, buffer, nbytes);
|
||||
if (n != nbytes) {
|
||||
return EXITCODE(n);
|
||||
}
|
||||
|
||||
@ -266,6 +281,9 @@ shearwater_common_transfer (shearwater_common_device_t *device, const unsigned c
|
||||
if (isize > SZ_PACKET || osize > SZ_PACKET)
|
||||
return DC_STATUS_INVALIDARGS;
|
||||
|
||||
if (device_is_cancelled (abstract))
|
||||
return DC_STATUS_CANCELLED;
|
||||
|
||||
// Setup the request packet.
|
||||
packet[0] = 0xFF;
|
||||
packet[1] = 0x01;
|
||||
|
||||
@ -88,7 +88,7 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, unsig
|
||||
// Initialize the base class.
|
||||
parser->petrel = petrel;
|
||||
if (petrel) {
|
||||
parser_init (&parser->base, context, &shearwater_predator_parser_vtable);
|
||||
parser_init (&parser->base, context, &shearwater_petrel_parser_vtable);
|
||||
} else {
|
||||
parser_init (&parser->base, context, &shearwater_predator_parser_vtable);
|
||||
}
|
||||
|
||||
@ -482,8 +482,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca
|
||||
case 0x06: // Mandatory Safety Stop Ceiling Error
|
||||
sample.event.type = SAMPLE_EVENT_CEILING_SAFETYSTOP;
|
||||
break;
|
||||
case 0x07: // Unknown (Deco related)
|
||||
sample.event.type = SAMPLE_EVENT_UNKNOWN;
|
||||
case 0x07: // Below Deco Floor
|
||||
sample.event.type = SAMPLE_EVENT_FLOOR;
|
||||
break;
|
||||
case 0x08: // Dive Time
|
||||
sample.event.type = SAMPLE_EVENT_DIVETIME;
|
||||
|
||||
@ -105,7 +105,7 @@ suunto_eon_device_open (dc_device_t **out, dc_context_t *context, const char *na
|
||||
}
|
||||
|
||||
// Set the timeout for receiving data (1000ms).
|
||||
if (serial_set_timeout (device->port, -1) == -1) {
|
||||
if (serial_set_timeout (device->port, 1000) == -1) {
|
||||
ERROR (context, "Failed to set the timeout.");
|
||||
serial_close (device->port);
|
||||
free (device);
|
||||
@ -170,16 +170,34 @@ suunto_eon_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
|
||||
}
|
||||
|
||||
// Receive the answer.
|
||||
unsigned int nbytes = 0;
|
||||
unsigned char answer[SZ_MEMORY + 1] = {0};
|
||||
rc = serial_read (device->port, answer, sizeof (answer));
|
||||
if (rc != sizeof (answer)) {
|
||||
ERROR (abstract->context, "Failed to receive the answer.");
|
||||
return EXITCODE (rc);
|
||||
}
|
||||
while (nbytes < sizeof(answer)) {
|
||||
// Set the minimum packet size.
|
||||
unsigned int len = 64;
|
||||
|
||||
// Update and emit a progress event.
|
||||
progress.current += sizeof (answer);
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
// Increase the packet size if more data is immediately available.
|
||||
int available = serial_get_received (device->port);
|
||||
if (available > len)
|
||||
len = available;
|
||||
|
||||
// Limit the packet size to the total size.
|
||||
if (nbytes + len > sizeof(answer))
|
||||
len = sizeof(answer) - nbytes;
|
||||
|
||||
// Read the packet.
|
||||
int n = serial_read (device->port, answer + nbytes, len);
|
||||
if (n != len) {
|
||||
ERROR (abstract->context, "Failed to receive the answer.");
|
||||
return EXITCODE (n);
|
||||
}
|
||||
|
||||
// Update and emit a progress event.
|
||||
progress.current += len;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
|
||||
nbytes += len;
|
||||
}
|
||||
|
||||
// Verify the checksum of the package.
|
||||
unsigned char crc = answer[sizeof (answer) - 1];
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#define ALADINTEC 0x12
|
||||
#define ALADINTEC2G 0x13
|
||||
#define SMARTCOM 0x14
|
||||
#define ALADIN2G 0x15
|
||||
#define SMARTTEC 0x18
|
||||
#define GALILEOTRIMIX 0x19
|
||||
#define SMARTZ 0x1C
|
||||
@ -207,6 +208,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
break;
|
||||
case GALILEO:
|
||||
case GALILEOTRIMIX:
|
||||
case ALADIN2G:
|
||||
case MERIDIAN:
|
||||
header = 152;
|
||||
if (data[43] & 0x80) {
|
||||
@ -456,6 +458,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
|
||||
break;
|
||||
case GALILEO:
|
||||
case GALILEOTRIMIX:
|
||||
case ALADIN2G:
|
||||
case MERIDIAN:
|
||||
header = 152;
|
||||
if (data[43] & 0x80) {
|
||||
@ -522,7 +525,8 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
|
||||
|
||||
// Process the type bits in the bitstream.
|
||||
unsigned int id = 0;
|
||||
if (parser->model == GALILEO || parser->model == GALILEOTRIMIX || parser->model == MERIDIAN) {
|
||||
if (parser->model == GALILEO || parser->model == GALILEOTRIMIX ||
|
||||
parser->model == ALADIN2G || parser->model == MERIDIAN) {
|
||||
// Uwatec Galileo
|
||||
id = uwatec_galileo_identify (data[offset]);
|
||||
} else {
|
||||
|
||||
@ -79,6 +79,9 @@ zeagle_n2ition3_packet (zeagle_n2ition3_device_t *device, const unsigned char co
|
||||
|
||||
assert (asize >= csize + 5);
|
||||
|
||||
if (device_is_cancelled (abstract))
|
||||
return DC_STATUS_CANCELLED;
|
||||
|
||||
// Send the command to the device.
|
||||
int n = serial_write (device->port, command, csize);
|
||||
if (n != csize) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user