[argyllcms/f16] Add an experimental ColorHug sensor driver.
Richard Hughes
rhughes at fedoraproject.org
Fri Dec 2 11:53:32 UTC 2011
commit 826c6b4a476123565767e921738c78635a79a935
Author: Richard Hughes <richard at hughsie.com>
Date: Fri Dec 2 10:51:00 2011 +0000
Add an experimental ColorHug sensor driver.
...dd-an-experimental-ColorHug-sensor-driver.patch | 949 ++++++++++++++++++++
argyllcms.spec | 16 +-
2 files changed, 964 insertions(+), 1 deletions(-)
---
diff --git a/0001-Add-an-experimental-ColorHug-sensor-driver.patch b/0001-Add-an-experimental-ColorHug-sensor-driver.patch
new file mode 100644
index 0000000..2edd6e8
--- /dev/null
+++ b/0001-Add-an-experimental-ColorHug-sensor-driver.patch
@@ -0,0 +1,949 @@
+commit c75380c239b950eff540d9c8d4ede12c67d2d886
+Author: Richard Hughes <richard at hughsie.com>
+Date: Wed Nov 30 15:28:57 2011 +0000
+
+ Add an experimental ColorHug sensor driver
+
+diff --git a/libusb/55-Argyll.rules b/libusb/55-Argyll.rules
+index a3b3cd4..a047d26 100644
+--- a/libusb/55-Argyll.rules
++++ b/libusb/55-Argyll.rules
+@@ -46,6 +46,9 @@ ATTRS{idVendor}=="085c", ATTRS{idProduct}=="0300", ENV{COLOR_MEASUREMENT_DEVICE}
+ # Huey
+ ATTRS{idVendor}=="0971", ATTRS{idProduct}=="2005", ENV{COLOR_MEASUREMENT_DEVICE}="1"
+
++# ColorHug
++ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="f8dA", ENV{COLOR_MEASUREMENT_DEVICE}="1"
++
+ # Let udev-acl and ConsoleKit manage these devices, if applicable
+ TEST=="/lib/udev/udev-acl", TEST=="/var/run/ConsoleKit/database", ENV{COLOR_MEASUREMENT_DEVICE}=="*?", ENV{ACL_MANAGE}="1"
+
+diff --git a/spectro/colorhug.c b/spectro/colorhug.c
+new file mode 100644
+index 0000000..90f1b7e
+--- /dev/null
++++ b/spectro/colorhug.c
+@@ -0,0 +1,752 @@
++/*
++ * Argyll Color Correction System
++ *
++ * Hughski ColorHug related functions
++ *
++ * Author: Richard Hughes
++ * Date: 30/11/2011
++ *
++ * Copyright 2006 - 2007, Graeme W. Gill
++ * Copyright 2011, Richard Hughes
++ * All rights reserved.
++ *
++ * (Based on huey.c)
++ *
++ * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
++ * see the License2.txt file for licencing details.
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <ctype.h>
++#include <string.h>
++#include <time.h>
++#include <stdarg.h>
++#include <math.h>
++#ifndef SALONEINSTLIB
++#include "copyright.h"
++#include "aconfig.h"
++#include "numlib.h"
++#else /* SALONEINSTLIB */
++#include "sa_config.h"
++#include "numsup.h"
++#endif /* SALONEINSTLIB */
++#include "xspect.h"
++#include "insttypes.h"
++#include "icoms.h"
++#include "conv.h"
++#include "colorhug.h"
++
++static inst_code colorhug_interp_code(inst *pp, int ec);
++
++/* Interpret an icoms error into a ColorHug error */
++static int icoms2colorhug_err(int se) {
++ if (se & ICOM_USERM) {
++ se &= ICOM_USERM;
++ if (se == ICOM_USER)
++ return COLORHUG_USER_ABORT;
++ if (se == ICOM_TERM)
++ return COLORHUG_USER_TERM;
++ if (se == ICOM_TRIG)
++ return COLORHUG_USER_TRIG;
++ if (se == ICOM_CMND)
++ return COLORHUG_USER_CMND;
++ }
++ if (se != ICOM_OK)
++ return COLORHUG_COMS_FAIL;
++ return COLORHUG_OK;
++}
++
++/* ColorHug commands that we care about */
++typedef enum {
++ ch_set_mult = 0x04, /* Set multiplier value */
++ ch_set_integral = 0x06, /* Set integral time */
++ ch_get_serial = 0x0b, /* Gets the serial number */
++ ch_set_leds = 0x0e, /* Sets the LEDs */
++ ch_take_reading = 0x23 /* Takes an XYZ reading */
++} ColorHugCmd;
++
++/* Diagnostic - return a description given the instruction code */
++static char *inst_desc(int cc) {
++ static char buf[40];
++ switch(cc) {
++ case 0x04:
++ return "SetMultiplier";
++ case 0x06:
++ return "SetIntegral";
++ case 0x0b:
++ return "GetSerial";
++ case 0x0e:
++ return "SetLeds";
++ case 0x23:
++ return "TakeReadingXYZ";
++ }
++ sprintf(buf,"Unknown %02x",cc);
++ return buf;
++}
++
++/* Error codes interpretation */
++static char *
++colorhug_interp_error(inst *pp, int ec) {
++ ec &= inst_imask;
++ switch (ec) {
++ case COLORHUG_INTERNAL_ERROR:
++ return "Internal software error";
++ case COLORHUG_COMS_FAIL:
++ return "Communications failure";
++ case COLORHUG_UNKNOWN_MODEL:
++ return "Not a known ColorHug Model";
++ case COLORHUG_USER_ABORT:
++ return "User hit Abort key";
++ case COLORHUG_USER_TERM:
++ return "User hit Terminate key";
++ case COLORHUG_USER_TRIG:
++ return "User hit Trigger key";
++ case COLORHUG_USER_CMND:
++ return "User hit a Command key";
++
++ case COLORHUG_OK:
++ return "OK";
++ case COLORHUG_UNKNOWN_CMD:
++ return "Unknown connamd";
++ case COLORHUG_WRONG_UNLOCK_CODE:
++ return "Wrong unlock code";
++ case COLORHUG_NOT_IMPLEMENTED:
++ return "Not implemented";
++ case COLORHUG_UNDERFLOW_SENSOR:
++ return "Sensor underflow";
++ case COLORHUG_NO_SERIAL:
++ return "No serial";
++ case COLORHUG_WATCHDOG:
++ return "Watchdog";
++ case COLORHUG_INVALID_ADDRESS:
++ return "Invalid address";
++ case COLORHUG_INVALID_LENGTH:
++ return "Invalid length";
++ case COLORHUG_INVALID_CHECKSUM:
++ return "Invlid checksum";
++ case COLORHUG_INVALID_VALUE:
++ return "Invalid value";
++ case COLORHUG_UNKNOWN_CMD_FOR_BOOTLOADER:
++ return "Unknown command for bootloader";
++ case COLORHUG_NO_CALIBRATION:
++ return "No calibration";
++ case COLORHUG_OVERFLOW_MULTIPLY:
++ return "Multiply overflow";
++ case COLORHUG_OVERFLOW_ADDITION:
++ return "Addition overflow";
++ case COLORHUG_OVERFLOW_SENSOR:
++ return "Sensor overflow";
++ case COLORHUG_OVERFLOW_STACK:
++ return "Stack overflow";
++
++ /* Internal errors */
++ case COLORHUG_NO_COMS:
++ return "Communications hasn't been established";
++ case COLORHUG_NOT_INITED:
++ return "Insrument hasn't been initialised";
++ default:
++ return "Unknown error code";
++ }
++}
++
++/* Do a command/response exchange with the colorhug */
++static inst_code
++colorhug_command(colorhug *p,
++ ColorHugCmd cmd,
++ unsigned char *in, uint in_size,
++ unsigned char *out, uint out_size,
++ double timeout)
++{
++ int i;
++ unsigned char buf[64];
++ int wbytes;
++ int rbytes;
++ int se, ua = 0, rv = inst_ok;
++ int isdeb = 0;
++
++ /* Turn off low level debug messages, and sumarise them here */
++ isdeb = p->icom->debug;
++ if (isdeb <= 2)
++ p->icom->debug = 0;
++
++ if (isdeb) {
++ fprintf(stderr,"colorhug: Sending cmd '%s' args '%s'\n",
++ inst_desc(cmd), icoms_tohex(in, in_size));
++ }
++
++ /* Send the command with any specified data */
++ buf[0] = cmd;
++ if (in != NULL)
++ memcpy(buf + 1, in, in_size);
++ if (p->icom->is_hid) {
++ se = p->icom->hid_write(p->icom, buf, in_size + 1, &wbytes, timeout);
++ } else {
++ se = p->icom->usb_write(p->icom, 0x01, buf, in_size + 1, &wbytes, timeout);
++ }
++ if (se != 0) {
++ if (se & ICOM_USERM) {
++ ua = (se & ICOM_USERM);
++ }
++ if (se & ~ICOM_USERM) {
++ if (isdeb)
++ fprintf(stderr,"colorhug: Command send failed with ICOM err 0x%x\n", se);
++ p->icom->debug = isdeb;
++ return colorhug_interp_code((inst *)p, COLORHUG_COMS_FAIL);
++ }
++ }
++ rv = colorhug_interp_code((inst *)p, icoms2colorhug_err(ua));
++ if (isdeb)
++ fprintf(stderr,"colorhug: ICOM err 0x%x\n",ua);
++ if (wbytes != in_size + 1)
++ rv = colorhug_interp_code((inst *)p, COLORHUG_BAD_WR_LENGTH);
++ if (rv != inst_ok) {
++ p->icom->debug = isdeb;
++ return rv;
++ }
++
++ /* Now fetch the response */
++ if (isdeb)
++ fprintf(stderr,"colorhug: Reading response\n");
++
++ if (p->icom->is_hid) {
++ se = p->icom->hid_read(p->icom, buf, out_size + 2, &rbytes, timeout);
++ } else {
++ se = p->icom->usb_read(p->icom, 0x81, buf, out_size + 2, &rbytes, timeout);
++ }
++
++ if (isdeb && rbytes >= 2) {
++ fprintf(stderr,"Recieved cmd '%s' error '%s' args '%s'\n",
++ inst_desc(buf[1]),
++ colorhug_interp_error((inst *) p, buf[0]),
++ icoms_tohex(buf, rbytes - 2));
++ }
++
++ if (se != 0) {
++
++ /* deal with command error */
++ if (rbytes == 2 && buf[0] != COLORHUG_OK) {
++ rv = colorhug_interp_code((inst *)p, buf[0]);
++ return rv;
++ }
++
++ /* deal with underrun or overrun */
++ if (rbytes != out_size + 2) {
++ rv = colorhug_interp_code((inst *)p, COLORHUG_BAD_RD_LENGTH);
++ return rv;
++ }
++
++ /* there's another reason it failed */
++ if (se & ICOM_USERM) {
++ ua = (se & ICOM_USERM);
++ }
++ if (se & ~ICOM_USERM) {
++ if (isdeb)
++ fprintf(stderr,"colorhug: Response read failed with ICOM err 0x%x\n",se);
++ p->icom->debug = isdeb;
++ return colorhug_interp_code((inst *)p, COLORHUG_COMS_FAIL);
++ }
++ }
++ rv = colorhug_interp_code((inst *)p, icoms2colorhug_err(ua));
++ if (rv != inst_ok)
++ return rv;
++
++ /* check the command was the same */
++ if (buf[1] != cmd) {
++ rv = colorhug_interp_code((inst *)p, COLORHUG_BAD_RET_CMD);
++ return rv;
++ }
++ if (out != NULL) {
++ memcpy(out, buf + 2, out_size);
++ }
++ if (isdeb) {
++ fprintf(stderr,"colorhug: '%s' ICOM err 0x%x\n",
++ icoms_tohex(buf + 2, out_size),ua);
++ }
++ p->icom->debug = isdeb;
++ return rv;
++}
++
++/* Take a short, and convert it into a byte buffer */
++static void short2buf(unsigned char *buf, int inv)
++{
++ buf[0] = (inv >> 0) & 0xff;
++ buf[1] = (inv >> 8) & 0xff;
++}
++
++/* Converts a packed float to a double */
++static double packed_float_to_double (uint32_t pf)
++{
++ return (double) pf / (double) 0x10000;
++}
++
++/* Set the device LED state */
++static inst_code
++colorhug_set_LEDs(colorhug *p, int mask)
++{
++ int i;
++ unsigned char ibuf[4];
++ inst_code ev;
++
++ mask &= 0x3;
++ p->led_state = mask;
++
++ ibuf[0] = mask;
++ ibuf[1] = 0; /* repeat */
++ ibuf[2] = 0; /* on */
++ ibuf[3] = 0; /* off */
++
++ /* Do command */
++ ev = colorhug_command(p, ch_set_leds,
++ ibuf, sizeof (ibuf), /* input */
++ NULL, 0, /* output */
++ 1.0);
++ return ev;
++}
++
++/* Take a XYZ measurement from the device */
++static inst_code
++colorhug_take_XYZ_measurement(colorhug *p, double XYZ[3])
++{
++ inst_code ev;
++ int i;
++ uint8_t ibuf[2];
++ uint32_t obuf[3];
++
++ if (!p->inited)
++ return colorhug_interp_code((inst *)p, COLORHUG_NOT_INITED);
++
++ /* Choose the calibration matrix */
++ short2buf(ibuf + 0, p->crt ? 65 : 64);
++
++ /* Do the measurement, and return the values */
++ ev = colorhug_command(p, ch_take_reading,
++ ibuf, sizeof (ibuf),
++ (unsigned char *) obuf, sizeof (obuf),
++ 1.0);
++ if (ev != inst_ok)
++ return ev;
++
++ /* Convert to doubles */
++ for (i = 0; i < 3; i++)
++ XYZ[i] = packed_float_to_double (obuf[i]);
++
++ /* Apply the colorimeter correction matrix */
++ icmMulBy3x3(XYZ, p->ccmat, XYZ);
++
++ if (p->debug) {
++ fprintf(stderr,"colorhug: returning XYZ = %f %f %f\n",
++ XYZ[0],XYZ[1],XYZ[2]);
++ }
++ return inst_ok;
++}
++
++/* Establish communications with a ColorHug */
++static inst_code
++colorhug_init_coms(inst *pp, int port, baud_rate br, flow_control fc, double tout) {
++ colorhug *p = (colorhug *) pp;
++
++ if (p->debug) {
++ p->icom->debug = p->debug; /* Turn on debugging */
++ fprintf(stderr,"colorhug: About to init coms\n");
++ }
++
++ /* Open as an HID if available */
++ if (p->icom->is_hid_portno(p->icom, port) != instUnknown) {
++
++ if (p->debug)
++ fprintf(stderr,"colorhug: About to init HID\n");
++
++ /* Set config, interface */
++ p->icom->set_hid_port(p->icom, port, icomuf_none, 0, NULL);
++
++ } else if (p->icom->is_usb_portno(p->icom, port) != instUnknown) {
++
++ if (p->debug)
++ fprintf(stderr,"colorhug: About to init USB\n");
++
++ /* Set config, interface, write end point, read end point */
++ p->icom->set_usb_port(p->icom, port, 1, 0x00, 0x00, icomuf_detach, 0, NULL);
++
++ } else {
++ if (p->debug)
++ fprintf(stderr,"colorhug: init_coms called to wrong device!\n");
++ return colorhug_interp_code((inst *)p, COLORHUG_UNKNOWN_MODEL);
++ }
++
++ if (p->debug)
++ fprintf(stderr,"colorhug: init coms has suceeded\n");
++
++ p->gotcoms = 1;
++ return inst_ok;
++}
++
++/* Set the device multiplier */
++static inst_code
++colorhug_set_multiplier (colorhug *p, int multiplier)
++{
++ inst_code ev;
++ unsigned char ibuf[1];
++
++ /* Set the desired multiplier */
++ ibuf[0] = multiplier;
++ ev = colorhug_command(p, ch_set_mult,
++ ibuf, sizeof (ibuf),
++ NULL, 0,
++ 1.0);
++ return ev;
++}
++
++/* Set the device integral time */
++static inst_code
++colorhug_set_integral (colorhug *p, int integral)
++{
++ inst_code ev;
++ unsigned char ibuf[2];
++
++ /* Set the desired integral time */
++ short2buf(ibuf + 0, integral);
++ ev = colorhug_command(p, ch_set_integral,
++ ibuf, sizeof (ibuf),
++ NULL, 0,
++ 1.0);
++ return ev;
++}
++
++/* Initialise the ColorHug */
++static inst_code
++colorhug_init_inst(inst *pp)
++{
++ colorhug *p = (colorhug *)pp;
++ inst_code ev;
++
++ if (p->debug)
++ fprintf(stderr,"colorhug: About to init instrument\n");
++
++ /* Must establish coms first */
++ if (p->gotcoms == 0)
++ return colorhug_interp_code((inst *)p, COLORHUG_NO_COMS);
++
++ /* Turn the LEDs off */
++ ev = colorhug_set_LEDs(p, 0x0);
++ if (ev != inst_ok)
++ return ev;
++
++ /* Turn the sensor on */
++ ev = colorhug_set_multiplier(p, 0x03);
++ if (ev != inst_ok)
++ return ev;
++
++ /* Set the integral time to maximum precision */
++ ev = colorhug_set_integral(p, 0xffff);
++ if (ev != inst_ok)
++ return ev;
++
++ p->itype = instColorHug;
++ p->trig = inst_opt_trig_keyb;
++ p->inited = 1;
++ if (p->debug)
++ fprintf(stderr,"colorhug: instrument inited OK\n");
++
++ /* Flash the LEDs */
++ ev = colorhug_set_LEDs(p, 0x1);
++ if (ev != inst_ok)
++ return ev;
++ msec_sleep(50);
++ ev = colorhug_set_LEDs(p, 0x2);
++ if (ev != inst_ok)
++ return ev;
++ msec_sleep(50);
++ ev = colorhug_set_LEDs(p, 0x1);
++ if (ev != inst_ok)
++ return ev;
++ msec_sleep(50);
++ ev = colorhug_set_LEDs(p, 0x0);
++ if (ev != inst_ok)
++ return ev;
++
++ return ev;
++}
++
++/* Read a single sample */
++static inst_code
++colorhug_read_sample(
++inst *pp,
++char *name, /* Strip name (7 chars) */
++ipatch *val) { /* Pointer to instrument patch value */
++ colorhug *p = (colorhug *)pp;
++ int user_trig = 0;
++ int rv = inst_protocol_error;
++
++ if (p->trig == inst_opt_trig_keyb) {
++ int se;
++ if ((se = icoms_poll_user(p->icom, 1)) != ICOM_TRIG) {
++ /* Abort, term or command */
++ return colorhug_interp_code((inst *)p, icoms2colorhug_err(se));
++ }
++ user_trig = 1;
++ if (p->trig_return)
++ printf("\n");
++ }
++
++ /* Read the XYZ value */
++ if ((rv = colorhug_take_XYZ_measurement(p, val->aXYZ)) != inst_ok) {
++ return rv;
++ }
++
++ val->XYZ_v = 0;
++ val->aXYZ_v = 1; /* These are absolute XYZ readings ? */
++ val->Lab_v = 0;
++ val->sp.spec_n = 0;
++ val->duration = 0.0;
++
++ if (user_trig)
++ return inst_user_trig;
++ return rv;
++}
++
++/* Insert a colorimetric correction matrix */
++inst_code colorhug_col_cor_mat(
++inst *pp,
++double mtx[3][3]
++) {
++ colorhug *p = (colorhug *)pp;
++
++ if (mtx == NULL)
++ icmSetUnity3x3(p->ccmat);
++ else
++ icmCpy3x3(p->ccmat, mtx);
++
++ return inst_ok;
++}
++
++/* Determine if a calibration is needed */
++inst_cal_type colorhug_needs_calibration(inst *pp) {
++ return inst_ok;
++}
++
++/* Request an instrument calibration */
++inst_code colorhug_calibrate(
++inst *pp,
++inst_cal_type calt, /* Calibration type. inst_calt_all for all neeeded */
++inst_cal_cond *calc, /* Current condition/desired condition */
++char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
++) {
++ id[0] = '\000';
++ return inst_unsupported;
++}
++
++/* Convert a machine specific error code into an abstract dtp code */
++static inst_code
++colorhug_interp_code(inst *pp, int ec) {
++ ec &= inst_imask;
++ switch (ec) {
++
++ case COLORHUG_OK:
++ return inst_ok;
++
++ case COLORHUG_INTERNAL_ERROR:
++ case COLORHUG_NO_COMS:
++ case COLORHUG_NOT_INITED:
++ return inst_internal_error | ec;
++
++ case COLORHUG_COMS_FAIL:
++ return inst_coms_fail | ec;
++
++ case COLORHUG_UNKNOWN_MODEL:
++ return inst_unknown_model | ec;
++
++ case COLORHUG_UNKNOWN_CMD:
++ case COLORHUG_WRONG_UNLOCK_CODE:
++ case COLORHUG_NOT_IMPLEMENTED:
++ case COLORHUG_UNDERFLOW_SENSOR:
++ case COLORHUG_NO_SERIAL:
++ case COLORHUG_WATCHDOG:
++ case COLORHUG_INVALID_ADDRESS:
++ case COLORHUG_INVALID_LENGTH:
++ case COLORHUG_INVALID_CHECKSUM:
++ case COLORHUG_INVALID_VALUE:
++ case COLORHUG_UNKNOWN_CMD_FOR_BOOTLOADER:
++ case COLORHUG_NO_CALIBRATION:
++ case COLORHUG_OVERFLOW_MULTIPLY:
++ case COLORHUG_OVERFLOW_ADDITION:
++ case COLORHUG_OVERFLOW_SENSOR:
++ case COLORHUG_OVERFLOW_STACK:
++ case COLORHUG_BAD_WR_LENGTH:
++ case COLORHUG_BAD_RD_LENGTH:
++ case COLORHUG_BAD_RET_CMD:
++ case COLORHUG_BAD_RET_STAT:
++ return inst_protocol_error | ec;
++
++ case COLORHUG_USER_ABORT:
++ return inst_user_abort | ec;
++ case COLORHUG_USER_TERM:
++ return inst_user_term | ec;
++ case COLORHUG_USER_TRIG:
++ return inst_user_trig | ec;
++ case COLORHUG_USER_CMND:
++ return inst_user_cmnd | ec;
++ }
++ return inst_other_error | ec;
++}
++
++/* Destroy ourselves */
++static void
++colorhug_del(inst *pp) {
++ colorhug *p = (colorhug *)pp;
++ if (p->icom != NULL)
++ p->icom->del(p->icom);
++ free(p);
++}
++
++/* Return the instrument capabilities */
++inst_capability colorhug_capabilities(inst *pp) {
++ colorhug *p = (colorhug *)pp;
++ inst_capability rv;
++
++ rv = inst_emis_spot
++ | inst_emis_disp
++ | inst_emis_disp_lcd
++ | inst_colorimeter
++ | inst_ccmx
++ ;
++
++ return rv;
++}
++
++/* Return the instrument capabilities 2 */
++inst2_capability colorhug_capabilities2(inst *pp) {
++ colorhug *p = (colorhug *)pp;
++ inst2_capability rv = 0;
++
++ rv |= inst2_prog_trig;
++ rv |= inst2_keyb_trig;
++ rv |= inst2_has_leds;
++
++ return rv;
++}
++
++/* Set device measurement mode */
++inst_code colorhug_set_mode(inst *pp, inst_mode m)
++{
++ colorhug *p = (colorhug *)pp;
++ inst_mode mm; /* Measurement mode */
++
++ /* The measurement mode portion of the mode */
++ mm = m & inst_mode_measurement_mask;
++
++ /* only display emission mode and ambient supported */
++ if (mm != inst_mode_emis_spot
++ && mm != inst_mode_emis_disp
++ && mm != inst_mode_emis_ambient) {
++ return inst_unsupported;
++ }
++
++ /* Spectral mode is not supported */
++ if (m & inst_mode_spectral)
++ return inst_unsupported;
++
++ p->mode = m;
++ return inst_ok;
++}
++
++/* Set or reset an optional mode */
++static inst_code
++colorhug_set_opt_mode(inst *pp, inst_opt_mode m, ...)
++{
++ colorhug *p = (colorhug *)pp;
++ inst_code ev = inst_ok;
++
++ /* Select CRT/LCD */
++ if (m == inst_opt_disp_crt) {
++ if (p->crt == 0)
++ p->crt = 1;
++ return inst_ok;
++ } else if (m == inst_opt_disp_lcd) {
++ if (p->crt != 0)
++ p->crt = 0;
++ return inst_ok;
++
++ }
++ /* Record the trigger mode */
++ if (m == inst_opt_trig_prog
++ || m == inst_opt_trig_keyb) {
++ p->trig = m;
++ return inst_ok;
++ }
++ if (m == inst_opt_trig_return) {
++ p->trig_return = 1;
++ return inst_ok;
++ } else if (m == inst_opt_trig_no_return) {
++ p->trig_return = 0;
++ return inst_ok;
++ }
++
++ /* Operate the LEDs */
++ if (m == inst_opt_get_gen_ledmask) {
++ va_list args;
++ int *mask = NULL;
++
++ va_start(args, m);
++ mask = va_arg(args, int *);
++ va_end(args);
++ *mask = 0x3; /* Two general LEDs */
++ return inst_ok;
++ } else if (m == inst_opt_get_led_state) {
++ va_list args;
++ int *mask = NULL;
++
++ va_start(args, m);
++ mask = va_arg(args, int *);
++ va_end(args);
++ *mask = p->led_state;
++ return inst_ok;
++ } else if (m == inst_opt_set_led_state) {
++ va_list args;
++ int mask = 0;
++
++ va_start(args, m);
++ mask = va_arg(args, int);
++ va_end(args);
++ return colorhug_set_LEDs(p, mask);
++ }
++
++ return inst_unsupported;
++}
++
++/* Constructor */
++extern colorhug *new_colorhug(icoms *icom, int debug, int verb)
++{
++ colorhug *p;
++ if ((p = (colorhug *)calloc(sizeof(colorhug),1)) == NULL)
++ error("colorhug: malloc failed!");
++
++ if (icom == NULL)
++ p->icom = new_icoms();
++ else
++ p->icom = icom;
++
++ p->debug = debug;
++ p->verb = verb;
++
++ /* Set the colorimeter correction matrix to do nothing */
++ icmSetUnity3x3(p->ccmat);
++
++ p->init_coms = colorhug_init_coms;
++ p->init_inst = colorhug_init_inst;
++ p->capabilities = colorhug_capabilities;
++ p->capabilities2 = colorhug_capabilities2;
++ p->set_mode = colorhug_set_mode;
++ p->set_opt_mode = colorhug_set_opt_mode;
++ p->read_sample = colorhug_read_sample;
++ p->needs_calibration = colorhug_needs_calibration;
++ p->col_cor_mat = colorhug_col_cor_mat;
++ p->calibrate = colorhug_calibrate;
++ p->interp_error = colorhug_interp_error;
++ p->del = colorhug_del;
++
++ /* Until initalisation */
++ p->itype = instUnknown;
++
++ return p;
++}
+diff --git a/spectro/colorhug.h b/spectro/colorhug.h
+new file mode 100644
+index 0000000..6c0a485
+--- /dev/null
++++ b/spectro/colorhug.h
+@@ -0,0 +1,85 @@
++/*
++ * Argyll Color Correction System
++ *
++ * Hughski ColorHug related defines
++ *
++ * Author: Richard Hughes
++ * Date: 30/11/2011
++ *
++ * Copyright 2006 - 2007, Graeme W. Gill
++ * Copyright 2011, Richard Hughes
++ * All rights reserved.
++ *
++ * (Based on huey.h)
++ *
++ * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
++ * see the License2.txt file for licencing details.
++ */
++
++#ifndef COLORHUG_H
++
++#include "inst.h"
++
++/* Note: update colorhug_interp_error() and colorhug_interp_code() in colorhug.c */
++/* if anything of these #defines are added or subtracted */
++
++/* Fake Error codes */
++#define COLORHUG_INTERNAL_ERROR 0x61 /* Internal software error */
++#define COLORHUG_COMS_FAIL 0x62 /* Communication failure */
++#define COLORHUG_UNKNOWN_MODEL 0x63 /* Not an colorhug */
++#define COLORHUG_DATA_PARSE_ERROR 0x64 /* Read data parsing error */
++#define COLORHUG_USER_ABORT 0x65 /* User hit abort */
++#define COLORHUG_USER_TERM 0x66 /* User hit terminate */
++#define COLORHUG_USER_TRIG 0x67 /* User hit trigger */
++#define COLORHUG_USER_CMND 0x68 /* User hit command */
++
++/* Real error codes */
++#define COLORHUG_OK 0x00
++#define COLORHUG_UNKNOWN_CMD 0x01
++#define COLORHUG_WRONG_UNLOCK_CODE 0x02
++#define COLORHUG_NOT_IMPLEMENTED 0x03
++#define COLORHUG_UNDERFLOW_SENSOR 0x04
++#define COLORHUG_NO_SERIAL 0x05
++#define COLORHUG_WATCHDOG 0x06
++#define COLORHUG_INVALID_ADDRESS 0x07
++#define COLORHUG_INVALID_LENGTH 0x08
++#define COLORHUG_INVALID_CHECKSUM 0x09
++#define COLORHUG_INVALID_VALUE 0x0a
++#define COLORHUG_UNKNOWN_CMD_FOR_BOOTLOADER 0x0b
++#define COLORHUG_NO_CALIBRATION 0x0c
++#define COLORHUG_OVERFLOW_MULTIPLY 0x0d
++#define COLORHUG_OVERFLOW_ADDITION 0x0e
++#define COLORHUG_OVERFLOW_SENSOR 0x0f
++#define COLORHUG_OVERFLOW_STACK 0x10
++
++/* Internal errors */
++#define COLORHUG_NO_COMS 0x22
++#define COLORHUG_NOT_INITED 0x23
++#define COLORHUG_BAD_WR_LENGTH 0x25
++#define COLORHUG_BAD_RD_LENGTH 0x26
++#define COLORHUG_BAD_RET_CMD 0x27
++#define COLORHUG_BAD_RET_STAT 0x28
++
++
++/* COLORHUG communication object */
++struct _colorhug {
++ INST_OBJ_BASE
++
++ inst_mode mode; /* Currently selected mode */
++
++ inst_opt_mode trig; /* Reading trigger mode */
++ int trig_return; /* Emit "\n" after trigger */
++
++ int ser_no; /* Serial number */
++ int crt; /* NZ if set to CRT */
++ double ccmat[3][3]; /* Colorimeter correction matrix */
++ int led_state; /* Current LED state */
++
++}; typedef struct _colorhug colorhug;
++
++/* Constructor */
++extern colorhug *new_colorhug(icoms *icom, int debug, int verb);
++
++
++#define COLORHUG_H
++#endif /* COLORHUG_H */
+diff --git a/spectro/inst.c b/spectro/inst.c
+index b73ff6c..cbcda9e 100644
+--- a/spectro/inst.c
++++ b/spectro/inst.c
+@@ -476,6 +476,8 @@ int verb /* Verbosity flag */
+ p = (inst *)new_spyd2(icom, debug, verb);
+ else if (itype == instHuey)
+ p = (inst *)new_huey(icom, debug, verb);
++ else if (itype == instColorHug)
++ p = (inst *)new_colorhug(icom, debug, verb);
+ else {
+ return NULL;
+ }
+diff --git a/spectro/insttypes.c b/spectro/insttypes.c
+index a11f299..ed0170e 100644
+--- a/spectro/insttypes.c
++++ b/spectro/insttypes.c
+@@ -73,6 +73,8 @@ char *inst_name(instType itype) {
+ return "Datacolor Spyder3";
+ case instHuey:
+ return "GretagMacbeth Huey";
++ case instColorHug:
++ return "Hughski ColorHug";
+ default:
+ break;
+ }
+@@ -124,6 +126,8 @@ instType inst_enum(char *name) {
+ return instSpyder3;
+ else if (strcmp(name, "GretagMacbeth Huey") == 0)
+ return instHuey;
++ else if (strcmp(name, "Hughski ColorHug") == 0)
++ return instColorHug;
+
+ return instUnknown;
+ }
+@@ -183,6 +187,11 @@ unsigned short idProduct) {
+ return instSpyder3;
+ }
+
++ if (idVendor == 0x04d8) { /* Microchip */
++ if (idProduct == 0xf8da) /* Hughski ColorHug */
++ return instColorHug;
++ }
++
+ /* Add other instruments here */
+
+ return instUnknown;
+@@ -260,6 +269,8 @@ int inst_illuminant(xspect *sp, instType itype) {
+ case instHuey:
+ return 1; /* Not applicable */
+
++ case instColorHug:
++ return 1; /* Not applicable */
+
+ default:
+ break;
+diff --git a/spectro/insttypes.h b/spectro/insttypes.h
+index 6155cf0..15c6545 100644
+--- a/spectro/insttypes.h
++++ b/spectro/insttypes.h
+@@ -44,6 +44,7 @@ typedef enum {
+ instSpyder2, /* Datacolor/ColorVision Spyder2 */
+ instSpyder3, /* Datacolor Spyder3 */
+ instHuey, /* GretagMacbeth Huey */
++ instColorHug, /* Hughski ColorHug */
+
+ } instType;
+
+diff --git a/lib/Makefile.am b/lib/Makefile.am
+index ad5fcdc..d393228 100644
+--- a/lib/Makefile.am
++++ b/lib/Makefile.am
+@@ -42,6 +42,7 @@ libargyll_a_SOURCES += ../spectro/inst.h ../spectro/inst.c ../spectro/insttypes.
+ ../spectro/i1disp.c ../spectro/i1disp.h ../spectro/i1pro.c ../spectro/i1pro.h ../spectro/i1pro_imp.c ../spectro/i1pro_imp.h \
+ ../spectro/munki.c ../spectro/munki_imp.c ../spectro/ss.c ../spectro/ss.h ../spectro/ss_imp.c ../spectro/ss_imp.h ../spectro/hcfr.c ../spectro/hcfr.h \
+ ../spectro/spyd2.c ../spectro/spyd2.h ../spectro/spyd2setup.h ../spectro/spyd2PLD.h ../spectro/huey.c ../spectro/huey.h ../spectro/unixio.c \
++ ../spectro/colorhug.c ../spectro/colorhug.c \
+ ../spectro/usbio.c ../spectro/hidio.c ../spectro/pollem.c ../spectro/pollem.h ../spectro/icoms.h ../spectro/conv.h ../spectro/usbio.h \
+ ../spectro/hidio.h ../spectro/munki.h ../spectro/munki_imp.h
+
diff --git a/argyllcms.spec b/argyllcms.spec
index 4fa57ce..57f943c 100644
--- a/argyllcms.spec
+++ b/argyllcms.spec
@@ -1,11 +1,19 @@
Name: argyllcms
Version: 1.3.5
-Release: 1%{?dist}
+Release: 3%{?dist}
Summary: ICC compatible color management system
Group: User Interface/X
License: GPLv3 and MIT
URL: http://gitorious.org/hargyllcms
Source0: http://people.freedesktop.org/~hughsient/releases/hargyllcms-%{version}.tar.xz
+
+# Pending upstream review
+Patch1: 0001-Add-an-experimental-ColorHug-sensor-driver.patch
+
+BuildRequires: automake
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: libtool
BuildRequires: libtiff-devel
BuildRequires: libusb1-devel
BuildRequires: libX11-devel
@@ -47,6 +55,9 @@ This package contains the Argyll color management system documentation.
%prep
%setup -q -n hargyllcms-%{version}
+%patch1 -p1 -b .add-colorhug-sensor
+autoreconf
+automake
# we're not allowed to refer to acquisition devices as scanners
./legal.sh
@@ -76,6 +87,9 @@ rm -rf %{buildroot}
%doc doc/*.html doc/*.jpg doc/*.txt
%changelog
+* Fri Dec 02 2011 Richard Hughes <rhughes at redhat.com> - 1.3.5-3
+- Add an experimental ColorHug sensor driver.
+
* Thu Dec 01 2011 Richard Hughes <rhughes at redhat.com> - 1.3.5-1
- Update to 1.3.5
More information about the scm-commits
mailing list