Merge branch 'ix3m'
This commit is contained in:
commit
e2d623fc65
@ -290,8 +290,15 @@ static const dc_descriptor_t g_descriptors[] = {
|
||||
{"DiveSystem", "iDive Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x0B},
|
||||
{"DiveSystem", "iX3M Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x22},
|
||||
{"DiveSystem", "iX3M Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x23},
|
||||
{"DiveSystem", "iX3M Tec", DC_FAMILY_DIVESYSTEM_IDIVE, 0x24},
|
||||
{"DiveSystem", "iX3M Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x24},
|
||||
{"DiveSystem", "iX3M Reb", DC_FAMILY_DIVESYSTEM_IDIVE, 0x25},
|
||||
{"DiveSystem", "iX3M Pro Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x32},
|
||||
{"DiveSystem", "iX3M Pro Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x34},
|
||||
{"DiveSystem", "iX3M Pro Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x35},
|
||||
{"DiveSystem", "iDive2 Free", DC_FAMILY_DIVESYSTEM_IDIVE, 0x40},
|
||||
{"DiveSystem", "iDive2 Easy", DC_FAMILY_DIVESYSTEM_IDIVE, 0x42},
|
||||
{"DiveSystem", "iDive2 Deep", DC_FAMILY_DIVESYSTEM_IDIVE, 0x44},
|
||||
{"DiveSystem", "iDive2 Tech+", DC_FAMILY_DIVESYSTEM_IDIVE, 0x45},
|
||||
{"Cochran", "Commander", DC_FAMILY_COCHRAN_COMMANDER, 0},
|
||||
{"Cochran", "EMC-14", DC_FAMILY_COCHRAN_COMMANDER, 1},
|
||||
{"Cochran", "EMC-16", DC_FAMILY_COCHRAN_COMMANDER, 2},
|
||||
|
||||
@ -57,6 +57,7 @@ typedef struct divesystem_idive_commands_t {
|
||||
divesystem_idive_command_t range;
|
||||
divesystem_idive_command_t header;
|
||||
divesystem_idive_command_t sample;
|
||||
unsigned int nsamples;
|
||||
} divesystem_idive_commands_t;
|
||||
|
||||
typedef struct divesystem_idive_device_t {
|
||||
@ -86,6 +87,7 @@ static const divesystem_idive_commands_t idive = {
|
||||
{0x98, 0x04},
|
||||
{0xA0, 0x32},
|
||||
{0xA8, 0x2A},
|
||||
1,
|
||||
};
|
||||
|
||||
static const divesystem_idive_commands_t ix3m = {
|
||||
@ -93,6 +95,15 @@ static const divesystem_idive_commands_t ix3m = {
|
||||
{0x78, 0x04},
|
||||
{0x79, 0x36},
|
||||
{0x7A, 0x36},
|
||||
1,
|
||||
};
|
||||
|
||||
static const divesystem_idive_commands_t ix3m_apos4 = {
|
||||
{0x11, 0x1A},
|
||||
{0x78, 0x04},
|
||||
{0x79, 0x36},
|
||||
{0x7A, 0x40},
|
||||
3,
|
||||
};
|
||||
|
||||
dc_status_t
|
||||
@ -356,7 +367,7 @@ divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb
|
||||
unsigned char packet[MAXPACKET - 2];
|
||||
|
||||
const divesystem_idive_commands_t *commands = &idive;
|
||||
if (device->model >= IX3M_EASY && device->model <= IX3M_REB) {
|
||||
if (device->model >= IX3M_EASY) {
|
||||
commands = &ix3m;
|
||||
}
|
||||
|
||||
@ -372,7 +383,7 @@ divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb
|
||||
// Emit a device info event.
|
||||
dc_event_devinfo_t devinfo;
|
||||
devinfo.model = array_uint16_le (packet);
|
||||
devinfo.firmware = 0;
|
||||
devinfo.firmware = array_uint32_le (packet + 2);
|
||||
devinfo.serial = array_uint32_le (packet + 6);
|
||||
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
|
||||
|
||||
@ -382,6 +393,14 @@ divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb
|
||||
vendor.size = commands->id.size;
|
||||
device_event_emit (abstract, DC_EVENT_VENDOR, &vendor);
|
||||
|
||||
if (device->model >= IX3M_EASY) {
|
||||
// Detect the APOS4 firmware.
|
||||
unsigned int apos4 = (devinfo.firmware / 10000000) >= 4;
|
||||
if (apos4) {
|
||||
commands = &ix3m_apos4;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char cmd_range[] = {commands->range.cmd, 0x8D};
|
||||
rc = divesystem_idive_transfer (device, cmd_range, sizeof(cmd_range), packet, commands->range.size);
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
@ -429,20 +448,28 @@ divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb
|
||||
dc_buffer_reserve(buffer, commands->header.size + commands->sample.size * nsamples);
|
||||
dc_buffer_append(buffer, packet, commands->header.size);
|
||||
|
||||
for (unsigned int j = 0; j < nsamples; ++j) {
|
||||
for (unsigned int j = 0; j < nsamples; j += commands->nsamples) {
|
||||
unsigned int idx = j + 1;
|
||||
unsigned char cmd_sample[] = {commands->sample.cmd,
|
||||
(idx ) & 0xFF,
|
||||
(idx >> 8) & 0xFF};
|
||||
rc = divesystem_idive_transfer (device, cmd_sample, sizeof(cmd_sample), packet, commands->sample.size);
|
||||
rc = divesystem_idive_transfer (device, cmd_sample, sizeof(cmd_sample), packet, commands->sample.size * commands->nsamples);
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
return rc;
|
||||
|
||||
// If the number of samples is not an exact multiple of the
|
||||
// number of samples per packet, then the last packet
|
||||
// appears to contain garbage data. Ignore those samples.
|
||||
unsigned int n = commands->nsamples;
|
||||
if (j + n > nsamples) {
|
||||
n = nsamples - j;
|
||||
}
|
||||
|
||||
// Update and emit a progress event.
|
||||
progress.current = i * NSTEPS + STEP(j + 2, nsamples + 1);
|
||||
progress.current = i * NSTEPS + STEP(j + n + 1, nsamples + 1);
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
|
||||
dc_buffer_append(buffer, packet, commands->sample.size);
|
||||
dc_buffer_append(buffer, packet, commands->sample.size * n);
|
||||
}
|
||||
|
||||
unsigned char *data = dc_buffer_get_data(buffer);
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
#define SZ_SAMPLE_IDIVE 0x2A
|
||||
#define SZ_HEADER_IX3M 0x36
|
||||
#define SZ_SAMPLE_IX3M 0x36
|
||||
#define SZ_SAMPLE_IX3M_APOS4 0x40
|
||||
|
||||
#define NGASMIXES 8
|
||||
|
||||
@ -53,8 +54,8 @@ typedef struct divesystem_idive_parser_t divesystem_idive_parser_t;
|
||||
|
||||
struct divesystem_idive_parser_t {
|
||||
dc_parser_t base;
|
||||
unsigned int model;
|
||||
unsigned int headersize;
|
||||
unsigned int samplesize;
|
||||
// Cached fields.
|
||||
unsigned int cached;
|
||||
unsigned int divemode;
|
||||
@ -97,12 +98,11 @@ divesystem_idive_parser_create (dc_parser_t **out, dc_context_t *context, unsign
|
||||
}
|
||||
|
||||
// Set the default values.
|
||||
if (model >= IX3M_EASY && model <= IX3M_REB) {
|
||||
parser->model = model;
|
||||
if (model >= IX3M_EASY) {
|
||||
parser->headersize = SZ_HEADER_IX3M;
|
||||
parser->samplesize = SZ_SAMPLE_IX3M;
|
||||
} else {
|
||||
parser->headersize = SZ_HEADER_IDIVE;
|
||||
parser->samplesize = SZ_SAMPLE_IDIVE;
|
||||
}
|
||||
parser->cached = 0;
|
||||
parser->divemode = INVALID;
|
||||
@ -241,8 +241,27 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
|
||||
unsigned int mode_previous = INVALID;
|
||||
unsigned int divemode = INVALID;
|
||||
|
||||
unsigned int nsamples = array_uint16_le (data + 1);
|
||||
unsigned int samplesize = SZ_SAMPLE_IDIVE;
|
||||
if (parser->model >= IX3M_EASY) {
|
||||
// Detect the APOS4 firmware.
|
||||
unsigned int firmware = array_uint32_le(data + 0x2A);
|
||||
unsigned int apos4 = (firmware / 10000000) >= 4;
|
||||
if (apos4) {
|
||||
// Dive downloaded and recorded with the APOS4 firmware.
|
||||
samplesize = SZ_SAMPLE_IX3M_APOS4;
|
||||
} else if (size == parser->headersize + nsamples * SZ_SAMPLE_IX3M_APOS4) {
|
||||
// Dive downloaded with the APOS4 firmware, but recorded
|
||||
// with an older firmware.
|
||||
samplesize = SZ_SAMPLE_IX3M_APOS4;
|
||||
} else {
|
||||
// Dive downloaded and recorded with an older firmware.
|
||||
samplesize = SZ_SAMPLE_IX3M;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int offset = parser->headersize;
|
||||
while (offset + parser->samplesize <= size) {
|
||||
while (offset + samplesize <= size) {
|
||||
dc_sample_value_t sample = {0};
|
||||
|
||||
// Time (seconds).
|
||||
@ -328,7 +347,7 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba
|
||||
sample.cns = cns / 100.0;
|
||||
if (callback) callback (DC_SAMPLE_CNS, sample, userdata);
|
||||
|
||||
offset += parser->samplesize;
|
||||
offset += samplesize;
|
||||
}
|
||||
|
||||
// Cache the data for later use.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user