예제 #1
0
dc_status_t
shearwater_common_open (shearwater_common_device_t *device, dc_context_t *context, const char *name)
{
	// Open the device.
	int rc = serial_open (&device->port, context, name);
	if (rc == -1) {
		ERROR (context, "Failed to open the serial port.");
		return DC_STATUS_IO;
	}

	// Set the serial communication protocol (115200 8N1).
	rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		ERROR (context, "Failed to set the terminal attributes.");
		serial_close (device->port);
		return DC_STATUS_IO;
	}

	// Set the timeout for receiving data (3000ms).
	if (serial_set_timeout (device->port, 3000) == -1) {
		ERROR (context, "Failed to set the timeout.");
		serial_close (device->port);
		return DC_STATUS_IO;
	}

	// Make sure everything is in a sane state.
	serial_sleep (device->port, 300);
	serial_flush (device->port, SERIAL_QUEUE_BOTH);

	return DC_STATUS_SUCCESS;
}
예제 #2
0
dc_status_t
shearwater_common_custom_open (shearwater_common_device_t *device, dc_context_t *context, dc_serial_t *serial)
{
	// 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);
			return DC_STATUS_IO;
		}
	}

	// Set the timeout for receiving data (3000ms).
	if (device->serial->ops->set_timeout (device->serial->port, 3000) == -1) {
		ERROR (context, "Failed to set the timeout.");
		device->serial->ops->close (device->serial->port);
		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);

	return DC_STATUS_SUCCESS;
}
예제 #3
0
dc_status_t
hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{
	if (out == NULL)
		return DC_STATUS_INVALIDARGS;

	// Allocate memory.
	hw_ostc_device_t *device = (hw_ostc_device_t *) malloc (sizeof (hw_ostc_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_ostc_device_vtable);

	// Set the default values.
	device->port = NULL;
	memset (device->fingerprint, 0, sizeof (device->fingerprint));

	// Open the device.
	int rc = serial_open (&device->port, context, name);
	if (rc == -1) {
		ERROR (context, "Failed to open the serial port.");
		free (device);
		return DC_STATUS_IO;
	}

	// Set the serial communication protocol (115200 8N1).
	rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		ERROR (context, "Failed to set the terminal attributes.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Set the timeout for receiving data.
	if (serial_set_timeout (device->port, 4000) == -1) {
		ERROR (context, "Failed to set the timeout.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Make sure everything is in a sane state.
	serial_sleep (device->port, 100);
	serial_flush (device->port, SERIAL_QUEUE_BOTH);

	*out = (dc_device_t*) device;

	return DC_STATUS_SUCCESS;
}
예제 #4
0
static dc_status_t
reefnet_sensus_handshake (reefnet_sensus_device_t *device)
{
	dc_device_t *abstract = (dc_device_t *) device;

	// Send the command to the device.
	unsigned char command = 0x0A;
	int n = serial_write (device->port, &command, 1);
	if (n != 1) {
		ERROR (abstract->context, "Failed to send the command.");
		return EXITCODE (n);
	}

	// Receive the answer from the device.
	unsigned char handshake[SZ_HANDSHAKE + 2] = {0};
	n = serial_read (device->port, handshake, sizeof (handshake));
	if (n != sizeof (handshake)) {
		ERROR (abstract->context, "Failed to receive the handshake.");
		return EXITCODE (n);
	}

	// Verify the header of the packet.
	if (handshake[0] != 'O' || handshake[1] != 'K') {
		ERROR (abstract->context, "Unexpected answer header.");
		return DC_STATUS_PROTOCOL;
	}

	// The device is now waiting for a data request.
	device->waiting = 1;

	// Store the clock calibration values.
	device->systime = dc_datetime_now ();
	device->devtime = array_uint32_le (handshake + 8);

	// Store the handshake packet.
	memcpy (device->handshake, handshake + 2, SZ_HANDSHAKE);

	// Emit a clock event.
	dc_event_clock_t clock;
	clock.systime = device->systime;
	clock.devtime = device->devtime;
	device_event_emit (&device->base, DC_EVENT_CLOCK, &clock);

	// Emit a device info event.
	dc_event_devinfo_t devinfo;
	devinfo.model = handshake[2] - '0';
	devinfo.firmware = handshake[3] - '0';
	devinfo.serial = array_uint16_le (handshake + 6);
	device_event_emit (&device->base, DC_EVENT_DEVINFO, &devinfo);

	// Emit a vendor event.
	dc_event_vendor_t vendor;
	vendor.data = device->handshake;
	vendor.size = sizeof (device->handshake);
	device_event_emit (abstract, DC_EVENT_VENDOR, &vendor);

	// Wait at least 10 ms to ensures the data line is
	// clear before transmission from the host begins.

	serial_sleep (device->port, 10);

	return DC_STATUS_SUCCESS;
}
예제 #5
0
device_status_t
suunto_d9_device_open (device_t **out, const char* name)
{
	if (out == NULL)
		return DEVICE_STATUS_ERROR;

	// Allocate memory.
	suunto_d9_device_t *device = (suunto_d9_device_t *) malloc (sizeof (suunto_d9_device_t));
	if (device == NULL) {
		WARNING ("Failed to allocate memory.");
		return DEVICE_STATUS_MEMORY;
	}

	// Initialize the base class.
	suunto_common2_device_init (&device->base, &suunto_d9_device_backend);

	// Set the default values.
	device->port = NULL;

	// Open the device.
	int rc = serial_open (&device->port, name);
	if (rc == -1) {
		WARNING ("Failed to open the serial port.");
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Set the serial communication protocol (9600 8N1).
	rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		WARNING ("Failed to set the terminal attributes.");
		serial_close (device->port);
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Set the timeout for receiving data (3000 ms).
	if (serial_set_timeout (device->port, 3000) == -1) {
		WARNING ("Failed to set the timeout.");
		serial_close (device->port);
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Set the DTR line (power supply for the interface).
	if (serial_set_dtr (device->port, 1) == -1) {
		WARNING ("Failed to set the DTR line.");
		serial_close (device->port);
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Give the interface 100 ms to settle and draw power up.
	serial_sleep (100);

	// Make sure everything is in a sane state.
	serial_flush (device->port, SERIAL_QUEUE_BOTH);

	*out = (device_t*) device;

	return DEVICE_STATUS_SUCCESS;
}
예제 #6
0
dc_status_t
oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{
	if (out == NULL)
		return DC_STATUS_INVALIDARGS;

	// Allocate memory.
	oceanic_vtpro_device_t *device = (oceanic_vtpro_device_t *) malloc (sizeof (oceanic_vtpro_device_t));
	if (device == NULL) {
		ERROR (context, "Failed to allocate memory.");
		return DC_STATUS_NOMEMORY;
	}

	// Initialize the base class.
	oceanic_common_device_init (&device->base, context, &oceanic_vtpro_device_vtable);

	// Override the base class values.
	device->base.multipage = MULTIPAGE;

	// Set the default values.
	device->port = NULL;

	// Open the device.
	int rc = serial_open (&device->port, context, name);
	if (rc == -1) {
		ERROR (context, "Failed to open the serial port.");
		free (device);
		return DC_STATUS_IO;
	}

	// Set the serial communication protocol (9600 8N1).
	rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		ERROR (context, "Failed to set the terminal attributes.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Set the timeout for receiving data (3000 ms).
	if (serial_set_timeout (device->port, 3000) == -1) {
		ERROR (context, "Failed to set the timeout.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Set the DTR and RTS lines.
	if (serial_set_dtr (device->port, 1) == -1 ||
		serial_set_rts (device->port, 1) == -1) {
		ERROR (context, "Failed to set the DTR/RTS line.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Give the interface 100 ms to settle and draw power up.
	serial_sleep (device->port, 100);

	// Make sure everything is in a sane state.
	serial_flush (device->port, SERIAL_QUEUE_BOTH);

	// Initialize the data cable (MOD mode).
	dc_status_t status = oceanic_vtpro_init (device);
	if (status != DC_STATUS_SUCCESS) {
		serial_close (device->port);
		free (device);
		return status;
	}

	// Switch the device from surface mode into download mode. Before sending
	// this command, the device needs to be in PC mode (manually activated by
	// the user), or already in download mode.
	status = oceanic_vtpro_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version));
	if (status != DC_STATUS_SUCCESS) {
		serial_close (device->port);
		free (device);
		return status;
	}

	// Calibrate the device. Although calibration is optional, it's highly
	// recommended because it reduces the transfer time considerably, even
	// when processing the command itself is quite slow.
	status = oceanic_vtpro_calibrate (device);
	if (status != DC_STATUS_SUCCESS) {
		serial_close (device->port);
		free (device);
		return status;
	}

	// Override the base class values.
	if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_wisdom_version)) {
		device->base.layout = &oceanic_wisdom_layout;
	} else {
		device->base.layout = &oceanic_vtpro_layout;
	}

	*out = (dc_device_t*) device;

	return DC_STATUS_SUCCESS;
}