summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2015-10-24 21:50:53 +0100
committerRichard Hughes <richard@hughsie.com>2015-10-26 15:53:31 +0000
commitd49b89f32422759b6cf182417ccb05146d0662cf (patch)
tree80e849a946821a0b93dd3785a4c3ac3e406c7383
parent1bb5be35f41e5dbe1b6be87862525c3604ced5cf (diff)
downloadcolord-d49b89f32422759b6cf182417ccb05146d0662cf.tar.gz
libospark: Add methods for getting the nonlinearity and irradiance calibrations
Although, disappointingly, there appears to be no stored data on the device.
-rw-r--r--lib/ospark/osp-device.c182
-rw-r--r--lib/ospark/osp-device.h8
-rw-r--r--lib/ospark/osp-self-test.c12
3 files changed, 193 insertions, 9 deletions
diff --git a/lib/ospark/osp-device.c b/lib/ospark/osp-device.c
index 27fa108..c2e442d 100644
--- a/lib/ospark/osp-device.c
+++ b/lib/ospark/osp-device.c
@@ -155,7 +155,28 @@ osp_device_query (GUsbDevice *device, OspCmd cmd,
/* check the error code */
hdr = (OspProtocolHeader *) buffer_out;
- if (hdr->error_code != OSP_ERROR_CODE_SUCCESS) {
+ switch (hdr->error_code) {
+ case OSP_ERROR_CODE_SUCCESS:
+ break;
+ case OSP_ERROR_CODE_MESSAGE_TOO_LARGE:
+ case OSP_ERROR_CODE_UNKNOWN_CHECKSUM_TYPE:
+ case OSP_ERROR_CODE_UNSUPPORTED_PROTOCOL:
+ g_set_error (error,
+ OSP_DEVICE_ERROR,
+ OSP_DEVICE_ERROR_NO_SUPPORT,
+ "Failed to %s",
+ osp_cmd_to_string (cmd));
+ return FALSE;
+ break;
+ case OSP_ERROR_CODE_COMMAND_DATA_MISSING:
+ g_set_error (error,
+ OSP_DEVICE_ERROR,
+ OSP_DEVICE_ERROR_NO_DATA,
+ "Failed to %s",
+ osp_cmd_to_string (cmd));
+ return FALSE;
+ break;
+ default:
g_set_error (error,
OSP_DEVICE_ERROR,
OSP_DEVICE_ERROR_INTERNAL,
@@ -163,6 +184,7 @@ osp_device_query (GUsbDevice *device, OspCmd cmd,
osp_cmd_to_string (cmd),
osp_error_code_to_string (hdr->error_code));
return FALSE;
+ break;
}
/* copy out the data */
@@ -305,8 +327,8 @@ osp_device_get_wavelength_cal_for_idx (GUsbDevice *device,
guint8 idx_buf[1] = { idx };
g_autofree guint8 *data = NULL;
- g_return_val_if_fail (G_USB_IS_DEVICE (device), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (G_USB_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
/* query hardware */
if (!osp_device_query (device, OSP_CMD_GET_WAVELENGTH_COEFFICIENT,
@@ -389,17 +411,17 @@ osp_device_get_wavelength_cal (GUsbDevice *device, guint *length, GError **error
}
/* check sanity */
- if (data_len != 1) {
+ if (data[0] != 4) {
g_set_error (error,
OSP_DEVICE_ERROR,
OSP_DEVICE_ERROR_INTERNAL,
- "Expected 3 coefs, got %li", data_len);
+ "Expected 4 coefs, got %i", data[0]);
return FALSE;
}
/* get the coefs */
- coefs = g_new0 (gdouble, 3);
- for (i = 0; i < 3; i++) {
+ coefs = g_new0 (gdouble, data[0] - 1);
+ for (i = 0; i < (guint) data[0] - 1; i++) {
ret = osp_device_get_wavelength_cal_for_idx (device,
i + 1,
&cx,
@@ -411,7 +433,151 @@ osp_device_get_wavelength_cal (GUsbDevice *device, guint *length, GError **error
/* this is optional */
if (length != NULL)
- *length = 3;
+ *length = data[0] - 1;
+
+ /* success */
+ return coefs;
+}
+
+/**
+ * osp_device_get_nonlinearity_cal_for_idx:
+ *
+ * Since: 1.3.1
+ **/
+static gboolean
+osp_device_get_nonlinearity_cal_for_idx (GUsbDevice *device,
+ guint idx,
+ gfloat *cal,
+ GError **error)
+{
+ gsize data_len;
+ guint8 idx_buf[1] = { idx };
+ g_autofree guint8 *data = NULL;
+
+ g_return_val_if_fail (G_USB_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ /* query hardware */
+ if (!osp_device_query (device, OSP_CMD_GET_NONLINEARITY_COEFFICIENT,
+ idx_buf, 1, &data, &data_len, error))
+ return NULL;
+
+ /* check values */
+ if (data_len != 4) {
+ g_set_error (error,
+ OSP_DEVICE_ERROR,
+ OSP_DEVICE_ERROR_INTERNAL,
+ "Expected %i bytes, got %li", 4, data_len);
+ return FALSE;
+ }
+
+ /* convert to floating point */
+ if (cal != NULL)
+ *cal = *((gfloat *) data);
+
+ /* format value */
+ return TRUE;
+}
+
+/**
+ * osp_device_get_nonlinearity_cal:
+ *
+ * Since: 1.3.1
+ **/
+gdouble *
+osp_device_get_nonlinearity_cal (GUsbDevice *device, guint *length, GError **error)
+{
+ gboolean ret;
+ gdouble *coefs = NULL;
+ gfloat cx;
+ gsize data_len;
+ guint i;
+ g_autofree guint8 *data = NULL;
+
+ g_return_val_if_fail (G_USB_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ /* query hardware */
+ if (!osp_device_query (device, OSP_CMD_GET_NONLINEARITY_COEFFICIENT_COUNT,
+ NULL, 0, &data, &data_len, error))
+ return NULL;
+
+ /* check values */
+ if (data_len != 1) {
+ g_set_error (error,
+ OSP_DEVICE_ERROR,
+ OSP_DEVICE_ERROR_INTERNAL,
+ "Expected 1 bytes, got %li", data_len);
+ return FALSE;
+ }
+
+ /* check sanity */
+ if (data[0] != 8) {
+ g_set_error (error,
+ OSP_DEVICE_ERROR,
+ OSP_DEVICE_ERROR_INTERNAL,
+ "Expected 8 coefs, got %i", data[0]);
+ return FALSE;
+ }
+
+ /* get the coefs */
+ coefs = g_new0 (gdouble, data[0]);
+ for (i = 0; i < data[0]; i++) {
+ ret = osp_device_get_nonlinearity_cal_for_idx (device,
+ i,
+ &cx,
+ error);
+ if (!ret)
+ return FALSE;
+ coefs[i] = cx;
+ }
+
+ /* this is optional */
+ if (length != NULL)
+ *length = data[0];
+
+ /* success */
+ return coefs;
+}
+
+/**
+ * osp_device_get_irradiance_cal:
+ *
+ * Since: 1.3.1
+ **/
+gdouble *
+osp_device_get_irradiance_cal (GUsbDevice *device, guint *length, GError **error)
+{
+ gdouble *coefs = NULL;
+ gsize data_len;
+ guint i;
+ g_autofree guint8 *data = NULL;
+
+ g_return_val_if_fail (G_USB_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ /* query hardware */
+ if (!osp_device_query (device, OSP_CMD_GET_IRRADIANCE_CALIBRATION,
+ NULL, 0, &data, &data_len, error))
+ return NULL;
+
+ /* check values */
+ if (data_len != 4096 * 4) {
+ g_set_error (error,
+ OSP_DEVICE_ERROR,
+ OSP_DEVICE_ERROR_INTERNAL,
+ "Expected %i bytes, got %li", 4096 * 4, data_len);
+ return FALSE;
+ }
+
+ /* copy out the coefs */
+ coefs = g_new0 (gdouble, 4096);
+ for (i = 0; i < 4096; i++)
+ coefs[i] = *((gfloat *) &data[i*4]);
+
+ /* this is optional */
+ if (length != NULL)
+ *length = 4096;
/* success */
return coefs;
diff --git a/lib/ospark/osp-device.h b/lib/ospark/osp-device.h
index d8aadbe..1616f39 100644
--- a/lib/ospark/osp-device.h
+++ b/lib/ospark/osp-device.h
@@ -55,6 +55,14 @@ gchar *osp_device_get_serial (GUsbDevice *device,
gchar *osp_device_get_fw_version (GUsbDevice *device,
GError **error)
G_GNUC_WARN_UNUSED_RESULT;
+gdouble *osp_device_get_nonlinearity_cal(GUsbDevice *device,
+ guint *length,
+ GError **error)
+ G_GNUC_WARN_UNUSED_RESULT;
+gdouble *osp_device_get_irradiance_cal (GUsbDevice *device,
+ guint *length,
+ GError **error)
+ G_GNUC_WARN_UNUSED_RESULT;
gdouble *osp_device_get_wavelength_cal (GUsbDevice *device,
guint *length,
GError **error)
diff --git a/lib/ospark/osp-self-test.c b/lib/ospark/osp-self-test.c
index 11b04a7..529ee67 100644
--- a/lib/ospark/osp-self-test.c
+++ b/lib/ospark/osp-self-test.c
@@ -43,7 +43,7 @@ osp_client_get_default (GError **error)
if (usb_ctx == NULL) {
g_set_error (error,
G_USB_DEVICE_ERROR,
- G_USB_DEVICE_ERROR_NO_DEVICE,
+ G_USB_DEVICE_ERROR_NOT_SUPPORTED,
"No device found; USB initialisation failed");
return NULL;
}
@@ -163,6 +163,16 @@ osp_test_wavelength_cal_func (void)
g_assert_no_error (error);
g_assert (start > 0);
g_assert_cmpfloat (ABS (start - 355), <, 5);
+
+ /* get irradiance coefficients */
+ coefficients = osp_device_get_irradiance_cal (device, NULL, &error);
+ g_assert_error (error, OSP_DEVICE_ERROR, OSP_DEVICE_ERROR_NO_DATA);
+ g_clear_error (&error);
+
+ /* get nonlinearity coefficients */
+ coefficients = osp_device_get_nonlinearity_cal (device, NULL, &error);
+ g_assert_error (error, OSP_DEVICE_ERROR, OSP_DEVICE_ERROR_NO_DATA);
+ g_clear_error (&error);
}
int