This patch is incomplete. Please excuse my lack of git-worthiness. I'll see if I can have a complete one in a few minutes.
On Fri, Oct 17, 2014 at 8:41 PM, John Van Ostrand <[email protected]> wrote: > I fixed up the decode and finished the parse for Cochran > EMC, Commander and Gemini computers. I suspect that this > code may only work with files from certain versions of > Cochran Analyst. It works with my own CAN files and with the > samples that came with Analyst v4.01v. > > A seemingly arbitrary offset of 0x4914 is needed to access data. > The previous code uses 0x4a14 and 0x4b14. I suspect these are from > different version of Analyst. > > Signed-off-by: John Van Ostrand <[email protected]> > --- > cochran_cmdr.h | 88 ++++++++++++++++++++++++++++ > cochran_emc.h | 180 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 268 insertions(+) > create mode 100644 cochran_cmdr.h > create mode 100644 cochran_emc.h > > diff --git a/cochran_cmdr.h b/cochran_cmdr.h > new file mode 100644 > index 0000000..6c66165 > --- /dev/null > +++ b/cochran_cmdr.h > @@ -0,0 +1,88 @@ > +/* > + * subsurface > + * > + * Copyright (C) 2014 John Van Ostrand > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, > + * MA 02110-1301 USA > + */ > + > + > +struct cochran_cmdr_log_t { > + // Pre-dive 128 bytes > + unsigned char minutes, seconds; // 2 bytes > + unsigned char day, hour, year, month; // 4 bytes > + unsigned char sample_start_offset[4]; // 4 bytes > + unsigned char start_timestamp[4]; // 4 bytes > + unsigned char pre_dive_timestamp[4]; // 4 bytes > + unsigned char unknown1[6]; // 6 bytes > + unsigned char water_conductivity; // 1 byte [0=low, > 2=high] > + unsigned char unknown2[5]; // 5 bytes > +//30 > + unsigned char sample_pre_event_offset[4];// 4 bytes > + unsigned char unknown3[4]; // 4 bytes > + unsigned char start_battery_voltage[2]; // 2 bytes [/256] > +//40 > + unsigned char unknown4[2]; // 2 bytes > + unsigned char start_sgc[2]; // 2 bytes > + unsigned char entered_or_computed_po[2];// 2 bytes ??? > + unsigned char unknown5[10]; // 10 bytes > +//56 > + unsigned char start_depth[2]; // 2 byte [/4] > + unsigned char unknown6[4]; // 3 bytes > + unsigned char start_psi[2]; // 2 bytes > LE > + unsigned char unknown7[4]; // 4 bytes > + unsigned char sit[2]; // 2 bytes > +//70 > + unsigned char number[2]; // 2 bytes > + unsigned char unknown8[1]; // 1 byte > + unsigned char altitude; // 1 byte > [/4 = kft] > + unsigned char unknown9[28]; // 27 bytes > + unsigned char alarm_depth[2]; // 2 bytes > + unsigned char unknown10[4]; // 5 bytes > +//108 > + unsigned char repetitive_dive; // 1 byte > + unsigned char unknown11[3]; // 3 bytes > + unsigned char start_tissue_nsat[16]; // 16 bytes [/256] > + > + // Post-dive 128 bytes > + unsigned char sample_end_offset[4]; // 4 bytes > + unsigned char unknown12[21]; // 21 bytes > + unsigned char temp; // > 1 byte > + unsigned char unknown13[12]; // 12 bytes > + unsigned char bt[2]; // 2 bytes > [minutes] > +//168 > + unsigned char max_depth[2]; // 2 bytes > [/4] > + unsigned char avg_depth[2]; // 2 bytes > + unsigned char unknown14[38]; // 38 bytes > +//210 > + unsigned char o2_percent[4][2]; // 8 bytes > + unsigned char unknown15[22]; // 22 bytes > + unsigned char end_tissue_nsat[16]; // 16 bytes [/256] > +} __attribute__((packed)); > + > + > +typedef struct cochran_cmdr_log_t cochran_cmdr_log_t; > + > + > +struct cochran_cmdr_config1_t { > + unsigned char unknown1[209]; > + unsigned short int dive_count; > + unsigned char unknown2[274]; > + unsigned short int serial_num; // @170 > + unsigned char unknown3[24]; > +} __attribute__((packed)); > + > +typedef struct cochran_emc_config1_t cochran_emc_config1_t; > diff --git a/cochran_emc.h b/cochran_emc.h > new file mode 100644 > index 0000000..33c4757 > --- /dev/null > +++ b/cochran_emc.h > @@ -0,0 +1,180 @@ > +/* > + * subsurface > + * > + * Copyright (C) 2014 John Van Ostrand > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, > + * MA 02110-1301 USA > + */ > + > +// 512 bytes for each dive in the log book > +struct cochran_emc_log_t { > + // Pre-dive 256 bytes > + unsigned char seconds, minutes, hour; // 3 bytes > + unsigned char day, month, year; // 3 bytes > + unsigned char sample_start_offset[4]; // 4 bytes > + unsigned char start_timestamp[4]; // 4 bytes > [secs from jan 1,92] > + unsigned char pre_dive_timestamp[4]; // 4 bytes [secs > from Jan 1,92] > + unsigned char unknown1[6]; // > 6 bytes > + unsigned char water_conductivity; // 1 byte > [0 =low, 2-high] > + unsigned char unknown2[5]; // > 5 bytes > +//30 > + unsigned char sample_pre_event_offset[4]; // 4 bytes > + unsigned char config_bitfield[6]; // 6 bytes > + unsigned char unknown3[2]; // > 2 bytes > + unsigned char start_depth[2]; // 2 bytes > [/256] > + unsigned char unknown4[2]; // > 2 bytes > + unsigned char start_battery_voltage[2]; // 2 bytes [/256] > +//48 > + unsigned char unknown5[7]; // > 7 bytes > + unsigned char start_temperature; // 1 byte > [F] > + unsigned char unknown6[28]; // > 28 bytes > + unsigned char sit[2]; // > 2 bytes [minutes] > + unsigned char number[2]; // > 2 bytes > + unsigned char unknown7[1]; // > 1 bytes > + unsigned char altitude; // > 1 byte [/4 = kft] > + unsigned char start_nofly[2]; // 2 bytes > [/256 = hours] > +//92 > + unsigned char unknown8[18]; // 18 bytes > + unsigned char post_dive_sit[2]; // 2 > bytes [seconds] > + unsigned char po2_set_point[9][2]; // 18 > bytes [/256 = %] > + unsigned char unknown9[12]; // 12 bytes > + unsigned char po2_alarm[2]; // 2 > bytes [/256 = %] > +//144 > + unsigned char o2_percent[10][2]; // 20 > bytes [/256 = %] > + unsigned char he_percent[10][2]; // 20 > bytes [/256 = %] > + unsigned char alarm_depth[2]; // 2 bytes > + unsigned char unknown10[14]; // 14 bytes > + unsigned char conservatism; // > 1 bytes [/256 = fraction] > + unsigned char unknown11[2]; // > 2 bytes > + unsigned char repetitive_dive; // 1 byte > + unsigned char unknown12[12]; // 12 bytes > + unsigned char start_tissue_nsat[20][2]; // 40 bytes [/256] > + > + // Post-dive 256 bytes > + unsigned char sample_end_offset[4]; // 4 bytes > + unsigned char unknown13[33]; // 33 bytes > + unsigned char temp; > // 1 byte [F] > + unsigned char unknown14[10]; // 10 bytes > +// 48 > + unsigned char bt[2]; // > 2 bytes [minutes] > + unsigned char max_depth[2]; // > 2 bytes [/4 = ft] > + unsigned char unknown15[2]; // > 2 bytes > + unsigned char avg_depth[2]; // > 2 bytes [/4 = ft] > + unsigned char min_ndc[2]; // > 2 bytes [minutes] > + unsigned char min_ndx_bt[2]; // 2 bytes > [minutes] > + unsigned char max_forecast_deco[2]; // 2 bytes > [minutes] > + unsigned char max_forecast_deco_bt[2]; // 2 bytes > [minutes] > +//64 > + unsigned char max_ceiling[2]; // 2 bytes > [*10 = ft] > + unsigned char max_ceiling_bt[2]; // 2 bytes > [minutes] > + unsigned char unknown16[10]; // 18 bytes > + unsigned char max_ascent_rate; // 1 byte > [ft/min] > + unsigned char unknown17[3]; // > 3 bytes > + unsigned char max_ascent_rate_bt[2]; // 2 bytes > [seconds] > +//84 > + unsigned char unknown18[54]; // 54 bytes > +//138 > + unsigned char end_battery_voltage[2]; // 2 bytes [/256 = > v] > + unsigned char unknown19[8]; // > 8 bytes > + unsigned char min_temp_bt[2]; // 2 bytes > [seconds] > +//150 > + unsigned char unknown20[22]; // 22 bytes > +//172 > + unsigned char end_nofly[2]; // > 2 bytes [/256 = hours] > + unsigned char alarm_count[2]; // 2 byte > + unsigned char actual_deco_time[2]; // 2 bytes > [seconds] > +//178 > + unsigned char unknown21[38]; // 38 bytes > +//216 > + unsigned char end_tissue_nsat[20][2]; // 40 bytes [/256 > = fraction] > +} __attribute__((packed)); > + > +typedef struct cochran_emc_log_t cochran_emc_log_t; > + > +typedef enum cochran_emc_bitfield_config_t { > + BF_TEMP_DEPENDENT_N2, > + BF_ASCENT_RATE_BAR_GRAPH, > + BF_BLEND_2_SWITCHING, > + BF_ALTITUDE_AS_ONE_ZONE, > + BF_DECOMPRESSION_TIME_DISPLAY, > + BF_BLEND_3_SWITCHING, > + BF_VARIABLE_ASCENT_RATE_ALARM, > + BF_ASCENT_RATE_RESPONSE, > + BF_REPETITIVE_DIVE_DEPENDENT_N2, > + BF_TRAINING_MODE, > + BF_CONSTANT_MODE_COMPUTATIONS, > + BF_DISPLAYED_UNITS, > + BF_AUDIBLE_ALARM, > + BF_CLOCK, > + BF_CEILING_DISPLAY_DIV_BY_10, > + BF_GAS_2_AS_FIRST_GAS, > + BF_ENABLE_HELIUM_COMPUTATIONS, > + BF_AUTOMATIC_PO2_FO2_SWITCHING, > + BF_TOUCH_PROGRAMMING_PO2_FO2_SWITCH, > +} cochran_emc_bitfield_config_t; > + > + > +typedef struct cochran_emc_bitfield_t { > + cochran_emc_bitfield_config_t config; > + unsigned char word; > + unsigned char byte; > + unsigned char mask; > + unsigned char shift; > +} cochran_emc_bitfield_t; > + > +static cochran_emc_bitfield_t cochran_emc_bits[] = { > +// Word BD > + { BF_TEMP_DEPENDENT_N2, 0xBD, 0, 0x40, 6 }, // > 0=normal, > + > // 1=reduced > + { BF_ASCENT_RATE_BAR_GRAPH, 0xBD, 0, 0x20, 5 }, // > 0=fixed, > + > // 1=proportional > + { BF_BLEND_2_SWITCHING, 0xBD, 0, 0x04, 2 }, > // 0=dis, 1=ena > + { BF_ALTITUDE_AS_ONE_ZONE, 0xBD, 0, 0x02, 1}, // > 0=off, 1=on > + > + { BF_DECOMPRESSION_TIME_DISPLAY, 0xBD, 1, 0xC0, 5}, // > 111=both, > + > // 011=stop, > + > // 001=total > + { BF_BLEND_3_SWITCHING, 0xBD, 1, 0x10, 4 }, > // 0=dis, 1=ena > + { BF_VARIABLE_ASCENT_RATE_ALARM, 0xBD, 1, 0x04, 3}, // > 0=off, 1=on > + { BF_ASCENT_RATE_RESPONSE, 0xBD, 1, 0x07, 0}, > + > +//WORD BE > + { BF_REPETITIVE_DIVE_DEPENDENT_N2, 0xBE, 0, 0x80, 7 }, // 0=off, > 1=on > + { BF_TRAINING_MODE, 0xBE, 0, 0x04, 2 }, > // 0=off, 1=on > + { BF_CONSTANT_MODE_COMPUTATIONS, 0xBE, 0, 0x04, 2 }, // 0=FO2, > 1=PO2 > + { BF_DISPLAYED_UNITS, 0xBE, 0, 0x01, 0 }, > // 1=metric, > + > // 0=imperial > + > +// WORD BF > + { BF_AUDIBLE_ALARM, 0xBF, 0, 0x40, 6 }, > // 0=on, 1=off *** > + { BF_CLOCK, 0xBF, 0, 0x20, 5 }, > // 0=off, 1=on > + { BF_CEILING_DISPLAY_DIV_BY_10, 0xBF, 0, 0x10, 4 }, // > 0=off, 1=on > + { BF_GAS_2_AS_FIRST_GAS, 0xBF, 0, 0x02, 1 }, // > 0=dis, 1=ena > + { BF_ENABLE_HELIUM_COMPUTATIONS, 0xBF, 0, 0x01, 0 }, // 0=dis, > 1=ena > + > + { BF_AUTOMATIC_PO2_FO2_SWITCHING, 0xBF, 1, 0x04, 2 }, // 0=dis, > 1=ena > + { BF_TOUCH_PROGRAMMING_PO2_FO2_SWITCH, 0xBF, 1, 0x02, 1 }, // > 0=dis, 1=ena > +}; > + > +struct cochran_emc_config1_t { > + unsigned char unknown1[209]; > + unsigned short int dive_count; > + unsigned char unknown2[274]; > + unsigned short int serial_num; > + unsigned char unknown3[24]; > +} __attribute__((packed)); > + > +typedef struct cochran_emc_config1_t cochran_emc_config1_t; > -- > 1.8.3.1 > > -- John Van Ostrand At large on sabbatical
_______________________________________________ subsurface mailing list [email protected] http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
