>From 253ee26f6ae1dd0f7630ab0571171511996746f9 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Wed, 24 Sep 2014 21:39:28 -0700 Subject: [PATCH 3/5] 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. TODO: - we need to verify that this doesn't cause any issues with earlier models. Signed-off-by: Dirk Hohndel --- src/descriptor.c | 1 + src/oceanic_atom2.c | 29 +++++++++++++++++++++++++++-- src/oceanic_atom2_parser.c | 33 ++++++++++++++++++++++++++++----- 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 403b67a8746f..617c279cc185 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 9fd10f56a90d..5119ec57b2ea 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -151,6 +151,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 */ @@ -333,6 +337,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 */ + 0x40000, /* 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) { @@ -470,8 +487,7 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char } // Set the serial communication protocol (38400 8N1). - rc = serial_configure (device->port, 38400, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); - if (rc == -1) { + if (serial_configure (device->port, 38400, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE) == -1) { ERROR (context, "Failed to set the terminal attributes."); serial_close (device->port); free (device); @@ -489,6 +505,11 @@ 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); + // at least the Aeris A300CS needs these two commands to respond to the serial interface + // need to verify that these don't cause problem with earlier models + 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); @@ -535,6 +556,10 @@ 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; + device->base.multipage = 16; } else { device->base.layout = &oceanic_default_layout; } diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index beed0a85278b..b081b3be812a 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,14 @@ 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]); + pm = p[1] & 0x80; + break; default: datetime->year = bcd2dec (((p[3] & 0xC0) >> 2) + (p[4] & 0x0F)) + 2000; datetime->month = (p[4] & 0xF0) >> 4; @@ -345,7 +354,7 @@ 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; @@ -357,6 +366,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]; @@ -403,6 +414,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) @@ -414,7 +427,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) { + int offset = 0x17; + if (parser->model == A300CS) + offset = 0x1f; + switch (data[offset] & 0x03) { case 0: interval = 2; break; @@ -433,7 +449,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; @@ -458,7 +474,8 @@ 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); + int idx = parser->model == A300CS ? 16 : 2; + pressure = data[header + idx] + (data[header + idx + 1] << 8); if (pressure == 10000) have_pressure = 0; } @@ -510,6 +527,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; @@ -551,6 +572,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) @@ -583,7 +606,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]; -- 1.8.0.rc0.18.gf84667d