diff options
Diffstat (limited to 'spectro/i1d3.c')
-rwxr-xr-x[-rw-r--r--] | spectro/i1d3.c | 81 |
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); |