From d89dd952c9f601ce1be2b93bbad250e72506fea7 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Wed, 24 Sep 2014 21:39:28 -0700 Subject: [PATCH] Add initial support for the Aeris A300CS This is ignoring a ton of data that the dive computer provides. But it gives profile, tank pressure and temperatures - so it's a start. This patch adds a set_dtr and set_rts call to the serial interface prior to interacting with the device. This change is required for the A300CS to talk to the computer. Signed-off-by: Dirk Hohndel --- src/descriptor.c | 1 + src/oceanic_atom2.c | 24 ++++++++++++++++++++++++ src/oceanic_atom2_parser.c | 35 ++++++++++++++++++++++++++++++----- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 403b67a..617c279 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -171,6 +171,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545}, {"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548}, {"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B}, + {"Aeris", "A300CS", DC_FAMILY_OCEANIC_ATOM2, 0x454C}, /* Mares Nemo */ {"Mares", "Nemo", DC_FAMILY_MARES_NEMO, 0}, {"Mares", "Nemo Steel", DC_FAMILY_MARES_NEMO, 0}, diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 80639db..2606be7 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -150,6 +150,10 @@ static const oceanic_common_version_t oceanic_reactpro_version[] = { {"REACPRO2 \0\0 512K"}, }; +static const oceanic_common_version_t aeris_a300cs_version[] = { + {"AER300CS \0\0 2048"}, +}; + static const oceanic_common_layout_t aeris_f10_layout = { 0x10000, /* memsize */ 0x0000, /* cf_devinfo */ @@ -332,6 +336,19 @@ static const oceanic_common_layout_t oceanic_reactpro_layout = { 1 /* pt_mode_logbook */ }; +static const oceanic_common_layout_t aeris_a300cs_layout = { + 0x40000, /* memsize */ + 0x0000, /* cf_devinfo */ + 0x0040, /* cf_pointers */ + 0x0900, /* rb_logbook_begin */ + 0x1000, /* rb_logbook_end */ + 16, /* rb_logbook_entry_size */ + 0x1000, /* rb_profile_begin */ + 0x3FE00, /* rb_profile_end */ + 0, /* 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) { @@ -488,6 +505,10 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char // Give the interface 100 ms to settle and draw power up. serial_sleep (device->port, 100); + // Set the DTR/RTS lines. + serial_set_dtr(device->port, 1); + serial_set_rts(device->port, 1); + // Make sure everything is in a sane state. serial_flush (device->port, SERIAL_QUEUE_BOTH); @@ -534,6 +555,9 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char device->base.layout = &oceanic_veo1_layout; } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_reactpro_version)) { device->base.layout = &oceanic_reactpro_layout; + } else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_a300cs_version)) { + device->base.layout = &aeris_a300cs_layout; + device->bigpage = 16; } else { device->base.layout = &oceanic_default_layout; } diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 423c5a5..8afa6ea 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -69,6 +69,7 @@ #define AMPHOS 0x4545 #define PROPLUS3 0x4548 #define OCI 0x454B +#define A300CS 0x454C typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t; @@ -218,6 +219,13 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim datetime->hour = p[11]; datetime->minute = p[10]; break; + case A300CS: + datetime->year = (p[10]) + 2000; + datetime->month = (p[8]); + datetime->day = (p[9]); + datetime->hour = bcd2dec(p[1] & 0x1F); + datetime->minute = bcd2dec(p[0]); + break; default: datetime->year = bcd2dec (((p[3] & 0xC0) >> 2) + (p[4] & 0x0F)) + 2000; datetime->month = (p[4] & 0xF0) >> 4; @@ -346,7 +354,8 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns case DC_FIELD_GASMIX_COUNT: if (parser->model == DATAMASK || parser->model == COMPUMASK) *((unsigned int *) value) = 1; - else if (parser->model == VT4 || parser->model == VT41 || parser->model == OCI) + else if (parser->model == VT4 || parser->model == VT41 || + parser->model == OCI || parser->model == A300CS) *((unsigned int *) value) = 4; else if (parser->model == TX1) *((unsigned int *) value) = 6; @@ -358,6 +367,8 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns oxygen = data[header + 3]; } else if (parser->model == OCI) { oxygen = data[0x28 + flags]; + } else if (parser->model == A300CS) { + oxygen = data[0x2A + flags]; } else if (parser->model == TX1) { oxygen = data[0x3E + flags]; helium = data[0x48 + flags]; @@ -404,6 +415,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ } else if (parser->model == F10) { headersize = 3 * PAGESIZE; footersize = PAGESIZE / 2; + } else if (parser->model == A300CS) { + headersize = 5 * PAGESIZE; } if (size < headersize + footersize) @@ -415,7 +428,10 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ unsigned int time = 0; unsigned int interval = 1; if (parser->model != F10) { - switch (data[0x17] & 0x03) { + unsigned int idx = 0x17; + if (parser->model == A300CS) + idx = 0x1f; + switch (data[idx] & 0x03) { case 0: interval = 2; break; @@ -434,7 +450,7 @@ 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 || parser->model == OCI || - parser->model == TX1) + parser->model == TX1 || parser->model == A300CS) samplesize = PAGESIZE; else if (parser->model == F10) samplesize = 2; @@ -459,7 +475,10 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ unsigned int tank = 0; unsigned int pressure = 0; if (have_pressure) { - pressure = data[header + 2] + (data[header + 3] << 8); + unsigned int idx = 2; + if (parser->model == A300CS) + idx = 16; + pressure = data[header + idx] + (data[header + idx + 1] << 8); if (pressure == 10000) have_pressure = 0; } @@ -511,6 +530,10 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ // Tank pressure (1 psi) and number tank = 0; pressure = (((data[offset + 7] << 8) + data[offset + 6]) & 0x0FFF); + } else if (parser->model == A300CS) { + // Tank pressure (1 psi) and number (one based index) + tank = (data[offset + 1] & 0x03) - 1; + pressure = ((data[offset + 7] << 8) + data[offset + 6]) & 0x0FFF; } else { // Tank pressure (2 psi) and number (one based index) tank = (data[offset + 1] & 0x03) - 1; @@ -552,6 +575,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ temperature = data[offset + 1]; } else if (parser->model == VT4 || parser->model == VT41 || parser->model == ATOM3 || parser->model == ATOM31 || parser->model == A300AI) { temperature = ((data[offset + 7] & 0xF0) >> 4) | ((data[offset + 7] & 0x0C) << 2) | ((data[offset + 5] & 0x0C) << 4); + } else if (parser->model == A300CS) { + temperature = data[offset + 11]; } else { unsigned int sign; if (parser->model == DG03 || parser->model == PROPLUS3) @@ -584,7 +609,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == ZENAIR ||parser->model == A300AI || parser->model == DG03 || parser->model == PROPLUS3) pressure = (((data[offset + 0] & 0x03) << 8) + data[offset + 1]) * 5; - else if (parser->model == TX1) + else if (parser->model == TX1 || parser->model == A300CS) pressure = array_uint16_le (data + offset + 4); else pressure -= data[offset + 1];