Add support for the Cressi Drake
The Cressi Drake is a mainly a freedive computer. The data format is almost identical to the Leonardo. The main difference is that a single dive now contains an entire freedive session. Each freedive in the session is delimited with a 4 byte header containing the surface interval and a special marker.
This commit is contained in:
parent
3dbfe9d66d
commit
07dcc8998b
@ -39,6 +39,9 @@ cressi_leonardo_extract_dives (dc_device_t *abstract, const unsigned char data[]
|
|||||||
dc_status_t
|
dc_status_t
|
||||||
cressi_leonardo_parser_create (dc_parser_t **parser, dc_context_t *context);
|
cressi_leonardo_parser_create (dc_parser_t **parser, dc_context_t *context);
|
||||||
|
|
||||||
|
dc_status_t
|
||||||
|
cressi_leonardo_parser_create2 (dc_parser_t **parser, dc_context_t *context, unsigned int model);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
@ -31,10 +31,13 @@
|
|||||||
|
|
||||||
#define SZ_HEADER 82
|
#define SZ_HEADER 82
|
||||||
|
|
||||||
|
#define DRAKE 6
|
||||||
|
|
||||||
typedef struct cressi_leonardo_parser_t cressi_leonardo_parser_t;
|
typedef struct cressi_leonardo_parser_t cressi_leonardo_parser_t;
|
||||||
|
|
||||||
struct cressi_leonardo_parser_t {
|
struct cressi_leonardo_parser_t {
|
||||||
dc_parser_t base;
|
dc_parser_t base;
|
||||||
|
unsigned int model;
|
||||||
};
|
};
|
||||||
|
|
||||||
static dc_status_t cressi_leonardo_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
|
static dc_status_t cressi_leonardo_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
|
||||||
@ -54,7 +57,7 @@ static const dc_parser_vtable_t cressi_leonardo_parser_vtable = {
|
|||||||
|
|
||||||
|
|
||||||
dc_status_t
|
dc_status_t
|
||||||
cressi_leonardo_parser_create (dc_parser_t **out, dc_context_t *context)
|
cressi_leonardo_parser_create2 (dc_parser_t **out, dc_context_t *context, unsigned int model)
|
||||||
{
|
{
|
||||||
cressi_leonardo_parser_t *parser = NULL;
|
cressi_leonardo_parser_t *parser = NULL;
|
||||||
|
|
||||||
@ -68,12 +71,21 @@ cressi_leonardo_parser_create (dc_parser_t **out, dc_context_t *context)
|
|||||||
return DC_STATUS_NOMEMORY;
|
return DC_STATUS_NOMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parser->model = model;
|
||||||
|
|
||||||
*out = (dc_parser_t*) parser;
|
*out = (dc_parser_t*) parser;
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dc_status_t
|
||||||
|
cressi_leonardo_parser_create (dc_parser_t **parser, dc_context_t *context)
|
||||||
|
{
|
||||||
|
return cressi_leonardo_parser_create2 (parser, context, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static dc_status_t
|
static dc_status_t
|
||||||
cressi_leonardo_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
|
cressi_leonardo_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
|
||||||
{
|
{
|
||||||
@ -105,23 +117,33 @@ cressi_leonardo_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datet
|
|||||||
static dc_status_t
|
static dc_status_t
|
||||||
cressi_leonardo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value)
|
cressi_leonardo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value)
|
||||||
{
|
{
|
||||||
|
cressi_leonardo_parser_t *parser = (cressi_leonardo_parser_t *) abstract;
|
||||||
if (abstract->size < SZ_HEADER)
|
if (abstract->size < SZ_HEADER)
|
||||||
return DC_STATUS_DATAFORMAT;
|
return DC_STATUS_DATAFORMAT;
|
||||||
|
|
||||||
const unsigned char *data = abstract->data;
|
const unsigned char *data = abstract->data;
|
||||||
|
|
||||||
|
unsigned int interval = 20;
|
||||||
|
if (parser->model == DRAKE) {
|
||||||
|
interval = 1;
|
||||||
|
}
|
||||||
|
|
||||||
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
|
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DC_FIELD_DIVETIME:
|
case DC_FIELD_DIVETIME:
|
||||||
*((unsigned int *) value) = array_uint16_le (data + 0x06) * 20;
|
*((unsigned int *) value) = array_uint16_le (data + 0x06) * interval;
|
||||||
break;
|
break;
|
||||||
case DC_FIELD_MAXDEPTH:
|
case DC_FIELD_MAXDEPTH:
|
||||||
*((double *) value) = array_uint16_le (data + 0x20) / 10.0;
|
*((double *) value) = array_uint16_le (data + 0x20) / 10.0;
|
||||||
break;
|
break;
|
||||||
case DC_FIELD_GASMIX_COUNT:
|
case DC_FIELD_GASMIX_COUNT:
|
||||||
*((unsigned int *) value) = 1;
|
if (parser->model == DRAKE) {
|
||||||
|
*((unsigned int *) value) = 0;
|
||||||
|
} else {
|
||||||
|
*((unsigned int *) value) = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DC_FIELD_GASMIX:
|
case DC_FIELD_GASMIX:
|
||||||
gasmix->helium = 0.0;
|
gasmix->helium = 0.0;
|
||||||
@ -143,11 +165,15 @@ cressi_leonardo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, u
|
|||||||
static dc_status_t
|
static dc_status_t
|
||||||
cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
|
cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
|
||||||
{
|
{
|
||||||
|
cressi_leonardo_parser_t *parser = (cressi_leonardo_parser_t *) abstract;
|
||||||
const unsigned char *data = abstract->data;
|
const unsigned char *data = abstract->data;
|
||||||
unsigned int size = abstract->size;
|
unsigned int size = abstract->size;
|
||||||
|
|
||||||
unsigned int time = 0;
|
unsigned int time = 0;
|
||||||
unsigned int interval = 20;
|
unsigned int interval = 20;
|
||||||
|
if (parser->model == DRAKE) {
|
||||||
|
interval = 1;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int gasmix_previous = 0xFFFFFFFF;
|
unsigned int gasmix_previous = 0xFFFFFFFF;
|
||||||
unsigned int gasmix = 0;
|
unsigned int gasmix = 0;
|
||||||
@ -156,36 +182,53 @@ cressi_leonardo_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callbac
|
|||||||
while (offset + 2 <= size) {
|
while (offset + 2 <= size) {
|
||||||
dc_sample_value_t sample = {0};
|
dc_sample_value_t sample = {0};
|
||||||
|
|
||||||
unsigned int value = array_uint16_le (data + offset);
|
if (offset + 4 <= size &&
|
||||||
unsigned int depth = value & 0x07FF;
|
array_uint16_le (data + offset + 2) == 0xFF00)
|
||||||
unsigned int ascent = (value & 0xC000) >> 14;
|
{
|
||||||
|
unsigned int surftime = data[offset] + (data[offset + 1] & 0x07) * 60;
|
||||||
|
|
||||||
// Time (seconds).
|
// Time (seconds).
|
||||||
time += interval;
|
time += surftime;
|
||||||
sample.time = time;
|
sample.time = time;
|
||||||
if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
|
if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
|
||||||
|
|
||||||
// Depth (1/10 m).
|
// Depth (1/10 m).
|
||||||
sample.depth = depth / 10.0;
|
sample.depth = 0.0;
|
||||||
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
|
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
|
||||||
|
|
||||||
// Gas change.
|
offset += 4;
|
||||||
if (gasmix != gasmix_previous) {
|
} else {
|
||||||
sample.gasmix = gasmix;
|
unsigned int value = array_uint16_le (data + offset);
|
||||||
if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
|
unsigned int depth = value & 0x07FF;
|
||||||
gasmix_previous = gasmix;
|
unsigned int ascent = (value & 0xC000) >> 14;
|
||||||
|
|
||||||
|
// Time (seconds).
|
||||||
|
time += interval;
|
||||||
|
sample.time = time;
|
||||||
|
if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
|
||||||
|
|
||||||
|
// Depth (1/10 m).
|
||||||
|
sample.depth = depth / 10.0;
|
||||||
|
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
|
||||||
|
|
||||||
|
// Gas change.
|
||||||
|
if (gasmix != gasmix_previous) {
|
||||||
|
sample.gasmix = gasmix;
|
||||||
|
if (callback) callback (DC_SAMPLE_GASMIX, sample, userdata);
|
||||||
|
gasmix_previous = gasmix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ascent rate
|
||||||
|
if (ascent) {
|
||||||
|
sample.event.type = SAMPLE_EVENT_ASCENT;
|
||||||
|
sample.event.time = 0;
|
||||||
|
sample.event.flags = 0;
|
||||||
|
sample.event.value = ascent;
|
||||||
|
if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ascent rate
|
|
||||||
if (ascent) {
|
|
||||||
sample.event.type = SAMPLE_EVENT_ASCENT;
|
|
||||||
sample.event.time = 0;
|
|
||||||
sample.event.flags = 0;
|
|
||||||
sample.event.value = ascent;
|
|
||||||
if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -253,6 +253,7 @@ static const dc_descriptor_t g_descriptors[] = {
|
|||||||
{"Cressi", "Leonardo", DC_FAMILY_CRESSI_LEONARDO, 1},
|
{"Cressi", "Leonardo", DC_FAMILY_CRESSI_LEONARDO, 1},
|
||||||
{"Cressi", "Giotto", DC_FAMILY_CRESSI_LEONARDO, 4},
|
{"Cressi", "Giotto", DC_FAMILY_CRESSI_LEONARDO, 4},
|
||||||
{"Cressi", "Newton", DC_FAMILY_CRESSI_LEONARDO, 5},
|
{"Cressi", "Newton", DC_FAMILY_CRESSI_LEONARDO, 5},
|
||||||
|
{"Cressi", "Drake", DC_FAMILY_CRESSI_LEONARDO, 6},
|
||||||
/* Zeagle N2iTiON3 */
|
/* Zeagle N2iTiON3 */
|
||||||
{"Zeagle", "N2iTiON3", DC_FAMILY_ZEAGLE_N2ITION3, 0},
|
{"Zeagle", "N2iTiON3", DC_FAMILY_ZEAGLE_N2ITION3, 0},
|
||||||
{"Apeks", "Quantum X", DC_FAMILY_ZEAGLE_N2ITION3, 0},
|
{"Apeks", "Quantum X", DC_FAMILY_ZEAGLE_N2ITION3, 0},
|
||||||
|
|||||||
@ -66,6 +66,7 @@ hw_ostc_parser_create
|
|||||||
hw_ostc3_parser_create
|
hw_ostc3_parser_create
|
||||||
cressi_edy_parser_create
|
cressi_edy_parser_create
|
||||||
cressi_leonardo_parser_create
|
cressi_leonardo_parser_create
|
||||||
|
cressi_leonardo_parser_create2
|
||||||
atomics_cobalt_parser_create
|
atomics_cobalt_parser_create
|
||||||
atomics_cobalt_parser_set_calibration
|
atomics_cobalt_parser_set_calibration
|
||||||
shearwater_predator_parser_create
|
shearwater_predator_parser_create
|
||||||
|
|||||||
@ -123,7 +123,7 @@ dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, dc_family_t fa
|
|||||||
rc = cressi_edy_parser_create (&parser, context, model);
|
rc = cressi_edy_parser_create (&parser, context, model);
|
||||||
break;
|
break;
|
||||||
case DC_FAMILY_CRESSI_LEONARDO:
|
case DC_FAMILY_CRESSI_LEONARDO:
|
||||||
rc = cressi_leonardo_parser_create (&parser, context);
|
rc = cressi_leonardo_parser_create2 (&parser, context, model);
|
||||||
break;
|
break;
|
||||||
case DC_FAMILY_ATOMICS_COBALT:
|
case DC_FAMILY_ATOMICS_COBALT:
|
||||||
rc = atomics_cobalt_parser_create (&parser, context);
|
rc = atomics_cobalt_parser_create (&parser, context);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user