summaryrefslogtreecommitdiffstats
path: root/plugins/xkit/uca-xkit-camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/xkit/uca-xkit-camera.c')
-rw-r--r--plugins/xkit/uca-xkit-camera.c665
1 files changed, 665 insertions, 0 deletions
diff --git a/plugins/xkit/uca-xkit-camera.c b/plugins/xkit/uca-xkit-camera.c
new file mode 100644
index 0000000..2386dff
--- /dev/null
+++ b/plugins/xkit/uca-xkit-camera.c
@@ -0,0 +1,665 @@
+/* Copyright (C) 2011-2013 Matthias Vogelgesang <matthias.vogelgesang@kit.edu>
+ (Karlsruhe Institute of Technology)
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License along
+ with this library; if not, write to the Free Software Foundation, Inc., 51
+ Franklin St, Fifth Floor, Boston, MA 02110, USA */
+
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <gmodule.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "uca-camera.h"
+#include "uca-xkit-camera.h"
+
+
+#define UCA_XKIT_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_XKIT_CAMERA, UcaXkitCameraPrivate))
+
+#define XKIT_DEFAULT_IP "192.168.1.115"
+#define XKIT_DEFAULT_PORT 5002
+#define XKIT_MESSAGE_SIZE 512
+
+#define MEDIPIX_SENSOR_SIZE 256
+#define CHIPS_PER_ROW 3
+#define CHIPS_PER_COLUMN 1
+#define NUM_CHIPS CHIPS_PER_ROW * CHIPS_PER_COLUMN
+#define NUM_FSRS 256
+
+static void uca_xkit_camera_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaXkitCamera, uca_xkit_camera, UCA_TYPE_CAMERA,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ uca_xkit_camera_initable_iface_init))
+
+GQuark uca_xkit_camera_error_quark()
+{
+ return g_quark_from_static_string("uca-xkit-camera-error-quark");
+}
+
+enum {
+ PROP_NUM_CHIPS = N_BASE_PROPERTIES,
+ PROP_ADDR,
+ PROP_PORT_CHIP_0,
+ PROP_PORT_CHIP_1,
+ PROP_PORT_CHIP_2,
+ PROP_FLIP_CHIP_0,
+ PROP_FLIP_CHIP_1,
+ PROP_FLIP_CHIP_2,
+ /* PROP_FLIP_CHIP_3, */
+ /* PROP_FLIP_CHIP_4, */
+ /* PROP_FLIP_CHIP_5, */
+ PROP_READOUT_BIG_ENDIAN,
+ PROP_READOUT_MIRRORED,
+ PROP_READOUT_INCREMENTAL_GREYSCALE,
+ N_PROPERTIES
+};
+
+static gint base_overrideables[] = {
+ PROP_NAME,
+ PROP_SENSOR_WIDTH,
+ PROP_SENSOR_HEIGHT,
+ PROP_SENSOR_MAX_FRAME_RATE,
+ PROP_SENSOR_BITDEPTH,
+ PROP_EXPOSURE_TIME,
+ PROP_ROI_X,
+ PROP_ROI_Y,
+ PROP_ROI_WIDTH,
+ PROP_ROI_HEIGHT,
+ PROP_HAS_STREAMING,
+ PROP_HAS_CAMRAM_RECORDING,
+ 0,
+};
+
+static GParamSpec *xkit_properties[N_PROPERTIES] = { NULL, };
+
+enum {
+ X_KIT_ACQUIRE_NORMAL = 0x0,
+ X_KIT_ACQUIRE_CONTINUOUS = 0x1,
+ X_KIT_ACQUIRE_TRIGGERED = 0x2,
+ X_KIT_ACQUIRE_CONTINUOUS_TRIGGERED = 0x3,
+};
+
+enum {
+ X_KIT_READOUT_DEFAULT = 0,
+ X_KIT_READOUT_BIG_ENDIAN = 1 << 2,
+ X_KIT_READOUT_MIRRORED = 1 << 3,
+ X_KIT_READOUT_INCREMENTAL_GREYSCALE = 1 << 4,
+};
+
+struct _UcaXkitCameraPrivate {
+ GError *construct_error;
+ gsize n_chips;
+ gsize n_max_chips;
+ guint16 **buffers;
+ gboolean flip[NUM_CHIPS];
+
+ gchar *addr;
+ guint ports[NUM_CHIPS];
+ GSocket* sockets[NUM_CHIPS];
+
+ guint8 readout_mode;
+ guint8 acquisition_mode;
+
+ gdouble exposure_time;
+ guint acq_time_cycles;
+};
+
+static gboolean
+xkit_send_recv_ackd (GSocket *socket, gchar *buffer, gsize size, GError **error)
+{
+ gchar ack;
+
+ g_socket_send (socket, buffer, size, NULL, error);
+ g_socket_receive (socket, &ack, 1, NULL, error);
+ return ack == 0x21;
+}
+
+static void
+xkit_recv_chunked (GSocket *socket, gchar *buffer, gsize size, GError **error)
+{
+ gsize total_read = 0;
+
+ while (total_read < size) {
+ gssize read;
+
+ read = g_socket_receive_with_blocking (socket, buffer + total_read, size - total_read,
+ FALSE, NULL, NULL);
+
+ if (read > 0)
+ total_read += read;
+ }
+}
+
+static gboolean
+xkit_reset (GSocket *socket, GError **error)
+{
+ gchar buffer = 0x32;
+ return xkit_send_recv_ackd (socket, &buffer, 1, error);
+}
+
+static gboolean
+xkit_set_exposure_time (GSocket *socket, guint32 exposure_time, GError **error)
+{
+ struct {
+ guint8 msg;
+ guint32 time;
+ } __attribute__((packed))
+ buffer = {
+ .msg = 0x38,
+ .time = exposure_time
+ };
+
+ return xkit_send_recv_ackd (socket, (gchar *) &buffer, sizeof (buffer), error);
+}
+
+static gboolean
+xkit_start_acquisition (GSocket *socket, guint8 acquisition_mode, GError **error)
+{
+ gchar msg[] = { 0x34, 0x00, acquisition_mode };
+ return xkit_send_recv_ackd (socket, msg, 3, error);
+}
+
+static gboolean
+xkit_serial_matrix_readout (GSocket *socket, gchar *data, guint8 acquisition_mode, GError **error)
+{
+ gchar msg[] = { 0x35, acquisition_mode };
+ gchar ack;
+
+ g_socket_send (socket, msg, 2, NULL, error);
+ xkit_recv_chunked (socket, data, MEDIPIX_SENSOR_SIZE * MEDIPIX_SENSOR_SIZE * 2, error);
+ g_socket_receive (socket, &ack, 1, NULL, error);
+ return ack == 0x21;
+}
+
+static gboolean
+connect_xkit (UcaXkitCameraPrivate *priv)
+{
+ GInetAddress *local_addr;
+
+ local_addr = g_inet_address_new_from_string (priv->addr);
+
+ for (guint i = 0; i < NUM_CHIPS; i++) {
+ GSocketAddress *socket_addr;
+
+ socket_addr = g_inet_socket_address_new (local_addr, priv->ports[i]);
+
+ priv->sockets[i] = g_socket_new (G_SOCKET_FAMILY_IPV4,
+ G_SOCKET_TYPE_DATAGRAM,
+ G_SOCKET_PROTOCOL_UDP,
+ &priv->construct_error);
+
+ if (priv->sockets[i] == NULL)
+ return FALSE;
+
+ if (!g_socket_connect (priv->sockets[i], socket_addr, NULL, &priv->construct_error))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+setup_xkit (UcaXkitCameraPrivate *priv)
+{
+ priv->n_max_chips = priv->n_chips = NUM_CHIPS;
+ priv->buffers = g_new0 (guint16 *, priv->n_max_chips);
+
+ for (guint i = 0; i < priv->n_max_chips; i++)
+ priv->buffers[i] = (guint16 *) g_malloc0 (MEDIPIX_SENSOR_SIZE * MEDIPIX_SENSOR_SIZE * sizeof(guint16));
+
+ return connect_xkit (priv);
+}
+
+static void
+compose_image (guint16 *output, guint16 **buffers, gboolean *flip, gsize n)
+{
+ gsize dst_stride;
+ gsize cx = 0;
+ gsize cy = 0;
+
+ dst_stride = CHIPS_PER_ROW * MEDIPIX_SENSOR_SIZE;
+
+ for (gsize i = 0; i < n; i++) {
+ guint16 *dst;
+ guint16 *src;
+ gsize src_stride;
+
+ if (cx == CHIPS_PER_ROW) {
+ cx = 0;
+ cy++;
+ }
+
+ if (flip[i]) {
+ src = buffers[i] + MEDIPIX_SENSOR_SIZE * MEDIPIX_SENSOR_SIZE;
+ src_stride = -MEDIPIX_SENSOR_SIZE;
+ }
+ else {
+ src = buffers[i];
+ src_stride = MEDIPIX_SENSOR_SIZE;
+ }
+
+ dst = output + (cy * MEDIPIX_SENSOR_SIZE * dst_stride + cx * MEDIPIX_SENSOR_SIZE);
+
+ for (gsize row = 0; row < 256; row++) {
+ memcpy (dst, src, MEDIPIX_SENSOR_SIZE * sizeof (guint16));
+ dst += dst_stride;
+ src += src_stride;
+ }
+
+ cx++;
+ }
+}
+
+static void
+uca_xkit_camera_start_recording (UcaCamera *camera,
+ GError **error)
+{
+ UcaXkitCameraPrivate *priv;
+ UcaCameraTrigger trigger_mode;
+
+ g_return_if_fail (UCA_IS_XKIT_CAMERA (camera));
+
+ priv = UCA_XKIT_CAMERA_GET_PRIVATE (camera);
+ g_object_get (camera, "trigger-mode", &trigger_mode, NULL);
+
+ if (trigger_mode == UCA_CAMERA_TRIGGER_AUTO)
+ priv->acquisition_mode = X_KIT_ACQUIRE_NORMAL;
+ else if (trigger_mode == UCA_CAMERA_TRIGGER_SOFTWARE)
+ priv->acquisition_mode = X_KIT_ACQUIRE_NORMAL;
+ else if (trigger_mode == UCA_CAMERA_TRIGGER_EXTERNAL)
+ priv->acquisition_mode = X_KIT_ACQUIRE_TRIGGERED;
+
+ priv->acquisition_mode |= priv->readout_mode;
+
+ if (!xkit_reset (priv->sockets[0], error))
+ return;
+
+ if (!xkit_set_exposure_time (priv->sockets[0], 0x1000, error))
+ return;
+
+ xkit_start_acquisition (priv->sockets[0], priv->acquisition_mode, error);
+}
+
+static void
+uca_xkit_camera_stop_recording (UcaCamera *camera,
+ GError **error)
+{
+ g_return_if_fail (UCA_IS_XKIT_CAMERA (camera));
+}
+
+static void
+uca_xkit_camera_start_readout (UcaCamera *camera,
+ GError **error)
+{
+ g_return_if_fail( UCA_IS_XKIT_CAMERA (camera));
+}
+
+static void
+uca_xkit_camera_stop_readout (UcaCamera *camera,
+ GError **error)
+{
+ g_return_if_fail (UCA_IS_XKIT_CAMERA (camera));
+}
+
+static gboolean
+uca_xkit_camera_grab (UcaCamera *camera,
+ gpointer data,
+ GError **error)
+{
+ g_return_val_if_fail (UCA_IS_XKIT_CAMERA (camera), FALSE);
+ UcaXkitCameraPrivate *priv;
+ GTimer *timer;
+
+
+ priv = UCA_XKIT_CAMERA_GET_PRIVATE (camera);
+ timer = g_timer_new ();
+
+ #pragma omp parallel for num_threads(NUM_CHIPS)
+ for (guint i = 0; i < NUM_CHIPS; i++) {
+ GError *local_error = NULL;
+
+ xkit_serial_matrix_readout (priv->sockets[i],
+ (gchar *) priv->buffers[i],
+ priv->acquisition_mode,
+ &local_error);
+
+ if (local_error != NULL) {
+ g_error_free (local_error);
+ local_error = NULL;
+ }
+ }
+
+ compose_image ((guint16 *) data, priv->buffers, priv->flip, priv->n_chips);
+ g_timer_destroy (timer);
+
+ return TRUE;
+}
+
+static void
+uca_xkit_camera_trigger (UcaCamera *camera,
+ GError **error)
+{
+ g_return_if_fail (UCA_IS_XKIT_CAMERA (camera));
+}
+
+static void
+uca_xkit_camera_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ UcaXkitCameraPrivate *priv;
+
+ priv = UCA_XKIT_CAMERA_GET_PRIVATE (object);
+
+ switch (property_id) {
+ case PROP_EXPOSURE_TIME:
+ priv->exposure_time = g_value_get_double(value);
+ break;
+ case PROP_FLIP_CHIP_0:
+ case PROP_FLIP_CHIP_1:
+ case PROP_FLIP_CHIP_2:
+ /* case PROP_FLIP_CHIP_3: */
+ /* case PROP_FLIP_CHIP_4: */
+ /* case PROP_FLIP_CHIP_5: */
+ priv->flip[property_id - PROP_FLIP_CHIP_0] = g_value_get_boolean (value);
+ break;
+
+ case PROP_READOUT_BIG_ENDIAN:
+ if (g_value_get_boolean (value))
+ priv->readout_mode |= X_KIT_READOUT_BIG_ENDIAN;
+ else
+ priv->readout_mode &= ~X_KIT_READOUT_BIG_ENDIAN;
+ break;
+
+ case PROP_READOUT_MIRRORED:
+ if (g_value_get_boolean (value))
+ priv->readout_mode |= X_KIT_READOUT_MIRRORED;
+ else
+ priv->readout_mode &= ~X_KIT_READOUT_MIRRORED;
+ break;
+
+ case PROP_READOUT_INCREMENTAL_GREYSCALE:
+ if (g_value_get_boolean (value))
+ priv->readout_mode |= X_KIT_READOUT_INCREMENTAL_GREYSCALE;
+ else
+ priv->readout_mode &= ~X_KIT_READOUT_INCREMENTAL_GREYSCALE;
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ return;
+ }
+}
+
+static void
+uca_xkit_camera_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ UcaXkitCameraPrivate *priv;
+
+ priv = UCA_XKIT_CAMERA_GET_PRIVATE (object);
+
+ switch (property_id) {
+ case PROP_NAME:
+ g_value_set_string (value, "xkit");
+ break;
+ case PROP_SENSOR_MAX_FRAME_RATE:
+ g_value_set_float (value, 150.0f);
+ break;
+ case PROP_SENSOR_WIDTH:
+ g_value_set_uint (value, CHIPS_PER_ROW * MEDIPIX_SENSOR_SIZE);
+ break;
+ case PROP_SENSOR_HEIGHT:
+ g_value_set_uint (value, CHIPS_PER_COLUMN * MEDIPIX_SENSOR_SIZE);
+ break;
+ case PROP_SENSOR_BITDEPTH:
+ g_value_set_uint (value, 14);
+ break;
+ case PROP_EXPOSURE_TIME:
+ g_value_set_double (value, priv->exposure_time);
+ break;
+ case PROP_HAS_STREAMING:
+ g_value_set_boolean (value, TRUE);
+ break;
+ case PROP_HAS_CAMRAM_RECORDING:
+ g_value_set_boolean (value, FALSE);
+ break;
+ case PROP_ROI_X:
+ g_value_set_uint (value, 0);
+ break;
+ case PROP_ROI_Y:
+ g_value_set_uint (value, 0);
+ break;
+ case PROP_ROI_WIDTH:
+ g_value_set_uint (value, CHIPS_PER_ROW * MEDIPIX_SENSOR_SIZE);
+ break;
+ case PROP_ROI_HEIGHT:
+ g_value_set_uint (value, CHIPS_PER_COLUMN * MEDIPIX_SENSOR_SIZE);
+ break;
+ case PROP_NUM_CHIPS:
+ g_value_set_uint (value, priv->n_chips);
+ break;
+ case PROP_ADDR:
+ g_value_set_string (value, priv->addr);
+ break;
+ case PROP_FLIP_CHIP_0:
+ case PROP_FLIP_CHIP_1:
+ case PROP_FLIP_CHIP_2:
+ /* case PROP_FLIP_CHIP_3: */
+ /* case PROP_FLIP_CHIP_4: */
+ /* case PROP_FLIP_CHIP_5: */
+ g_value_set_boolean (value, priv->flip[property_id - PROP_FLIP_CHIP_0]);
+ break;
+ case PROP_PORT_CHIP_0:
+ case PROP_PORT_CHIP_1:
+ case PROP_PORT_CHIP_2:
+ /* case PROP_FLIP_CHIP_3: */
+ /* case PROP_FLIP_CHIP_4: */
+ /* case PROP_FLIP_CHIP_5: */
+ g_value_set_uint (value, priv->ports[property_id - PROP_PORT_CHIP_0]);
+ break;
+ case PROP_READOUT_BIG_ENDIAN:
+ g_value_set_boolean (value, priv->readout_mode & X_KIT_READOUT_BIG_ENDIAN);
+ break;
+ case PROP_READOUT_MIRRORED:
+ g_value_set_boolean (value, priv->readout_mode & X_KIT_READOUT_MIRRORED);
+ break;
+ case PROP_READOUT_INCREMENTAL_GREYSCALE:
+ g_value_set_boolean (value, priv->readout_mode & X_KIT_READOUT_INCREMENTAL_GREYSCALE);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+uca_xkit_camera_dispose (GObject *object)
+{
+ UcaXkitCameraPrivate *priv;
+
+ priv = UCA_XKIT_CAMERA_GET_PRIVATE (object);
+
+ for (guint i = 0; i < NUM_CHIPS; i++) {
+ if (priv->sockets[i] != NULL) {
+ g_object_unref (priv->sockets[i]);
+ priv->sockets[i] = NULL;
+ }
+ }
+
+ G_OBJECT_CLASS (uca_xkit_camera_parent_class)->dispose (object);
+}
+
+static void
+uca_xkit_camera_finalize (GObject *object)
+{
+ UcaXkitCameraPrivate *priv;
+
+ priv = UCA_XKIT_CAMERA_GET_PRIVATE (object);
+ g_clear_error (&priv->construct_error);
+
+ for (guint i = 0; i < priv->n_max_chips; i++)
+ g_free (priv->buffers[i]);
+
+ g_free (priv->buffers);
+ g_free (priv->addr);
+
+ G_OBJECT_CLASS (uca_xkit_camera_parent_class)->finalize (object);
+}
+
+static gboolean
+ufo_xkit_camera_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ UcaXkitCamera *camera;
+ UcaXkitCameraPrivate *priv;
+
+ g_return_val_if_fail (UCA_IS_XKIT_CAMERA (initable), FALSE);
+
+ if (cancellable != NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Cancellable initialization not supported");
+ return FALSE;
+ }
+
+ camera = UCA_XKIT_CAMERA (initable);
+ priv = camera->priv;
+
+ if (priv->construct_error != NULL) {
+ if (error)
+ *error = g_error_copy (priv->construct_error);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+uca_xkit_camera_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = ufo_xkit_camera_initable_init;
+}
+
+static void
+uca_xkit_camera_class_init (UcaXkitCameraClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+ UcaCameraClass *camera_class = UCA_CAMERA_CLASS (klass);
+
+ oclass->set_property = uca_xkit_camera_set_property;
+ oclass->get_property = uca_xkit_camera_get_property;
+ oclass->dispose = uca_xkit_camera_dispose;
+ oclass->finalize = uca_xkit_camera_finalize;
+
+ camera_class->start_recording = uca_xkit_camera_start_recording;
+ camera_class->stop_recording = uca_xkit_camera_stop_recording;
+ camera_class->start_readout = uca_xkit_camera_start_readout;
+ camera_class->stop_readout = uca_xkit_camera_stop_readout;
+ camera_class->grab = uca_xkit_camera_grab;
+ camera_class->trigger = uca_xkit_camera_trigger;
+
+ for (guint i = 0; base_overrideables[i] != 0; i++)
+ g_object_class_override_property (oclass, base_overrideables[i], uca_camera_props[base_overrideables[i]]);
+
+ xkit_properties[PROP_NUM_CHIPS] =
+ g_param_spec_uint("num-sensor-chips",
+ "Number of sensor chips",
+ "Number of sensor chips",
+ 1, 6, 6,
+ G_PARAM_READABLE);
+
+ xkit_properties[PROP_ADDR] =
+ g_param_spec_string ("address",
+ "Address of board",
+ "Address of board",
+ "192.168.1.115",
+ G_PARAM_READWRITE);
+
+ xkit_properties[PROP_READOUT_BIG_ENDIAN] =
+ g_param_spec_boolean("big-endian",
+ "Big Endian Readout",
+ "Big Endian Readout",
+ FALSE,
+ (GParamFlags) G_PARAM_READWRITE);
+
+ xkit_properties[PROP_READOUT_MIRRORED] =
+ g_param_spec_boolean("mirrored",
+ "Mirrored Readout",
+ "Mirrored Readout",
+ FALSE,
+ (GParamFlags) G_PARAM_READWRITE);
+
+ xkit_properties[PROP_READOUT_INCREMENTAL_GREYSCALE] =
+ g_param_spec_boolean("incremental-greyscale",
+ "Incremental Greyscale Readout",
+ "Incremental Greyscale Readout",
+ FALSE,
+ (GParamFlags) G_PARAM_READWRITE);
+
+ for (guint i = 0; i < NUM_CHIPS; i++) {
+ gchar *prop_name;
+
+ prop_name = g_strdup_printf ("flip-chip-%i", i);
+
+ xkit_properties[PROP_FLIP_CHIP_0 + i] =
+ g_param_spec_boolean (prop_name, "Flip chip", "Flip chip", FALSE, (GParamFlags) G_PARAM_READWRITE);
+
+ g_free (prop_name);
+
+ prop_name = g_strdup_printf ("port-chip-%i", i);
+
+ xkit_properties[PROP_PORT_CHIP_0 + i] =
+ g_param_spec_uint (prop_name, "Connection port", "Connection port", 0, 65535, 5002 + i, (GParamFlags) G_PARAM_READWRITE);
+
+ g_free (prop_name);
+ }
+
+ for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++)
+ g_object_class_install_property (oclass, id, xkit_properties[id]);
+
+ g_type_class_add_private (klass, sizeof(UcaXkitCameraPrivate));
+}
+
+static void
+uca_xkit_camera_init (UcaXkitCamera *self)
+{
+ UcaXkitCameraPrivate *priv;
+
+ self->priv = priv = UCA_XKIT_CAMERA_GET_PRIVATE (self);
+ priv->exposure_time = 0.5;
+ priv->addr = g_strdup (XKIT_DEFAULT_IP);
+ priv->construct_error = NULL;
+
+ for (guint i = 0; i < NUM_CHIPS; i++) {
+ priv->sockets[i] = NULL;
+ priv->flip[i] = FALSE;
+ priv->ports[i] = XKIT_DEFAULT_PORT + i;
+ }
+
+ if (!setup_xkit (priv))
+ return;
+}
+
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
+{
+ return UCA_TYPE_XKIT_CAMERA;
+}