diff options
-rw-r--r-- | src/cameras/uca-mock-camera.c | 4 | ||||
-rw-r--r-- | src/cameras/uca-pco-camera.c | 56 | ||||
-rw-r--r-- | src/uca-camera.c | 61 | ||||
-rw-r--r-- | src/uca-camera.h | 11 |
4 files changed, 131 insertions, 1 deletions
diff --git a/src/cameras/uca-mock-camera.c b/src/cameras/uca-mock-camera.c index 1c2ea91..6f3344f 100644 --- a/src/cameras/uca-mock-camera.c +++ b/src/cameras/uca-mock-camera.c @@ -35,6 +35,7 @@ static const gint mock_overrideables[] = { PROP_SENSOR_HORIZONTAL_BINNINGS, PROP_SENSOR_VERTICAL_BINNING, PROP_SENSOR_VERTICAL_BINNINGS, + PROP_TRIGGER_MODE, PROP_EXPOSURE_TIME, PROP_ROI_X, PROP_ROI_Y, @@ -283,6 +284,9 @@ static void uca_mock_camera_get_property(GObject *object, guint property_id, GVa case PROP_EXPOSURE_TIME: g_value_set_double(value, 0.001); break; + case PROP_TRIGGER_MODE: + g_value_set_enum(value, UCA_CAMERA_TRIGGER_AUTO); + break; case PROP_ROI_X: g_value_set_uint(value, 0); break; diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c index b808766..2dd13b6 100644 --- a/src/cameras/uca-pco-camera.c +++ b/src/cameras/uca-pco-camera.c @@ -84,6 +84,7 @@ static gint base_overrideables[] = { PROP_SENSOR_VERTICAL_BINNING, PROP_SENSOR_VERTICAL_BINNINGS, PROP_SENSOR_MAX_FRAME_RATE, + PROP_TRIGGER_MODE, PROP_ROI_X, PROP_ROI_Y, PROP_ROI_WIDTH, @@ -351,6 +352,20 @@ static void uca_pco_camera_start_readout(UcaCamera *camera, GError **error) priv->current_image = 1; } +static void uca_pco_camera_trigger(UcaCamera *camera, GError **error) +{ + g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); + UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); + + /* TODO: Check if we can trigger */ + guint32 success = 0; + pco_force_trigger(priv->pco, &success); + + if (!success) + g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL, + "Could not trigger frame acquisition"); +} + static void uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error) { g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); @@ -404,6 +419,25 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons pco_set_cooling_temperature(priv->pco, temperature); } break; + + case PROP_TRIGGER_MODE: + { + UcaCameraTrigger trigger_mode = (UcaCameraTrigger) g_value_get_enum(value); + + switch (trigger_mode) { + case UCA_CAMERA_TRIGGER_AUTO: + pco_set_trigger_mode(priv->pco, TRIGGER_MODE_AUTOTRIGGER); + break; + case UCA_CAMERA_TRIGGER_INTERNAL: + pco_set_trigger_mode(priv->pco, TRIGGER_MODE_SOFTWARETRIGGER); + break; + case UCA_CAMERA_TRIGGER_EXTERNAL: + pco_set_trigger_mode(priv->pco, TRIGGER_MODE_EXTERNALTRIGGER); + break; + } + } + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); return; @@ -465,6 +499,27 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal g_value_set_boolean(value, priv->camera_description->has_camram); break; + case PROP_TRIGGER_MODE: + { + guint16 mode; + pco_get_trigger_mode(priv->pco, &mode); + + switch (mode) { + case TRIGGER_MODE_AUTOTRIGGER: + g_value_set_enum(value, UCA_CAMERA_TRIGGER_AUTO); + break; + case TRIGGER_MODE_SOFTWARETRIGGER: + g_value_set_enum(value, UCA_CAMERA_TRIGGER_INTERNAL); + break; + case TRIGGER_MODE_EXTERNALTRIGGER: + g_value_set_enum(value, UCA_CAMERA_TRIGGER_EXTERNAL); + break; + default: + g_warning("pco trigger mode not handled\n"); + } + } + break; + case PROP_ROI_X: { guint16 roi[4] = {0}; @@ -554,6 +609,7 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) camera_class->start_recording = uca_pco_camera_start_recording; camera_class->stop_recording = uca_pco_camera_stop_recording; camera_class->start_readout = uca_pco_camera_start_readout; + camera_class->trigger = uca_pco_camera_trigger; camera_class->grab = uca_pco_camera_grab; for (guint i = 0; base_overrideables[i] != 0; i++) diff --git a/src/uca-camera.c b/src/uca-camera.c index 67951cb..ba7d912 100644 --- a/src/uca-camera.c +++ b/src/uca-camera.c @@ -82,6 +82,7 @@ const gchar *uca_camera_props[N_BASE_PROPERTIES] = { "sensor-vertical-binning", "sensor-vertical-binnings", "sensor-max-frame-rate", + "trigger-mode", "exposure-time", "roi-x", "roi-y", @@ -102,7 +103,30 @@ struct _UcaCameraPrivate { gboolean transfer_async; }; -/* static guint camera_signals[LAST_SIGNAL] = { 0 }; */ +/** + * UcaCameraTrigger: + * @UCA_CAMERA_TRIGGER_AUTO: Trigger automatically + * @UCA_CAMERA_TRIGGER_EXTERNAL: Trigger from an external source + * @UCA_CAMERA_TRIGGER_INTERNAL: Trigger internally from software using + * #uca_camera_trigger + */ +static GType uca_camera_trigger_get_type(void) +{ + static GType camera_trigger_type = 0; + + if (!camera_trigger_type) { + static GEnumValue trigger_types[] = { + { UCA_CAMERA_TRIGGER_AUTO, "Automatic internal camera trigger", "auto" }, + { UCA_CAMERA_TRIGGER_EXTERNAL, "External trigger", "external" }, + { UCA_CAMERA_TRIGGER_INTERNAL, "Internal software trigger", "internal" }, + { 0, NULL, NULL } + }; + + camera_trigger_type = g_enum_register_static("UcaCameraTrigger", trigger_types); + } + + return camera_trigger_type; +} static void uca_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { @@ -219,6 +243,13 @@ static void uca_camera_class_init(UcaCameraClass *klass) 0.0f, G_MAXFLOAT, 1.0f, G_PARAM_READABLE); + camera_properties[PROP_TRIGGER_MODE] = + g_param_spec_enum("trigger-mode", + "Trigger mode", + "Trigger mode", + UCA_TYPE_CAMERA_TRIGGER, UCA_CAMERA_TRIGGER_AUTO, + G_PARAM_READWRITE); + camera_properties[PROP_ROI_X] = g_param_spec_uint(uca_camera_props[PROP_ROI_X], "Horizontal coordinate", @@ -508,6 +539,34 @@ void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointe } /** + * uca_camera_trigger: + * @camera: A #UcaCamera object + * @error: Location to store a #UcaCameraError error or %NULL + * + * Trigger from software if supported by camera. + * + * You must have called uca_camera_start_recording() before, otherwise you will + * get a #UCA_CAMERA_ERROR_NOT_RECORDING error. + */ +void uca_camera_trigger(UcaCamera *camera, GError **error) +{ + g_return_if_fail(UCA_IS_CAMERA(camera)); + + UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera); + + g_return_if_fail(klass != NULL); + g_return_if_fail(klass->trigger != NULL); + + if (!camera->priv->is_recording) { + g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, + "Camera is not recording"); + return; + } + + (*klass->trigger)(camera, error); +} + +/** * uca_camera_grab: * @camera: A #UcaCamera object * @data: Pointer to pointer to the data. Must not be %NULL. diff --git a/src/uca-camera.h b/src/uca-camera.h index 9f1c31f..39fd7ab 100644 --- a/src/uca-camera.h +++ b/src/uca-camera.h @@ -40,6 +40,14 @@ typedef enum { UCA_CAMERA_ERROR_NOT_IMPLEMENTED } UcaCameraError; +#define UCA_TYPE_CAMERA_TRIGGER (uca_camera_trigger_get_type()) + +typedef enum { + UCA_CAMERA_TRIGGER_AUTO, + UCA_CAMERA_TRIGGER_INTERNAL, + UCA_CAMERA_TRIGGER_EXTERNAL +} UcaCameraTrigger; + typedef struct _UcaCamera UcaCamera; typedef struct _UcaCameraClass UcaCameraClass; typedef struct _UcaCameraPrivate UcaCameraPrivate; @@ -54,6 +62,7 @@ enum { PROP_SENSOR_VERTICAL_BINNING, PROP_SENSOR_VERTICAL_BINNINGS, PROP_SENSOR_MAX_FRAME_RATE, + PROP_TRIGGER_MODE, PROP_EXPOSURE_TIME, PROP_ROI_X, PROP_ROI_Y, @@ -102,6 +111,7 @@ struct _UcaCameraClass { void (*start_recording) (UcaCamera *camera, GError **error); void (*stop_recording) (UcaCamera *camera, GError **error); void (*start_readout) (UcaCamera *camera, GError **error); + void (*trigger) (UcaCamera *camera, GError **error); void (*grab) (UcaCamera *camera, gpointer *data, GError **error); void (*recording_started) (UcaCamera *camera); @@ -114,6 +124,7 @@ UcaCamera *uca_camera_new(const gchar *type, GError **error); void uca_camera_start_recording(UcaCamera *camera, GError **error); void uca_camera_stop_recording(UcaCamera *camera, GError **error); void uca_camera_start_readout(UcaCamera *camera, GError **error); +void uca_camera_trigger(UcaCamera *camera, GError **error); void uca_camera_grab(UcaCamera *camera, gpointer *data, GError **error); void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data); |