[PATCH 005/007] Cochran: Using structs now to switch layouts for different DCs.
John Van Ostrand
john at vanostrand.com
Fri Jan 8 11:23:47 PST 2016
I removed the conf member from the data struct, that's not being
carried around any more. Each function that needs layout information
will be call cochran_commander_get_layout to obtain the layout to use
in parsing the data.
---
src/cochran_commander.c | 320 ++++++++++++++++++++++-------------------
src/cochran_commander.h | 54 +++++--
src/cochran_commander_parser.c | 19 +--
3 files changed, 224 insertions(+), 169 deletions(-)
diff --git a/src/cochran_commander.c b/src/cochran_commander.c
index 2287541..036ca6c 100644
--- a/src/cochran_commander.c
+++ b/src/cochran_commander.c
@@ -38,6 +38,105 @@
rc == -1 ? DC_STATUS_IO : DC_STATUS_TIMEOUT \
)
+
+/*
+* Hardware and data layout information for various Cochran models.
+*
+* EMC models are identical except for the size of logbook and profile
+* memory.
+*/
+static cochran_layout_t cochran_layout_cmdr = {
+ COCHRAN_MODEL_COMMANDER_AIR_NITROX, /* model */
+ ENDIAN_BE, /* endian */
+ DATE_MSDHYM, /* date_format */
+ ADDRESS_24_BIT, /* address_size */
+ 115200, /* high_baud_rate */
+
+ 0x00000000, /* rb_logbook_begin */
+ 0x00020000, /* rb_logbook_end */
+ 256, /* rb_log_size */
+ 0x00020000, /* rb_profile_begin */
+ 0x00100000, /* rb_profile_end */
+
+ 0x006, /* pt_log_profile_begin */
+ 0x01e, /* pt_log_profile_pre */
+ 0x046, /* pt_log_dive_number */
+ 0x080, /* pt_log_profile_end */
+
+ 0x046, /* pt_conf_dive_count */
+ 0x06e, /* pt_conf_last_log */
+ 0x0a7, /* pt_conf_last_interdive */
+};
+
+static cochran_layout_t cochran_layout_emc20 = {
+ COCHRAN_MODEL_EMC_20, /* model */
+ ENDIAN_LE, /* endian */
+ DATE_SMHDMY, /* date_format */
+ ADDRESS_32_BIT, /* address_size */
+ 825600, /* high_baud_rate */
+
+ 0x00000000, /* rb_logbook_begin */
+ 0x00080000, /* rb_logbook_end */
+ 512, /* rb_log_size */
+ 0x00094000, /* rb_profile_begin */
+ 0x01000000, /* rb_profile_end */
+
+ 0x006, /* pt_log_profile_begin */
+ 0x01e, /* pt_log_profile_pre */
+ 0x056, /* pt_log_dive_number */
+ 0x100, /* pt_log_profile_end */
+
+ 0x0d2, /* pt_conf_dive_count */
+ 0x142, /* pt_conf_last_log */
+ 0x13e, /* pt_conf_last_interdive */
+};
+
+static cochran_layout_t cochran_layout_emc16 = {
+ COCHRAN_MODEL_EMC_16, /* model */
+ ENDIAN_LE, /* endian */
+ DATE_SMHDMY, /* date_format */
+ ADDRESS_32_BIT, /* address_size */
+ 825600, /* high_baud_rate */
+
+ 0x00000000, /* rb_logbook_begin */
+ 0x00080000, /* rb_logbook_end */
+ 512, /* rb_log_size */
+ 0x00094000, /* rb_profile_begin */
+ 0x00800000, /* rb_profile_end */
+
+ 0x006, /* pt_log_profile_begin */
+ 0x01e, /* pt_log_profile_pre */
+ 0x056, /* pt_log_dive_number */
+ 0x100, /* pt_log_profile_end */
+
+ 0x0d2, /* pt_conf_dive_count */
+ 0x142, /* pt_conf_last_log */
+ 0x13e, /* pt_conf_last_interdive */
+};
+
+static cochran_layout_t cochran_layout_emc14 = {
+ COCHRAN_MODEL_EMC_14, /* model */
+ ENDIAN_LE, /* endian */
+ DATE_SMHDMY, /* date_format */
+ ADDRESS_32_BIT, /* address_size */
+ 825600, /* high_baud_rate */
+
+ 0x00000000, /* rb_logbook_begin */
+ 0x00020000, /* rb_logbook_end */
+ 512, /* rb_log_size */
+ 0x00022000, /* rb_profile_begin */
+ 0x00200000, /* rb_profile_end */
+
+ 0x006, /* pt_log_profile_begin */
+ 0x01e, /* pt_log_profile_pre */
+ 0x056, /* pt_log_dive_number */
+ 0x100, /* pt_log_profile_end */
+
+ 0x0d2, /* pt_conf_dive_count */
+ 0x142, /* pt_conf_last_log */
+ 0x13e, /* pt_conf_last_interdive */
+};
+
static const dc_device_vtable_t cochran_commander_device_vtable = {
DC_FAMILY_COCHRAN_COMMANDER,
cochran_commander_device_set_fingerprint, /* set_fingerprint */
@@ -83,7 +182,8 @@ cochran_packet (cochran_device_t *device, dc_event_progress_t *progress,
serial_sleep(device->port, 45);
// Rates are odd, like 825600 for the EMC, 115200 for commander
- rc = serial_configure(device->port, device->data.conf.high_baud, 8,
+ cochran_layout_t *layout = cochran_commander_get_layout(device->model_string);
+ rc = serial_configure(device->port, layout->high_baud_rate, 8,
SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE);
if (rc == -1) {
ERROR (abstract->context, "Failed to set the high baud rate.");
@@ -142,7 +242,7 @@ cochran_commander_serial_setup (cochran_device_t *device, dc_context_t *context)
serial_set_break(device->port, 1);
serial_sleep(device->port, 16);
-
+
serial_set_break(device->port, 0);
// Set the timeout for receiving data (5000 ms).
@@ -185,6 +285,7 @@ cochran_commander_device_open (dc_device_t **out, dc_context_t *context,
const char *name)
{
dc_status_t rc;
+ cochran_layout_t *layout;
if (out == NULL)
return DC_STATUS_INVALIDARGS;
@@ -222,14 +323,18 @@ cochran_commander_device_open (dc_device_t **out, dc_context_t *context,
return rc;
}
+ memcpy(device->model_string, device->data.id + 0x3b, 8);
+ device->model_string[8] = 0;
+ layout = cochran_commander_get_layout(device->model_string);
+
// Check ID
- if ((device->data.conf.model & 0xFF0000) == COCHRAN_MODEL_UNKNOWN) {
+ if ((layout->model & 0xFF0000) == COCHRAN_MODEL_UNKNOWN) {
ERROR (context,
"Unknown Cochran model %02x %02x %02x %02x %02x %02x %02x %02x",
- *(device->data.id + 0x3B), *(device->data.id + 0x3B + 1),
- *(device->data.id + 0x3B + 2), *(device->data.id + 0x3B + 3),
- *(device->data.id + 0x3B + 4), *(device->data.id + 0x3B + 5),
- *(device->data.id + 0x3B + 6), *(device->data.id + 0x3B + 7));
+ device->model_string[0], device->model_string[1],
+ device->model_string[2], device->model_string[3],
+ device->model_string[4], device->model_string[5],
+ device->model_string[6], device->model_string[7]);
serial_close (device->port);
free (device);
return DC_STATUS_UNSUPPORTED;
@@ -293,14 +398,15 @@ cochran_commander_read (dc_device_t *abstract, dc_event_progress_t *progress,
unsigned int address, unsigned char data[], unsigned int size)
{
cochran_device_t *device = (cochran_device_t*) abstract;
+ cochran_layout_t *layout = cochran_commander_get_layout(device->model_string);
// Build the command
unsigned char command[10];
unsigned char command_size;
- switch (device->data.conf.address_length)
+ switch (layout->address_size)
{
- case COCHRAN_ADDRESS_LENGTH_32:
+ case ADDRESS_32_BIT:
// EMC uses 32 bit addressing
command[0] = 0x15;
command[1] = (address ) & 0xff;
@@ -314,7 +420,7 @@ cochran_commander_read (dc_device_t *abstract, dc_event_progress_t *progress,
command[9] = 0x05;
command_size = 10;
break;
- case COCHRAN_ADDRESS_LENGTH_24:
+ case ADDRESS_24_BIT:
// Commander uses 24 byte addressing
command[0] = 0x15;
command[1] = (address ) & 0xff;
@@ -339,89 +445,28 @@ cochran_commander_read (dc_device_t *abstract, dc_event_progress_t *progress,
}
-void
-cochran_commander_get_config (const unsigned char *model,
- cochran_config_t *conf)
+cochran_layout_t *
+cochran_commander_get_layout (const unsigned char *model)
{
// Determine model
if (memcmp(model, "AM2315\xA3\x71", 8) == 0)
{
- conf->model = COCHRAN_MODEL_EMC_20;
- conf->log_size = 512;
- conf->sample_memory_start_address = 0x94000;
- conf->sample_memory_end_address = 0x1000000; // 16MB
- conf->dive_num_ptr = 0x56;
- conf->dive_count_ptr = 0xD2;
- conf->dive_count_endian = COCHRAN_LE_TYPE;
- conf->sample_end_ptr = 256;
- conf->log_pre_dive_ptr = 30;
- conf->log_end_dive_ptr = 256;
- conf->last_interdive_ptr = 233;
- conf->last_entry_ptr = 194;
- conf->date_format = COCHRAN_DATE_FORMAT_SMHDMY;
- conf->address_length = COCHRAN_ADDRESS_LENGTH_32;
- conf->high_baud = 825600;
+ return &cochran_layout_emc20;
}
else if (memcmp(model, "AMA315\xC3\xC5", 8) == 0)
{
- conf->model = COCHRAN_MODEL_EMC_16;
- conf->log_size = 512;
- conf->sample_memory_start_address = 0x94000;
- conf->sample_memory_end_address = 0x800000; // 8MB, a guess
- conf->dive_num_ptr = 0x56;
- conf->dive_count_ptr = 0xD2;
- conf->dive_count_endian = COCHRAN_LE_TYPE;
- conf->sample_end_ptr = 256;
- conf->log_pre_dive_ptr = 30;
- conf->log_end_dive_ptr = 256;
- conf->last_interdive_ptr = 233;
- conf->last_entry_ptr = 194;
- conf->date_format = COCHRAN_DATE_FORMAT_SMHDMY;
- conf->address_length = COCHRAN_ADDRESS_LENGTH_32;
- conf->high_baud = 825600;
+ return &cochran_layout_emc16;
}
else if (memcmp(model, "AM7303\x8b\x43", 8) == 0)
{
- conf->model = COCHRAN_MODEL_EMC_14;
- conf->log_size = 512;
- conf->sample_memory_start_address = 0x22000;
- conf->sample_memory_end_address = 0x200000; // 2MB, a guess
- conf->dive_num_ptr = 0x56;
- conf->dive_count_ptr = 0xD2;
- conf->dive_count_endian = COCHRAN_LE_TYPE;
- conf->sample_end_ptr = 256;
- conf->log_pre_dive_ptr = 30;
- conf->log_end_dive_ptr = 256;
- conf->last_interdive_ptr = 233;
- conf->last_entry_ptr = 194;
- conf->date_format = COCHRAN_DATE_FORMAT_SMHDMY;
- conf->address_length = COCHRAN_ADDRESS_LENGTH_32;
- conf->high_baud = 825600;
+ return &cochran_layout_emc14;
}
else if (memcmp(model, "AM\x11""2212\x02", 8) == 0)
{
- conf->model = COCHRAN_MODEL_COMMANDER_AIR_NITROX;
- conf->log_size = 256;
- conf->sample_memory_start_address = 0x20000;
- conf->sample_memory_end_address = 0x100000;
- conf->dive_num_ptr = 0x46;
- conf->dive_count_ptr = 0x46;
- conf->dive_count_endian = COCHRAN_BE_TYPE;
- conf->sample_end_ptr = 256;
- conf->log_pre_dive_ptr = 30;
- conf->log_end_dive_ptr = 128;
- conf->last_interdive_ptr = 167;
- conf->last_entry_ptr = -1;
- conf->date_format = COCHRAN_DATE_FORMAT_MSDHYM;
- conf->address_length = COCHRAN_ADDRESS_LENGTH_24;
- conf->high_baud = 115200;
- }
- else
- {
- conf->model = 0;
+ return &cochran_layout_cmdr;
}
- return;
+ return NULL;
}
@@ -449,9 +494,6 @@ cochran_read_id (dc_device_t *abstract)
return rc;
}
- cochran_commander_get_config(device->data.id + 0x3B, &device->data.conf);
-
-
return DC_STATUS_SUCCESS;
}
@@ -488,10 +530,11 @@ cochran_read_misc (dc_device_t *abstract, dc_event_progress_t *progress)
cochran_device_t *device = (cochran_device_t *) abstract;
dc_status_t rc;
dc_event_vendor_t vendor;
+ cochran_layout_t *layout = cochran_commander_get_layout(device->model_string);
unsigned char command[7] = { 0x89, 0x05, 0x00, 0x00, 0x00, 0xDC, 0x05 };
- switch (device->data.conf.model & 0xFF0000)
+ switch (layout->model & 0xFF0000)
{
case COCHRAN_MODEL_COMMANDER_FAMILY:
command[2] = 0xCA;
@@ -563,14 +606,14 @@ cochran_find_fingerprint(dc_device_t *abstract)
{
cochran_device_t *device = (cochran_device_t *) abstract;
cochran_data_t *d = (cochran_data_t *) &device->data;
- cochran_config_t *conf = &d->conf;
+ cochran_layout_t *layout = cochran_commander_get_layout(device->model_string);
// Skip to fingerprint to reduce time
d->fp_dive_num = d->dive_count - 1;
while (d->fp_dive_num >= 0 && memcmp(&d->fingerprint,
- d->logbook + d->fp_dive_num * conf->log_size
- + conf->dive_num_ptr,
+ d->logbook + d->fp_dive_num * layout->rb_log_size
+ + layout->pt_log_dive_number,
sizeof(d->fingerprint)))
d->fp_dive_num--;
}
@@ -581,9 +624,9 @@ cochran_get_sample_parms(dc_device_t *abstract)
{
cochran_device_t *device = (cochran_device_t *) abstract;
cochran_data_t *d = (cochran_data_t *) &device->data;
- cochran_config_t *conf = &d->conf;
unsigned int pre_dive_offset = 0, end_dive_offset = 0;
unsigned int low_offset, high_offset;
+ cochran_layout_t *layout = cochran_commander_get_layout(device->model_string);
// Find lowest and highest offsets into sample data
low_offset = 0xFFFFFFFF;
@@ -591,15 +634,15 @@ cochran_get_sample_parms(dc_device_t *abstract)
int i;
for (i = d->fp_dive_num + 1; i < d->dive_count; i++) {
- pre_dive_offset = array_uint32_le (&(d->logbook[i * conf->log_size
- + conf->log_pre_dive_ptr]));
- end_dive_offset = array_uint32_le (&(d->logbook[i * conf->log_size
- + conf->log_end_dive_ptr]));
+ pre_dive_offset = array_uint32_le (&(d->logbook[i * layout->rb_log_size
+ + layout->pt_log_profile_pre]));
+ end_dive_offset = array_uint32_le (&(d->logbook[i * layout->rb_log_size
+ + layout->pt_log_profile_begin]));
// Check for ring buffer wrap-around.
if (pre_dive_offset > end_dive_offset)
break;
-
+
if (pre_dive_offset < low_offset)
low_offset = pre_dive_offset;
if (end_dive_offset > high_offset && end_dive_offset != 0xFFFFFFFF )
@@ -611,8 +654,8 @@ cochran_get_sample_parms(dc_device_t *abstract)
// I'll round to 128K, dives longer than 12 hrs aren't likely
// and memory in sizes not rounded to 128K might be odd.
high_offset = ((pre_dive_offset - 1) & 0xE0000) + 0x20000;
- conf->sample_memory_end_address = high_offset;
- low_offset = conf->sample_memory_start_address;
+ layout->rb_profile_end = high_offset;
+ low_offset = layout->rb_profile_begin;
d->sample_data_offset = low_offset;
d->sample_size = high_offset - low_offset;
} else if (low_offset < 0xFFFFFFFF && high_offset > 0) {
@@ -668,25 +711,19 @@ cochran_commander_device_read_all (dc_device_t *abstract)
{
cochran_device_t *device = (cochran_device_t *) abstract;
cochran_data_t *d = (cochran_data_t *) &device->data;
- cochran_config_t *conf = &d->conf;
dc_event_progress_t progress = {0};
+ cochran_layout_t *layout = cochran_commander_get_layout(device->model_string);
dc_status_t rc;
- int sample_size;
- int max_config, max_misc, max_logbook, max_sample;
+ int max_config, max_logbook, max_sample;
- if ((conf->model & 0xFFFF0000) == COCHRAN_MODEL_COMMANDER_FAMILY)
- sample_size = 2;
- else
- sample_size = 3;
-
- max_config = 512 * 4; // max config page size
- max_misc = 1500; // misc size
- max_logbook = 1024 * conf->log_size; // max logbook size
- max_sample = 1450 * 3600 * sample_size; // max sample size
+ // Calculate max data sizes
+ max_config = 512 * 2;
+ max_logbook =layout->rb_logbook_end - layout->rb_logbook_begin;
+ max_sample = layout->rb_profile_end - layout->rb_profile_begin;
progress.current = 0;
- progress.maximum = max_config + max_misc + max_logbook + max_sample;
+ progress.maximum = max_config + max_logbook + max_sample;
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
// Read config
@@ -694,21 +731,13 @@ cochran_commander_device_read_all (dc_device_t *abstract)
if (rc != DC_STATUS_SUCCESS)
return rc;
- // Update max based on what's read
- progress.maximum -= max_config - progress.current;
- device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
-
- rc = cochran_read_misc(abstract, &progress);
- if (rc != DC_STATUS_SUCCESS)
- return rc;
-
// Determine size of dive list to read. Round up to nearest 16K
- if (conf->dive_count_endian == COCHRAN_LE_TYPE)
- d->dive_count = array_uint16_le (d->config[0] + conf->dive_count_ptr);
- else
- d->dive_count = array_uint16_be (d->config[0] + conf->dive_count_ptr);
-
- d->logbook_size = ((d->dive_count * conf->log_size) & 0xFFFFC000)
+ if (layout->endian == ENDIAN_LE)
+ d->dive_count = array_uint16_le (d->config[0] + layout->pt_conf_dive_count);
+ else
+ d->dive_count = array_uint16_be (d->config[0] + layout->pt_conf_dive_count);
+
+ d->logbook_size = ((d->dive_count * layout->rb_log_size) & 0xFFFFC000)
+ 0x4000;
progress.maximum -= max_logbook - d->logbook_size;
@@ -719,7 +748,7 @@ cochran_commander_device_read_all (dc_device_t *abstract)
return rc;
// Determine sample memory to read
- cochran_find_fingerprint(abstract);
+ cochran_find_fingerprint(abstract);
cochran_get_sample_parms(abstract);
progress.maximum -= max_sample - d->sample_size;
@@ -745,6 +774,7 @@ cochran_commander_device_dump (dc_device_t *abstract, dc_buffer_t *data)
cochran_data_t *d = (cochran_data_t *) &device->data;
dc_event_progress_t progress = {0};
dc_event_vendor_t vendor;
+ cochran_layout_t *layout = cochran_commander_get_layout(device->model_string);
dc_status_t rc;
int size;
@@ -756,7 +786,7 @@ cochran_commander_device_dump (dc_device_t *abstract, dc_buffer_t *data)
}
// Determine size for progress
- size = 512 + 512 + 1500 + d->conf.sample_memory_end_address;
+ size = 512 + 512 + 1500 + layout->rb_profile_end;
progress.current = 0;
progress.maximum = size;
@@ -776,7 +806,7 @@ cochran_commander_device_dump (dc_device_t *abstract, dc_buffer_t *data)
rc = cochran_read_config (abstract, &progress);
if (rc != DC_STATUS_SUCCESS)
return rc;
-
+
rc = cochran_read_misc (abstract, &progress);
if (rc != DC_STATUS_SUCCESS)
return rc;
@@ -784,7 +814,7 @@ cochran_commander_device_dump (dc_device_t *abstract, dc_buffer_t *data)
// Read logbook and sample memory
// Reserve space
- if (!dc_buffer_resize(data, d->conf.sample_memory_end_address)) {
+ if (!dc_buffer_resize(data, layout->rb_profile_end)) {
ERROR(abstract->context, "Insufficient buffer space available.");
return DC_STATUS_NOMEMORY;
}
@@ -795,8 +825,8 @@ cochran_commander_device_dump (dc_device_t *abstract, dc_buffer_t *data)
cochran_commander_serial_setup(device, abstract->context);
// Read the sample data, from 0 to sample end will include logbook
- rc = cochran_commander_read (abstract, &progress, 0,
- dc_buffer_get_data(data), d->conf.sample_memory_end_address);
+ rc = cochran_commander_read (abstract, &progress, 0,
+ dc_buffer_get_data(data), layout->rb_profile_end);
if (rc != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the sample data.");
return rc;
@@ -813,18 +843,17 @@ cochran_commander_device_dump (dc_device_t *abstract, dc_buffer_t *data)
*/
static unsigned int
-cochran_guess_sample_end_address(cochran_data_t *data, unsigned int log_num)
+cochran_guess_sample_end_address(cochran_layout_t *layout, cochran_data_t *data, unsigned int log_num)
{
- cochran_config_t *conf = &data->conf;
- const unsigned char *log = data->logbook + data->conf.log_size * log_num;
+ const unsigned char *log = data->logbook + layout->rb_log_size * log_num;
if (log_num == data->dive_count)
// Return next usable address from config0 page
return array_uint32_le(data->config[0]
- + conf->sample_memory_end_address);
+ + layout->rb_profile_end);
// Next log's start address
- return array_uint32_le(log + conf->log_size + 6);
+ return array_uint32_le(log + layout->rb_log_size + 6);
}
@@ -834,7 +863,7 @@ cochran_commander_device_foreach (dc_device_t *abstract,
{
cochran_device_t *device = (cochran_device_t *) abstract;
cochran_data_t *data = &device->data;
- cochran_config_t *conf = &data->conf;
+ cochran_layout_t *layout = cochran_commander_get_layout(device->model_string);
unsigned int sample_start_address, sample_end_address;
dc_status_t rc;
@@ -850,14 +879,14 @@ cochran_commander_device_foreach (dc_device_t *abstract,
// Loop through each dive
int i;
for (i = data->dive_count - 1; i > data->fp_dive_num; i--) {
- log = data->logbook + i * conf->log_size;
+ log = data->logbook + i * layout->rb_log_size;
sample_start_address = array_uint32_le (log + 6);
- sample_end_address = array_uint32_le (log + conf->log_size / 2);
+ sample_end_address = array_uint32_le (log + layout->rb_log_size / 2);
if (sample_end_address == 0xFFFFFFFF)
// Corrupt dive, guess the end address
- sample_end_address = cochran_guess_sample_end_address(data, i);
+ sample_end_address = cochran_guess_sample_end_address(layout, data, i);
sample = data->sample + sample_start_address - data->sample_data_offset;
@@ -865,28 +894,29 @@ cochran_commander_device_foreach (dc_device_t *abstract,
sample_size = sample_end_address - sample_start_address;
if (sample_size < 0)
// Adjust for ring buffer wrap-around
- sample_size += conf->sample_memory_end_address
- - conf->sample_memory_start_address;
+ sample_size += layout->rb_profile_end
+ - layout->rb_profile_begin;
- fingerprint = log + conf->dive_num_ptr;
+ fingerprint = log + layout->pt_log_dive_number;
// Build dive blob
- dive_size = COCHRAN_MODEL_SIZE + conf->log_size + sample_size;
+ dive_size = COCHRAN_MODEL_SIZE + layout->rb_log_size + sample_size;
dive = malloc(dive_size);
if (dive == NULL)
return DC_STATUS_NOMEMORY;
- memcpy(dive, data->id + 0x3B, 8); // model string
- memcpy(dive + COCHRAN_MODEL_SIZE, log, conf->log_size);
+ memcpy(dive, data->id + 0x3B, 8); // model string
+ memcpy(dive + COCHRAN_MODEL_SIZE, log, layout->rb_log_size);
+
if (sample_start_address <= sample_end_address) {
- memcpy(dive + COCHRAN_MODEL_SIZE + conf->log_size, sample,
+ memcpy(dive + COCHRAN_MODEL_SIZE + layout->rb_log_size, sample,
sample_size);
} else {
// It wrapped the buffer, copy two sections
- unsigned int size = conf->sample_memory_end_address
+ unsigned int size = layout->rb_profile_end
- sample_start_address;
- memcpy(dive + COCHRAN_MODEL_SIZE + conf->log_size, sample, size);
- memcpy(dive + COCHRAN_MODEL_SIZE + conf->log_size + size,
+ memcpy(dive + COCHRAN_MODEL_SIZE + layout->rb_log_size, sample, size);
+ memcpy(dive + COCHRAN_MODEL_SIZE + layout->rb_log_size + size,
data->sample, sample_size - size);
}
diff --git a/src/cochran_commander.h b/src/cochran_commander.h
index 57962d8..f9d09ec 100644
--- a/src/cochran_commander.h
+++ b/src/cochran_commander.h
@@ -32,15 +32,6 @@
#define COCHRAN_CMDR_LOG_SIZE 256
#define COCHRAN_CMDR_SAMPLE_SIZE 2
-#define COCHRAN_LE_TYPE 0
-#define COCHRAN_BE_TYPE 1
-
-#define COCHRAN_DATE_FORMAT_SMHDMY 0
-#define COCHRAN_DATE_FORMAT_MSDHYM 1
-
-#define COCHRAN_ADDRESS_LENGTH_32 0
-#define COCHRAN_ADDRESS_LENGTH_24 1
-
typedef enum cochran_model_t {
COCHRAN_MODEL_UNKNOWN = 0,
COCHRAN_MODEL_EMC_FAMILY = 1 << 16,
@@ -51,7 +42,46 @@ typedef enum cochran_model_t {
COCHRAN_MODEL_COMMANDER_AIR_NITROX,
} cochran_model_t;
+typedef enum cochran_endian_t {
+ ENDIAN_LE,
+ ENDIAN_BE,
+} cochran_endian_t;
+
+typedef enum cochran_dateformat_t {
+ DATE_SMHDMY,
+ DATE_MSDHYM,
+} cochran_dateformat_t;
+
+typedef enum cochran_addresssize_t {
+ ADDRESS_24_BIT,
+ ADDRESS_32_BIT,
+} cochran_addresssize_t;
+
+typedef struct cochran_layout_t {
+ cochran_model_t model;
+ cochran_endian_t endian;
+ cochran_dateformat_t date_format;
+ cochran_addresssize_t address_size;
+ unsigned int high_baud_rate;
+
+ unsigned int rb_logbook_begin;
+ unsigned int rb_logbook_end;
+ unsigned int rb_log_size;
+ unsigned int rb_profile_begin;
+ unsigned int rb_profile_end;
+
+ unsigned int pt_log_profile_begin;
+ unsigned int pt_log_profile_pre;
+ unsigned int pt_log_dive_number;
+ unsigned int pt_log_profile_end;
+
+ unsigned int pt_conf_dive_count;
+ unsigned int pt_conf_last_log;
+ unsigned int pt_conf_last_interdive;
+} cochran_layout_t;
+
// Device configuration items
+/*
typedef struct cochran_config_t {
cochran_model_t model;
int log_size;
@@ -69,6 +99,7 @@ typedef struct cochran_config_t {
int address_length;
int high_baud; // baud rate to switch to for log/sample download
} cochran_config_t;
+*/
typedef struct cochran_data_t {
unsigned char id0[67];
@@ -89,14 +120,13 @@ typedef struct cochran_data_t {
unsigned int sample_data_offset;
unsigned int sample_size;
-
- cochran_config_t conf;
} cochran_data_t;
typedef struct cochran_device_t {
dc_device_t base;
const char *name; // serial port name
serial_t *port;
+ unsigned char model_string[COCHRAN_MODEL_SIZE + 1];
cochran_data_t data; // dive data used in parsing
} cochran_device_t;
@@ -156,4 +186,4 @@ dc_status_t cochran_commander_device_foreach (dc_device_t *abstract,
dc_dive_callback_t callback, void *userdata);
dc_status_t cochran_commander_device_dump (dc_device_t *abstract,
dc_buffer_t *data);
-void cochran_commander_get_config(const unsigned char *model, cochran_config_t *conf);
+cochran_layout_t *cochran_commander_get_layout(const unsigned char *model);
diff --git a/src/cochran_commander_parser.c b/src/cochran_commander_parser.c
index 8db87cf..434d332 100644
--- a/src/cochran_commander_parser.c
+++ b/src/cochran_commander_parser.c
@@ -109,11 +109,10 @@ cochran_commander_parser_get_datetime (dc_parser_t *abstract,
{
const unsigned char *data = abstract->data;
const unsigned char *log = data + COCHRAN_MODEL_SIZE;
- cochran_config_t conf;
+ // abstract->data is prefixed by the model string
+ cochran_layout_t *layout = cochran_commander_get_layout(data);
- cochran_commander_get_config(data, &conf);
-
- if (conf.date_format == COCHRAN_DATE_FORMAT_SMHDMY) {
+ if (layout->date_format == DATE_SMHDMY) {
datetime->second = log[0];
datetime->minute = log[1];
datetime->hour = log[2];
@@ -136,11 +135,9 @@ static dc_status_t
cochran_commander_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
unsigned int flags, void *value)
{
- cochran_config_t conf;
-
- cochran_commander_get_config(abstract->data, &conf);
+ cochran_layout_t *layout = cochran_commander_get_layout(abstract->data);
- switch (conf.model & 0xFF0000)
+ switch (layout->model & 0xFF0000)
{
case COCHRAN_MODEL_COMMANDER_FAMILY:
return cochran_cmdr_parser_get_field(abstract, type, flags, value);
@@ -157,11 +154,9 @@ static dc_status_t
cochran_commander_parser_samples_foreach (dc_parser_t *abstract,
dc_sample_callback_t callback, void *userdata)
{
- cochran_config_t conf;
-
- cochran_commander_get_config(abstract->data, &conf);
+ cochran_layout_t *layout = cochran_commander_get_layout(abstract->data);
- switch (conf.model & 0xFF0000)
+ switch (layout->model & 0xFF0000)
{
case COCHRAN_MODEL_COMMANDER_FAMILY:
return cochran_cmdr_parser_samples_foreach(abstract, callback,
--
2.4.3
More information about the devel
mailing list