diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2011-10-03 12:27:14 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2011-10-03 12:31:56 -0700 |
commit | 0c343f2a476a9e7ee86d491b5fba5376b746a042 (patch) | |
tree | e478c9b29b6baf432d22f5c4ce78b1ee395675ba /uemis.c | |
parent | 09ef299044246890d6e257593e4f5742191c13bb (diff) | |
download | subsurface-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.c | 71 |
1 files changed, 64 insertions, 7 deletions
@@ -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; |