summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2016-10-06 21:26:58 +0100
committerRichard Hughes <richard@hughsie.com>2016-10-10 17:16:08 +0100
commit88e0916d79b9b25de1ed1353f4110b8497e822d6 (patch)
treed44af47107f0975616519bb566d1975e3a3e8c25
parent4e8e5ccf11e7c0750d5ddbe24ebb0f1cdbbc2738 (diff)
downloadcolord-88e0916d79b9b25de1ed1353f4110b8497e822d6.tar.gz
colorhug: Add commands for getting and setting each device calibration spectrum
-rw-r--r--lib/colorhug/ch-common.h8
-rw-r--r--lib/colorhug/ch-device.c121
-rw-r--r--lib/colorhug/ch-device.h19
3 files changed, 134 insertions, 14 deletions
diff --git a/lib/colorhug/ch-common.h b/lib/colorhug/ch-common.h
index a60b1da..7256e61 100644
--- a/lib/colorhug/ch-common.h
+++ b/lib/colorhug/ch-common.h
@@ -1636,6 +1636,14 @@ typedef enum {
CH_DEVICE_MODE_LAST
} ChDeviceMode;
+typedef enum {
+ CH_SPECTRUM_KIND_RAW = 0x00, /* since 1.3.4 */
+ CH_SPECTRUM_KIND_DARK_CAL = 0x01, /* since 1.3.4 */
+ CH_SPECTRUM_KIND_TEMP_CAL = 0x02, /* since 1.3.4 */
+ CH_SPECTRUM_KIND_IRRADIANCE_CAL = 0x03, /* since 1.3.4 */
+ CH_SPECTRUM_KIND_LAST
+} ChSpectrumKind;
+
typedef guint8 ChCmd;
/* prototypes */
diff --git a/lib/colorhug/ch-device.c b/lib/colorhug/ch-device.c
index 80d6498..3446aa7 100644
--- a/lib/colorhug/ch-device.c
+++ b/lib/colorhug/ch-device.c
@@ -2356,8 +2356,117 @@ ch_device_take_reading_xyz (GUsbDevice *device, guint16 calibration_idx,
}
/**
- * ch_device_get_spectrum:
+ * ch_device_set_spectrum_full:
+ * @device: A #GUsbDevice
+ * @kind: A #ChSpectrumKind
+ * @sp: A #CdSpectrum
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Sets the spectrum from the device. This sends data multiple multiple times
+ * until the spectrum has been populated.
+ *
+ * Returns: %TRUE for success
+ *
+ * Since: 1.3.4
+ **/
+gboolean
+ch_device_set_spectrum_full (GUsbDevice *device,
+ ChSpectrumKind kind,
+ CdSpectrum *sp,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const guint sp_len = 1024 * sizeof(guint16);
+ gboolean ret;
+ guint16 buf[CH_EP0_TRANSFER_SIZE_V2 / sizeof(guint16)];
+ gsize actual_length;
+ guint16 i;
+ guint16 j;
+ guint8 protocol_ver = ch_device_get_protocol_ver (device);
+ g_autoptr(CdSpectrum) sp_resampled = NULL;
+
+ g_return_val_if_fail (G_USB_DEVICE (device), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ if (protocol_ver != 2) {
+ g_set_error_literal (error,
+ CH_DEVICE_ERROR,
+ CH_ERROR_NOT_IMPLEMENTED,
+ "Setting a spectrum is not supported");
+ return FALSE;
+ }
+
+ /* ensure spectrum has 1024 elements */
+ if (cd_spectrum_get_size (sp) != 1024) {
+ g_debug ("resampling sample from %u points to 1024",
+ cd_spectrum_get_size (sp));
+ sp_resampled = cd_spectrum_resample_to_size (sp, 1024);
+ } else {
+ sp_resampled = cd_spectrum_dup (sp);
+ }
+
+ /* set buf data from sp */
+ for (i = 0; i < sp_len / CH_EP0_TRANSFER_SIZE_V2; i++) {
+
+ /* create normalised data blob */
+ for (j = 0; j < 1024; j++) {
+ guint16 tmp;
+ gdouble val = cd_spectrum_get_value (sp_resampled, j);
+ if (val < 0.f || val > 1.f) {
+ g_set_error (error,
+ CH_DEVICE_ERROR,
+ CH_ERROR_NOT_IMPLEMENTED,
+ "expected normalised data for %u, got %f",
+ j, val);
+ return FALSE;
+ }
+ tmp = val * (gdouble) 0xffff;
+ memcpy (&buf[j], &tmp, sizeof (guint16));
+ }
+
+ /* send to device */
+ ret = g_usb_device_control_transfer (device,
+ G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
+ G_USB_DEVICE_REQUEST_TYPE_CLASS,
+ G_USB_DEVICE_RECIPIENT_INTERFACE,
+ CH_CMD_WRITE_SRAM,
+ i + (kind * sp_len),/* wValue */
+ CH_USB_INTERFACE, /* idx */
+ (guint8 *) buf, /* data */
+ sizeof(buf), /* length */
+ &actual_length, /* actual_length */
+ CH_DEVICE_USB_TIMEOUT,
+ cancellable,
+ error);
+ if (!ret)
+ return FALSE;
+ if (actual_length != sizeof(buf)) {
+ g_set_error (error,
+ G_USB_DEVICE_ERROR,
+ G_USB_DEVICE_ERROR_IO,
+ "Failed to get spectrum data, got %" G_GSIZE_FORMAT,
+ actual_length);
+ return FALSE;
+ }
+ }
+
+ /* check status */
+ if (!ch_device_check_status (device, cancellable, error))
+ return FALSE;
+
+ /* sync to eeprom */
+ if (!ch_device_save_sram (device, cancellable, error))
+ return FALSE;
+
+ /* success */
+ return TRUE;
+}
+
+/**
+ * ch_device_get_spectrum_full:
* @device: A #GUsbDevice
+ * @kind: A #ChSpectrumKind
* @cancellable: a #GCancellable, or %NULL
* @error: a #GError, or %NULL
*
@@ -2366,11 +2475,15 @@ ch_device_take_reading_xyz (GUsbDevice *device, guint16 calibration_idx,
*
* Returns: a #CdSpectrum, or %NULL for error
*
- * Since: 1.3.1
+ * Since: 1.3.4
**/
CdSpectrum *
-ch_device_get_spectrum (GUsbDevice *device, GCancellable *cancellable, GError **error)
+ch_device_get_spectrum_full (GUsbDevice *device,
+ ChSpectrumKind kind,
+ GCancellable *cancellable,
+ GError **error)
{
+ const guint sp_len = 1024 * sizeof(guint16);
gboolean ret;
guint16 buf[CH_EP0_TRANSFER_SIZE_V2 / sizeof(guint16)];
gsize actual_length;
@@ -2398,7 +2511,7 @@ ch_device_get_spectrum (GUsbDevice *device, GCancellable *cancellable, GError **
G_USB_DEVICE_REQUEST_TYPE_CLASS,
G_USB_DEVICE_RECIPIENT_INTERFACE,
CH_CMD_READ_SRAM,
- i, /* wValue */
+ i + (kind * sp_len),/* wValue */
CH_USB_INTERFACE, /* idx */
(guint8 *) buf, /* data */
sizeof(buf), /* length */
diff --git a/lib/colorhug/ch-device.h b/lib/colorhug/ch-device.h
index 3d0ffbb..3af81b6 100644
--- a/lib/colorhug/ch-device.h
+++ b/lib/colorhug/ch-device.h
@@ -74,16 +74,6 @@ gboolean ch_device_check_firmware (GUsbDevice *device,
G_GNUC_WARN_UNUSED_RESULT;
guint16 ch_device_get_runcode_address (GUsbDevice *device);
const gchar *ch_device_get_guid (GUsbDevice *device);
-
-
-// FIXME: add to spec
-typedef enum {
- CH_SPECTRUM_KIND_RAW = 0x00,
- CH_SPECTRUM_KIND_DARK_CAL = 0x01,
- CH_SPECTRUM_KIND_TEMP_CAL = 0x02,
- CH_SPECTRUM_KIND_LAST
-} ChSpectrumKind;
-
gboolean ch_device_open_full (GUsbDevice *device,
GCancellable *cancellable,
GError **error);
@@ -176,6 +166,15 @@ CdColorXYZ *ch_device_take_reading_xyz (GUsbDevice *device,
CdSpectrum *ch_device_get_spectrum (GUsbDevice *device,
GCancellable *cancellable,
GError **error);
+CdSpectrum *ch_device_get_spectrum_full (GUsbDevice *device,
+ ChSpectrumKind kind,
+ GCancellable *cancellable,
+ GError **error);
+gboolean ch_device_set_spectrum_full (GUsbDevice *device,
+ ChSpectrumKind kind,
+ CdSpectrum *sp,
+ GCancellable *cancellable,
+ GError **error);
gboolean ch_device_load_sram (GUsbDevice *device,
GCancellable *cancellable,
GError **error);