From 311bc856454391a8a02d2d44aa9141e41e800108 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 14 Apr 2015 22:48:48 +0200 Subject: [PATCH] Add support for the Tusa IQ-700. The Tusa IQ-700 is very similar to the other Seiko based models. The most important change is that due the smaller amount of memory (8K vs 32K), the logbook entries are only 1 byte large instead of two bytes. --- src/array.c | 23 +++++++++++++++++++++++ src/array.h | 6 ++++++ src/cressi_edy.c | 30 ++++++++++++++++++++++++++---- src/cressi_edy_parser.c | 15 ++++++++++----- src/descriptor.c | 3 ++- 5 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/array.c b/src/array.c index be8d696..26a6c1b 100644 --- a/src/array.c +++ b/src/array.c @@ -146,6 +146,29 @@ array_convert_hex2bin (const unsigned char input[], unsigned int isize, unsigned return 0; } +unsigned int +array_uint_be (const unsigned char data[], unsigned int n) +{ + unsigned int shift = n * 8; + unsigned int value = 0; + for (unsigned int i = 0; i < n; ++i) { + shift -= 8; + value |= data[i] << shift; + } + return value; +} + +unsigned int +array_uint_le (const unsigned char data[], unsigned int n) +{ + unsigned int shift = 0; + unsigned int value = 0; + for (unsigned int i = 0; i < n; ++i) { + value |= data[i] << shift; + shift += 8; + } + return value; +} unsigned int array_uint32_be (const unsigned char data[]) diff --git a/src/array.h b/src/array.h index 622e0d5..49e8ab1 100644 --- a/src/array.h +++ b/src/array.h @@ -49,6 +49,12 @@ array_convert_bin2hex (const unsigned char input[], unsigned int isize, unsigned int array_convert_hex2bin (const unsigned char input[], unsigned int isize, unsigned char output[], unsigned int osize); +unsigned int +array_uint_be (const unsigned char data[], unsigned int n); + +unsigned int +array_uint_le (const unsigned char data[], unsigned int n); + unsigned int array_uint32_be (const unsigned char data[]); diff --git a/src/cressi_edy.c b/src/cressi_edy.c index 49cefd9..504b79c 100644 --- a/src/cressi_edy.c +++ b/src/cressi_edy.c @@ -44,11 +44,15 @@ #define SZ_PACKET 0x80 #define SZ_PAGE (SZ_PACKET / 4) +#define IQ700 0x05 +#define EDY 0x08 + typedef struct cressi_edy_layout_t { unsigned int memsize; unsigned int rb_profile_begin; unsigned int rb_profile_end; unsigned int rb_logbook_offset; + unsigned int rb_logbook_size; unsigned int rb_logbook_begin; unsigned int rb_logbook_end; unsigned int config; @@ -83,11 +87,23 @@ static const cressi_edy_layout_t cressi_edy_layout = { 0x3FE0, /* rb_profile_begin */ 0x7F80, /* rb_profile_end */ 0x7F80, /* rb_logbook_offset */ + 2, /* rb_logbook_size */ 0, /* rb_logbook_begin */ 60, /* rb_logbook_end */ 0x7C, /* config */ }; +static const cressi_edy_layout_t tusa_iq700_layout = { + 0x2000, /* memsize */ + 0x0000, /* rb_profile_begin */ + 0x1F60, /* rb_profile_end */ + 0x1F80, /* rb_logbook_offset */ + 1, /* rb_logbook_size */ + 0, /* rb_logbook_begin */ + 60, /* rb_logbook_end */ + 0x3C, /* config */ +}; + static unsigned int ifloor (unsigned int x, unsigned int n) { @@ -235,7 +251,7 @@ cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *na // Set the default values. device->port = NULL; - device->layout = &cressi_edy_layout; + device->layout = NULL; device->model = 0; memset (device->fingerprint, 0, sizeof (device->fingerprint)); @@ -282,6 +298,12 @@ cressi_edy_device_open (dc_device_t **out, dc_context_t *context, const char *na cressi_edy_init2 (device); cressi_edy_init3 (device); + if (device->model == IQ700) { + device->layout = &tusa_iq700_layout; + } else { + device->layout = &cressi_edy_layout; + } + // Set the serial communication protocol (4800 8N1). rc = serial_configure (device->port, 4800, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); if (rc == -1) { @@ -430,7 +452,7 @@ cressi_edy_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v unsigned int count = ringbuffer_distance (first, last, 0, layout->rb_logbook_begin, layout->rb_logbook_end) + 1; // Get the profile pointer. - unsigned int eop = array_uint16_le (logbook + layout->config + 2) * SZ_PAGE + layout->rb_profile_begin; + unsigned int eop = array_uint_le (logbook + layout->config + 2, layout->rb_logbook_size) * SZ_PAGE + layout->rb_profile_begin; if (eop < layout->rb_profile_begin || eop >= layout->rb_profile_end) { ERROR (abstract->context, "Invalid ringbuffer pointer detected."); return DC_STATUS_DATAFORMAT; @@ -445,7 +467,7 @@ cressi_edy_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v unsigned int previous = eop; for (unsigned int i = 0; i < count; ++i) { // Get the pointer to the profile data. - unsigned int current = array_uint16_le (logbook + 2 * idx) * SZ_PAGE + layout->rb_profile_begin; + unsigned int current = array_uint_le (logbook + idx * layout->rb_logbook_size, layout->rb_logbook_size) * SZ_PAGE + layout->rb_profile_begin; if (current < layout->rb_profile_begin || current >= layout->rb_profile_end) { ERROR (abstract->context, "Invalid ringbuffer pointer detected."); return DC_STATUS_DATAFORMAT; @@ -508,7 +530,7 @@ cressi_edy_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v previous = eop; for (unsigned int i = 0; i < count; ++i) { // Get the pointer to the profile data. - unsigned int current = array_uint16_le (logbook + 2 * idx) * SZ_PAGE + layout->rb_profile_begin; + unsigned int current = array_uint_le (logbook + idx * layout->rb_logbook_size, layout->rb_logbook_size) * SZ_PAGE + layout->rb_profile_begin; if (current < layout->rb_profile_begin || current >= layout->rb_profile_end) { ERROR (abstract->context, "Invalid ringbuffer pointer detected."); free(buffer); diff --git a/src/cressi_edy_parser.c b/src/cressi_edy_parser.c index e6d12a8..0c4d143 100644 --- a/src/cressi_edy_parser.c +++ b/src/cressi_edy_parser.c @@ -29,6 +29,9 @@ #define ISINSTANCE(parser) dc_parser_isinstance((parser), &cressi_edy_parser_vtable) +#define IQ700 0x05 +#define EDY 0x08 + typedef struct cressi_edy_parser_t cressi_edy_parser_t; struct cressi_edy_parser_t { @@ -145,7 +148,7 @@ cressi_edy_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign if (value) { switch (type) { case DC_FIELD_DIVETIME: - if (parser->model == 0x08) + if (parser->model == EDY) *((unsigned int *) value) = bcd2dec (p[0x0C] & 0x0F) * 60 + bcd2dec (p[0x0D]); else *((unsigned int *) value) = (bcd2dec (p[0x0C] & 0x0F) * 100 + bcd2dec (p[0x0D])) * 60; @@ -179,11 +182,13 @@ cressi_edy_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t c unsigned int size = abstract->size; unsigned int time = 0; - unsigned int interval = 0; - if (parser->model == 0x08) + unsigned int interval = 30; + if (parser->model == EDY) { interval = 1; - else - interval = 30; + } else if (parser->model == IQ700) { + if (data[0x07] & 0x40) + interval = 15; + } unsigned int ngasmixes = cressi_edy_parser_count_gasmixes(data); unsigned int gasmix = 0xFFFFFFFF; diff --git a/src/descriptor.c b/src/descriptor.c index bfee247..879015d 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -217,7 +217,8 @@ static const dc_descriptor_t g_descriptors[] = { {"Heinrichs Weikamp", "OSTC cR", DC_FAMILY_HW_OSTC3, 0x05}, {"Heinrichs Weikamp", "OSTC Sport", DC_FAMILY_HW_OSTC3, 0x12}, /* Cressi Edy */ - {"Cressi", "Edy", DC_FAMILY_CRESSI_EDY, 0}, + {"Tusa", "IQ-700", DC_FAMILY_CRESSI_EDY, 0x05}, + {"Cressi", "Edy", DC_FAMILY_CRESSI_EDY, 0x08}, /* Cressi Leonardo */ {"Cressi", "Leonardo", DC_FAMILY_CRESSI_LEONARDO, 1}, {"Cressi", "Giotto", DC_FAMILY_CRESSI_LEONARDO, 4},