Add support for the Mares Darwin.

The Darwin and Darwin Air share a very similar layout, but with a few
differences here and there. Unfortunately, there seems to be no way to
autodetect the exact model during the download. Therefore, an extra
model parameter is added to select the appropriate model manually.
This commit is contained in:
Jef Driesen 2011-12-31 06:44:24 +01:00
parent f062623323
commit ca56b5932a
5 changed files with 51 additions and 16 deletions

View File

@ -32,7 +32,7 @@ test_dump_memory (const char* name, const char* filename)
device_t *device = NULL;
message ("mares_darwinair_device_open\n");
device_status_t rc = mares_darwinair_device_open (&device, name);
device_status_t rc = mares_darwinair_device_open (&device, name, 0);
if (rc != DEVICE_STATUS_SUCCESS) {
WARNING ("Error opening serial port.");
return rc;

View File

@ -336,7 +336,7 @@ doparse (FILE *fp, device_data_t *devdata, const unsigned char data[], unsigned
rc = mares_nemo_parser_create (&parser, devdata->devinfo.model);
break;
case DEVICE_TYPE_MARES_DARWINAIR:
rc = mares_darwinair_parser_create (&parser);
rc = mares_darwinair_parser_create (&parser, devdata->devinfo.model);
break;
case DEVICE_TYPE_MARES_ICONHD:
rc = mares_iconhd_parser_create (&parser, devdata->devinfo.model);
@ -635,7 +635,7 @@ dowork (device_type_t backend, const char *devname, const char *rawfile, const c
rc = mares_puck_device_open (&device, devname);
break;
case DEVICE_TYPE_MARES_DARWINAIR:
rc = mares_darwinair_device_open (&device, devname);
rc = mares_darwinair_device_open (&device, devname, 0);
break;
case DEVICE_TYPE_MARES_ICONHD:
rc = mares_iconhd_device_open (&device, devname);

View File

@ -30,6 +30,9 @@
#include "utils.h"
#include "array.h"
#define DARWIN 0
#define DARWINAIR 1
typedef struct mares_darwinair_layout_t {
// Memory size.
unsigned int memsize;
@ -47,6 +50,7 @@ typedef struct mares_darwinair_layout_t {
typedef struct mares_darwinair_device_t {
mares_common_device_t base;
const mares_darwinair_layout_t *layout;
unsigned int model;
unsigned char fingerprint[6];
} mares_darwinair_device_t;
@ -66,6 +70,16 @@ static const device_backend_t mares_darwinair_device_backend = {
mares_darwinair_device_close /* close */
};
static const mares_darwinair_layout_t mares_darwin_layout = {
0x4000, /* memsize */
0x0100, /* rb_logbook_offset */
52, /* rb_logbook_size */
50, /* rb_logbook_count */
0x0B30, /* rb_profile_begin */
0x4000, /* rb_profile_end */
2 /* samplesize */
};
static const mares_darwinair_layout_t mares_darwinair_layout = {
0x4000, /* memsize */
0x0100, /* rb_logbook_offset */
@ -86,7 +100,7 @@ device_is_mares_darwinair (device_t *abstract)
}
device_status_t
mares_darwinair_device_open (device_t **out, const char* name)
mares_darwinair_device_open (device_t **out, const char* name, unsigned int model)
{
if (out == NULL)
return DEVICE_STATUS_ERROR;
@ -103,7 +117,11 @@ mares_darwinair_device_open (device_t **out, const char* name)
// Set the default values.
memset (device->fingerprint, 0, sizeof (device->fingerprint));
device->layout = &mares_darwinair_layout;
device->model = model;
if (model == DARWINAIR)
device->layout = &mares_darwinair_layout;
else
device->layout = &mares_darwin_layout;
// Open the device.
int rc = serial_open (&device->base.port, name);
@ -224,7 +242,7 @@ mares_darwinair_device_foreach (device_t *abstract, dive_callback_t callback, vo
// Emit a device info event.
unsigned char *data = dc_buffer_get_data (buffer);
device_devinfo_t devinfo;
devinfo.model = 0;
devinfo.model = device->model;
devinfo.firmware = 0;
devinfo.serial = array_uint16_be (data + 8);
device_event_emit (abstract, DEVICE_EVENT_DEVINFO, &devinfo);

View File

@ -30,13 +30,13 @@ extern "C" {
#endif /* __cplusplus */
device_status_t
mares_darwinair_device_open (device_t **device, const char *name);
mares_darwinair_device_open (device_t **device, const char *name, unsigned int model);
device_status_t
mares_darwinair_extract_dives (device_t *device, const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);
parser_status_t
mares_darwinair_parser_create (parser_t **parser);
mares_darwinair_parser_create (parser_t **parser, unsigned int model);
#ifdef __cplusplus
}

View File

@ -28,12 +28,15 @@
#include "utils.h"
#include "array.h"
#define HEADERSIZE 60
#define DARWIN 0
#define DARWINAIR 1
typedef struct mares_darwinair_parser_t mares_darwinair_parser_t;
struct mares_darwinair_parser_t {
parser_t base;
unsigned int headersize;
unsigned int samplesize;
};
static parser_status_t mares_darwinair_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size);
@ -63,7 +66,7 @@ parser_is_mares_darwinair (parser_t *abstract)
parser_status_t
mares_darwinair_parser_create (parser_t **out)
mares_darwinair_parser_create (parser_t **out, unsigned int model)
{
if (out == NULL)
return PARSER_STATUS_ERROR;
@ -78,6 +81,14 @@ mares_darwinair_parser_create (parser_t **out)
// Initialize the base class.
parser_init (&parser->base, &mares_darwinair_parser_backend);
if (model == DARWINAIR) {
parser->headersize = 60;
parser->samplesize = 3;
} else {
parser->headersize = 52;
parser->samplesize = 2;
}
*out = (parser_t *) parser;
return PARSER_STATUS_SUCCESS;
@ -107,7 +118,9 @@ mares_darwinair_parser_set_data (parser_t *abstract, const unsigned char *data,
static parser_status_t
mares_darwinair_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime)
{
if (abstract->size < HEADERSIZE)
mares_darwinair_parser_t *parser = (mares_darwinair_parser_t *) abstract;
if (abstract->size < parser->headersize)
return PARSER_STATUS_ERROR;
const unsigned char *p = abstract->data;
@ -128,7 +141,9 @@ mares_darwinair_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime
static parser_status_t
mares_darwinair_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value)
{
if (abstract->size < HEADERSIZE)
mares_darwinair_parser_t *parser = (mares_darwinair_parser_t *) abstract;
if (abstract->size < parser->headersize)
return PARSER_STATUS_ERROR;
const unsigned char *p = abstract->data;
@ -163,13 +178,15 @@ mares_darwinair_parser_get_field (parser_t *abstract, parser_field_type_t type,
static parser_status_t
mares_darwinair_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata)
{
if (abstract->size < HEADERSIZE)
mares_darwinair_parser_t *parser = (mares_darwinair_parser_t *) abstract;
if (abstract->size < parser->headersize)
return PARSER_STATUS_ERROR;
unsigned int time = 0;
unsigned int offset = HEADERSIZE;
while (offset + 3 <= abstract->size) {
unsigned int offset = parser->headersize;
while (offset + parser->samplesize <= abstract->size) {
parser_sample_value_t sample = {0};
// Surface Time (seconds).
@ -182,7 +199,7 @@ mares_darwinair_parser_samples_foreach (parser_t *abstract, sample_callback_t ca
sample.depth = depth / 10.0;
if (callback) callback (SAMPLE_TYPE_DEPTH, sample, userdata);
offset += 3;
offset += parser->samplesize;
}
return PARSER_STATUS_SUCCESS;