Added a function to extract individual dives for the Suunto Vyper/Eon.
This commit is contained in:
parent
0c2444ae07
commit
e0151bacf4
74
suunto_common.c
Normal file
74
suunto_common.c
Normal file
@ -0,0 +1,74 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "suunto_common.h"
|
||||
|
||||
#define SUBSTRACT(a, x, begin, end) substract (a - begin, x, end - begin) + begin
|
||||
#define DISTANCE(a, b, begin, end) distance (a, b, end - begin)
|
||||
|
||||
static unsigned int
|
||||
substract (unsigned int a, unsigned int x, unsigned int size)
|
||||
{
|
||||
if (x <= a) {
|
||||
return (a - x) % size;
|
||||
} else {
|
||||
return size - (x - a) % size;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
distance (unsigned int a, unsigned int b, unsigned int size)
|
||||
{
|
||||
if (a <= b) {
|
||||
return (b - a) % size;
|
||||
} else {
|
||||
return size - (a - b) % size;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
suunto_common_extract_dives (const unsigned char data[], unsigned int begin, unsigned int end, unsigned int eop, unsigned int peek, dive_callback_t callback, void *userdata)
|
||||
{
|
||||
assert (eop >= begin && eop < end);
|
||||
assert (data[eop] == 0x82);
|
||||
|
||||
unsigned char buffer[0x2000 - 0x4C] = {0};
|
||||
assert (sizeof (buffer) >= end - begin);
|
||||
|
||||
unsigned int current = eop;
|
||||
unsigned int previous = eop;
|
||||
for (unsigned int i = 0; i < end - begin; ++i) {
|
||||
// Move backwards through the ringbuffer.
|
||||
if (current == begin)
|
||||
current = end;
|
||||
current--;
|
||||
|
||||
// Check for an end of profile marker.
|
||||
if (data[current] == 0x82)
|
||||
break;
|
||||
|
||||
// Check for an end of dive marker (of the next dive),
|
||||
// to find the start of the current dive.
|
||||
unsigned int peek = SUBSTRACT (current, peek, begin, end);
|
||||
if (data[peek] == 0x80) {
|
||||
unsigned int len = DISTANCE (current, previous, begin, end);
|
||||
if (current + len > end) {
|
||||
unsigned int a = end - current;
|
||||
unsigned int b = (current + len) - end;
|
||||
memcpy (buffer + 0, data + current, a);
|
||||
memcpy (buffer + a, data + begin, b);
|
||||
} else {
|
||||
memcpy (buffer, data + current, len);
|
||||
}
|
||||
|
||||
if (callback)
|
||||
callback (buffer, len, userdata);
|
||||
|
||||
previous = current;
|
||||
}
|
||||
}
|
||||
|
||||
assert (data[current] == 0x82);
|
||||
|
||||
return SUUNTO_SUCCESS;
|
||||
}
|
||||
15
suunto_common.h
Normal file
15
suunto_common.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef SUUNTO_COMMON_H
|
||||
#define SUUNTO_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "suunto.h"
|
||||
|
||||
int suunto_common_extract_dives (const unsigned char data[], unsigned int begin, unsigned int end, unsigned int eop, unsigned int peek, dive_callback_t callback, void *userdata);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* SUUNTO_COMMON_H */
|
||||
20
suunto_eon.c
20
suunto_eon.c
@ -1,7 +1,9 @@
|
||||
#include <string.h> // memcmp, memcpy
|
||||
#include <stdlib.h> // malloc, free
|
||||
#include <assert.h> // assert
|
||||
|
||||
#include "suunto.h"
|
||||
#include "suunto_common.h"
|
||||
#include "serial.h"
|
||||
#include "utils.h"
|
||||
|
||||
@ -184,3 +186,21 @@ suunto_eon_write_interval (eon *device, unsigned char interval)
|
||||
|
||||
return SUUNTO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
suunto_eon_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata)
|
||||
{
|
||||
assert (size >= SUUNTO_EON_MEMORY_SIZE);
|
||||
|
||||
// Search the end-of-profile marker.
|
||||
unsigned int eop = 0x100;
|
||||
while (eop < SUUNTO_EON_MEMORY_SIZE) {
|
||||
if (data[eop] == 0x82) {
|
||||
break;
|
||||
}
|
||||
eop++;
|
||||
}
|
||||
|
||||
return suunto_common_extract_dives (data, 0x100, SUUNTO_EON_MEMORY_SIZE, eop, 3, callback, userdata);
|
||||
}
|
||||
|
||||
@ -19,6 +19,8 @@ int suunto_eon_write_name (eon *device, unsigned char data[], unsigned int size)
|
||||
|
||||
int suunto_eon_write_interval (eon *device, unsigned char interval);
|
||||
|
||||
int suunto_eon_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <assert.h> // assert
|
||||
|
||||
#include "suunto.h"
|
||||
#include "suunto_common.h"
|
||||
#include "serial.h"
|
||||
#include "utils.h"
|
||||
|
||||
@ -533,3 +534,25 @@ suunto_vyper_read_dives (vyper *device, dive_callback_t callback, void *userdata
|
||||
|
||||
return SUUNTO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
suunto_vyper_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata)
|
||||
{
|
||||
assert (size >= SUUNTO_VYPER_MEMORY_SIZE);
|
||||
|
||||
unsigned int eop = (data[0x51] << 8) + data[0x52];
|
||||
|
||||
return suunto_common_extract_dives (data, 0x71, SUUNTO_VYPER_MEMORY_SIZE, eop, 5, callback, userdata);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
suunto_spyder_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata)
|
||||
{
|
||||
assert (size >= SUUNTO_VYPER_MEMORY_SIZE);
|
||||
|
||||
unsigned int eop = (data[0x1C] << 8) + data[0x1D];
|
||||
|
||||
return suunto_common_extract_dives (data, 0x4C, SUUNTO_VYPER_MEMORY_SIZE, eop, 3, callback, userdata);
|
||||
}
|
||||
|
||||
@ -26,6 +26,10 @@ int suunto_vyper_write_memory (vyper *device, unsigned int address, const unsign
|
||||
|
||||
int suunto_vyper_read_dives (vyper *device, dive_callback_t callback, void *userdata);
|
||||
|
||||
int suunto_vyper_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);
|
||||
|
||||
int suunto_spyder_extract_dives (const unsigned char data[], unsigned int size, dive_callback_t callback, void *userdata);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user