Read and cache the hardware descriptor.

By reading the hardware descriptor immediately after entering download
or service mode, we can identify the specific model and adapt to minor
differences in the communication protocol.
This commit is contained in:
Jef Driesen 2016-01-23 08:23:26 +01:00 committed by Dirk Hohndel
parent 6bb60bba31
commit 2e0db552ad

View File

@ -78,6 +78,8 @@
#define INIT 0xBB #define INIT 0xBB
#define EXIT 0xFF #define EXIT 0xFF
#define INVALID 0xFFFFFFFF
#define UNKNOWN 0x00
#define OSTC3 0x0A #define OSTC3 0x0A
#define SPORT 0x12 #define SPORT 0x12
#define CR 0x05 #define CR 0x05
@ -92,6 +94,7 @@ typedef enum hw_ostc3_state_t {
typedef struct hw_ostc3_device_t { typedef struct hw_ostc3_device_t {
dc_device_t base; dc_device_t base;
dc_serial_t *serial; dc_serial_t *serial;
unsigned int hardware;
unsigned char fingerprint[5]; unsigned char fingerprint[5];
hw_ostc3_state_t state; hw_ostc3_state_t state;
} hw_ostc3_device_t; } hw_ostc3_device_t;
@ -292,6 +295,7 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name
// Set the default values. // Set the default values.
device->serial = NULL; device->serial = NULL;
device->hardware = INVALID;
memset (device->fingerprint, 0, sizeof (device->fingerprint)); memset (device->fingerprint, 0, sizeof (device->fingerprint));
// Open the device. // Open the device.
@ -456,6 +460,7 @@ static dc_status_t
hw_ostc3_device_init (hw_ostc3_device_t *device, hw_ostc3_state_t state) hw_ostc3_device_init (hw_ostc3_device_t *device, hw_ostc3_state_t state)
{ {
dc_status_t rc = DC_STATUS_SUCCESS; dc_status_t rc = DC_STATUS_SUCCESS;
dc_device_t *abstract = (dc_device_t *) device;
if (device->state == state) { if (device->state == state) {
// No change. // No change.
@ -479,7 +484,24 @@ hw_ostc3_device_init (hw_ostc3_device_t *device, hw_ostc3_state_t state)
rc = DC_STATUS_INVALIDARGS; rc = DC_STATUS_INVALIDARGS;
} }
return rc; if (rc != DC_STATUS_SUCCESS)
return rc;
if (device->hardware != INVALID)
return DC_STATUS_SUCCESS;
// Read the hardware descriptor.
unsigned char hardware[SZ_HARDWARE] = {UNKNOWN};
rc = hw_ostc3_transfer (device, NULL, HARDWARE, NULL, 0, hardware, sizeof(hardware));
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
ERROR (abstract->context, "Failed to read the hardware descriptor.");
return rc;
}
// Cache the descriptor.
device->hardware = hardware[0];
return DC_STATUS_SUCCESS;
} }
@ -596,20 +618,13 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi
return rc; 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. // Emit a device info event.
dc_event_devinfo_t devinfo; dc_event_devinfo_t devinfo;
devinfo.firmware = array_uint16_be (id + 2); devinfo.firmware = array_uint16_be (id + 2);
devinfo.serial = array_uint16_le (id + 0); devinfo.serial = array_uint16_le (id + 0);
devinfo.model = hardware[0]; if (device->hardware != UNKNOWN) {
if (devinfo.model == 0) { devinfo.model = device->hardware;
} else {
// Fallback to the serial number. // Fallback to the serial number.
if (devinfo.serial > 10000) if (devinfo.serial > 10000)
devinfo.model = SPORT; devinfo.model = SPORT;