Add support for the Hollis TX1.

The Hollis TX1 has several new features compared to the other models. It
supports trimix and up to 6 different gas mixes can be configured. It
also has twice the amount of memory, which requires an extra bit for the
ringbuffer pointers.
This commit is contained in:
Jef Driesen 2014-04-02 08:30:20 +02:00
parent 3c99f55b6f
commit 148f059bcb
4 changed files with 48 additions and 4 deletions

View File

@ -164,6 +164,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Oceanic", "Atom 3.1", DC_FAMILY_OCEANIC_ATOM2, 0x4456}, {"Oceanic", "Atom 3.1", DC_FAMILY_OCEANIC_ATOM2, 0x4456},
{"Aeris", "A300 AI", DC_FAMILY_OCEANIC_ATOM2, 0x4457}, {"Aeris", "A300 AI", DC_FAMILY_OCEANIC_ATOM2, 0x4457},
{"Sherwood", "Wisdom 3", DC_FAMILY_OCEANIC_ATOM2, 0x4458}, {"Sherwood", "Wisdom 3", DC_FAMILY_OCEANIC_ATOM2, 0x4458},
{"Hollis", "TX1", DC_FAMILY_OCEANIC_ATOM2, 0x4542},
{"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545}, {"Sherwood", "Amphos", DC_FAMILY_OCEANIC_ATOM2, 0x4545},
{"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548}, {"Oceanic", "Pro Plus 3", DC_FAMILY_OCEANIC_ATOM2, 0x4548},
{"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B}, {"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B},

View File

@ -134,6 +134,10 @@ static const oceanic_common_version_t oceanic_vt4_version[] = {
{"AERISAIR \0\0 1024"}, {"AERISAIR \0\0 1024"},
}; };
static const oceanic_common_version_t hollis_tx1_version[] = {
{"HOLLDG04 \0\0 2048"},
};
static const oceanic_common_version_t oceanic_veo1_version[] = { static const oceanic_common_version_t oceanic_veo1_version[] = {
{"OCEVEO10 \0\0 8K"}, {"OCEVEO10 \0\0 8K"},
{"AERIS XR1 NX R\0\0"}, {"AERIS XR1 NX R\0\0"},
@ -286,6 +290,19 @@ static const oceanic_common_layout_t oceanic_vt4_layout = {
1 /* pt_mode_logbook */ 1 /* pt_mode_logbook */
}; };
static const oceanic_common_layout_t hollis_tx1_layout = {
0x40000, /* memsize */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0780, /* rb_logbook_begin */
0x1000, /* rb_logbook_end */
8, /* rb_logbook_entry_size */
0x1000, /* rb_profile_begin */
0x40000, /* rb_profile_end */
0, /* pt_mode_global */
1 /* pt_mode_logbook */
};
static const oceanic_common_layout_t oceanic_veo1_layout = { static const oceanic_common_layout_t oceanic_veo1_layout = {
0x0400, /* memsize */ 0x0400, /* memsize */
0x0000, /* cf_devinfo */ 0x0000, /* cf_devinfo */
@ -501,6 +518,8 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char
device->base.layout = &oceanic_atom3_layout; device->base.layout = &oceanic_atom3_layout;
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_vt4_version)) { } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_vt4_version)) {
device->base.layout = &oceanic_vt4_layout; device->base.layout = &oceanic_vt4_layout;
} else if (OCEANIC_COMMON_MATCH (device->base.version, hollis_tx1_version)) {
device->base.layout = &hollis_tx1_layout;
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_veo1_version)) { } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_veo1_version)) {
device->base.layout = &oceanic_veo1_layout; device->base.layout = &oceanic_veo1_layout;
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_reactpro_version)) { } else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_reactpro_version)) {

View File

@ -58,6 +58,7 @@
#define EPICB 0x4453 #define EPICB 0x4453
#define ATOM31 0x4456 #define ATOM31 0x4456
#define A300AI 0x4457 #define A300AI 0x4457
#define TX1 0x4542
#define AMPHOS 0x4545 #define AMPHOS 0x4545
#define PROPLUS3 0x4548 #define PROPLUS3 0x4548
#define OCI 0x454B #define OCI 0x454B
@ -202,6 +203,13 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
datetime->minute = bcd2dec (p[12]); datetime->minute = bcd2dec (p[12]);
pm = p[13] & 0x80; pm = p[13] & 0x80;
break; break;
case TX1:
datetime->year = bcd2dec (p[13]) + 2000;
datetime->month = bcd2dec (p[14]);
datetime->day = bcd2dec (p[15]);
datetime->hour = p[11];
datetime->minute = p[10];
break;
default: default:
datetime->year = bcd2dec (((p[3] & 0xC0) >> 2) + (p[4] & 0x0F)) + 2000; datetime->year = bcd2dec (((p[3] & 0xC0) >> 2) + (p[4] & 0x0F)) + 2000;
datetime->month = (p[4] & 0xF0) >> 4; datetime->month = (p[4] & 0xF0) >> 4;
@ -274,6 +282,8 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
headersize -= PAGESIZE; headersize -= PAGESIZE;
} else if (parser->model == VT4 || parser->model == VT41) { } else if (parser->model == VT4 || parser->model == VT41) {
headersize += PAGESIZE; headersize += PAGESIZE;
} else if (parser->model == TX1) {
headersize += 2 * PAGESIZE;
} else if (parser->model == ATOM1) { } else if (parser->model == ATOM1) {
headersize -= 2 * PAGESIZE; headersize -= 2 * PAGESIZE;
} else if (parser->model == F10) { } else if (parser->model == F10) {
@ -327,6 +337,8 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
*((unsigned int *) value) = 1; *((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)
*((unsigned int *) value) = 4; *((unsigned int *) value) = 4;
else if (parser->model == TX1)
*((unsigned int *) value) = 6;
else else
*((unsigned int *) value) = 3; *((unsigned int *) value) = 3;
break; break;
@ -335,6 +347,9 @@ oceanic_atom2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
oxygen = data[header + 3]; oxygen = data[header + 3];
} else if (parser->model == OCI) { } else if (parser->model == OCI) {
oxygen = data[0x28 + flags]; oxygen = data[0x28 + flags];
} else if (parser->model == TX1) {
oxygen = data[0x3E + flags];
helium = data[0x48 + flags];
} else { } else {
oxygen = data[header + 4 + flags]; oxygen = data[header + 4 + flags];
} }
@ -369,6 +384,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
headersize -= PAGESIZE; headersize -= PAGESIZE;
} else if (parser->model == VT4 || parser->model == VT41) { } else if (parser->model == VT4 || parser->model == VT41) {
headersize += PAGESIZE; headersize += PAGESIZE;
} else if (parser->model == TX1) {
headersize += 2 * PAGESIZE;
} else if (parser->model == ATOM1) { } else if (parser->model == ATOM1) {
headersize -= 2 * PAGESIZE; headersize -= 2 * PAGESIZE;
} else if (parser->model == F10) { } else if (parser->model == F10) {
@ -403,7 +420,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
unsigned int samplesize = PAGESIZE / 2; unsigned int samplesize = PAGESIZE / 2;
if (parser->model == OC1A || parser->model == OC1B || if (parser->model == OC1A || parser->model == OC1B ||
parser->model == OC1C || parser->model == OCI) parser->model == OC1C || parser->model == OCI ||
parser->model == TX1)
samplesize = PAGESIZE; samplesize = PAGESIZE;
else if (parser->model == F10) else if (parser->model == F10)
samplesize = 2; samplesize = 2;
@ -516,7 +534,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
parser->model == OC1B || parser->model == OC1C || parser->model == OC1B || parser->model == OC1C ||
parser->model == OCI) { parser->model == OCI) {
temperature = data[offset + 3]; temperature = data[offset + 3];
} else if (parser->model == OCS) { } else if (parser->model == OCS || parser->model == TX1) {
temperature = data[offset + 1]; temperature = data[offset + 1];
} else if (parser->model == VT4 || parser->model == VT41 || parser->model == ATOM3 || parser->model == ATOM31 || parser->model == A300AI) { } 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); temperature = ((data[offset + 7] & 0xF0) >> 4) | ((data[offset + 7] & 0x0C) << 2) | ((data[offset + 5] & 0x0C) << 4);
@ -549,6 +567,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
parser->model == ZENAIR ||parser->model == A300AI || parser->model == ZENAIR ||parser->model == A300AI ||
parser->model == DG03 || parser->model == PROPLUS3) parser->model == DG03 || parser->model == PROPLUS3)
pressure = (((data[offset + 0] & 0x03) << 8) + data[offset + 1]) * 5; pressure = (((data[offset + 0] & 0x03) << 8) + data[offset + 1]) * 5;
else if (parser->model == TX1)
pressure = array_uint16_le (data + offset + 4);
else else
pressure -= data[offset + 1]; pressure -= data[offset + 1];
sample.pressure.tank = tank; sample.pressure.tank = tank;

View File

@ -65,7 +65,9 @@ get_profile_first (const unsigned char data[], const oceanic_common_layout_t *la
return array_uint16_le (data + 16); return array_uint16_le (data + 16);
} }
if (layout->memsize > 0x10000) if (layout->memsize > 0x20000)
return (value & 0x3FFF) * PAGESIZE;
else if (layout->memsize > 0x10000)
return (value & 0x1FFF) * PAGESIZE; return (value & 0x1FFF) * PAGESIZE;
else else
return (value & 0x0FFF) * PAGESIZE; return (value & 0x0FFF) * PAGESIZE;
@ -85,7 +87,9 @@ get_profile_last (const unsigned char data[], const oceanic_common_layout_t *lay
return array_uint16_le(data + 18); return array_uint16_le(data + 18);
} }
if (layout->memsize > 0x10000) if (layout->memsize > 0x20000)
return (value & 0x3FFF) * PAGESIZE;
else if (layout->memsize > 0x10000)
return (value & 0x1FFF) * PAGESIZE; return (value & 0x1FFF) * PAGESIZE;
else else
return (value & 0x0FFF) * PAGESIZE; return (value & 0x0FFF) * PAGESIZE;