From: Linus Torvalds <[email protected]>
Date: Mon, 20 Jun 2016 22:51:52 -0700
Subject: [PATCH 2/2] Initial Suunto EON Steel CCR support

This does the basic divemode and setpoint parsing for the EON Steel, and
gets the CCR download right in the big picture.

The cylinder information is still confusing and incorrect, but this is a
big step in the right direction.

Signed-off-by: Linus Torvalds <[email protected]>
---

The first big hunk is mainly just re-indentation of the sample type enum 
descriptions, with a coupld of new ones added for the setpoint data.

The rest is literally just adding trivial support for parsing the dive 
mode and the setpoint fields. Nothing surprising here, I think.

 src/suunto_eonsteel_parser.c | 123 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 103 insertions(+), 20 deletions(-)

diff --git a/src/suunto_eonsteel_parser.c b/src/suunto_eonsteel_parser.c
index bc40f491890f..0fb05f62926c 100644
--- a/src/suunto_eonsteel_parser.c
+++ b/src/suunto_eonsteel_parser.c
@@ -40,27 +40,30 @@
 
 enum eon_sample {
        ES_none = 0,
-       ES_dtime,       // duint16,precision=3 (time delta in ms)
-       ES_depth,       // uint16,precision=2,nillable=65535 (depth in cm)
-       ES_temp,        // int16,precision=2,nillable=-3000 (temp in 
deci-Celsius)
-       ES_ndl,         // int16,nillable=-1 (ndl in minutes)
-       ES_ceiling,     // uint16,precision=2,nillable=65535 (ceiling in cm)
-       ES_tts,         // uint16,nillable=65535 (time to surface)
-       ES_heading,     // uint16,precision=4,nillable=65535 (heading in 
degrees)
-       ES_abspressure, // uint16,precision=0,nillable=65535 (abs presure in 
centibar)
-       ES_gastime,     // int16,nillable=-1 (remaining gas time in minutes)
-       ES_ventilation, // uint16,precision=6,nillable=65535 ("x/6000000,x"? No 
idea)
-       ES_gasnr,       // uint8
-       ES_pressure,    // uint16,nillable=65535 (cylinder pressure in centibar)
-       ES_state,
-       ES_state_active,
-       ES_notify,
-       ES_notify_active,
-       ES_warning,
-       ES_warning_active,
+       ES_dtime,               // duint16,precision=3 (time delta in ms)
+       ES_depth,               // uint16,precision=2,nillable=65535 (depth in 
cm)
+       ES_temp,                // int16,precision=2,nillable=-3000 (temp in 
deci-Celsius)
+       ES_ndl,                 // int16,nillable=-1 (ndl in minutes)
+       ES_ceiling,             // uint16,precision=2,nillable=65535 (ceiling 
in cm)
+       ES_tts,                 // uint16,nillable=65535 (time to surface)
+       ES_heading,             // uint16,precision=4,nillable=65535 (heading 
in degrees)
+       ES_abspressure,         // uint16,precision=0,nillable=65535 (abs 
presure in centibar)
+       ES_gastime,             // int16,nillable=-1 (remaining gas time in 
minutes)
+       ES_ventilation,         // uint16,precision=6,nillable=65535 
("x/6000000,x"? No idea)
+       ES_gasnr,               // uint8
+       ES_pressure,            // uint16,nillable=65535 (cylinder pressure in 
centibar)
+       ES_state,               // enum:0=Wet Outside,1=Below Wet Activation 
Depth,2=Below Surface,3=Dive Active,4=Surface Calculation,5=Tank pressure 
available,6=Closed Circuit Mode
+       ES_state_active,        // bool
+       ES_notify,              // enum:0=NoFly Time,1=Depth,2=Surface 
Time,3=Tissue Level,4=Deco,5=Deco Window,6=Safety Stop Ahead,7=Safety 
Stop,8=Safety Stop Broken,9=Deep Stop Ahead,10=Deep Stop,11=Dive Time,12=Gas 
Available,13=SetPoint Switch,14=Diluent Hypoxia,15=Air Time,16=Tank Pressure
+       ES_notify_active,       // bool
+       ES_warning,             // enum:0=ICD Penalty,1=Deep Stop 
Penalty,2=Mandatory Safety 
Stop,3=OTU250,4=OTU300,5=CNS80%,6=CNS100%,7=Max.Depth,8=Air Time,9=Tank 
Pressure,10=Safety Stop Broken,11=Deep Stop Broken,12=Ceiling Broken,13=PO2 High
+       ES_warning_active,      // bool
        ES_alarm,
        ES_alarm_active,
-       ES_gasswitch,   // uint16
+       ES_gasswitch,           // uint16
+       ES_setpoint_type,       // enum:0=Low,1=High,2=Custom
+       ES_setpoint_po2,        // uint32
+       ES_setpoint_automatic,  // bool
        ES_bookmark,
 };
 
@@ -89,6 +92,10 @@ typedef struct suunto_eonsteel_parser_t {
                dc_gasmix_t gasmix[MAXGASES];
                dc_salinity_t salinity;
                double surface_pressure;
+               dc_divemode_t divemode;
+               double lowsetpoint;
+               double highsetpoint;
+               double customsetpoint;
                dc_field_string_t strings[MAXSTRINGS];
                double tanksize[MAXGASES];
                double tankworkingpressure[MAXGASES];
@@ -123,6 +130,9 @@ static const struct {
        { "Events.Alarm.Active",                ES_alarm_active },
        { "Events.Bookmark.Name",               ES_bookmark },
        { "Events.GasSwitch.GasNumber",         ES_gasswitch },
+       { "Events.SetPoint.Type",               ES_setpoint_type },
+       { "Events.Events.SetPoint.PO2",         ES_setpoint_po2 },
+       { "Events.SetPoint.Automatic",          ES_setpoint_automatic },
        { "Events.DiveTimer.Active",            ES_none },
        { "Events.DiveTimer.Time",              ES_none },
 };
@@ -744,6 +754,41 @@ static void sample_event_alarm_value(struct sample_data 
*info, unsigned char val
        if (info->callback) info->callback(DC_SAMPLE_EVENT, sample, 
info->userdata);
 }
 
+// enum:0=Low,1=High,2=Custom
+static void sample_setpoint_type(struct sample_data *info, unsigned char value)
+{
+       dc_sample_value_t sample = {0};
+
+       switch (value) {
+       case 0:
+               sample.ppo2 = info->eon->cache.lowsetpoint;
+               break;
+       case 1:
+               sample.ppo2 = info->eon->cache.highsetpoint;
+               break;
+       case 2:
+               sample.ppo2 = info->eon->cache.customsetpoint;
+               break;
+       default:
+               DEBUG(info->eon->base.context, "sample_setpoint_type(%u)", 
value);
+               return;
+       }
+       if (info->callback) info->callback(DC_SAMPLE_SETPOINT, sample, 
info->userdata);
+}
+
+// uint32
+static void sample_setpoint_po2(struct sample_data *info, unsigned int 
pressure)
+{
+       // I *think* this just sets the custom SP, and then
+       // we'll get a setpoint_type(2) later.
+       info->eon->cache.customsetpoint = pressure / 100000.0;  // Pascal to bar
+}
+
+static void sample_setpoint_automatic(struct sample_data *info, unsigned char 
value)
+{
+       DEBUG(info->eon->base.context, "sample_setpoint_automatic(%u)", value);
+}
+
 static int handle_sample_type(struct sample_data *info, enum eon_sample type, 
const unsigned char *data)
 {
        switch (type) {
@@ -835,6 +880,18 @@ static int handle_sample_type(struct sample_data *info, 
enum eon_sample type, co
                sample_gas_switch_event(info, array_uint16_le(data));
                return 2;
 
+       case ES_setpoint_type:
+               sample_setpoint_type(info, data[0]);
+               return 1;
+
+       case ES_setpoint_po2:
+               sample_setpoint_po2(info, array_uint32_le(data));
+               return 4;
+
+       case ES_setpoint_automatic:     // bool
+               sample_setpoint_automatic(info, data[0]);
+               return 1;
+
        default:
                return 0;
        }
@@ -946,6 +1003,9 @@ suunto_eonsteel_parser_get_field(dc_parser_t *parser, 
dc_field_type_t type, unsi
        case DC_FIELD_ATMOSPHERIC:
                field_value(value, eon->cache.surface_pressure);
                break;
+       case DC_FIELD_DIVEMODE:
+               field_value(value, eon->cache.divemode);
+               break;
        case DC_FIELD_TANK:
                /* Sadly it seems that the EON Steel doesn't tell us whether we 
get imperial
                 * or metric data - the only indication is metric is always 
whole liters */
@@ -1129,6 +1189,12 @@ static int 
traverse_device_fields(suunto_eonsteel_parser_t *eon, const struct ty
 //   AlgorithmTransitionDepth (uint8)
 //   DaysInSeries (uint32)
 //   PreviousDiveDepth (float32,precision=2)
+//   LowSetPoint (uint32)
+//   HighSetPoint (uint32)
+//   SwitchHighSetPoint.Enabled (bool)
+//   SwitchHighSetPoint.Depth (float32,precision=1)
+//   SwitchLowSetPoint.Enabled (bool)
+//   SwitchLowSetPoint.Depth (float32,precision=1)
 //   StartTissue.CNS (float32,precision=3)
 //   StartTissue.OTU (float32)
 //   StartTissue.OLF (float32,precision=3)
@@ -1182,8 +1248,13 @@ static int 
traverse_diving_fields(suunto_eonsteel_parser_t *eon, const struct ty
        if (!strcmp(name, "Algorithm"))
                return add_string(eon, "Deco algorithm", data);
 
-       if (!strcmp(name, "DiveMode"))
+       if (!strcmp(name, "DiveMode")) {
+               if (!strncmp(data, "CCR", 3)) {
+                       eon->cache.divemode = DC_DIVEMODE_CC;
+                       eon->cache.initialized |= 1 << DC_FIELD_DIVEMODE;
+               }
                return add_string(eon, "Dive Mode", data);
+       }
 
        /* Signed byte of conservatism (-2 .. +2) */
        if (!strcmp(name, "Conservatism")) {
@@ -1194,6 +1265,18 @@ static int 
traverse_diving_fields(suunto_eonsteel_parser_t *eon, const struct ty
                return add_string(eon, "Personal Adjustment", buffer);
        }
 
+       if (!strcmp(name, "LowSetPoint")) {
+               unsigned int pressure = array_uint32_le(data); // in SI units - 
Pascal
+               eon->cache.lowsetpoint = pressure / 100000.0; // bar
+               return 0;
+       }
+
+       if (!strcmp(name, "HighSetPoint")) {
+               unsigned int pressure = array_uint32_le(data); // in SI units - 
Pascal
+               eon->cache.highsetpoint = pressure / 100000.0; // bar
+               return 0;
+       }
+
        return 0;
 }
 
-- 
2.9.0.rc1.20.g6326f19

_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to