From e1b679912abd107ba39050beeba4cc7858ed5ec8 Mon Sep 17 00:00:00 2001 From: John Van Ostrand Date: Fri, 30 Jun 2017 14:12:58 -0400 Subject: [PATCH] Fix bad profiles when profile ringbuffer wraps around The method used to calculate the data used by dives (to determine when we run out of ringbuffer) incorrectly didn't include surface sample data. Ten to twenty minute of sample data is recorded at the surface in case the diver re-descends, continuing the dive. The code then thought that older dive profiles were not yet overwritten. The improper data was returned to the user. --- src/cochran_commander.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/cochran_commander.c b/src/cochran_commander.c index 651a0f9..0203ae6 100644 --- a/src/cochran_commander.c +++ b/src/cochran_commander.c @@ -147,8 +147,8 @@ static const cochran_device_layout_t cochran_cmdr_device_layout = { ENDIAN_WORD_BE, // endian 115200, // baudrate 0x046, // cf_dive_count - 0x070, // cf_last_log - 0x06C, // cf_last_interdive + 0x06C, // cf_last_log + 0x070, // cf_last_interdive 0x0AA, // cf_serial_number 0x00000000, // rb_logbook_begin 0x00020000, // rb_logbook_end @@ -566,12 +566,9 @@ cochran_commander_find_fingerprint(cochran_commander_device_t *device, cochran_d // Remove the pre-dive events that occur after the last dive unsigned int rb_head_ptr = 0; if (device->layout->endian == ENDIAN_WORD_BE) - rb_head_ptr = (array_uint32_word_be(data->config + device->layout->cf_last_interdive) & 0xfffff000) + 0x2000; + rb_head_ptr = (array_uint32_word_be(data->config + device->layout->cf_last_log) & 0xfffff000) + 0x2000; else - rb_head_ptr = (array_uint32_le(data->config + device->layout->cf_last_interdive) & 0xfffff000) + 0x2000; - unsigned int last_dive_end_address = array_uint32_le(data->logbook + dive_count * device->layout->rb_logbook_entry_size + device->layout->pt_profile_end); - if (rb_head_ptr > last_dive_end_address) - profile_capacity_remaining -= rb_head_ptr - last_dive_end_address; + rb_head_ptr = (array_uint32_le(data->config + device->layout->cf_last_log) & 0xfffff000) + 0x2000; unsigned int head_dive = 0, tail_dive = 0; @@ -584,6 +581,18 @@ cochran_commander_find_fingerprint(cochran_commander_device_t *device, cochran_d head_dive = tail_dive; } + unsigned int last_profile_idx = (device->layout->rb_logbook_entry_count + head_dive - 1) % device->layout->rb_logbook_entry_count; + unsigned int last_profile_end = array_uint32_le(data->logbook + last_profile_idx * device->layout->rb_logbook_entry_size + device->layout->pt_profile_end); + unsigned int last_profile_pre = 0xFFFFFFFF; + + if (device->layout->endian == ENDIAN_WORD_BE) + last_profile_pre = array_uint32_word_be(data->config + device->layout->cf_last_log); + else + last_profile_pre = array_uint32_le(data->config + device->layout->cf_last_log); + + if (rb_head_ptr > last_profile_end) + profile_capacity_remaining -= rb_head_ptr - last_profile_end; + // Loop through dives to find FP, Accumulate profile data size, // and find the last dive with invalid profile for (unsigned int i = 0; i <= dive_count; ++i) { @@ -601,8 +610,9 @@ cochran_commander_find_fingerprint(cochran_commander_device_t *device, cochran_d unsigned int profile_begin = array_uint32_le(log_entry + device->layout->pt_profile_begin); unsigned int profile_end = array_uint32_le(log_entry + device->layout->pt_profile_end); - unsigned int sample_size = cochran_commander_profile_size(device, data, idx, profile_pre, profile_end); + unsigned int sample_size = cochran_commander_profile_size(device, data, idx, profile_pre, last_profile_pre); unsigned int read_size = cochran_commander_profile_size(device, data, idx, profile_begin, profile_end); + last_profile_pre = profile_pre; // Determine if sample exists if (profile_capacity_remaining > 0) {