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.
This commit is contained in:
Jef Driesen 2014-09-13 00:06:44 +02:00
parent af43c80d78
commit 853477b3b1
4 changed files with 40 additions and 7 deletions

View File

@ -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 */

View File

@ -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)) {

View File

@ -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

View File

@ -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);
}