From 52388efe593247bcd79d5fb3f5670c05b250b34e Mon Sep 17 00:00:00 2001 From: Janice McLaughlin Date: Thu, 20 Sep 2018 14:13:17 +0200 Subject: [PATCH] Add support for the Aqualung i770R It appears that the Aqualung i770R looks almost the same as the Pro Plus X, but has an additional pO2 field for each gas by the O2 field, which impacts the offset calculations. --- src/descriptor.c | 1 + src/oceanic_atom2.c | 25 ++++++++++++++++++++++++- src/oceanic_atom2_parser.c | 29 ++++++++++++++++++++--------- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index d9b5f01..e9f4540 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -220,6 +220,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Aqualung", "i550", DC_FAMILY_OCEANIC_ATOM2, 0x4642, DC_TRANSPORT_SERIAL, NULL}, {"Aqualung", "i200", DC_FAMILY_OCEANIC_ATOM2, 0x4646, DC_TRANSPORT_SERIAL, NULL}, {"Aqualung", "i100", DC_FAMILY_OCEANIC_ATOM2, 0x464E, DC_TRANSPORT_SERIAL, NULL}, + {"Aqualung", "i770R", DC_FAMILY_OCEANIC_ATOM2, 0x4651, DC_TRANSPORT_SERIAL, NULL}, /* Mares Nemo */ {"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0, DC_TRANSPORT_SERIAL, NULL}, {"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0, DC_TRANSPORT_SERIAL, NULL}, diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 7d1f68c..debade1 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -35,6 +35,7 @@ #define PROPLUSX 0x4552 #define VTX 0x4557 #define I750TC 0x455A +#define I770R 0x4651 #define MAXRETRIES 2 #define MAXDELAY 16 @@ -192,6 +193,10 @@ static const oceanic_common_version_t oceanic_proplusx_version[] = { {"OCEANOCX \0\0 2048"}, }; +static const oceanic_common_version_t aqualung_i770r_version[] = { + {"AQUA770R \0\0 2048"}, +}; + static const oceanic_common_version_t aeris_a300cs_version[] = { {"AER300CS \0\0 2048"}, {"OCEANVTX \0\0 2048"}, @@ -472,6 +477,21 @@ static const oceanic_common_layout_t oceanic_proplusx_layout = { 0, /* pt_mode_serial */ }; +static const oceanic_common_layout_t aqualung_i770r_layout = { + 0x440000, /* memsize */ + 0x40000, /* highmem */ + 0x0000, /* cf_devinfo */ + 0x0040, /* cf_pointers */ + 0x2000, /* rb_logbook_begin */ + 0x10000, /* rb_logbook_end */ + 16, /* rb_logbook_entry_size */ + 0x40000, /* rb_profile_begin */ + 0x440000, /* rb_profile_end */ + 0, /* pt_mode_global */ + 1, /* pt_mode_logbook */ + 0, /* pt_mode_serial */ +}; + static const oceanic_common_layout_t aeris_a300cs_layout = { 0x40000, /* memsize */ 0, /* highmem */ @@ -643,7 +663,7 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, dc_iostream // Get the correct baudrate. unsigned int baudrate = 38400; - if (model == VTX || model == I750TC || model == PROPLUSX) { + if (model == VTX || model == I750TC || model == PROPLUSX || model == I770R) { baudrate = 115200; } @@ -746,6 +766,9 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, dc_iostream } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_proplusx_version)) { device->base.layout = &oceanic_proplusx_layout; device->bigpage = 16; + } else if (OCEANIC_COMMON_MATCH (device->base.version, aqualung_i770r_version)) { + device->base.layout = &aqualung_i770r_layout; + device->bigpage = 16; } else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_a300cs_version)) { device->base.layout = &aeris_a300cs_layout; device->bigpage = 16; diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index bdf7174..8a35c4f 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -87,6 +87,7 @@ #define I550 0x4642 #define I200 0x4646 #define I100 0x464E +#define I770R 0x4651 #define NORMAL 0 #define GAUGE 1 @@ -174,7 +175,8 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned parser->headersize = 5 * PAGESIZE; parser->footersize = 0; } else if (model == A300CS || model == VTX || - model == I450T || model == I750TC) { + model == I450T || model == I750TC || + model == I770R) { parser->headersize = 5 * PAGESIZE; } else if (model == PROPLUSX) { parser->headersize = 3 * PAGESIZE; @@ -315,6 +317,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim case I450T: case I750TC: case PROPLUSX: + case I770R: datetime->year = (p[10]) + 2000; datetime->month = (p[8]); datetime->day = (p[9]); @@ -416,6 +419,7 @@ oceanic_atom2_parser_cache (oceanic_atom2_parser_t *parser) unsigned int ngasmixes = 0; unsigned int o2_offset = 0; unsigned int he_offset = 0; + unsigned int o2_step = 1; if (mode == FREEDIVE) { ngasmixes = 0; } else if (parser->model == DATAMASK || parser->model == COMPUMASK) { @@ -454,6 +458,10 @@ oceanic_atom2_parser_cache (oceanic_atom2_parser_t *parser) } else if (parser->model == PROPLUSX) { o2_offset = 0x24; ngasmixes = 4; + } else if (parser->model == I770R) { + o2_offset = 0x30; + ngasmixes = 4; + o2_step = 2; } else { o2_offset = header + 4; ngasmixes = 3; @@ -465,8 +473,8 @@ oceanic_atom2_parser_cache (oceanic_atom2_parser_t *parser) parser->mode = mode; parser->ngasmixes = ngasmixes; for (unsigned int i = 0; i < ngasmixes; ++i) { - if (data[o2_offset + i]) { - parser->oxygen[i] = data[o2_offset + i]; + if (data[o2_offset + i * o2_step]) { + parser->oxygen[i] = data[o2_offset + i * o2_step]; } else { parser->oxygen[i] = 21; } @@ -632,7 +640,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ unsigned int idx = 0x17; if (parser->model == A300CS || parser->model == VTX || parser->model == I450T || parser->model == I750TC || - parser->model == PROPLUSX) + parser->model == PROPLUSX || parser->model == I770R) idx = 0x1f; switch (data[idx] & 0x03) { case 0: @@ -687,7 +695,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == OC1C || parser->model == OCI || parser->model == TX1 || parser->model == A300CS || parser->model == VTX || parser->model == I450T || - parser->model == I750TC || parser->model == PROPLUSX) { + parser->model == I750TC || parser->model == PROPLUSX || + parser->model == I770R) { samplesize = PAGESIZE; } @@ -865,7 +874,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == XPAIR) { temperature = ((data[offset + 7] & 0xF0) >> 4) | ((data[offset + 7] & 0x0C) << 2) | ((data[offset + 5] & 0x0C) << 4); } else if (parser->model == A300CS || parser->model == VTX || - parser->model == I750TC || parser->model == PROPLUSX) { + parser->model == I750TC || parser->model == PROPLUSX || + parser->model == I770R) { temperature = data[offset + 11]; } else { unsigned int sign; @@ -906,7 +916,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ pressure = (((data[offset + 0] & 0x03) << 8) + data[offset + 1]) * 5; else if (parser->model == TX1 || parser->model == A300CS || parser->model == VTX || parser->model == I750TC || - parser->model == PROPLUSX) + parser->model == PROPLUSX || parser->model == I770R) pressure = array_uint16_le (data + offset + 4); else pressure -= data[offset + 1]; @@ -955,7 +965,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ unsigned int decostop = 0, decotime = 0; if (parser->model == A300CS || parser->model == VTX || parser->model == I450T || parser->model == I750TC || - parser->model == PROPLUSX) { + parser->model == PROPLUSX || parser->model == I770R) { decostop = (data[offset + 15] & 0x70) >> 4; decotime = array_uint16_le(data + offset + 6) & 0x03FF; have_deco = 1; @@ -999,7 +1009,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ have_rbt = 1; } else if (parser->model == I450T || parser->model == OC1A || parser->model == OC1B || parser->model == OC1C || - parser->model == OCI || parser->model == PROPLUSX) { + parser->model == OCI || parser->model == PROPLUSX || + parser->model == I770R) { rbt = array_uint16_le(data + offset + 8) & 0x01FF; have_rbt = 1; } else if (parser->model == VISION || parser->model == XPAIR ||