aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--uemis.c71
-rw-r--r--uemis.h30
2 files changed, 91 insertions, 10 deletions
diff --git a/uemis.c b/uemis.c
index 46878e22a..dc11a6dec 100644
--- a/uemis.c
+++ b/uemis.c
@@ -119,6 +119,59 @@ bail:
return datalen;
}
+/* Create events from the flag bits;
+ * These bits basically represent what is displayed on screen at sample time.
+ * Many of these 'warnings' are way hyper-active and seriously clutter the
+ * profile plot - so these are disabled by default
+ */
+void uemis_event(struct dive *dive, struct sample *sample, uemis_sample_t *u_sample)
+{
+ uint8_t *flags = u_sample->flags;
+
+ if (flags[1] & 0x01)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Safety Stop Violation");
+ if (flags[1] & 0x08)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Speed Alarm");
+#if WANT_CRAZY_WARNINGS
+ if (flags[1] & 0x06) /* both bits 1 and 2 are a warning */
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Speed Warning");
+ if (flags[1] & 0x10)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "PO2 Green Warning");
+#endif
+ if (flags[1] & 0x20)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "PO2 Ascend Warning");
+ if (flags[1] & 0x40)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "PO2 Ascend Alarm");
+ /* flags[2] reflects the deco / time bar
+ * flags[3] reflects more display details on deco and pO2 */
+ if (flags[4] & 0x01)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Tank Pressure Info");
+ if (flags[4] & 0x04)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "RGT Warning");
+ if (flags[4] & 0x08)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "RGT Alert");
+ if (flags[4] & 0x40)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Tank Change Suggest");
+ if (flags[4] & 0x80)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Depth Limit Exceeded");
+ if (flags[5] & 0x01)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Max Deco Time Warning");
+ if (flags[5] & 0x04)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Dive Time Info");
+ if (flags[5] & 0x08)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Dive Time Alert");
+ if (flags[5] & 0x10)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Marker");
+ if (flags[6] & 0x02)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "No Tank Data");
+ if (flags[6] & 0x04)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Low Battery Warning");
+ if (flags[6] & 0x08)
+ add_event(dive, sample->time.seconds, 0, 0, 0, "Low Battery Alert");
+ /* flags[7] reflects the little on screen icons that remind of previous
+ * warnings / alerts - not useful for events */
+}
+
/*
* parse uemis base64 data blob into struct dive
*/
@@ -127,6 +180,7 @@ void uemis_parse_divelog_binary(char *base64, void *datap) {
int i;
uint8_t *data;
struct sample *sample;
+ uemis_sample_t *u_sample;
struct dive **divep = datap;
struct dive *dive = *divep;
int template, gasoffset;
@@ -160,22 +214,25 @@ void uemis_parse_divelog_binary(char *base64, void *datap) {
}
/* first byte of divelog data is at offset 0x123 */
i = 0x123;
- while ((i < datalen) && (*(uint16_t *)(data+i))) {
+ u_sample = (uemis_sample_t *)(data + i);
+ while ((i < datalen) && (u_sample->dive_time)) {
/* it seems that a dive_time of 0 indicates the end of the valid readings */
/* the SDA usually records more samples after the end of the dive --
* we want to discard those, but not cut the dive short; sadly the dive
* duration in the header is a) in minutes and b) up to 3 minutes short */
- if (*(uint16_t *)(data+i) > dive->duration.seconds + 180)
+ if (u_sample->dive_time > dive->duration.seconds + 180)
break;
sample = prepare_sample(divep);
dive = *divep; /* prepare_sample might realloc the dive */
- sample->time.seconds = *(uint16_t *)(data+i);
- sample->depth.mm = pressure_to_depth(*(uint16_t *)(data+i+2));
- sample->temperature.mkelvin = (*(uint16_t *)(data+i+4) * 100) + 273150;
- sample->cylinderpressure.mbar= *(uint16_t *)(data+i+23) * 10;
- sample->cylinderindex = *(uint8_t *)(data+i+22);
+ sample->time.seconds = u_sample->dive_time;
+ sample->depth.mm = pressure_to_depth(u_sample->water_pressure);
+ sample->temperature.mkelvin = (u_sample->dive_temperature * 100) + 273150;
+ sample->cylinderindex = u_sample->active_tank;
+ sample->cylinderpressure.mbar= u_sample->tank_pressure * 10;
+ uemis_event(dive, sample, u_sample);
finish_sample(dive, sample);
i += 0x25;
+ u_sample++;
}
dive->duration.seconds = sample->time.seconds - 1;
return;
diff --git a/uemis.h b/uemis.h
index e4e8532c2..29a168f5d 100644
--- a/uemis.h
+++ b/uemis.h
@@ -1,10 +1,34 @@
-#ifndef UEMIS_H
-#define UEMIS_H
-
/*
* defines and prototypes for the uemis Zurich SDA file parser
*/
+#ifndef UEMIS_H
+#define UEMIS_H
+
+#include <stdint.h>
+
void uemis_parse_divelog_binary(char *base64, void *divep);
+typedef struct {
+ uint16_t dive_time;
+ uint16_t water_pressure; // (in cbar)
+ uint16_t dive_temperature; // (in dC)
+ uint8_t ascent_speed; // (units unclear)
+ uint8_t work_fact;
+ uint8_t cold_fact;
+ uint8_t bubble_fact;
+ uint16_t ascent_time;
+ uint16_t ascent_time_opt;
+ uint16_t p_amb_tol;
+ uint16_t satt;
+ uint16_t hold_depth;
+ uint16_t hold_time;
+ uint8_t active_tank;
+ uint16_t tank_pressure; // (in cbar)
+ uint16_t consumption; // (units unclear)
+ uint8_t rgt; // (remaining gas time in minutes)
+ uint8_t cns;
+ uint8_t flags[8];
+} __attribute((packed)) uemis_sample_t;
+
#endif /* DIVE_H */