summaryrefslogtreecommitdiff
path: root/spectro/i1d3.c
diff options
context:
space:
mode:
Diffstat (limited to 'spectro/i1d3.c')
-rwxr-xr-x[-rw-r--r--]spectro/i1d3.c81
1 files changed, 50 insertions, 31 deletions
diff --git a/spectro/i1d3.c b/spectro/i1d3.c
index 4562a52..7e5c396 100644..100755
--- a/spectro/i1d3.c
+++ b/spectro/i1d3.c
@@ -53,6 +53,7 @@
#include "sa_config.h"
#include "numsup.h"
#endif /* SALONEINSTLIB */
+#include "cgats.h"
#include "xspect.h"
#include "insttypes.h"
#include "conv.h"
@@ -125,8 +126,8 @@ typedef enum {
i1d3_firmver = 0x0012, /* Firmware version string */
i1d3_firmdate = 0x0013, /* Firmware date string */
i1d3_locked = 0x0020, /* Get locked status */
- i1d3_measure1 = 0x0100, /* Used by all measure */
- i1d3_measure2 = 0x0200, /* Used by all measure except ambient */
+ i1d3_freqmeas = 0x0100, /* Measure transition over given time */
+ i1d3_periodmeas = 0x0200, /* Measure time between transition count */
i1d3_readintee = 0x0800, /* Read internal EEPROM */
i1d3_readextee = 0x1200, /* Read external EEPROM */
i1d3_setled = 0x2100, /* Set the LED state */
@@ -155,10 +156,10 @@ static char *inst_desc(i1Disp3CC cc) {
return "GetFirmwareDate";
case i1d3_locked:
return "GetLockedStatus";
- case i1d3_measure1:
- return "Measure1";
- case i1d3_measure2:
- return "Measure2";
+ case i1d3_freqmeas:
+ return "Frequency Measure";
+ case i1d3_periodmeas:
+ return "Period Measure";
case i1d3_readintee:
return "ReadInternalEEPROM";
case i1d3_readextee:
@@ -278,9 +279,9 @@ i1d3_command(
}
/* Hmm. Not sure about this bug workaround. Is this a rev B thing ? */
- /* May get status 0x83 on i1d3_measure2 when there are no transitions ? */
+ /* May get status 0x83 on i1d3_periodmeas when there are no transitions ? */
/* If so, ignore the error. */
- if (rv == inst_ok && cc == i1d3_measure2 && recv[1] == 0x02 && recv[0] == 0x83) {
+ if (rv == inst_ok && cc == i1d3_periodmeas && recv[1] == 0x02 && recv[0] == 0x83) {
int i;
for (i = 2; i < 14; i++) {
if (recv[i] != 0)
@@ -587,7 +588,7 @@ i1d3_unlock(
struct {
char *pname; /* Product name */
unsigned int key[2]; /* Unlock code */
- i1d3_dtype dtype; /* Base type enumerator */
+ i1d3_dtype btype; /* Base type enumerator */
i1d3_dtype stype; /* Sub type enumerator */
} codes[] = {
{ "i1Display3 ", { 0xe9622e9f, 0x8d63e133 }, i1d3_disppro, i1d3_disppro },
@@ -597,6 +598,7 @@ i1d3_unlock(
{ "i1Display3 ", { 0x160eb6ae, 0x14440e70 }, i1d3_disppro, i1d3_quato_sh3 },
{ "i1Display3 ", { 0x291e41d7, 0x51937bdd }, i1d3_disppro, i1d3_hp_dreamc },
{ "i1Display3 ", { 0xc9bfafe0, 0x02871166 }, i1d3_disppro, i1d3_sc_c6 },
+ { "i1Display3 ", { 0x1abfae03, 0xf25ac8e8 }, i1d3_disppro, i1d3_wacom_dc },
{ NULL }
};
inst_code ev;
@@ -630,7 +632,7 @@ i1d3_unlock(
// codes[ix].key[0], codes[ix].key[1]);
a1logd(p->log, 3, "i1d3_unlock: Trying unlock key %d/%d\n", ix+1, nix);
- p->dtype = codes[ix].dtype;
+ p->btype = codes[ix].btype;
p->stype = codes[ix].stype;
/* Attempt unlock */
@@ -778,7 +780,7 @@ i1d3_read_external_eeprom(
/* Take a raw measurement using a given integration time. */
/* The measurent is the count of (both) edges from the L2V */
-/* over the integration time */
+/* over the integration time. */
static inst_code
i1d3_freq_measure(
i1d3 *p, /* Object */
@@ -804,21 +806,31 @@ i1d3_freq_measure(
todev[23] = 0; /* Unknown parameter, always 0 */
- if ((ev = i1d3_command(p, i1d3_measure1, todev, fromdev, I1D3_MEAS_TIMEOUT, 0)) != inst_ok)
+ if ((ev = i1d3_command(p, i1d3_freqmeas, todev, fromdev, I1D3_MEAS_TIMEOUT, 0)) != inst_ok)
return ev;
rgb[0] = (double)buf2uint(fromdev + 2);
rgb[1] = (double)buf2uint(fromdev + 6);
rgb[2] = (double)buf2uint(fromdev + 10);
+ /* The HW holds the L2F *OE high (disabled) until the start of the measurement period, */
+ /* and this has the effect of holding the internal integrator in a reset state. */
+ /* This then synchronizes the frequency output to the start of */
+ /* the measurement, which has the effect of rounding down the count output. */
+ /* To compensate, we have to add 0.5 to the count. */
+ rgb[0] += 0.5;
+ rgb[1] += 0.5;
+ rgb[2] += 0.5;
+
return inst_ok;
}
/* Take a raw measurement that returns the number of clocks */
-/* between and initial edge and edgec[] subsequent edges of the L2F. */
-/* The edge count must be between 1 and 65535 inclusive. */
-/* Both edges are counted. It's advisable to use an even edgec[], */
-/* because the L2F output may not be symetric. */
+/* between and initial edge at the start of the period (triggered by */
+/* the *OE going low and the integrator being started) and edgec[] */
+/* subsequent edges of the L2F. The edge count must be between */
+/* 1 and 65535 inclusive. Both edges are counted. It's advisable */
+/* to use an even edgec[], because the L2F output may not be symetric. */
/* If there are no edges within 10 seconds, return a count of 0 */
static inst_code
i1d3_period_measure(
@@ -841,7 +853,7 @@ i1d3_period_measure(
todev[7] = (unsigned char)mask;
todev[8] = 0; /* Unknown parameter, always 0 */
- if ((ev = i1d3_command(p, i1d3_measure2, todev, fromdev, I1D3_MEAS_TIMEOUT, 0)) != inst_ok)
+ if ((ev = i1d3_command(p, i1d3_periodmeas, todev, fromdev, I1D3_MEAS_TIMEOUT, 0)) != inst_ok)
return ev;
rgb[0] = (double)buf2uint(fromdev + 2);
@@ -932,6 +944,9 @@ i1d3_set_LEDs(
To break up the USB synchronization, the integration time
is randomized slightly.
+
+ NOTE :- we should really switch to using period measurement mode here,
+ since it is more accurate ?
*/
#ifndef PSRAND32L
@@ -1577,7 +1592,8 @@ i1d3_take_emis_measurement(
isth = p->th_en;
p->th_en = 0;
- /* If we should take a frequency measurement first */
+ /* If we should take a frequency measurement first, */
+ /* since it is done in a predictable duration */
if (mode == i1d3_adaptive || mode == i1d3_frequency) {
/* Typically this is 200msec for non-refresh, 400msec for refresh. */
@@ -1635,7 +1651,7 @@ i1d3_take_emis_measurement(
continue;
if (rmeas[i] < 10.0
- || (p->dtype != i1d3_munkdisp && rmeas[i] < 20.0)) {
+ || (p->btype != i1d3_munkdisp && rmeas[i] < 20.0)) {
a1logd(p->log,3,"chan %d needs pre-measurement\n",i);
mask2 |= 1 << i;
} else {
@@ -1667,7 +1683,7 @@ i1d3_take_emis_measurement(
/* Transfer updated counts from 1st initial measurement */
for (i = 0; i < 3; i++) {
if ((mask2 & (1 << i)) != 0) {
- rmeas[i] = rmeas2[i];
+ rmeas[i] = rmeas2[i];
/* Compute trial RGB in case we need it later */
if (rmeas[i] >= 0.5) {
@@ -1680,7 +1696,7 @@ i1d3_take_emis_measurement(
/* we are measuring a CRT with a refresh rate which adds innacuracy, */
/* and could result in a unecessarily long re-reading. */
/* Don't do this for Munki Display, because of its slow measurements. */
- if (p->dtype != i1d3_munkdisp) {
+ if (p->btype != i1d3_munkdisp) {
for (i = 0; i < 3; i++) {
if ((mask2 & (1 << i)) == 0)
continue;
@@ -2465,9 +2481,12 @@ i1d3_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
/* something to do with detaching the default HID driver ?? */
#if defined(UNIX_X11)
usbflags |= icomuf_detach;
- usbflags |= icomuf_no_open_clear;
usbflags |= icomuf_reset_before_close;
#endif
+
+ /* On MSWin it doesn't like clearing on open when running direct (i.e not HID) */
+ usbflags |= icomuf_no_open_clear;
+
/* Open as an HID if available */
if (p->icom->port_type(p->icom) == icomt_hid) {
@@ -2579,7 +2598,7 @@ i1d3_init_inst(inst *pp) {
return ev;
if (p->prod_type == 0x0002) { /* If ColorMunki Display */
/* Set this in case it doesn't need unlocking */
- p->dtype = p->stype = i1d3_munkdisp;
+ p->btype = p->stype = i1d3_munkdisp;
}
if ((ev = i1d3_get_firmver(p, p->firm_ver)) != inst_ok)
return ev;
@@ -2731,7 +2750,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
}
/* Attempt a refresh display frame rate calibration if needed */
- if (p->dtype != i1d3_munkdisp && p->refrmode != 0 && p->rrset == 0) {
+ if (p->btype != i1d3_munkdisp && p->refrmode != 0 && p->rrset == 0) {
inst_code ev = inst_ok;
p->mininttime = 2.0 * p->dinttime;
@@ -2804,7 +2823,7 @@ double *ref_rate) {
if (!p->inited)
return inst_no_init;
- if (p->dtype == i1d3_munkdisp)
+ if (p->btype == i1d3_munkdisp)
return inst_unsupported;
if (ref_rate != NULL)
@@ -2928,7 +2947,7 @@ static inst_code i1d3_get_n_a_cals(inst *pp, inst_cal_type *pn_cals, inst_cal_ty
inst_cal_type n_cals = inst_calt_none;
inst_cal_type a_cals = inst_calt_none;
- if (p->dtype != i1d3_munkdisp && p->refrmode != 0) {
+ if (p->btype != i1d3_munkdisp && p->refrmode != 0) {
if (p->rrset == 0)
n_cals |= inst_calt_ref_freq;
a_cals |= inst_calt_ref_freq;
@@ -2988,7 +3007,7 @@ char id[CALIDLEN] /* Condition identifier (ie. white reference ID) */
return inst_unsupported;
}
- if ((*calt & inst_calt_ref_freq) && p->dtype != i1d3_munkdisp && p->refrmode != 0) {
+ if ((*calt & inst_calt_ref_freq) && p->btype != i1d3_munkdisp && p->refrmode != 0) {
inst_code ev = inst_ok;
p->mininttime = 2.0 * p->dinttime;
@@ -3498,7 +3517,7 @@ inst3_capability *pcap3) {
| inst2_set_min_int_time
;
- if (p->dtype != i1d3_munkdisp) {
+ if (p->btype != i1d3_munkdisp) {
cap2 |= inst2_meas_disp_update;
cap2 |= inst2_get_refresh_rate;
cap2 |= inst2_set_refresh_rate;
@@ -3865,7 +3884,7 @@ i1d3_get_set_opt(inst *pp, inst_opt_type m, ...) {
p->omininttime = dval;
/* Hmm. This code is duplicated a lot.. */
- if (p->dtype != i1d3_munkdisp && p->refrmode != 0) {
+ if (p->btype != i1d3_munkdisp && p->refrmode != 0) {
inst_code ev = inst_ok;
p->mininttime = 2.0 * p->dinttime;
@@ -4038,7 +4057,7 @@ i1d3_get_set_opt(inst *pp, inst_opt_type m, ...) {
}
/* Constructor */
-extern i1d3 *new_i1d3(icoms *icom, instType itype) {
+extern i1d3 *new_i1d3(icoms *icom, instType dtype) {
i1d3 *p;
if ((p = (i1d3 *)calloc(sizeof(i1d3),1)) == NULL) {
@@ -4073,7 +4092,7 @@ extern i1d3 *new_i1d3(icoms *icom, instType itype) {
p->del = i1d3_del;
p->icom = icom;
- p->itype = itype;
+ p->dtype = dtype;
amutex_init(p->lock);
icmSetUnity3x3(p->ccmat);