Merge upstream changes from Jef Driesen:

 - New dive computer support:
    - Ratio iX3M 2
    - Sherwood Amphos Air 2.0

 - Cleanups and fixes

* https://github.com/libdivecomputer/libdivecomputer:
  Add support for the Ratio iX3M 2 models
  Add support for the Sherwood Amphos Air 2.0
  Replace switch statements with an array lookup
  Add Shearwater Perdix 2 and Petrel 3
  Update the Shearwater hardware IDs
  Fix the clock synchronization
  Remove unused time parameters
  Add support for a new Aqualung i200C variant
This commit is contained in:
Linus Torvalds 2022-07-30 17:18:51 -07:00
commit 09a5801b9f
11 changed files with 54 additions and 49 deletions

View File

@ -272,6 +272,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Sherwood", "Wisdom 4", DC_FAMILY_OCEANIC_ATOM2, 0x4655, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_oceanic},
{"Oceanic", "Pro Plus 4", DC_FAMILY_OCEANIC_ATOM2, 0x4656, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_oceanic},
{"Sherwood", "Amphos 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4657, DC_TRANSPORT_SERIAL, NULL},
{"Sherwood", "Amphos Air 2.0", DC_FAMILY_OCEANIC_ATOM2, 0x4658, DC_TRANSPORT_SERIAL, NULL},
{"Sherwood", "Beacon", DC_FAMILY_OCEANIC_ATOM2, 0x4742, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_oceanic},
{"Aqualung", "i470TC", DC_FAMILY_OCEANIC_ATOM2, 0x4743, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_oceanic},
{"Aqualung", "i200Cv2", DC_FAMILY_OCEANIC_ATOM2, 0x4749, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_oceanic},
@ -412,6 +413,11 @@ static const dc_descriptor_t g_descriptors[] = {
{"Ratio", "iX3M 2021 Pro Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x73, DC_TRANSPORT_SERIAL, NULL},
{"Ratio", "iX3M 2021 Pro Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x74, DC_TRANSPORT_SERIAL, NULL},
{"Ratio", "iX3M 2021 Pro Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x75, DC_TRANSPORT_SERIAL, NULL},
{"Ratio", "iX3M 2 Gauge", DC_FAMILY_DIVESYSTEM_IDIVE, 0x100, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
{"Ratio", "iX3M 2 Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x101, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
{"Ratio", "iX3M 2 Pro", DC_FAMILY_DIVESYSTEM_IDIVE, 0x102, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
{"Ratio", "iX3M 2 Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x103, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
{"Ratio", "iX3M 2 Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x104, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, dc_filter_divesystem},
{"Seac", "Jack", DC_FAMILY_DIVESYSTEM_IDIVE, 0x1000, DC_TRANSPORT_SERIAL, NULL},
{"Seac", "Guru", DC_FAMILY_DIVESYSTEM_IDIVE, 0x1002, DC_TRANSPORT_SERIAL, NULL},
/* Cochran Commander */

View File

@ -460,6 +460,7 @@ static const oceanic_common_version_t versions[] = {
{"VOYAGE2G \0\0 512K", 0, &tusa_zenair_layout},
{"TUSTALIS \0\0 512K", 0, &tusa_zenair_layout},
{"AMPHOS20 \0\0 512K", 0, &tusa_zenair_layout},
{"AMPAIR20 \0\0 512K", 0, &tusa_zenair_layout},
{"REACPRO2 \0\0 512K", 0, &oceanic_reactpro_layout},
@ -477,6 +478,7 @@ static const oceanic_common_version_t versions[] = {
{"AQUA550C \0\0 1024", 0, &oceanic_oc1_layout},
{"WISDOM04 \0\0 1024", 0, &oceanic_oc1_layout},
{"AQUA470C \0\0 1024", 0, &oceanic_oc1_layout},
{"AQUA200C \0\0 1024", 0, &oceanic_oc1_layout},
{"OCEANOCI \0\0 1024", 0, &oceanic_oci_layout},

View File

@ -100,6 +100,7 @@
#define WISDOM4 0x4655
#define PROPLUS4 0x4656
#define AMPHOS2 0x4657
#define AMPHOSAIR2 0x4658
#define BEACON 0x4742
#define I470TC 0x4743
#define I200CV2 0x4749
@ -175,7 +176,7 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
model == A300 || model == MANTA ||
model == INSIGHT2 || model == ZEN ||
model == I300 || model == I550 ||
model == I200 || model == I200C || model == I200CV2 ||
model == I200 || model == I200C ||
model == I300C || model == GEO40 ||
model == VEO40 || model == I470TC) {
parser->headersize -= PAGESIZE;
@ -200,7 +201,8 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
parser->headersize = 5 * PAGESIZE;
} else if (model == PROPLUSX) {
parser->headersize = 3 * PAGESIZE;
} else if (model == I550C || model == WISDOM4) {
} else if (model == I550C || model == WISDOM4 ||
model == I200CV2) {
parser->headersize = 5 * PAGESIZE / 2;
}
@ -282,6 +284,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
case XPAIR:
case WISDOM4:
case I470TC:
case I200CV2:
datetime->year = ((p[5] & 0xE0) >> 5) + ((p[7] & 0xE0) >> 2) + 2000;
datetime->month = (p[3] & 0x0F);
datetime->day = ((p[0] & 0x80) >> 3) + ((p[3] & 0xF0) >> 4);
@ -302,7 +305,6 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
case I300:
case I200:
case I200C:
case I200CV2:
case I100:
case I300C:
case GEO40:
@ -320,6 +322,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
case VOYAGER2G:
case TALIS:
case AMPHOS2:
case AMPHOSAIR2:
datetime->year = (p[3] & 0x1F) + 2000;
datetime->month = (p[7] & 0xF0) >> 4;
datetime->day = ((p[3] & 0x80) >> 3) + ((p[5] & 0xF0) >> 4);
@ -694,44 +697,21 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
unsigned int interval = 1;
unsigned int samplerate = 1;
if (parser->mode != FREEDIVE) {
unsigned int idx = 0x17;
unsigned int offset = 0x17;
if (parser->model == A300CS || parser->model == VTX ||
parser->model == I450T || parser->model == I750TC ||
parser->model == PROPLUSX || parser->model == I770R ||
parser->model == SAGE || parser->model == BEACON)
idx = 0x1f;
switch (data[idx] & 0x03) {
case 0:
interval = 2;
break;
case 1:
interval = 15;
break;
case 2:
interval = 30;
break;
case 3:
interval = 60;
break;
}
offset = 0x1f;
const unsigned int intervals[] = {2, 15, 30, 60};
unsigned int idx = data[offset] & 0x03;
interval = intervals[idx];
} else if (parser->model == F11A || parser->model == F11B) {
unsigned int idx = 0x29;
switch (data[idx] & 0x03) {
case 0:
interval = 1;
samplerate = 4;
break;
case 1:
interval = 1;
samplerate = 2;
break;
case 2:
interval = 1;
break;
case 3:
interval = 2;
break;
}
const unsigned int intervals[] = {1, 1, 1, 2};
const unsigned int samplerates[] = {4, 2, 1, 1};
unsigned int idx = data[0x29] & 0x03;
interval = intervals[idx];
samplerate = samplerates[idx];
if (samplerate > 1) {
// Some models supports multiple samples per second.
// Since our smallest unit of time is one second, we can't
@ -954,7 +934,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
sign = (~data[offset + 5] & 0x04) >> 2;
else if (parser->model == VOYAGER2G || parser->model == AMPHOS ||
parser->model == AMPHOSAIR || parser->model == ZENAIR ||
parser->model == AMPHOS2)
parser->model == AMPHOS2 || parser->model == AMPHOSAIR2)
sign = (data[offset + 5] & 0x04) >> 2;
else if (parser->model == ATOM2 || parser->model == PROPLUS21 ||
parser->model == EPICA || parser->model == EPICB ||
@ -985,7 +965,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
parser->model == AMPHOSAIR || parser->model == I550 ||
parser->model == VISION || parser->model == XPAIR ||
parser->model == I550C || parser->model == PROPLUS4 ||
parser->model == WISDOM4)
parser->model == WISDOM4 || parser->model == AMPHOSAIR2)
pressure = (((data[offset + 0] & 0x03) << 8) + data[offset + 1]) * 5;
else if (parser->model == TX1 || parser->model == A300CS ||
parser->model == VTX || parser->model == I750TC ||

View File

@ -108,7 +108,7 @@ dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, dc_family_t fa
rc = uwatec_memomouse_parser_create (&parser, context, devtime, systime);
break;
case DC_FAMILY_UWATEC_SMART:
rc = uwatec_smart_parser_create (&parser, context, model, devtime, systime);
rc = uwatec_smart_parser_create (&parser, context, model);
break;
case DC_FAMILY_REEFNET_SENSUS:
rc = reefnet_sensus_parser_create (&parser, context, devtime, systime);

View File

@ -133,7 +133,12 @@ reefnet_sensus_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *dateti
unsigned int timestamp = array_uint32_le (abstract->data + 2);
dc_ticks_t ticks = parser->systime - (parser->devtime - timestamp);
dc_ticks_t ticks = parser->systime;
if (timestamp < parser->devtime) {
ticks -= parser->devtime - timestamp;
} else {
ticks += timestamp - parser->devtime;
}
if (!dc_datetime_localtime (datetime, ticks))
return DC_STATUS_DATAFORMAT;

View File

@ -132,7 +132,12 @@ reefnet_sensuspro_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *dat
unsigned int timestamp = array_uint32_le (abstract->data + 6);
dc_ticks_t ticks = parser->systime - (parser->devtime - timestamp);
dc_ticks_t ticks = parser->systime;
if (timestamp < parser->devtime) {
ticks -= parser->devtime - timestamp;
} else {
ticks += timestamp - parser->devtime;
}
if (!dc_datetime_localtime (datetime, ticks))
return DC_STATUS_DATAFORMAT;

View File

@ -132,7 +132,12 @@ reefnet_sensusultra_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *d
unsigned int timestamp = array_uint32_le (abstract->data + 4);
dc_ticks_t ticks = parser->systime - (parser->devtime - timestamp);
dc_ticks_t ticks = parser->systime;
if (timestamp < parser->devtime) {
ticks -= parser->devtime - timestamp;
} else {
ticks += timestamp - parser->devtime;
}
if (!dc_datetime_localtime (datetime, ticks))
return DC_STATUS_DATAFORMAT;

View File

@ -37,6 +37,7 @@ extern "C" {
#define PREDATOR 2
#define PETREL 3
#define PETREL2 PETREL
#define NERD 4
#define PERDIX 5
#define PERDIXAI 6

View File

@ -96,7 +96,12 @@ uwatec_memomouse_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *date
unsigned int timestamp = array_uint32_le (abstract->data + 11);
dc_ticks_t ticks = parser->systime - (parser->devtime - timestamp) / 2;
dc_ticks_t ticks = parser->systime;
if (timestamp < parser->devtime) {
ticks -= (parser->devtime - timestamp) / 2;
} else {
ticks += (timestamp - parser->devtime) / 2;
}
if (!dc_datetime_localtime (datetime, ticks))
return DC_STATUS_DATAFORMAT;

View File

@ -35,7 +35,7 @@ dc_status_t
uwatec_smart_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream);
dc_status_t
uwatec_smart_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model, unsigned int devtime, dc_ticks_t systime);
uwatec_smart_parser_create (dc_parser_t **parser, dc_context_t *context, unsigned int model);
#ifdef __cplusplus
}

View File

@ -139,8 +139,6 @@ typedef struct uwatec_smart_parser_t uwatec_smart_parser_t;
struct uwatec_smart_parser_t {
dc_parser_t base;
unsigned int model;
unsigned int devtime;
dc_ticks_t systime;
const uwatec_smart_sample_info_t *samples;
const uwatec_smart_header_info_t *header;
unsigned int headersize;
@ -570,7 +568,7 @@ uwatec_smart_parser_cache (uwatec_smart_parser_t *parser)
dc_status_t
uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int devtime, dc_ticks_t systime)
uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model)
{
dc_status_t status = DC_STATUS_SUCCESS;
uwatec_smart_parser_t *parser = NULL;
@ -587,8 +585,6 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
// Set the default values.
parser->model = model;
parser->devtime = devtime;
parser->systime = systime;
parser->trimix = 0;
for (unsigned int i = 0; i < NEVENTS; ++i) {
parser->events[i] = NULL;