diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 05dbf95..f47bbb3 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -65,6 +65,7 @@ static const device_backend_t oceanic_atom2_device_backend = { static const unsigned char aeris_atmosai_version[] = "ATMOSAI R\0\0 512K"; static const unsigned char aeris_epic_version[] = "2M EPIC r\0\0 512K"; +static const unsigned char aeris_f10_version[] = "FREEWAER \0\0 512K"; static const unsigned char oceanic_proplus2_version[] = "PROPLUS2 \0\0 512K"; static const unsigned char oceanic_atom1_version[] = "ATOM rev\0\0 256K"; static const unsigned char oceanic_atom2_version[] = "2M ATOM r\0\0 512K"; @@ -83,6 +84,20 @@ static const unsigned char tusa_element2_version[] = "ELEMENT2 \0\0 512K"; static const unsigned char tusa_zen_version[] = "TUSAZEN \0\0 512K"; static const unsigned char tusa_zenair_version[] = "TUZENAIR \0\0 512K"; + +static const oceanic_common_layout_t aeris_f10_layout = { + 0x10000, /* memsize */ + 0x0000, /* cf_devinfo */ + 0x0040, /* cf_pointers */ + 0x0100, /* rb_logbook_begin */ + 0x0D80, /* rb_logbook_end */ + 32, /* rb_logbook_entry_size */ + 0x0D90, /* rb_profile_begin */ + 0x10000, /* rb_profile_end */ + 0, /* pt_mode_global */ + 2 /* pt_mode_logbook */ +}; + static const oceanic_common_layout_t oceanic_default_layout = { 0x10000, /* memsize */ 0x0000, /* cf_devinfo */ @@ -345,6 +360,8 @@ oceanic_atom2_device_open (device_t **out, const char* name) oceanic_common_match (oceanic_vt4_version, device->version, sizeof (device->version)) || oceanic_common_match (oceanic_vt41_version, device->version, sizeof (device->version))) device->base.layout = &oceanic_oc1_layout; + else if (oceanic_common_match (aeris_f10_version, device->version, sizeof (device->version))) + device->base.layout = &aeris_f10_layout; else if (oceanic_common_match (tusa_zenair_version, device->version, sizeof (device->version))) device->base.layout = &tusa_zenair_layout; else if (oceanic_common_match (oceanic_atom1_version, device->version, sizeof (device->version))) diff --git a/src/oceanic_atom2_parser.c b/src/oceanic_atom2_parser.c index d2d131c..bb7cec3 100644 --- a/src/oceanic_atom2_parser.c +++ b/src/oceanic_atom2_parser.c @@ -37,6 +37,7 @@ #define DATAMASK 0x4347 #define COMPUMASK 0x4348 #define OC1A 0x434E +#define F10 0x434D #define VEO20 0x4359 #define VEO30 0x435A #define ZENAIR 0x4442 @@ -148,12 +149,19 @@ oceanic_atom2_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime) { oceanic_atom2_parser_t *parser = (oceanic_atom2_parser_t *) abstract; - if (abstract->size < 8) + unsigned int header = 8; + if (parser->model == F10) + header = 32; + + if (abstract->size < header) return PARSER_STATUS_ERROR; const unsigned char *p = abstract->data; if (datetime) { + // AM/PM bit of the 12-hour clock. + unsigned int pm = p[1] & 0x80; + switch (parser->model) { case OC1A: case OC1B: @@ -183,6 +191,14 @@ oceanic_atom2_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime) datetime->hour = bcd2dec (p[1] & 0x1F); datetime->minute = bcd2dec (p[0]); break; + case F10: + datetime->year = bcd2dec (p[6]) + 2000; + datetime->month = bcd2dec (p[7]); + datetime->day = bcd2dec (p[8]); + datetime->hour = bcd2dec (p[13] & 0x7F); + datetime->minute = bcd2dec (p[12]); + pm = p[13] & 0x80; + break; default: datetime->year = bcd2dec (((p[3] & 0xC0) >> 2) + (p[4] & 0x0F)) + 2000; datetime->month = (p[4] & 0xF0) >> 4; @@ -198,7 +214,7 @@ oceanic_atom2_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime) // Convert to a 24-hour clock. datetime->hour %= 12; - if (p[1] & 0x80) + if (pm) datetime->hour += 12; /* @@ -256,6 +272,9 @@ oceanic_atom2_parser_get_field (parser_t *abstract, parser_field_type_t type, un headersize += PAGESIZE; } else if (parser->model == ATOM1) { headersize -= 2 * PAGESIZE; + } else if (parser->model == F10) { + headersize = 3 * PAGESIZE; + footersize = PAGESIZE / 2; } if (size < headersize + footersize) @@ -287,10 +306,16 @@ oceanic_atom2_parser_get_field (parser_t *abstract, parser_field_type_t type, un if (value) { switch (type) { case FIELD_TYPE_DIVETIME: - *((unsigned int *) value) = parser->divetime; + if (parser->model == F10) + *((unsigned int *) value) = bcd2dec (data[2]) + bcd2dec (data[3]) * 60 + bcd2dec (data[1]) * 3600; + else + *((unsigned int *) value) = parser->divetime; break; case FIELD_TYPE_MAXDEPTH: - *((double *) value) = array_uint16_le (data + footer + 4) / 16.0 * FEET; + if (parser->model == F10) + *((double *) value) = array_uint16_le (data + 4) / 16.0 * FEET; + else + *((double *) value) = array_uint16_le (data + footer + 4) / 16.0 * FEET; break; case FIELD_TYPE_GASMIX_COUNT: if (parser->model == DATAMASK || parser->model == COMPUMASK) @@ -340,6 +365,9 @@ oceanic_atom2_parser_samples_foreach (parser_t *abstract, sample_callback_t call headersize += PAGESIZE; } else if (parser->model == ATOM1) { headersize -= 2 * PAGESIZE; + } else if (parser->model == F10) { + headersize = 3 * PAGESIZE; + footersize = PAGESIZE / 2; } if (size < headersize + footersize) @@ -349,29 +377,36 @@ oceanic_atom2_parser_samples_foreach (parser_t *abstract, sample_callback_t call unsigned int header = headersize - PAGESIZE / 2; unsigned int time = 0; - unsigned interval = 0; - switch (data[0x17] & 0x03) { - case 0: - interval = 2; - break; - case 1: - interval = 15; - break; - case 2: - interval = 30; - break; - case 3: - interval = 60; - break; + unsigned int interval = 1; + if (parser->model != F10) { + switch (data[0x17] & 0x03) { + case 0: + interval = 2; + break; + case 1: + interval = 15; + break; + case 2: + interval = 30; + break; + case 3: + interval = 60; + break; + } } unsigned int samplesize = PAGESIZE / 2; if (parser->model == OC1A || parser->model == OC1B) samplesize = PAGESIZE; + else if (parser->model == F10) + samplesize = 2; unsigned int have_temperature = 1, have_pressure = 1; if (parser->model == VEO30) { have_pressure = 0; + } else if (parser->model == F10) { + have_temperature = 0; + have_pressure = 0; } // Initial temperature. @@ -412,6 +447,8 @@ oceanic_atom2_parser_samples_foreach (parser_t *abstract, sample_callback_t call // Get the sample type. unsigned int sampletype = data[offset + 0]; + if (parser->model == F10) + sampletype = 0; // The sample size is usually fixed, but some sample types have a // larger size. Check whether we have that many bytes available. @@ -507,6 +544,8 @@ oceanic_atom2_parser_samples_foreach (parser_t *abstract, sample_callback_t call depth = (data[offset + 4] + (data[offset + 5] << 8)) & 0x0FFF; else if (parser->model == ATOM1) depth = data[offset + 3] * 16; + else if (parser->model == F10) + depth = array_uint16_le (data + offset); else depth = (data[offset + 2] + (data[offset + 3] << 8)) & 0x0FFF; sample.depth = depth / 16.0 * FEET; diff --git a/src/oceanic_common.c b/src/oceanic_common.c index 53f1530..ef3b1eb 100644 --- a/src/oceanic_common.c +++ b/src/oceanic_common.c @@ -59,8 +59,10 @@ get_profile_first (const unsigned char data[], const oceanic_common_layout_t *la if (layout->pt_mode_logbook == 0) { value = array_uint16_le (data + 5); - } else { + } else if (layout->pt_mode_logbook == 1) { value = array_uint16_le (data + 4); + } else { + return array_uint16_le (data + 16); } if (layout->memsize > 0x10000) @@ -77,8 +79,10 @@ get_profile_last (const unsigned char data[], const oceanic_common_layout_t *lay if (layout->pt_mode_logbook == 0) { value = array_uint16_le (data + 6) >> 4; - } else { + } else if (layout->pt_mode_logbook == 1) { value = array_uint16_le (data + 6); + } else { + return array_uint16_le(data + 18); } if (layout->memsize > 0x10000) diff --git a/src/oceanic_common.h b/src/oceanic_common.h index 4a700b6..8918f8b 100644 --- a/src/oceanic_common.h +++ b/src/oceanic_common.h @@ -29,7 +29,7 @@ extern "C" { #endif /* __cplusplus */ #define PAGESIZE 0x10 -#define FPMAXSIZE (PAGESIZE / 2) +#define FPMAXSIZE 0x20 typedef struct oceanic_common_layout_t { // Memory size.