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.
This commit is contained in:
Jef Driesen 2015-04-14 22:48:48 +02:00
parent f0974ed6bc
commit 311bc85645
5 changed files with 67 additions and 10 deletions

View File

@ -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[])

View File

@ -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[]);

View File

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

View File

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

View File

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