From 4f15fc39f9abbe9532a047112d8995e38481cf88 Mon Sep 17 00:00:00 2001 From: Mihael Koep Date: Mon, 18 May 2015 16:54:06 +0200 Subject: Update pylon and dexela plugins to the new trigger API --- plugins/dexela/uca-dexela-camera.c | 72 ++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 22 deletions(-) (limited to 'plugins/dexela/uca-dexela-camera.c') diff --git a/plugins/dexela/uca-dexela-camera.c b/plugins/dexela/uca-dexela-camera.c index 81d9f74..4a9fc82 100644 --- a/plugins/dexela/uca-dexela-camera.c +++ b/plugins/dexela/uca-dexela-camera.c @@ -57,7 +57,7 @@ static gint base_overrideables[] = { PROP_SENSOR_VERTICAL_BINNING, PROP_SENSOR_VERTICAL_BINNINGS, PROP_EXPOSURE_TIME, - PROP_TRIGGER_MODE, + PROP_TRIGGER_SOURCE, PROP_ROI_X, PROP_ROI_Y, PROP_ROI_WIDTH, @@ -85,7 +85,8 @@ struct _UcaDexelaCameraPrivate { guint roi_height; guint bits; gsize num_bytes; - UcaCameraTrigger uca_trigger_mode; + UcaCameraTriggerSource uca_trigger_source; + UcaCameraTriggerType uca_trigger_type; }; /** @@ -105,35 +106,51 @@ static void fill_binnings(UcaDexelaCameraPrivate *priv) g_value_array_append(priv->binnings, &val); } -static void map_dexela_trigger_mode_to_uca(UcaDexelaCameraPrivate *priv, GValue* value, TriggerMode mode) +static void map_dexela_trigger_mode_to_uca_source(UcaDexelaCameraPrivate *priv, GValue* value, TriggerMode mode) { if (mode == SOFTWARE) { - g_value_set_enum(value, priv->uca_trigger_mode); - return; + priv->uca_trigger_source = UCA_CAMERA_TRIGGER_SOURCE_AUTO; + } + if (mode == EDGE || mode == DURATION) { + priv->uca_trigger_source = UCA_CAMERA_TRIGGER_SOURCE_EXTERNAL; } + g_value_set_enum(value, priv->uca_trigger_source); +} + +static void map_dexela_trigger_mode_to_uca_type(UcaDexelaCameraPrivate *priv, GValue* value, TriggerMode mode) +{ if (mode == EDGE) { - g_value_set_enum(value, UCA_CAMERA_TRIGGER_EXTERNAL); - return; + priv->uca_trigger_type = UCA_CAMERA_TRIGGER_TYPE_EDGE; + } + if (mode == DURATION) { + priv->uca_trigger_type = UCA_CAMERA_TRIGGER_TYPE_LEVEL; } - g_warning("Unsupported dexela trigger mode: %d", mode); + g_value_set_enum(value, priv->uca_trigger_type); } -static void set_trigger_mode(UcaDexelaCameraPrivate *priv, UcaCameraTrigger mode) +static void set_triggering(UcaDexelaCameraPrivate *priv, UcaCameraTriggerSource source, UcaCameraTriggerType type) { - priv->uca_trigger_mode = mode; - if (mode == UCA_CAMERA_TRIGGER_AUTO) { + priv->uca_trigger_source = source; + priv->uca_trigger_type = type; + if (source == UCA_CAMERA_TRIGGER_SOURCE_AUTO) { dexela_set_trigger_mode(SOFTWARE); return; } - if (mode == UCA_CAMERA_TRIGGER_SOFTWARE) { + if (source == UCA_CAMERA_TRIGGER_SOURCE_SOFTWARE) { dexela_set_trigger_mode(SOFTWARE); return; } - if (mode == UCA_CAMERA_TRIGGER_EXTERNAL) { - dexela_set_trigger_mode(EDGE); - return; + if (source == UCA_CAMERA_TRIGGER_SOURCE_EXTERNAL) { + if (type == UCA_CAMERA_TRIGGER_TYPE_EDGE) { + dexela_set_trigger_mode(EDGE); + return; + } + if (type == UCA_CAMERA_TRIGGER_TYPE_LEVEL) { + dexela_set_trigger_mode(DURATION); + return; + } } - g_warning("Unsupported uca trigger mode: %d", mode); + g_warning("Unsupported uca trigger source and type: %d/%d", source, type); } static gboolean is_binning_allowed(UcaDexelaCameraPrivate *priv, guint binning) @@ -249,9 +266,14 @@ static void uca_dexela_camera_get_property(GObject *object, guint property_id, G g_value_set_boolean(value, dexela_get_control_register() & 1); break; } - case PROP_TRIGGER_MODE: + case PROP_TRIGGER_SOURCE: { - map_dexela_trigger_mode_to_uca(priv, value, dexela_get_trigger_mode()); + map_dexela_trigger_mode_to_uca_source(priv, value, dexela_get_trigger_mode()); + break; + } + case PROP_TRIGGER_TYPE: + { + map_dexela_trigger_mode_to_uca_type(priv, value, dexela_get_trigger_mode()); break; } default: @@ -342,9 +364,14 @@ static void uca_dexela_camera_set_property(GObject *object, guint property_id, c dexela_set_control_register(dexela_get_control_register() & 0xFFFE); break; } - case PROP_TRIGGER_MODE: + case PROP_TRIGGER_SOURCE: + { + set_triggering(priv, g_value_get_enum(value), priv->uca_trigger_type); + break; + } + case PROP_TRIGGER_TYPE: { - set_trigger_mode(priv, g_value_get_enum(value)); + set_triggering(priv, priv->uca_trigger_source, g_value_get_enum(value)); break; } default: @@ -371,7 +398,7 @@ static gboolean uca_dexela_camera_grab(UcaCamera *camera, gpointer data, GError g_return_val_if_fail(UCA_IS_DEXELA_CAMERA(camera), FALSE); UcaDexelaCameraPrivate *priv = UCA_DEXELA_CAMERA_GET_PRIVATE(camera); - if (priv->uca_trigger_mode == UCA_CAMERA_TRIGGER_SOFTWARE) { + if (priv->uca_trigger_source == UCA_CAMERA_TRIGGER_SOURCE_SOFTWARE) { // TODO: wait for a signal from uca_camera_trigger() } guchar* fullFrame = dexela_grab(); @@ -451,7 +478,8 @@ static void uca_dexela_camera_init(UcaDexelaCamera *self) priv->roi_width = priv->width; priv->roi_height = priv->height; priv->num_bytes = 2; - priv->uca_trigger_mode = UCA_CAMERA_TRIGGER_AUTO; + priv->uca_trigger_source = UCA_CAMERA_TRIGGER_SOURCE_AUTO; + priv->uca_trigger_type = UCA_CAMERA_TRIGGER_TYPE_EDGE; } G_MODULE_EXPORT GType -- cgit v1.2.3 From 9fa5eb803ea00ae42ab7a0c20329d3557a48e192 Mon Sep 17 00:00:00 2001 From: Mihael Koep Date: Mon, 18 May 2015 16:41:28 +0200 Subject: Improve error handling on dexela camera initialisation Conflicts: plugins/dexela/CMakeLists.txt plugins/dexela/changelog.txt --- plugins/dexela/uca-dexela-camera.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'plugins/dexela/uca-dexela-camera.c') diff --git a/plugins/dexela/uca-dexela-camera.c b/plugins/dexela/uca-dexela-camera.c index 4a9fc82..b5ecb5c 100644 --- a/plugins/dexela/uca-dexela-camera.c +++ b/plugins/dexela/uca-dexela-camera.c @@ -76,6 +76,8 @@ static const gdouble MINIMUM_EXPOSURE_TIME_IN_SECONDS = 0.017d; // 17ms as per d static const gdouble PIXEL_SIZE = 74.8e-6; // 74.8µm as per data sheet struct _UcaDexelaCameraPrivate { + GError* init_error; + GValueArray *binnings; guint width; guint height; @@ -417,12 +419,19 @@ static void uca_dexela_camera_finalize(GObject *object) static gboolean uca_dexela_camera_initable_init(GInitable *initable, GCancellable *cancellable, GError **error) { g_return_val_if_fail (UCA_IS_DEXELA_CAMERA (initable), FALSE); + UcaDexelaCameraPrivate *priv = UCA_DEXELA_CAMERA_GET_PRIVATE(initable); if (cancellable != NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Cancellable initialization not supported"); return FALSE; } + if (priv->init_error != NULL) { + if (error) { + *error = g_error_copy (priv->init_error); + } + return FALSE; + } return TRUE; } @@ -462,13 +471,13 @@ static void uca_dexela_camera_class_init(UcaDexelaCameraClass *klass) g_type_class_add_private(klass, sizeof(UcaDexelaCameraPrivate)); } -static void uca_dexela_camera_init(UcaDexelaCamera *self) +static gboolean setup_dexela(UcaDexelaCameraPrivate *priv) { - UcaDexelaCameraPrivate *priv = UCA_DEXELA_CAMERA_GET_PRIVATE(self); - self->priv = priv; - fill_binnings(priv); - // TODO implement error checking - dexela_open_detector(DEFAULT_FMT_FILE_PATH); + if (!dexela_open_detector(DEFAULT_FMT_FILE_PATH)) { + g_set_error_literal(&priv->init_error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to open dexela detector. Check cable, driver and permissions."); + return FALSE; + } + // TODO implement more error checking dexela_init_serial_connection(); priv->bits = dexela_get_bit_depth(); priv->width = dexela_get_width(); @@ -478,8 +487,17 @@ static void uca_dexela_camera_init(UcaDexelaCamera *self) priv->roi_width = priv->width; priv->roi_height = priv->height; priv->num_bytes = 2; + return TRUE; +} + +static void uca_dexela_camera_init(UcaDexelaCamera *self) +{ + UcaDexelaCameraPrivate *priv = UCA_DEXELA_CAMERA_GET_PRIVATE(self); + self->priv = priv; + fill_binnings(priv); priv->uca_trigger_source = UCA_CAMERA_TRIGGER_SOURCE_AUTO; priv->uca_trigger_type = UCA_CAMERA_TRIGGER_TYPE_EDGE; + setup_dexela(priv); } G_MODULE_EXPORT GType -- cgit v1.2.3 From 8c75b713ed6b1551af89a6ec31062b00fa8218f1 Mon Sep 17 00:00:00 2001 From: Mihael Koep Date: Mon, 16 Mar 2015 15:25:07 +0100 Subject: Only allow symmetricall binnings Other modes are technically possible but unsupported by the vendor. Since we experienced problems using asymmetrical binnings the plugin enforces symmetrical binnings. --- plugins/dexela/uca-dexela-camera.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/dexela/uca-dexela-camera.c') diff --git a/plugins/dexela/uca-dexela-camera.c b/plugins/dexela/uca-dexela-camera.c index b5ecb5c..378426a 100644 --- a/plugins/dexela/uca-dexela-camera.c +++ b/plugins/dexela/uca-dexela-camera.c @@ -330,7 +330,7 @@ static void uca_dexela_camera_set_property(GObject *object, guint property_id, c g_warning("Tried to set illegal horizontal binning: %d", horizontalBinning); return; } - dexela_set_binning_mode(horizontalBinning, dexela_get_binning_mode_vertical()); + dexela_set_binning_mode(horizontalBinning, horizontalBinning); break; } case PROP_SENSOR_VERTICAL_BINNING: @@ -340,7 +340,7 @@ static void uca_dexela_camera_set_property(GObject *object, guint property_id, c g_warning("Tried to set illegal vertical binning: %d", verticalBinning); return; } - dexela_set_binning_mode(dexela_get_binning_mode_horizontal(), verticalBinning); + dexela_set_binning_mode(verticalBinning, verticalBinning); break; } case PROP_GAIN_MODE: -- cgit v1.2.3 From f2436c659242ccf0d5bb30a59b81cef8ee0aae99 Mon Sep 17 00:00:00 2001 From: Mihael Koep Date: Tue, 17 Mar 2015 11:22:18 +0100 Subject: Correct the ROI dimensions respecting the binning mode Conflicts: plugins/dexela/changelog.txt --- plugins/dexela/uca-dexela-camera.c | 44 ++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 7 deletions(-) (limited to 'plugins/dexela/uca-dexela-camera.c') diff --git a/plugins/dexela/uca-dexela-camera.c b/plugins/dexela/uca-dexela-camera.c index 378426a..3e22c06 100644 --- a/plugins/dexela/uca-dexela-camera.c +++ b/plugins/dexela/uca-dexela-camera.c @@ -166,6 +166,28 @@ static gboolean is_binning_allowed(UcaDexelaCameraPrivate *priv, guint binning) return FALSE; } +static guint real_width(UcaDexelaCameraPrivate *priv) +{ + return priv->width / dexela_get_binning_mode_horizontal(); +} + +static guint real_height(UcaDexelaCameraPrivate *priv) +{ + return priv->height / dexela_get_binning_mode_vertical(); +} + +static void adjust_roi_width(UcaDexelaCameraPrivate *priv, guint requested_width) +{ + guint maxRoiWidth = real_width(priv) - priv->roi_x; + priv->roi_width = min(maxRoiWidth, requested_width); +} + +static void adjust_roi_height(UcaDexelaCameraPrivate *priv, guint requested_height) +{ + guint maxRoiHeight = real_height(priv) - priv->roi_y; + priv->roi_height = min(maxRoiHeight, requested_height); +} + static void uca_dexela_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { UcaDexelaCameraPrivate *priv = UCA_DEXELA_CAMERA_GET_PRIVATE(object); @@ -305,22 +327,28 @@ static void uca_dexela_camera_set_property(GObject *object, guint property_id, c } case PROP_ROI_X: { - priv->roi_x = g_value_get_uint(value); + guint maxRoiX = real_width(priv) - 1; + guint requestedRoiX = g_value_get_uint(value); + priv->roi_x = min(maxRoiX, requestedRoiX); + adjust_roi_width(priv, priv->roi_width); break; } case PROP_ROI_Y: { - priv->roi_y = g_value_get_uint(value); + guint maxRoiY = real_height(priv) -1; + guint requestedRoiY = g_value_get_uint(value); + priv->roi_y = min(maxRoiY, requestedRoiY); + adjust_roi_height(priv, priv->roi_height); break; } case PROP_ROI_WIDTH: { - priv->roi_width = g_value_get_uint(value); + adjust_roi_width(priv, g_value_get_uint(value)); break; } case PROP_ROI_HEIGHT: { - priv->roi_height = g_value_get_uint(value); + adjust_roi_height(priv, g_value_get_uint(value)); break; } case PROP_SENSOR_HORIZONTAL_BINNING: @@ -331,6 +359,7 @@ static void uca_dexela_camera_set_property(GObject *object, guint property_id, c return; } dexela_set_binning_mode(horizontalBinning, horizontalBinning); + adjust_roi_width(priv, priv->roi_width); break; } case PROP_SENSOR_VERTICAL_BINNING: @@ -341,6 +370,7 @@ static void uca_dexela_camera_set_property(GObject *object, guint property_id, c return; } dexela_set_binning_mode(verticalBinning, verticalBinning); + adjust_roi_height(priv, priv->roi_height); break; } case PROP_GAIN_MODE: @@ -404,7 +434,7 @@ static gboolean uca_dexela_camera_grab(UcaCamera *camera, gpointer data, GError // TODO: wait for a signal from uca_camera_trigger() } guchar* fullFrame = dexela_grab(); - apply_software_roi(fullFrame, priv->width, priv->num_bytes, data, priv->roi_x, priv->roi_y, priv->roi_width, priv->roi_height); + apply_software_roi(fullFrame, real_width(priv), priv->num_bytes, data, priv->roi_x, priv->roi_y, priv->roi_width, priv->roi_height); return TRUE; } @@ -484,8 +514,8 @@ static gboolean setup_dexela(UcaDexelaCameraPrivate *priv) priv->height = dexela_get_height(); priv->roi_x = 0; priv->roi_y = 0; - priv->roi_width = priv->width; - priv->roi_height = priv->height; + priv->roi_width = real_width(priv); + priv->roi_height = real_height(priv); priv->num_bytes = 2; return TRUE; } -- cgit v1.2.3