From 3b264d9cfd41324262f296f2d537aaeb4855609e Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 3 Mar 2015 19:20:36 +0100 Subject: [PATCH] Add support for the new hardware descriptor. The latest firmware v1.75 introduced a new hardware descriptor byte to identify the different models based on their hardware features. This new hardware descriptor is now used as the libdivecomputer model number. For older firmware versions, which do not support the descriptor yet, there is an automatic fallback to the previous method based on the serial number. --- include/libdivecomputer/hw_ostc3.h | 3 ++ src/descriptor.c | 6 ++-- src/hw_ostc3.c | 50 +++++++++++++++++++++++++++--- src/libdivecomputer.symbols | 1 + 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/include/libdivecomputer/hw_ostc3.h b/include/libdivecomputer/hw_ostc3.h index bc56a9d..c60dc63 100644 --- a/include/libdivecomputer/hw_ostc3.h +++ b/include/libdivecomputer/hw_ostc3.h @@ -40,6 +40,9 @@ hw_ostc3_device_open (dc_device_t **device, dc_context_t *context, const char *n dc_status_t hw_ostc3_device_version (dc_device_t *device, unsigned char data[], unsigned int size); +dc_status_t +hw_ostc3_device_hardware (dc_device_t *device, unsigned char data[], unsigned int size); + dc_status_t hw_ostc3_device_clock (dc_device_t *device, const dc_datetime_t *datetime); diff --git a/src/descriptor.c b/src/descriptor.c index c474e35..cf989e2 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -210,9 +210,9 @@ static const dc_descriptor_t g_descriptors[] = { {"Heinrichs Weikamp", "OSTC 2N", DC_FAMILY_HW_OSTC, 2}, {"Heinrichs Weikamp", "OSTC 2C", DC_FAMILY_HW_OSTC, 3}, {"Heinrichs Weikamp", "Frog", DC_FAMILY_HW_FROG, 0}, - {"Heinrichs Weikamp", "OSTC 3", DC_FAMILY_HW_OSTC3, 0}, - {"Heinrichs Weikamp", "OSTC cR", DC_FAMILY_HW_OSTC3, 0}, - {"Heinrichs Weikamp", "OSTC Sport", DC_FAMILY_HW_OSTC3, 1}, + {"Heinrichs Weikamp", "OSTC 3", DC_FAMILY_HW_OSTC3, 0x0A}, + {"Heinrichs Weikamp", "OSTC cR", DC_FAMILY_HW_OSTC3, 0x05}, + {"Heinrichs Weikamp", "OSTC Sport", DC_FAMILY_HW_OSTC3, 0x12}, /* Cressi Edy */ {"Cressi", "Edy", DC_FAMILY_CRESSI_EDY, 0}, /* Cressi Leonardo */ diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index f280eaf..a5f96bf 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -46,6 +46,7 @@ #define SZ_DISPLAY 16 #define SZ_CUSTOMTEXT 60 #define SZ_VERSION (SZ_CUSTOMTEXT + 4) +#define SZ_HARDWARE 1 #define SZ_MEMORY 0x200000 #define SZ_CONFIG 4 #define SZ_FIRMWARE 0x01E000 // 120KB @@ -66,6 +67,7 @@ #define CUSTOMTEXT 0x63 #define DIVE 0x66 #define IDENTITY 0x69 +#define HARDWARE 0x6A #define DISPLAY 0x6E #define READ 0x72 #define WRITE 0x77 @@ -73,6 +75,10 @@ #define INIT 0xBB #define EXIT 0xFF +#define OSTC3 0x0A +#define SPORT 0x12 +#define CR 0x05 + typedef enum hw_ostc3_state_t { OPEN, DOWNLOAD, @@ -461,6 +467,30 @@ hw_ostc3_device_version (dc_device_t *abstract, unsigned char data[], unsigned i } +dc_status_t +hw_ostc3_device_hardware (dc_device_t *abstract, unsigned char data[], unsigned int size) +{ + hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract; + + if (!ISINSTANCE (abstract)) + return DC_STATUS_INVALIDARGS; + + if (size != SZ_HARDWARE) + return DC_STATUS_INVALIDARGS; + + dc_status_t rc = hw_ostc3_device_init (device, DOWNLOAD); + if (rc != DC_STATUS_SUCCESS) + return rc; + + // Send the command. + rc = hw_ostc3_transfer (device, NULL, HARDWARE, NULL, 0, data, size); + if (rc != DC_STATUS_SUCCESS) + return rc; + + return DC_STATUS_SUCCESS; +} + + static dc_status_t hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata) { @@ -483,14 +513,26 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi return rc; } + // Download the hardware descriptor. + unsigned char hardware[SZ_HARDWARE] = {0}; + rc = hw_ostc3_device_hardware (abstract, hardware, sizeof (hardware)); + if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) { + ERROR (abstract->context, "Failed to read the hardware descriptor."); + return rc; + } + // Emit a device info event. dc_event_devinfo_t devinfo; devinfo.firmware = array_uint16_be (id + 2); devinfo.serial = array_uint16_le (id + 0); - if (devinfo.serial > 10000) - devinfo.model = 1; // OSTC Sport - else - devinfo.model = 0; // OSTC3 + devinfo.model = hardware[0]; + if (devinfo.model == 0) { + // Fallback to the serial number. + if (devinfo.serial > 10000) + devinfo.model = SPORT; + else + devinfo.model = OSTC3; + } device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo); // Allocate memory. diff --git a/src/libdivecomputer.symbols b/src/libdivecomputer.symbols index f27f6fd..732bb85 100644 --- a/src/libdivecomputer.symbols +++ b/src/libdivecomputer.symbols @@ -155,6 +155,7 @@ hw_frog_device_display hw_frog_device_customtext hw_ostc3_device_open hw_ostc3_device_version +hw_ostc3_device_hardware hw_ostc3_device_clock hw_ostc3_device_display hw_ostc3_device_customtext