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.
This commit is contained in:
John Van Ostrand 2017-06-30 14:12:58 -04:00 committed by Jef Driesen
parent 9c795e6e4e
commit e1b679912a

View File

@ -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) {