diff --git a/examples/mares_iconhd_test.c b/examples/mares_iconhd_test.c index 61f0ea6..2a935b2 100644 --- a/examples/mares_iconhd_test.c +++ b/examples/mares_iconhd_test.c @@ -20,6 +20,7 @@ */ #include // fopen, fwrite, fclose +#include #include @@ -27,7 +28,7 @@ #include "common.h" dc_status_t -test_dump_memory (const char* name, const char* filename) +test_dump_memory (const char* name, const char* filename, unsigned int model) { dc_context_t *context = NULL; dc_device_t *device = NULL; @@ -37,7 +38,7 @@ test_dump_memory (const char* name, const char* filename) dc_context_set_logfunc (context, logfunc, NULL); message ("mares_iconhd_device_open\n"); - dc_status_t rc = mares_iconhd_device_open (&device, context, name); + dc_status_t rc = mares_iconhd_device_open (&device, context, name, model); if (rc != DC_STATUS_SUCCESS) { WARNING ("Error opening serial port."); dc_context_free (context); @@ -88,14 +89,20 @@ int main(int argc, char *argv[]) #else const char* name = "/dev/ttyS0"; #endif + unsigned int model = 0; if (argc > 1) { name = argv[1]; } - message ("DEVICE=%s\n", name); + if (argc > 2) { + model = strtoul (argv[2], NULL, 0); + } - dc_status_t a = test_dump_memory (name, "ICONHD.DMP"); + message ("DEVICE=%s\n", name); + message ("MODEL=0x%02x\n", model); + + dc_status_t a = test_dump_memory (name, "ICONHD.DMP", model); message ("\nSUMMARY\n"); message ("-------\n"); diff --git a/include/libdivecomputer/mares_iconhd.h b/include/libdivecomputer/mares_iconhd.h index 00c1224..38f82b3 100644 --- a/include/libdivecomputer/mares_iconhd.h +++ b/include/libdivecomputer/mares_iconhd.h @@ -31,7 +31,7 @@ extern "C" { #endif /* __cplusplus */ dc_status_t -mares_iconhd_device_open (dc_device_t **device, dc_context_t *context, const char *name); +mares_iconhd_device_open (dc_device_t **device, dc_context_t *context, const char *name, unsigned int model); dc_status_t mares_iconhd_extract_dives (dc_device_t *device, const unsigned char data[], unsigned int size, dc_dive_callback_t callback, void *userdata); diff --git a/src/descriptor.c b/src/descriptor.c index be089af..ee29372 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -149,6 +149,7 @@ static const dc_descriptor_t g_descriptors[] = { /* Mares Icon HD */ {"Mares", "Icon HD", DC_FAMILY_MARES_ICONHD , 0x14}, {"Mares", "Icon HD Net Ready", DC_FAMILY_MARES_ICONHD , 0x15}, + {"Mares", "Nemo Wide 2", DC_FAMILY_MARES_ICONHD , 0x19}, /* Heinrichs Weikamp */ {"Heinrichs Weikamp", "OSTC", DC_FAMILY_HW_OSTC, 0}, {"Heinrichs Weikamp", "OSTC Mk2", DC_FAMILY_HW_OSTC, 1}, diff --git a/src/device.c b/src/device.c index 3fde549..bb3d765 100644 --- a/src/device.c +++ b/src/device.c @@ -118,7 +118,7 @@ dc_device_open (dc_device_t **out, dc_context_t *context, dc_descriptor_t *descr rc = mares_darwin_device_open (&device, context, name, dc_descriptor_get_model (descriptor)); break; case DC_FAMILY_MARES_ICONHD: - rc = mares_iconhd_device_open (&device, context, name); + rc = mares_iconhd_device_open (&device, context, name, dc_descriptor_get_model (descriptor)); break; case DC_FAMILY_HW_OSTC: rc = hw_ostc_device_open (&device, context, name); diff --git a/src/mares_iconhd.c b/src/mares_iconhd.c index 9e8dd07..b03f7c6 100644 --- a/src/mares_iconhd.c +++ b/src/mares_iconhd.c @@ -42,11 +42,13 @@ #define ICONHD 0x14 #define ICONHDNET 0x15 +#define NEMOWIDE2 0x19 #define ACK 0xAA #define EOF 0xEA #define SZ_MEMORY 0x100000 +#define SZ_PACKET 0x000100 #define RB_PROFILE_BEGIN 0xA000 #define RB_PROFILE_END SZ_MEMORY @@ -56,6 +58,7 @@ typedef struct mares_iconhd_device_t { serial_t *port; unsigned char fingerprint[10]; unsigned char version[140]; + unsigned int packetsize; } mares_iconhd_device_t; static dc_status_t mares_iconhd_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size); @@ -104,17 +107,10 @@ static dc_status_t mares_iconhd_transfer (mares_iconhd_device_t *device, const unsigned char command[], unsigned int csize, unsigned char answer[], unsigned int asize, - unsigned int events) + dc_event_progress_t *progress) { dc_device_t *abstract = (dc_device_t *) device; - // Enable progress notifications. - dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; - if (events) { - progress.maximum = asize; - device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); - } - // Send the command to the dive computer. int n = serial_write (device->port, command, csize); if (n != csize) { @@ -158,9 +154,9 @@ mares_iconhd_transfer (mares_iconhd_device_t *device, } // Update and emit a progress event. - if (events) { - progress.current += len; - device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); + if (progress) { + progress->current += len; + device_event_emit (abstract, DC_EVENT_PROGRESS, progress); } nbytes += len; @@ -188,28 +184,46 @@ static dc_status_t mares_iconhd_version (mares_iconhd_device_t *device, unsigned char data[], unsigned int size) { unsigned char command[] = {0xC2, 0x67}; - return mares_iconhd_transfer (device, command, sizeof (command), data, size, 0); + return mares_iconhd_transfer (device, command, sizeof (command), data, size, NULL); } static dc_status_t -mares_iconhd_read (mares_iconhd_device_t *device, unsigned int address, unsigned char data[], unsigned int size, int events) +mares_iconhd_read (mares_iconhd_device_t *device, unsigned int address, unsigned char data[], unsigned int size, dc_event_progress_t *progress) { - unsigned char command[] = {0xE7, 0x42, - (address ) & 0xFF, - (address >> 8) & 0xFF, - (address >> 16) & 0xFF, - (address >> 24) & 0xFF, - (size ) & 0xFF, - (size >> 8) & 0xFF, - (size >> 16) & 0xFF, - (size >> 24) & 0xFF}; - return mares_iconhd_transfer (device, command, sizeof (command), data, size, events); + dc_status_t rc = DC_STATUS_SUCCESS; + + unsigned int nbytes = 0; + while (nbytes < size) { + // Calculate the packet size. + unsigned int len = size - nbytes; + if (device->packetsize && len > device->packetsize) + len = device->packetsize; + + // Read the packet. + unsigned char command[] = {0xE7, 0x42, + (address ) & 0xFF, + (address >> 8) & 0xFF, + (address >> 16) & 0xFF, + (address >> 24) & 0xFF, + (len ) & 0xFF, + (len >> 8) & 0xFF, + (len >> 16) & 0xFF, + (len >> 24) & 0xFF}; + rc = mares_iconhd_transfer (device, command, sizeof (command), data, len, progress); + if (rc != DC_STATUS_SUCCESS) + return rc; + + nbytes += len; + address += len; + data += len; + } + + return rc; } - dc_status_t -mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *name) +mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char *name, unsigned int model) { if (out == NULL) return DC_STATUS_INVALIDARGS; @@ -228,6 +242,11 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * device->port = NULL; memset (device->fingerprint, 0, sizeof (device->fingerprint)); memset (device->version, 0, sizeof (device->version)); + if (model == NEMOWIDE2) { + device->packetsize = SZ_PACKET; + } else { + device->packetsize = 0; + } // Open the device. int rc = serial_open (&device->port, context, name); @@ -238,7 +257,11 @@ mares_iconhd_device_open (dc_device_t **out, dc_context_t *context, const char * } // Set the serial communication protocol (256000 8N1). - rc = serial_configure (device->port, BAUDRATE, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); + if (model == NEMOWIDE2) { + rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_EVEN, 1, SERIAL_FLOWCONTROL_NONE); + } else { + rc = serial_configure (device->port, BAUDRATE, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); + } if (rc == -1) { ERROR (context, "Failed to set the terminal attributes."); serial_close (device->port); @@ -324,7 +347,7 @@ mares_iconhd_device_read (dc_device_t *abstract, unsigned int address, unsigned { mares_iconhd_device_t *device = (mares_iconhd_device_t *) abstract; - return mares_iconhd_read (device, address, data, size, 0); + return mares_iconhd_read (device, address, data, size, NULL); } @@ -340,8 +363,13 @@ mares_iconhd_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) return DC_STATUS_NOMEMORY; } + // Enable progress notifications. + dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; + progress.maximum = SZ_MEMORY; + device_event_emit (abstract, DC_EVENT_PROGRESS, &progress); + return mares_iconhd_read (device, 0, dc_buffer_get_data (buffer), - dc_buffer_get_size (buffer), 1); + dc_buffer_get_size (buffer), &progress); }