diff --git a/include/libdivecomputer/hw_ostc3.h b/include/libdivecomputer/hw_ostc3.h index 454d45c..8463cb2 100644 --- a/include/libdivecomputer/hw_ostc3.h +++ b/include/libdivecomputer/hw_ostc3.h @@ -39,6 +39,9 @@ extern "C" { dc_status_t hw_ostc3_device_open (dc_device_t **device, dc_context_t *context, const char *name); +dc_status_t +hw_ostc3_device_custom_open (dc_device_t **device, dc_context_t *context, dc_serial_t *serial); + dc_status_t hw_ostc3_device_version (dc_device_t *device, unsigned char data[], unsigned int size); diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index adf2ded..eebda24 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -295,10 +295,10 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name // Open the device. int rc = dc_serial_native_open (&device->serial, context, name); - if (rc == -1) { + if (rc != DC_STATUS_SUCCESS) { ERROR (context, "Failed to open the serial port."); free (device); - return DC_STATUS_IO; + return rc; } // Set the serial communication protocol (115200 8N1). @@ -330,6 +330,59 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name } +dc_status_t +hw_ostc3_device_custom_open (dc_device_t **out, dc_context_t *context, dc_serial_t *serial) +{ + if (out == NULL || serial == NULL || serial->port == NULL) + return DC_STATUS_INVALIDARGS; + + // Allocate memory. + hw_ostc3_device_t *device = (hw_ostc3_device_t *) malloc (sizeof (hw_ostc3_device_t)); + if (device == NULL) { + ERROR (context, "Failed to allocate memory."); + return DC_STATUS_NOMEMORY; + } + + // Initialize the base class. + device_init (&device->base, context, &hw_ostc3_device_vtable); + + // Set the default values. + memset (device->fingerprint, 0, sizeof (device->fingerprint)); + + // Set the serial reference + device->serial = serial; + + if (serial->type == DC_TRANSPORT_SERIAL) { + // Set the serial communication protocol (115200 8N1). + int rc = serial_configure (device->serial->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE); + if (rc == -1) { + ERROR (context, "Failed to set the terminal attributes."); + device->serial->ops->close (device->serial->port); + free (device); + return DC_STATUS_IO; + } + } + + // Set the timeout for receiving data (3000ms). + if (serial_set_timeout (device->serial->port, 3000) == -1) { + ERROR (context, "Failed to set the timeout."); + device->serial->ops->close (device->serial->port); + free (device); + return DC_STATUS_IO; + } + + // Make sure everything is in a sane state. + serial_sleep (device->serial->port, 300); + device->serial->ops->flush (device->serial->port, SERIAL_QUEUE_BOTH); + + device->state = OPEN; + + *out = (dc_device_t *) device; + + return DC_STATUS_SUCCESS; +} + + static dc_status_t hw_ostc3_device_init_download (hw_ostc3_device_t *device) {