summaryrefslogtreecommitdiffstats
path: root/uemis.c
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2011-10-03 12:27:14 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2011-10-03 12:31:56 -0700
commit0c343f2a476a9e7ee86d491b5fba5376b746a042 (patch)
treee478c9b29b6baf432d22f5c4ce78b1ee395675ba /uemis.c
parent09ef299044246890d6e257593e4f5742191c13bb (diff)
downloadsubsurface-0c343f2a476a9e7ee86d491b5fba5376b746a042.tar.gz
Much nicer implementation of uemis sample parsing - and add events, too
This is something I wanted to do for a while. Every uemis sample is simply a packed structure with no padding. Instead of grabbing random bytes from the middle of an unstructured data blob let's just define the structure and access its members. And while we do that, add support for the more useful uemis events as well. A couple of the warnings are disabled by default (compile time flag) as they are just crazy - any normal dive will give you dozens and dozens of speed warnings. Same goes for the PO2 green warning (I haven't looked but this seems to trigger on a PO2 over 1.0 or something). Completely useless and just hides actually useful info. I still want to redo the way we visualize events in general - just printing the text ontop of the profile really is suboptimal. Especially as the uemis really seems to love to repeat several of the warnings quite frequently. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'uemis.c')
-rw-r--r--uemis.c71
1 files changed, 64 insertions, 7 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;