From 853477b3b1470241dee56627ec78b6fe24a207a1 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sat, 13 Sep 2014 00:06:44 +0200 Subject: [PATCH] Add support for the Aeris F11. Most of the changes needed for the F11 are the standard model specific tweaks. But the F11 also has another interesting "feature". If you try to download a full memory dump using the standard B1 read command, then the data starts to repeat after the first 64K. It seems that somehow, the B1 command can only address the first 64K of the memory. To avoid this problem, the newer B4 read command needs to be used instead. This might be a firmware bug, or maybe internally they store the address in a 12bit variable, which causes the upper bits to get lost? That would explain the repeating data. --- src/descriptor.c | 1 + src/oceanic_atom2.c | 20 ++++++++++++++++++++ src/oceanic_atom2_parser.c | 22 +++++++++++++++------- src/oceanic_common.c | 4 ++++ 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index 617c279..2845af1 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -170,6 +170,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Hollis", "TX1", DC_FAMILY_OCEANIC_ATOM2, 0x4542}, {"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545}, {"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548}, + {"Aeris", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4549}, {"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B}, {"Aeris", "A300CS", DC_FAMILY_OCEANIC_ATOM2, 0x454C}, /* Mares Nemo */ diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 733c547..2301c35 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -73,6 +73,10 @@ static const oceanic_common_version_t aeris_f10_version[] = { {"FREEWAER \0\0 512K"}, }; +static const oceanic_common_version_t aeris_f11_version[] = { + {"AERISF11 \0\0 1024"}, +}; + static const oceanic_common_version_t oceanic_atom1_version[] = { {"ATOM rev\0\0 256K"}, }; @@ -170,6 +174,19 @@ static const oceanic_common_layout_t aeris_f10_layout = { 2 /* pt_mode_logbook */ }; +static const oceanic_common_layout_t aeris_f11_layout = { + 0x20000, /* memsize */ + 0x0000, /* cf_devinfo */ + 0x0040, /* cf_pointers */ + 0x0100, /* rb_logbook_begin */ + 0x0AC0, /* rb_logbook_end */ + 32, /* rb_logbook_entry_size */ + 0xD810, /* rb_profile_begin */ + 0x20000, /* rb_profile_end */ + 0, /* pt_mode_global */ + 3 /* pt_mode_logbook */ +}; + static const oceanic_common_layout_t oceanic_default_layout = { 0x10000, /* memsize */ 0x0000, /* cf_devinfo */ @@ -530,6 +547,9 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char // Override the base class values. if (OCEANIC_COMMON_MATCH (device->base.version, aeris_f10_version)) { device->base.layout = &aeris_f10_layout; + } else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_f11_version)) { + device->base.layout = &aeris_f11_layout; + device->bigpage = 8; } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom1_version)) { device->base.layout = &oceanic_atom1_layout; } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_atom2_version)) { diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index 8dedf3f..f38afef 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -68,6 +68,7 @@ #define TX1 0x4542 #define AMPHOS 0x4545 #define PROPLUS3 0x4548 +#define F11 0x4549 #define OCI 0x454B #define A300CS 0x454C @@ -156,7 +157,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim oceanic_atom2_parser_t *parser = (oceanic_atom2_parser_t *) abstract; unsigned int header = 8; - if (parser->model == F10) + if (parser->model == F10 || parser->model == F11) header = 32; if (abstract->size < header) @@ -205,6 +206,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim datetime->minute = bcd2dec (p[0]); break; case F10: + case F11: datetime->year = bcd2dec (p[6]) + 2000; datetime->month = bcd2dec (p[7]); datetime->day = bcd2dec (p[8]); @@ -308,6 +310,9 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns } else if (parser->model == F10) { headersize = 3 * PAGESIZE; footersize = PAGESIZE / 2; + } else if (parser->model == F11) { + headersize = 5 * PAGESIZE; + footersize = PAGESIZE / 2; } if (size < headersize + footersize) @@ -341,13 +346,13 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns if (value) { switch (type) { case DC_FIELD_DIVETIME: - if (parser->model == F10) + if (parser->model == F10 || parser->model == F11) *((unsigned int *) value) = bcd2dec (data[2]) + bcd2dec (data[3]) * 60 + bcd2dec (data[1]) * 3600; else *((unsigned int *) value) = parser->divetime; break; case DC_FIELD_MAXDEPTH: - if (parser->model == F10) + if (parser->model == F10 || parser->model == F11) *((double *) value) = array_uint16_le (data + 4) / 16.0 * FEET; else *((double *) value) = array_uint16_le (data + footer + 4) / 16.0 * FEET; @@ -439,6 +444,9 @@ 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 == F11) { + headersize = 5 * PAGESIZE; + footersize = PAGESIZE / 2; } else if (parser->model == A300CS) { headersize = 5 * PAGESIZE; } @@ -451,7 +459,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ unsigned int time = 0; unsigned int interval = 1; - if (parser->model != F10) { + if (parser->model != F10 && parser->model != F11) { unsigned int idx = 0x17; if (parser->model == A300CS) idx = 0x1f; @@ -476,7 +484,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == OC1C || parser->model == OCI || parser->model == TX1 || parser->model == A300CS) samplesize = PAGESIZE; - else if (parser->model == F10) + else if (parser->model == F10 || parser->model == F11) samplesize = 2; unsigned int have_temperature = 1, have_pressure = 1; @@ -484,7 +492,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ parser->model == ELEMENT2 || parser->model == VEO20 || parser->model == A300 || parser->model == ZEN) { have_pressure = 0; - } else if (parser->model == F10) { + } else if (parser->model == F10 || parser->model == F11) { have_temperature = 0; have_pressure = 0; } @@ -530,7 +538,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_ // Get the sample type. unsigned int sampletype = data[offset + 0]; - if (parser->model == F10) + if (parser->model == F10 || parser->model == F11) sampletype = 0; // The sample size is usually fixed, but some sample types have a diff --git a/src/oceanic_common.c b/src/oceanic_common.c index f5f37a1..f29d176 100644 --- a/src/oceanic_common.c +++ b/src/oceanic_common.c @@ -61,6 +61,8 @@ get_profile_first (const unsigned char data[], const oceanic_common_layout_t *la value = array_uint16_le (data + 5); } else if (layout->pt_mode_logbook == 1) { value = array_uint16_le (data + 4); + } else if (layout->pt_mode_logbook == 3) { + value = array_uint16_le (data + 16); } else { return array_uint16_le (data + 16); } @@ -83,6 +85,8 @@ get_profile_last (const unsigned char data[], const oceanic_common_layout_t *lay value = array_uint16_le (data + 6) >> 4; } else if (layout->pt_mode_logbook == 1) { value = array_uint16_le (data + 6); + } else if (layout->pt_mode_logbook == 3) { + value = array_uint16_le (data + 18); } else { return array_uint16_le(data + 18); }