diff --git a/src/descriptor.c b/src/descriptor.c index 2061408..e45a286 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -72,6 +72,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Suunto", "D4i", DC_FAMILY_SUUNTO_D9, 0x19}, {"Suunto", "D6i", DC_FAMILY_SUUNTO_D9, 0x1A}, {"Suunto", "D9tx", DC_FAMILY_SUUNTO_D9, 0x1B}, + {"Suunto", "DX", DC_FAMILY_SUUNTO_D9, 0x1C}, /* Uwatec Aladin */ {"Uwatec", "Aladin Air Twin", DC_FAMILY_UWATEC_ALADIN, 0x1C}, {"Uwatec", "Aladin Sport Plus", DC_FAMILY_UWATEC_ALADIN, 0x3E}, diff --git a/src/suunto_d9.c b/src/suunto_d9.c index 259cbe9..cdd2961 100644 --- a/src/suunto_d9.c +++ b/src/suunto_d9.c @@ -41,6 +41,7 @@ #define D4i 0x19 #define D6i 0x1A #define D9tx 0x1B +#define DX 0x1C typedef struct suunto_d9_device_t { suunto_common2_device_t base; @@ -79,6 +80,15 @@ static const suunto_common2_layout_t suunto_d9tx_layout = { 0xEBF0 /* rb_profile_end */ }; +static const suunto_common2_layout_t suunto_dx_layout = { + 0x10000, /* memsize */ + 0x0017, /* fingerprint */ + 0x0024, /* serial */ + 0x019A, /* rb_profile_begin */ + 0xEBF0 /* rb_profile_end */ +}; + + static int device_is_suunto_d9 (dc_device_t *abstract) { @@ -100,7 +110,7 @@ suunto_d9_device_autodetect (suunto_d9_device_t *device, unsigned int model) // Use the model number as a hint to speedup the detection. unsigned int hint = 0; - if (model == D4i || model == D6i || model == D9tx) + if (model == D4i || model == D6i || model == D9tx || model == DX) hint = 1; for (unsigned int i = 0; i < C_ARRAY_SIZE(baudrates); ++i) { @@ -195,6 +205,8 @@ suunto_d9_device_open (dc_device_t **out, dc_context_t *context, const char *nam model = device->base.version[0]; if (model == D4i || model == D6i || model == D9tx) device->base.layout = &suunto_d9tx_layout; + else if (model == DX) + device->base.layout = &suunto_dx_layout; else device->base.layout = &suunto_d9_layout; diff --git a/src/suunto_d9_parser.c b/src/suunto_d9_parser.c index 24de752..d9d1ed2 100644 --- a/src/suunto_d9_parser.c +++ b/src/suunto_d9_parser.c @@ -41,6 +41,7 @@ #define D4i 0x19 #define D6i 0x1A #define D9tx 0x1B +#define DX 0x1C #define AIR 0 #define NITROX 1 @@ -146,7 +147,7 @@ suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime) suunto_d9_parser_t *parser = (suunto_d9_parser_t*) abstract; unsigned int offset = 0x11; - if (parser->model == HELO2) + if (parser->model == HELO2 || parser->model == DX) offset = 0x17; else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx) offset = 0x13; @@ -157,7 +158,8 @@ suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime) const unsigned char *p = abstract->data + offset; if (datetime) { - if (parser->model == D4i || parser->model == D6i || parser->model == D9tx) { + if (parser->model == D4i || parser->model == D6i || + parser->model == D9tx || parser->model == DX) { datetime->year = p[0] + (p[1] << 8); datetime->month = p[2]; datetime->day = p[3]; @@ -203,6 +205,9 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne } else if (parser->model == D9tx) { gasmix_offset = 0x87; gasmix_count = 8; + } else if (parser->model == DX) { + gasmix_offset = 0xC1; + gasmix_count = 11; } // Offset to the configuration data. @@ -210,7 +215,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne if (parser->model == D4) { config += 1; } else if (parser->model == HELO2 || parser->model == D4i || - parser->model == D6i || parser->model == D9tx) { + parser->model == D6i || parser->model == D9tx || + parser->model == DX) { config = gasmix_offset + gasmix_count * 6; } if (config + 1 > size) @@ -222,6 +228,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne gasmodel_offset = 0x1F; else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx) gasmodel_offset = 0x1D; + else if (parser->model == DX) + gasmodel_offset = 0x21; unsigned int gasmodel = data[gasmodel_offset]; dc_gasmix_t *gasmix = (dc_gasmix_t *) value; @@ -231,7 +239,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne case DC_FIELD_DIVETIME: if (parser->model == D4) *((unsigned int *) value) = array_uint16_le (data + 0x0B); - else if (parser->model == D4i || parser->model == D6i || parser->model == D9tx) + else if (parser->model == D4i || parser->model == D6i || + parser->model == D9tx || parser->model == DX) *((unsigned int *) value) = array_uint16_le (data + 0x0D); else if (parser->model == HELO2) *((unsigned int *) value) = array_uint16_le (data + 0x0D) * 60; @@ -253,7 +262,8 @@ suunto_d9_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigne gasmix->helium = 0.0; gasmix->oxygen = 0.21; } else if (parser->model == HELO2 || parser->model == D4i || - parser->model == D6i || parser->model == D9tx) { + parser->model == D6i || parser->model == D9tx || + parser->model == DX) { gasmix->helium = data[gasmix_offset + 6 * flags + 2] / 100.0; gasmix->oxygen = data[gasmix_offset + 6 * flags + 1] / 100.0; } else { @@ -299,6 +309,9 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca } else if (parser->model == D9tx) { gasmix_offset = 0x87; gasmix_count = 8; + } else if (parser->model == DX) { + gasmix_offset = 0xC1; + gasmix_count = 11; } // Offset to the configuration data. @@ -306,7 +319,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca if (parser->model == D4) { config += 1; } else if (parser->model == HELO2 || parser->model == D4i || - parser->model == D6i || parser->model == D9tx) { + parser->model == D6i || parser->model == D9tx || + parser->model == DX) { config = gasmix_offset + gasmix_count * 6; } if (config + 1 > size) @@ -357,6 +371,8 @@ suunto_d9_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t ca if (parser->model == HELO2 || parser->model == D4i || parser->model == D6i || parser->model == D9tx) interval_sample_offset = 0x1E; + else if (parser->model == DX) + interval_sample_offset = 0x22; unsigned int interval_sample = data[interval_sample_offset]; if (interval_sample == 0) return DC_STATUS_DATAFORMAT;