~ubuntu-branches/ubuntu/trusty/argyll/trusty-proposed

« back to all changes in this revision

Viewing changes to spectro/dtp92.c

  • Committer: Package Import Robot
  • Author(s): Artur Rona
  • Date: 2014-02-12 00:35:39 UTC
  • mfrom: (13.1.24 sid)
  • Revision ID: package-import@ubuntu.com-20140212003539-24tautzlitsiz61w
Tags: 1.5.1-5ubuntu1
* Merge from Debian unstable. (LP: #1275572) Remaining changes:
  - debian/control:
    + Build-depend on libtiff-dev rather than libtiff4-dev.
  - debian/control, debian/patches/06_fix_udev_rule.patch:
    + Fix udev rules to actually work; ENV{ACL_MANAGE} has
      stopped working ages ago, and with logind it's now the
      "uaccess" tag. Dropping also consolekit from Recommends.
  - debian/patches/drop-usb-db.patch:
    + Use hwdb builtin, instead of the obsolete usb-db
      in the udev rules.
* debian/patches/05_ftbfs-underlinkage.diff:
  - Dropped change, no needed anymore.
* Refresh the patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 * Author: Graeme W. Gill
7
7
 * Date:   5/10/1996
8
8
 *
9
 
 * Copyright 1996 - 2007, Graeme W. Gill
 
9
 * Copyright 1996 - 2013, Graeme W. Gill
10
10
 * All rights reserved.
11
11
 *
12
12
 * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
31
31
   and agreed to support.
32
32
 */
33
33
 
 
34
/*
 
35
        TTBD:
 
36
                Should make DTP92 switch trigger a reading.
 
37
 
 
38
 */
 
39
 
34
40
#include <stdio.h>
35
41
#include <stdlib.h>
36
42
#include <ctype.h>
47
53
#endif /* !SALONEINSTLIB */
48
54
#include "xspect.h"
49
55
#include "insttypes.h"
 
56
#include "conv.h"
50
57
#include "icoms.h"
51
 
#include "conv.h"
52
58
#include "dtp92.h"
53
59
 
54
 
#undef DEBUG
55
 
 
56
60
/* Default flow control */
57
61
#define DEFFC fc_none
58
62
 
90
94
 
91
95
/* Interpret an icoms error into a DTP92 error */
92
96
static int icoms2dtp92_err(int se) {
93
 
        if (se & ICOM_USERM) {
94
 
                se &= ICOM_USERM;
95
 
                if (se == ICOM_USER)
96
 
                        return DTP92_USER_ABORT;
97
 
                if (se == ICOM_TERM)
98
 
                        return DTP92_USER_TERM;
99
 
                if (se == ICOM_TRIG)
100
 
                        return DTP92_USER_TRIG;
101
 
                if (se == ICOM_CMND)
102
 
                        return DTP92_USER_CMND;
103
 
        }
104
 
        if (se != ICOM_OK)
 
97
        if (se != ICOM_OK) {
 
98
                if (se & ICOM_TO)
 
99
                        return DTP92_TIMEOUT; 
105
100
                return DTP92_COMS_FAIL;
 
101
        }
106
102
        return DTP92_OK;
107
103
}
108
104
 
123
119
        int rv, se;
124
120
 
125
121
        if ((se = p->icom->write_read(p->icom, in, out, bsize, tc, ntc, to)) != 0) {
126
 
#ifdef DEBUG
127
 
                printf("dtp92 fcommand: serial i/o failure on write_read '%s'\n",icoms_fix(in));
128
 
#endif
 
122
                a1logd(p->log, 1, "dtp92_fcommand: serial i/o failure on write_read '%s'\n",icoms_fix(in));
129
123
                return icoms2dtp92_err(se);
130
124
        }
131
125
        rv = DTP92_OK;
133
127
                rv = extract_ec(out);
134
128
 
135
129
#ifdef NEVER
136
 
if (strcmp(in, "0PR\r") == 0)
137
 
rv = DTP92_NEEDS_OFFSET_DRIFT_CAL;              /* Emulate 1B error */
 
130
        if (strcmp(in, "0PR\r") == 0)
 
131
                rv = DTP92_NEEDS_OFFSET_DRIFT_CAL;              /* Emulate 1B error */
138
132
#endif /* NEVER */
139
133
 
140
134
                if (rv > 0) {
145
139
                        }
146
140
                }
147
141
        }
148
 
#ifdef DEBUG
149
 
        printf("command '%s'",icoms_fix(in));
150
 
        printf(" returned '%s', value 0x%x\n",icoms_fix(out),rv);
151
 
#endif
 
142
        a1logd(p->log, 4, "dtp92_fcommand: command '%s' returned '%s', value 0x%x\n",
 
143
                                                  icoms_fix(in), icoms_fix(out),rv);
152
144
 
153
145
#ifdef IGNORE_NEEDS_OFFSET_DRIFT_CAL_ERR
154
146
        if (strcmp(in, "0PR\r") == 0 && rv == DTP92_NEEDS_OFFSET_DRIFT_CAL) {
155
147
                static int warned = 0;
156
148
                if (!warned) {
157
 
                        warning("Got error NEEDS_OFFSET_DRIFT_CAL on instrument reset - being ignored.");
 
149
                        a1logw(p->log,"dtp92: Got error NEEDS_OFFSET_DRIFT_CAL on instrument reset - being ignored.");
158
150
                        warned = 1;
159
151
                }
160
152
                rv = 0;
175
167
/* If it's a serial port, use the baud rate given, and timeout in to secs */
176
168
/* Return DTP_COMS_FAIL on failure to establish communications */
177
169
static inst_code
178
 
dtp92_init_coms(inst *pp, int port, baud_rate br, flow_control fc, double tout) {
 
170
dtp92_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
179
171
        dtp92 *p = (dtp92 *) pp;
180
172
        static char buf[MAX_MES_SIZE];
181
173
        baud_rate brt[5] = { baud_9600, baud_19200, baud_4800, baud_2400, baud_1200 };
182
174
        char *brc[5]     = { "30BR\r",  "60BR\r",   "18BR\r",  "0CBR\r",  "06BR\r" };
183
175
        char *fcc;
184
176
        unsigned int etime;
185
 
        instType itype;
186
 
        int ci, bi, i, rv;
 
177
        instType itype = pp->itype;
 
178
        int ci, bi, i, se;
187
179
        inst_code ev = inst_ok;
188
180
 
189
 
        if (p->debug) {
190
 
                p->icom->debug = p->debug;      /* Turn on debugging */
191
 
                fprintf(stderr,"dtp92: About to init coms\n");
192
 
        }
193
 
 
194
 
        if ((itype = p->icom->is_usb_portno(p->icom, port)) != instUnknown) {
195
 
 
196
 
                if (p->debug) fprintf(stderr,"dtp92Q/dtp94: About to init USB\n");
 
181
        if (p->icom->port_type(p->icom) == icomt_usb) {
 
182
#ifdef ENABLE_USB
 
183
 
 
184
                a1logd(p->log, 2, "dtp92_init_coms: About to init USB\n");
197
185
 
198
186
                /* Note that the 92Q and 94 have a different  */
199
187
                /* arrangement of end points:                           */
208
196
                /*                                                                                      */
209
197
                /* Set config, interface, write end point, read end point, read quanta */
210
198
                if (itype == instDTP94)
211
 
                        p->icom->set_usb_port(p->icom, port, 1, 0x02, 0x81, icomuf_none, 0, NULL); 
 
199
                        se = p->icom->set_usb_port(p->icom, 1, 0x02, 0x81, icomuf_none, 0, NULL); 
212
200
                else
213
 
                        p->icom->set_usb_port(p->icom, port, 1, 0x01, 0x81, icomuf_none, 0, NULL); 
 
201
                        se = p->icom->set_usb_port(p->icom, 1, 0x01, 0x81, icomuf_none, 0, NULL); 
 
202
 
 
203
                if (se != ICOM_OK) { 
 
204
                        a1logd(p->log, 1, "dtp92_init_coms: set_usb_port failed ICOM err 0x%x\n",se);
 
205
                        return dtp92_interp_code((inst *)p, icoms2dtp92_err(se));
 
206
                }
214
207
 
215
208
                /* Blind reset it twice - it seems to sometimes hang up */
216
209
                /* otherwise under OSX */
217
210
                dtp92_command(p, "0PR\r", buf, MAX_MES_SIZE, 0.5);
218
211
                dtp92_command(p, "0PR\r", buf, MAX_MES_SIZE, 0.5);
 
212
#else   /* !ENABLE_USB */
 
213
                a1logd(p->log, 1, "dtp20: Failed to find USB connection to instrument\n");
 
214
                return inst_coms_fail;
 
215
#endif  /* !ENABLE_USB */
219
216
 
220
217
        } else {
221
218
 
222
 
                if (p->debug) fprintf(stderr,"dtp92: About to init Serial I/O\n");
 
219
#ifdef ENABLE_SERIAL
 
220
                a1logd(p->log, 2, "dtp92_init_coms: About to init Serial I/O\n");
223
221
 
224
222
                /* Deal with flow control setting */
225
223
                if (fc == fc_nc)
254
252
 
255
253
                while (msec_time() < etime) {
256
254
 
257
 
                        if (p->debug) fprintf(stderr,"dtp92: Trying different baud rates (%u ticks to go)\n",etime - msec_time());
 
255
                        a1logd(p->log, 4, "dtp92_init_coms: Trying different baud rates (%u msec to go)\n",
 
256
                                                              etime - msec_time());
258
257
 
259
258
                        /* Until we time out, find the correct baud rate */
260
259
                        for (i = ci; msec_time() < etime;) {
261
 
                                p->icom->set_ser_port(p->icom, port, fc_none, brt[i], parity_none,
262
 
                                                                                 stop_1, length_8);
 
260
                                if ((se = p->icom->set_ser_port(p->icom, fc_none, brt[i], parity_none,
 
261
                                                                            stop_1, length_8)) != ICOM_OK) { 
 
262
                                        a1logd(p->log, 1, "dtp92_init_coms: set_ser_port failed ICOM err 0x%x\n",se);
 
263
                                        return dtp92_interp_code((inst *)p, icoms2dtp92_err(se));
 
264
                                }
 
265
 
263
266
                                if (((ev = dtp92_command(p, "\r", buf, MAX_MES_SIZE, 0.5)) & inst_mask)
264
 
                                                                                           != inst_coms_fail) {
 
267
                                                                                         != inst_coms_fail)
265
268
                                        break;          /* We've got coms or user abort */
 
269
 
 
270
                                /* Check for user abort */
 
271
                                if (p->uicallback != NULL) {
 
272
                                        inst_code ev;
 
273
                                        if ((ev = p->uicallback(p->uic_cntx, inst_negcoms)) == inst_user_abort) {
 
274
                                                a1logd(p->log, 1, "dtp92_init_coms: user aborted\n");
 
275
                                                return inst_user_abort;
 
276
                                        }
266
277
                                }
 
278
        
267
279
                                if (++i >= 5)
268
280
                                        i = 0;
269
281
                        }
270
 
 
271
 
                        if ((ev & inst_mask) == inst_user_abort)
272
 
                                return ev;
273
 
 
274
282
                        break;          /* Got coms */
275
283
                }
276
284
 
283
291
                        return ev;
284
292
 
285
293
                /* Change the baud rate to the rate we've been told */
286
 
                if ((rv = p->icom->write_read(p->icom, brc[bi], buf, MAX_MES_SIZE, '>', 1, .2)) != 0) {
 
294
                if ((se = p->icom->write_read(p->icom, brc[bi], buf, MAX_MES_SIZE, '>', 1, .2)) != 0) {
287
295
                        if (extract_ec(buf) != DTP92_OK)
288
296
                                return inst_coms_fail;
289
297
                }
290
298
 
291
299
                /* Configure our baud rate and handshaking as well */
292
 
                p->icom->set_ser_port(p->icom, port, fc, brt[bi], parity_none, stop_1, length_8);
 
300
                if ((se = p->icom->set_ser_port(p->icom, fc, brt[bi], parity_none,
 
301
                                                            stop_1, length_8)) != ICOM_OK) { 
 
302
                        a1logd(p->log, 1, "dtp92_init_coms: set_ser_port failed ICOM err 0x%x\n",se);
 
303
                        return dtp92_interp_code((inst *)p, icoms2dtp92_err(se));
 
304
                }
293
305
 
294
306
                /* Loose a character (not sure why) */
295
307
                p->icom->write_read(p->icom, "\r", buf, MAX_MES_SIZE, '>', 1, 0.1);
 
308
#else   /* !ENABLE_SERIAL */
 
309
                a1logd(p->log, 1, "dtp20: Failed to find serial connection to instrument\n");
 
310
                return inst_coms_fail;
 
311
#endif  /* !ENABLE_SERIAL */
296
312
        }
297
313
 
298
314
        /* Check instrument is responding, and reset it again. */
299
315
        if ((ev = dtp92_command(p, "\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok
300
316
         || (ev = dtp92_command(p, "0PR\r", buf, MAX_MES_SIZE, 2.0)) != inst_ok) {
301
317
 
302
 
                if (p->debug) fprintf(stderr,"dtp92: init coms has failed\n");
 
318
                a1logd(p->log, 1, "dtp92_init_coms: failed with ICOM 0x%x\n",ev);
303
319
 
304
320
#ifdef NEVER    /* Experimental code for fixing 0x1B "Offset Drift invalid" error */
305
321
                if ((ev & inst_mask) == inst_hardware_fail) {
334
350
                
335
351
                p->icom->del(p->icom);          /* Since caller may not clean up */
336
352
                p->icom = NULL;
337
 
#ifdef DEBUG
338
 
                printf("^M failed to get a response, returning inst_coms_fail\n");
339
 
#endif
340
353
                return inst_coms_fail;
341
354
        }
342
355
 
343
 
        if (p->debug) fprintf(stderr,"dtp92: init coms has suceeded\n");
344
 
#ifdef DEBUG
345
 
        printf("Got communications\n");
346
 
#endif
 
356
        a1logd(p->log, 2, "dtp92_init_coms: init coms has suceeded\n");
347
357
 
348
358
        p->gotcoms = 1;
349
359
        return inst_ok;
350
360
}
351
361
 
 
362
static inst_code set_default_disp_type(dtp92 *p);
 
363
 
352
364
/* Initialise the DTP92 */
353
365
/* return non-zero on an error, with dtp error code */
354
366
static inst_code
357
369
        static char buf[MAX_MES_SIZE];
358
370
        inst_code ev = inst_ok;
359
371
 
360
 
        if (p->debug) fprintf(stderr,"dtp92: About to init instrument\n");
 
372
        a1logd(p->log, 2, "dtp92_init_inst: called\n");
361
373
 
362
374
        if (p->gotcoms == 0)
363
375
                return inst_internal_error;             /* Must establish coms before calling init */
466
478
                if ((ev = dtp92_command(p, "10SS\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok)
467
479
                        return ev;
468
480
        }
469
 
        p->trig = inst_opt_trig_keyb;
 
481
        p->trig = inst_opt_trig_user;
 
482
 
 
483
        /* Set the default display type */
 
484
        if ((ev = set_default_disp_type(p)) != inst_ok)
 
485
                return ev;
470
486
 
471
487
        /* ??? Need to set CTYP appropriately ??? */
472
488
 
483
499
                                return inst_coms_fail;
484
500
                        tb[0] = val;
485
501
                        tb[1] = '\000';
486
 
                        printf("Mem location 0x%04x = 0x%02x '%s'\n",i,val,icoms_fix(tb));
 
502
                        a1logd(p->log, 0, "Mem location 0x%04x = 0x%02x '%s'\n",i,val,icoms_fix(tb));
487
503
                }
488
504
        }
489
505
#endif /* NEVER */
490
506
 
491
 
        if (p->verb) {
 
507
        if (p->log->verb) {
492
508
                int i, j;
493
 
                if ((ev = dtp92_command(p, "GI\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok)
 
509
                if ((ev = dtp92_command(p, "GI\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok) {
 
510
                        a1logd(p->log, 1, "dtp20: GI command failed with ICOM err 0x%x\n",ev);
494
511
                        return ev;
 
512
                }
495
513
                for (j = i = 0; ;i++) {
496
514
                        if (buf[i] == '<' || buf[i] == '\000')
497
515
                                break;
498
516
                        if (buf[i] == '\r') {
499
517
                                buf[i] = '\000';
500
 
                                printf(" %s\n",&buf[j]);
 
518
                                a1logv(p->log, 1, " %s\n",&buf[j]);
501
519
                                if (buf[i+1] == '\n')
502
520
                                        i++;
503
521
                                j = i+1;
505
523
                }
506
524
        }
507
525
 
508
 
        if (ev == inst_ok) {
509
 
                p->inited = 1;
510
 
                if (p->debug) fprintf(stderr,"dtp92: instrument inited OK\n");
511
 
        }
 
526
        p->inited = 1;
 
527
        a1logd(p->log, 2, "dtp92_init_inst: instrument inited OK\n");
512
528
 
513
 
        return ev;
 
529
        return inst_ok;
514
530
}
515
531
 
516
532
/* The DTP92 seems to have a bug whereby it adds a spurious */
522
538
dtp92_read_sample(
523
539
inst *pp,
524
540
char *name,                     /* Strip name (7 chars) */
525
 
ipatch *val) {          /* Pointer to instrument patch value */
 
541
ipatch *val,            /* Pointer to instrument patch value */
 
542
instClamping clamp) {           /* NZ if clamp XYZ/Lab to be +ve */
526
543
        dtp92 *p = (dtp92 *)pp;
527
544
        char buf[MAX_RD_SIZE];
528
545
        int tries;
529
546
        int user_trig = 0;
530
 
        int rv = inst_protocol_error;
 
547
        inst_code rv = inst_protocol_error;
531
548
 
532
549
        if (!p->gotcoms)
533
550
                return inst_no_coms;
543
560
        }
544
561
#endif
545
562
 
546
 
        if (p->trig == inst_opt_trig_keyb) {
547
 
                int se;
548
 
                if ((se = icoms_poll_user(p->icom, 1)) != ICOM_TRIG) {
549
 
                        /* Abort, term or command */
550
 
                        return dtp92_interp_code((inst *)p, icoms2dtp92_err(se));
551
 
                }
552
 
                user_trig = 1;
553
 
                if (p->trig_return)
554
 
                        printf("\n");
 
563
        if (p->trig == inst_opt_trig_user) {
 
564
 
 
565
                if (p->uicallback == NULL) {
 
566
                        a1logd(p->log, 1, "dtp92: inst_opt_trig_user but no uicallback function set!\n");
 
567
                        return inst_unsupported;
 
568
                }
 
569
 
 
570
                for (;;) {
 
571
                        if ((rv = p->uicallback(p->uic_cntx, inst_armed)) != inst_ok) {
 
572
                                if (rv == inst_user_abort)
 
573
                                        return rv;                              /* Abort */
 
574
                                if (rv == inst_user_trig) {
 
575
                                        user_trig = 1;
 
576
                                        break;                                  /* Trigger */
 
577
                                }
 
578
                        }
 
579
                        msec_sleep(200);
 
580
                }
 
581
                /* Notify of trigger */
 
582
                if (p->uicallback)
 
583
                        p->uicallback(p->uic_cntx, inst_triggered); 
 
584
 
 
585
        /* Progromatic Trigger */
 
586
        } else {
 
587
                /* Check for abort */
 
588
                if (p->uicallback != NULL
 
589
                 && (rv = p->uicallback(p->uic_cntx, inst_armed)) == inst_user_abort)
 
590
                        return rv;                              /* Abort */
555
591
        }
556
592
 
557
593
        /* Until we get a valid return */
562
598
                if ((rv = dtp92_command(p, "RM\r", buf, MAX_RD_SIZE, 10.0)) != inst_ok) {
563
599
                        if ((rv & inst_imask) == DTP92_NEEDS_OFFSET_CAL)
564
600
                                p->need_offset_cal = 1;
565
 
                        else if ((rv & inst_imask) == DTP92_NEEDS_RATIO_CAL)
 
601
                        else if ((rv & inst_imask) == DTP92_NEEDS_RATIO_CAL)    /* DTP92 only */
566
602
                                p->need_ratio_cal = 1;
567
603
                        return rv;
568
604
                }
569
605
 
570
606
                if (sscanf(buf, " X%*c %lf\t Y%*c %lf\t Z%*c %lf ",
571
 
                   &val->aXYZ[0], &val->aXYZ[1], &val->aXYZ[2]) == 3) {
 
607
                   &val->XYZ[0], &val->XYZ[1], &val->XYZ[2]) == 3) {
572
608
 
573
609
                        /* Apply the colorimeter correction matrix */
574
 
                        icmMulBy3x3(val->aXYZ, p->ccmat, val->aXYZ);
 
610
                        icmMulBy3x3(val->XYZ, p->ccmat, val->XYZ);
575
611
 
576
 
                        val->XYZ_v = 0;
577
 
                        val->aXYZ_v = 1;                /* These are absolute XYZ readings */
578
 
                        val->Lab_v = 0;
 
612
                        /* This may not change anything since instrument may clamp */
 
613
                        if (clamp)
 
614
                                icmClamp3(val->XYZ, val->XYZ);
 
615
                        val->loc[0] = '\000';
 
616
                        val->mtype = inst_mrt_emission;
 
617
                        val->XYZ_v = 1;         /* These are absolute XYZ readings */
579
618
                        val->sp.spec_n = 0;
580
619
                        val->duration = 0.0;
581
620
                        rv = inst_ok;
582
621
                        break;
583
622
                } else {
584
 
//printf("~1 failed to parse string '%s'\n",buf);
 
623
                        a1logd(p->log, 1, "dtp92_read_sample: failed to parse string '%s'\n",buf);
585
624
                        rv = inst_coms_fail;
586
625
                }
587
626
        }
599
638
        return rv;
600
639
}
601
640
 
 
641
/* Read an emissive refresh rate */
 
642
static inst_code
 
643
dtp92_read_refrate(
 
644
inst *pp,
 
645
double *ref_rate
 
646
) {
 
647
        dtp92 *p = (dtp92 *)pp;
 
648
        char buf[MAX_RD_SIZE];
 
649
        char buf2[MAX_RD_SIZE];
 
650
        double refrate = 0.0;
 
651
        inst_code rv;
 
652
 
 
653
        if (!p->gotcoms)
 
654
                return inst_no_coms;
 
655
        if (!p->inited)
 
656
                return inst_no_init;
 
657
 
 
658
        /* Measure the refresh rate */
 
659
        rv = dtp92_command(p, "00103RM\r", buf, MAX_RD_SIZE, 5.0);
 
660
 
 
661
        if (rv != inst_ok) {
 
662
                if ((rv & inst_imask) == DTP92_NO_DATA_AVAILABLE)
 
663
                        rv = inst_misread;
 
664
                return rv;
 
665
        }
 
666
 
 
667
        if (sscanf(buf, "Hz %lf ", &refrate) != 1) {
 
668
                a1logd(p->log, 1, "dtp92_read_refrate rate: failed to parse string '%s'\n",buf);
 
669
                *ref_rate = 0.0;
 
670
                return inst_misread;
 
671
        }
 
672
        if (refrate == 0.0) {
 
673
                return inst_misread;
 
674
        }
 
675
        *ref_rate = refrate;
 
676
        return inst_ok;
 
677
}
 
678
 
602
679
/* Insert a colorimetric correction matrix in the instrument XYZ readings */
603
680
/* This is only valid for colorimetric instruments. */
604
681
/* To remove the matrix, pass NULL for the filter filename */
605
 
inst_code dtp92_col_cor_mat(
 
682
static inst_code dtp92_col_cor_mat(
606
683
inst *pp,
607
684
double mtx[3][3]
608
685
) {
621
698
        return inst_ok;
622
699
}
623
700
 
624
 
/* Determine if a calibration is needed. Returns inst_calt_none if not, */
625
 
/* inst_calt_unknown if it is unknown, or inst_calt_XXX if needs calibration, */
626
 
/* and the first type of calibration needed. */
627
 
inst_cal_type dtp92_needs_calibration(inst *pp) {
 
701
/* Return needed and available inst_cal_type's */
 
702
static inst_code dtp92_get_n_a_cals(inst *pp, inst_cal_type *pn_cals, inst_cal_type *pa_cals) {
628
703
        dtp92 *p = (dtp92 *)pp;
629
 
 
630
 
        if (!p->gotcoms)
631
 
                return inst_no_coms;
632
 
        if (!p->inited)
633
 
                return inst_no_init;
 
704
        inst_cal_type n_cals = inst_calt_none;
 
705
        inst_cal_type a_cals = inst_calt_none;
 
706
                
 
707
        if (p->itype == instDTP92) {
 
708
                if (p->need_ratio_cal)
 
709
                        n_cals |= inst_calt_emis_ratio;
 
710
                a_cals |= inst_calt_emis_ratio;
 
711
        }
634
712
 
635
713
        if (p->need_offset_cal)
636
 
                return inst_calt_disp_offset;
637
 
 
638
 
        else if (p->need_ratio_cal)
639
 
                return inst_calt_disp_ratio;
640
 
 
641
 
        return inst_calt_unknown;
 
714
                n_cals |= inst_calt_emis_offset;
 
715
        a_cals |= inst_calt_emis_offset;
 
716
 
 
717
        if (pn_cals != NULL)
 
718
                *pn_cals = n_cals;
 
719
 
 
720
        if (pa_cals != NULL)
 
721
                *pa_cals = a_cals;
 
722
 
 
723
        return inst_ok;
642
724
}
643
725
 
644
726
/* Request an instrument calibration. */
648
730
/* returning inst_needs_cal. Initially use an inst_cal_cond of inst_calc_none, */
649
731
/* and then be prepared to setup the right conditions, or ask the */
650
732
/* user to do so, each time the error inst_cal_setup is returned. */
651
 
inst_code dtp92_calibrate(
 
733
static inst_code dtp92_calibrate(
652
734
inst *pp,
653
 
inst_cal_type calt,             /* Calibration type. inst_calt_all for all neeeded */
 
735
inst_cal_type *calt,    /* Calibration type to do/remaining */
654
736
inst_cal_cond *calc,    /* Current condition/desired condition */
655
737
char id[CALIDLEN]               /* Condition identifier (ie. white reference ID) */
656
738
) {
657
739
        dtp92 *p = (dtp92 *)pp;
658
740
        char buf[MAX_RD_SIZE];
659
 
        inst_code rv = inst_ok;
 
741
        inst_code ev = inst_ok;
 
742
    inst_cal_type needed, available;
 
743
 
 
744
        if (!p->gotcoms)
 
745
                return inst_no_coms;
 
746
        if (!p->inited)
 
747
                return inst_no_init;
 
748
 
660
749
        id[0] = '\000';
661
750
 
662
 
        if (!p->gotcoms)
663
 
                return inst_no_coms;
664
 
        if (!p->inited)
665
 
                return inst_no_init;
666
 
 
667
 
        /* Default to most likely calibration type */
668
 
        if (calt == inst_calt_all) {
669
 
                if (p->need_offset_cal)
670
 
                        calt = inst_calt_disp_offset;
671
 
        
672
 
                else if (p->need_ratio_cal)
673
 
                        calt = inst_calt_disp_ratio;
674
 
 
675
 
                else
676
 
                        calt = inst_calt_disp_offset;
 
751
        if ((ev = dtp92_get_n_a_cals((inst *)p, &needed, &available)) != inst_ok)
 
752
                return ev;
 
753
 
 
754
        /* Translate inst_calt_all/needed into something specific */
 
755
        if (*calt == inst_calt_all
 
756
         || *calt == inst_calt_needed
 
757
         || *calt == inst_calt_available) {
 
758
                if (*calt == inst_calt_all) 
 
759
                        *calt = (needed & inst_calt_n_dfrble_mask) | inst_calt_ap_flag;
 
760
                else if (*calt == inst_calt_needed)
 
761
                        *calt = needed & inst_calt_n_dfrble_mask;
 
762
                else if (*calt == inst_calt_available)
 
763
                        *calt = available & inst_calt_n_dfrble_mask;
 
764
 
 
765
                a1logd(p->log,4,"dtp92_calibrate: doing calt 0x%x\n",calt);
 
766
 
 
767
                if ((*calt & inst_calt_n_dfrble_mask) == 0)             /* Nothing todo */
 
768
                        return inst_ok;
677
769
        }
678
770
 
679
771
        /* See if it's a calibration we understand */
680
 
        if (calt != inst_calt_disp_offset
681
 
         && calt != inst_calt_disp_ratio)
 
772
        if (*calt & ~available & inst_calt_all_mask) { 
682
773
                return inst_unsupported;
683
 
                
684
 
        /* Make sure the conditions are right for the calbration */
685
 
        if (calt == inst_calt_disp_offset) {
 
774
        }
 
775
 
 
776
        if (*calt & inst_calt_emis_offset) {            /* Dark offset calibration */
 
777
 
686
778
                if (*calc != inst_calc_man_em_dark) {
687
779
                        *calc = inst_calc_man_em_dark;
688
780
                        return inst_cal_setup;
689
781
                }
690
 
        } else if (calt == inst_calt_disp_ratio) {
691
 
                if (*calc != inst_calc_disp_grey
692
 
                 && *calc != inst_calc_disp_grey_darker
693
 
                 && *calc != inst_calc_disp_grey_ligher) {
694
 
                        *calc = inst_calc_disp_grey;
695
 
                        return inst_cal_setup;
696
 
                }
697
 
        }
698
 
 
699
 
        /* Now that setup is right, perform calibration */
700
 
 
701
 
        if (calt == inst_calt_disp_offset) {            /* Dark offset calibration */
702
782
 
703
783
                /* Do offset calibration */
704
 
                if ((rv = dtp92_command(p, "CO\r", buf, MAX_RD_SIZE, 12)) != inst_ok)
705
 
                        return rv;
706
 
 
707
 
                return inst_ok;
708
 
 
709
 
        } else if (calt == inst_calt_disp_ratio) {      /* Cell ratio calibration */
 
784
                if ((ev = dtp92_command(p, "CO\r", buf, MAX_RD_SIZE, 12)) != inst_ok)
 
785
                        return ev;
 
786
 
 
787
                *calt &= inst_calt_emis_offset;
 
788
        }
 
789
 
 
790
        if (*calt & inst_calt_emis_ratio) {     /* Cell ratio calibration */
 
791
 
 
792
                if (*calc != inst_calc_emis_grey
 
793
                 && *calc != inst_calc_emis_grey_darker
 
794
                 && *calc != inst_calc_emis_grey_ligher) {
 
795
                        *calc = inst_calc_emis_grey;
 
796
                        return inst_cal_setup;
 
797
                }
710
798
 
711
799
                /* Do ratio calibration */
712
 
                if ((rv = dtp92_command(p, "CR\r", buf, MAX_RD_SIZE, 25.0)) != inst_ok) {
 
800
                if ((ev = dtp92_command(p, "CR\r", buf, MAX_RD_SIZE, 25.0)) != inst_ok) {
713
801
 
714
 
                        if ((rv & inst_imask) == DTP92_TOO_MUCH_LIGHT) {
715
 
                                *calc = inst_calc_disp_grey_darker;
 
802
                        if ((ev & inst_imask) == DTP92_TOO_MUCH_LIGHT) {
 
803
                                *calc = inst_calc_emis_grey_darker;
716
804
                                return inst_cal_setup;
717
 
                        } else if ((rv & inst_imask) == DTP92_NOT_ENOUGH_LIGHT) {
718
 
                                *calc = inst_calc_disp_grey_ligher;
 
805
                        } else if ((ev & inst_imask) == DTP92_NOT_ENOUGH_LIGHT) {
 
806
                                *calc = inst_calc_emis_grey_ligher;
719
807
                                return inst_cal_setup;
720
808
                        }
721
 
                        return rv;              /* Error */
 
809
                        return ev;              /* Error */
722
810
                }
723
 
        }
724
 
 
725
 
        return rv;
 
811
                *calt &= inst_calt_emis_ratio;
 
812
        }
 
813
 
 
814
        return ev;
 
815
}
 
816
 
 
817
/* Return the last reading refresh rate in Hz. */
 
818
static inst_code dtp92_get_refr_rate(inst *pp,
 
819
double *ref_rate
 
820
) {
 
821
        dtp92 *p = (dtp92 *)pp;
 
822
        char buf[MAX_RD_SIZE];
 
823
        char buf2[MAX_RD_SIZE];
 
824
        double refrate = 0.0;
 
825
        inst_code rv;
 
826
 
 
827
        if (!p->gotcoms)
 
828
                return inst_no_coms;
 
829
        if (!p->inited)
 
830
                return inst_no_init;
 
831
 
 
832
        /* Get the last readings refresh rate */
 
833
        rv = dtp92_command(p, "10103RM\r", buf, MAX_RD_SIZE, 5.0);
 
834
 
 
835
        if (rv != inst_ok) {
 
836
                if ((rv & inst_imask) == DTP92_NO_DATA_AVAILABLE)
 
837
                        rv = inst_misread;
 
838
                return rv;
 
839
        }
 
840
 
 
841
        if (sscanf(buf, "Hz %lf ", &refrate) != 1) {
 
842
                a1logd(p->log, 1, "dtp92_read_refresh rate: failed to parse string '%s'\n",buf);
 
843
                *ref_rate = 0.0;
 
844
                return inst_misread;
 
845
        }
 
846
        if (refrate == 0.0) {
 
847
                return inst_misread;
 
848
        }
 
849
        *ref_rate = refrate;
 
850
        return inst_ok;
 
851
}
 
852
 
 
853
/* Set the calibrated refresh rate in Hz. */
 
854
/* Set refresh rate to 0.0 to mark it as invalid */
 
855
/* Rates outside the range 5.0 to 150.0 Hz will return an error */
 
856
static inst_code dtp92_set_refr_rate(inst *pp,
 
857
double ref_rate
 
858
) {
 
859
        dtp92 *p = (dtp92 *)pp;
 
860
 
 
861
        /* The DTP92 can't have a refresh rate set */
 
862
        return inst_unsupported;
726
863
}
727
864
 
728
865
/* Error codes interpretation */
739
876
                        return "Not a DTP92 or DTP94";
740
877
                case DTP92_DATA_PARSE_ERROR:
741
878
                        return "Data from DTP didn't parse as expected";
742
 
                case DTP92_USER_ABORT:
743
 
                        return "User hit Abort key";
744
 
                case DTP92_USER_TERM:
745
 
                        return "User hit Terminate key";
746
 
                case DTP92_USER_TRIG:
747
 
                        return "User hit Trigger key";
748
 
                case DTP92_USER_CMND:
749
 
                        return "User hit a Command key";
750
879
 
751
880
                case DTP92_OK:
752
881
                        return "No device error";
832
961
                case DTP92_DATA_PARSE_ERROR:
833
962
                        return inst_protocol_error | ec;
834
963
 
835
 
                case DTP92_USER_ABORT:
836
 
                        return inst_user_abort | ec;
837
 
                case DTP92_USER_TERM:
838
 
                        return inst_user_term | ec;
839
 
                case DTP92_USER_TRIG:
840
 
                        return inst_user_trig | ec;
841
 
                case DTP92_USER_CMND:
842
 
                        return inst_user_cmnd | ec;
843
 
 
844
964
                case DTP92_NO_MODULATION:               /* ?? */
845
965
                case DTP92_TOO_MUCH_LIGHT:
846
966
                case DTP92_NOT_ENOUGH_LIGHT:
868
988
        dtp92 *p = (dtp92 *)pp;
869
989
        if (p->icom != NULL)
870
990
                p->icom->del(p->icom);
 
991
        inst_del_disptype_list(p->dtlist, p->ndtlist);
871
992
        free(p);
872
993
}
873
994
 
874
 
/* Return the instrument capabilities */
875
 
inst_capability dtp92_capabilities(inst *pp) {
 
995
/* Return the instrument mode capabilities */
 
996
void dtp92_capabilities(inst *pp,
 
997
inst_mode *pcap1,
 
998
inst2_capability *pcap2,
 
999
inst3_capability *pcap3) {
876
1000
        dtp92 *p = (dtp92 *)pp;
877
 
        inst_capability rv;
878
 
 
879
 
        rv = inst_emis_spot
880
 
           | inst_emis_disp
881
 
           | inst_colorimeter
882
 
           | inst_ccmx
883
 
             ;
 
1001
        inst_mode cap1 = 0;
 
1002
        inst2_capability cap2 = 0;
 
1003
 
 
1004
        cap1 |= inst_mode_emis_spot
 
1005
             |  inst_mode_colorimeter
 
1006
                ;
 
1007
 
 
1008
        cap2 |= inst2_prog_trig
 
1009
             |  inst2_user_trig
 
1010
             |  inst2_ccmx
 
1011
                ;                               /* The '92 does have a switch, but we're not currently supporting it */
884
1012
 
885
1013
        if (p->itype == instDTP94) {
886
 
                rv |= inst_emis_disptype;
887
 
                rv |= inst_emis_disptypem;
888
 
        }
889
 
 
890
 
        return rv;
891
 
}
892
 
 
893
 
/* Return the instrument capabilities 2 */
894
 
inst2_capability dtp92_capabilities2(inst *pp) {
895
 
        dtp92 *p = (dtp92 *)pp;
896
 
        inst2_capability rv;
897
 
 
898
 
        rv = inst2_cal_disp_offset
899
 
           | inst2_prog_trig
900
 
           | inst2_keyb_trig
901
 
           ;                            /* The '92 does have a switch, but we're not currently supporting it */
902
 
 
903
 
        if (p->itype == instDTP92)
904
 
                rv |= inst2_cal_disp_ratio;
905
 
 
906
 
        return rv;
 
1014
                cap2 |= inst2_disptype;
 
1015
        } else {
 
1016
                cap2 |= inst2_refresh_rate;
 
1017
                cap2 |= inst2_emis_refr_meas;
 
1018
        }
 
1019
 
 
1020
        if (pcap1 != NULL)
 
1021
                *pcap1 = cap1;
 
1022
        if (pcap2 != NULL)
 
1023
                *pcap2 = cap2;
 
1024
        if (pcap3 != NULL)
 
1025
                *pcap3 = inst3_none;
 
1026
}
 
1027
 
 
1028
/* Check device measurement mode */
 
1029
inst_code dtp92_check_mode(inst *pp, inst_mode m) {
 
1030
        inst_mode cap;
 
1031
 
 
1032
        if (!pp->gotcoms)
 
1033
                return inst_no_coms;
 
1034
        if (!pp->inited)
 
1035
                return inst_no_init;
 
1036
 
 
1037
        pp->capabilities(pp, &cap, NULL, NULL);
 
1038
 
 
1039
        /* Simple test */
 
1040
        if (m & ~cap)
 
1041
                return inst_unsupported;
 
1042
 
 
1043
        /* Only display emission mode supported */
 
1044
        if (!IMODETST(m, inst_mode_emis_spot)) {
 
1045
                return inst_unsupported;
 
1046
        }
 
1047
 
 
1048
        return inst_ok;
 
1049
}
 
1050
 
 
1051
/* Set device measurement mode */
 
1052
inst_code dtp92_set_mode(inst *pp, inst_mode m) {
 
1053
        inst_code ev;
 
1054
 
 
1055
        if ((ev = dtp92_check_mode(pp, m)) != inst_ok)
 
1056
                return ev;
 
1057
 
 
1058
        return inst_ok;
907
1059
}
908
1060
 
909
1061
inst_disptypesel dtp92_disptypesel[2] = {
910
1062
        {
911
 
                1,
912
 
                "c",
913
 
                "DTP92: CRT display [Default]",
914
 
                1
 
1063
                inst_dtflags_default,           /* flags */
 
1064
                2,                                                      /* cbid */
 
1065
                "c",                                            /* sel */
 
1066
                "CRT display",                          /* desc */
 
1067
                1,                                                      /* refr */
 
1068
                0                                                       /* ix */
915
1069
        },
916
1070
        {
917
 
                0,
918
 
                "",
919
 
                "",
920
 
                -1
 
1071
                inst_dtflags_end,
 
1072
                0,
 
1073
                "",
 
1074
                "",
 
1075
                0,
 
1076
                0
921
1077
        }
922
1078
};
923
1079
 
924
 
inst_disptypesel dtp94_disptypesel[3] = {
 
1080
inst_disptypesel dtp94_disptypesel[4] = {
925
1081
        {
 
1082
                inst_dtflags_default,
926
1083
                1,
927
 
                "c",
928
 
                "DTP94: CRT display",
929
 
                1
930
 
        },
931
 
        {
932
 
                2,
933
1084
                "l",
934
 
                "DTP94: LCD display",
935
 
                0
936
 
        },
937
 
        {
938
 
                0,
939
 
                "",
940
 
                "",
941
 
                -1
 
1085
                "LCD display",
 
1086
                0,
 
1087
                2
 
1088
        },
 
1089
        {
 
1090
                inst_dtflags_none,                      /* flags */
 
1091
                2,                                                      /* cbid */
 
1092
                "c",                                            /* sel */
 
1093
                "CRT display",                          /* desc */
 
1094
                1,                                                      /* refr */
 
1095
                1                                                       /* ix */
 
1096
        },
 
1097
        {
 
1098
                inst_dtflags_none,
 
1099
                3,
 
1100
                "g",
 
1101
                "Generic display",
 
1102
                0,                                                      /* Might be auto refresh detect ? */
 
1103
                0
 
1104
        },
 
1105
        {
 
1106
                inst_dtflags_end,
 
1107
                0,
 
1108
                "",
 
1109
                "",
 
1110
                0,
 
1111
                0
942
1112
        }
943
1113
};
944
1114
 
 
1115
static void set_base_disptype_list(dtp92 *p) {
 
1116
        if (p->itype == instDTP94) {
 
1117
                p->_dtlist = dtp94_disptypesel;
 
1118
        } else {
 
1119
                p->_dtlist = dtp92_disptypesel;
 
1120
        }
 
1121
}
 
1122
 
945
1123
/* Get mode and option details */
946
 
static inst_code dtp92_get_opt_details(
 
1124
static inst_code dtp92_get_disptypesel(
947
1125
inst *pp,
948
 
inst_optdet_type m,     /* Requested option detail type */
949
 
...) {                          /* Status parameters */                             
 
1126
int *pnsels,                            /* Return number of display types */
 
1127
inst_disptypesel **psels,       /* Return the array of display types */
 
1128
int allconfig,                          /* nz to return list for all configs, not just current. */
 
1129
int recreate                            /* nz to re-check for new ccmx & ccss files */
 
1130
) {
950
1131
        dtp92 *p = (dtp92 *)pp;
951
 
 
952
 
        if (m == inst_optdet_disptypesel) {
953
 
                va_list args;
954
 
                int *pnsels;
955
 
                inst_disptypesel **psels;
956
 
 
957
 
                va_start(args, m);
958
 
                pnsels = va_arg(args, int *);
959
 
                psels = va_arg(args, inst_disptypesel **);
960
 
                va_end(args);
961
 
 
962
 
                if (p->itype == instDTP94) {
963
 
                        *pnsels = 2;
964
 
                        *psels = dtp94_disptypesel;
 
1132
        inst_code rv = inst_ok;
 
1133
 
 
1134
        /* Create/Re-create a current list of abailable display types */
 
1135
        if (p->dtlist == NULL || recreate) {
 
1136
                if ((rv = inst_creat_disptype_list(pp, &p->ndtlist, &p->dtlist,
 
1137
                    p->_dtlist, 0 /* doccss*/, 1 /* doccmx */)) != inst_ok)
 
1138
                        return rv;
 
1139
        }
 
1140
 
 
1141
        if (pnsels != NULL)
 
1142
                *pnsels = p->ndtlist;
 
1143
 
 
1144
        if (psels != NULL)
 
1145
                *psels = p->dtlist;
 
1146
 
 
1147
        return inst_ok;
 
1148
}
 
1149
 
 
1150
/* Given a display type entry, setup for that type */
 
1151
static inst_code set_disp_type(dtp92 *p, inst_disptypesel *dentry) {
 
1152
 
 
1153
        p->icx = dentry->ix; 
 
1154
        p->cbid = dentry->cbid; 
 
1155
        p->refrmode = dentry->refr; 
 
1156
 
 
1157
        if (p->itype == instDTP92) {
 
1158
                if (p->icx != 0)
 
1159
                        return inst_unsupported;
 
1160
 
 
1161
        } else {        /* DTP94 */
 
1162
                static char buf[MAX_MES_SIZE];
 
1163
                inst_code ev;
 
1164
                
 
1165
                if (p->icx == 0) {                      /* Generic/Non-specific */
 
1166
                        if ((ev = dtp92_command(p, "0016CF\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok)
 
1167
                                return ev;
 
1168
                } else if (p->icx == 1) {       /* CRT */
 
1169
                        if ((ev = dtp92_command(p, "0116CF\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok)
 
1170
                                return ev;
 
1171
                } else if (p->icx == 2) {       /* LCD */
 
1172
                        if ((ev = dtp92_command(p, "0216CF\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok)
 
1173
                                return ev;
965
1174
                } else {
966
 
                        *pnsels = 1;
967
 
                        *psels = dtp92_disptypesel;
 
1175
                        return inst_unsupported;
968
1176
                }
969
 
                
970
 
                return inst_ok;
971
 
        }
972
 
 
973
 
        return inst_unsupported;
974
 
}
975
 
 
976
 
/* Set device measurement mode */
977
 
inst_code dtp92_set_mode(inst *pp, inst_mode m)
978
 
{
979
 
        inst_mode mm;           /* Measurement mode */
980
 
 
981
 
        if (!pp->gotcoms)
 
1177
        }
 
1178
 
 
1179
        if (dentry->flags & inst_dtflags_ccmx) {
 
1180
                icmCpy3x3(p->ccmat, dentry->mat);
 
1181
        } else {
 
1182
                icmSetUnity3x3(p->ccmat);
 
1183
        }
 
1184
 
 
1185
        return inst_ok;
 
1186
}
 
1187
 
 
1188
/* Setup the default display type */
 
1189
static inst_code set_default_disp_type(dtp92 *p) {
 
1190
        inst_code ev;
 
1191
        int i;
 
1192
 
 
1193
        if (p->dtlist == NULL) {
 
1194
                if ((ev = inst_creat_disptype_list((inst *)p, &p->ndtlist, &p->dtlist,
 
1195
                    p->_dtlist, 0 /* doccss*/, 1 /* doccmx */)) != inst_ok)
 
1196
                        return ev;
 
1197
        }
 
1198
 
 
1199
        for (i = 0; !(p->dtlist[i].flags & inst_dtflags_end); i++) {
 
1200
                if (p->dtlist[i].flags & inst_dtflags_default)
 
1201
                        break;
 
1202
        }
 
1203
        if (p->dtlist[i].flags & inst_dtflags_end) {
 
1204
                a1loge(p->log, 1, "set_default_disp_type: failed to find type!\n");
 
1205
                return inst_internal_error; 
 
1206
        }
 
1207
        if ((ev = set_disp_type(p, &p->dtlist[i])) != inst_ok) {
 
1208
                return ev;
 
1209
        }
 
1210
 
 
1211
        return inst_ok;
 
1212
}
 
1213
 
 
1214
/* Set the display type */
 
1215
static inst_code dtp92_set_disptype(inst *pp, int ix) {
 
1216
        dtp92 *p = (dtp92 *)pp;
 
1217
        inst_code ev;
 
1218
        inst_disptypesel *dentry;
 
1219
 
 
1220
        if (!p->gotcoms)
982
1221
                return inst_no_coms;
983
 
        if (!pp->inited)
 
1222
        if (!p->inited)
984
1223
                return inst_no_init;
985
1224
 
986
 
        /* The measurement mode portion of the mode */
987
 
        mm = m & inst_mode_measurement_mask;
988
 
 
989
 
        /* only display emission mode supported */
990
 
        if (mm != inst_mode_emis_disp
991
 
         && mm != inst_mode_emis_spot) {
992
 
                return inst_unsupported;
993
 
        }
994
 
 
995
 
        /* Spectral mode is not supported */
996
 
        if (m & inst_mode_spectral)
997
 
                return inst_unsupported;
 
1225
        if (p->dtlist == NULL) {
 
1226
                if ((ev = inst_creat_disptype_list(pp, &p->ndtlist, &p->dtlist,
 
1227
                    p->_dtlist, 0 /* doccss*/, 1 /* doccmx */)) != inst_ok)
 
1228
                        return ev;
 
1229
        }
 
1230
 
 
1231
        if (ix < 0 || ix >= p->ndtlist)
 
1232
                return inst_unsupported;
 
1233
 
 
1234
        dentry = &p->dtlist[ix];
 
1235
 
 
1236
        if ((ev = set_disp_type(p, dentry)) != inst_ok) {
 
1237
                return ev;
 
1238
        }
998
1239
 
999
1240
        return inst_ok;
1000
1241
}
1001
1242
 
1002
1243
/* 
1003
1244
 * set or reset an optional mode
1004
 
 * We assume that the instrument has been initialised.
 
1245
 *
 
1246
 * Some options talk to the instrument, and these will
 
1247
 * error if it hasn't been initialised.
1005
1248
 */
1006
1249
static inst_code
1007
 
dtp92_set_opt_mode(inst *pp, inst_opt_mode m, ...)
 
1250
dtp92_get_set_opt(inst *pp, inst_opt_type m, ...)
1008
1251
{
1009
1252
        dtp92 *p = (dtp92 *)pp;
1010
1253
        char buf[MAX_MES_SIZE];
1011
1254
        inst_code ev = inst_ok;
1012
1255
 
1013
 
        if (!p->gotcoms)
1014
 
                return inst_no_coms;
1015
 
        if (!p->inited)
1016
 
                return inst_no_init;
1017
 
 
1018
 
        /* Set the display type */
1019
 
        if (m == inst_opt_disp_type) {
1020
 
                va_list args;
1021
 
                int ix;
1022
 
 
1023
 
                va_start(args, m);
1024
 
                ix = va_arg(args, int);
1025
 
                va_end(args);
1026
 
 
1027
 
                if (ix == 0 && p->itype == instDTP92)
1028
 
                        return inst_ok;
1029
 
                        
1030
 
                if (ix == 1) {
1031
 
                        if (p->itype == instDTP94) {
1032
 
                                if ((ev = dtp92_command(p, "0116CF\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok)
1033
 
                                        return ev;
1034
 
                        }
1035
 
                        return inst_ok;
1036
 
                } else if (ix == 2) {
1037
 
                        if (p->itype == instDTP92)
1038
 
                                return inst_unsupported;
1039
 
                        if ((ev = dtp92_command(p, "0216CF\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok)
1040
 
                                return ev;
1041
 
                        return inst_ok;
1042
 
                } else {
1043
 
                        return inst_unsupported;
1044
 
                }
1045
 
        }
1046
 
 
1047
1256
        /* Record the trigger mode */
1048
1257
        if (m == inst_opt_trig_prog
1049
 
         || m == inst_opt_trig_keyb) {
 
1258
         || m == inst_opt_trig_user) {
1050
1259
                p->trig = m;
1051
1260
                return inst_ok;
1052
1261
        }
1053
 
        if (m == inst_opt_trig_return) {
1054
 
                p->trig_return = 1;
1055
 
                return inst_ok;
1056
 
        } else if (m == inst_opt_trig_no_return) {
1057
 
                p->trig_return = 0;
 
1262
 
 
1263
        if (!p->gotcoms)
 
1264
                return inst_no_coms;
 
1265
        if (!p->inited)
 
1266
                return inst_no_init;
 
1267
 
 
1268
        /* Get the display type information */
 
1269
        if (m == inst_opt_get_dtinfo) {
 
1270
                va_list args;
 
1271
                int *refrmode, *cbid;
 
1272
 
 
1273
                va_start(args, m);
 
1274
                refrmode = va_arg(args, int *);
 
1275
                cbid = va_arg(args, int *);
 
1276
                va_end(args);
 
1277
 
 
1278
                if (refrmode != NULL)
 
1279
                        *refrmode = p->refrmode;
 
1280
                if (cbid != NULL)
 
1281
                        *cbid = p->cbid;
 
1282
 
1058
1283
                return inst_ok;
1059
1284
        }
1060
1285
 
1062
1287
}
1063
1288
 
1064
1289
/* Constructor */
1065
 
extern dtp92 *new_dtp92(icoms *icom, instType itype, int debug, int verb)
1066
 
{
 
1290
extern dtp92 *new_dtp92(icoms *icom, instType itype) {
1067
1291
        dtp92 *p;
1068
 
        if ((p = (dtp92 *)calloc(sizeof(dtp92),1)) == NULL)
1069
 
                error("dtp92: malloc failed!");
1070
 
 
1071
 
        if (icom == NULL)
1072
 
                p->icom = new_icoms();
1073
 
        else
1074
 
                p->icom = icom;
1075
 
 
1076
 
        p->debug = debug;
1077
 
        p->verb = verb;
1078
 
 
1079
 
        icmSetUnity3x3(p->ccmat);       /* Set the colorimeter correction matrix to do nothing */
 
1292
        if ((p = (dtp92 *)calloc(sizeof(dtp92),1)) == NULL) {
 
1293
                a1loge(icom->log, 1, "new_dtp92: malloc failed!\n");
 
1294
                return NULL;
 
1295
        }
 
1296
 
 
1297
        p->log = new_a1log_d(icom->log);
1080
1298
 
1081
1299
        p->init_coms         = dtp92_init_coms;
1082
1300
        p->init_inst         = dtp92_init_inst;
1083
1301
        p->capabilities      = dtp92_capabilities;
1084
 
        p->capabilities2     = dtp92_capabilities2;
1085
 
        p->get_opt_details   = dtp92_get_opt_details;
 
1302
        p->check_mode        = dtp92_check_mode;
1086
1303
        p->set_mode          = dtp92_set_mode;
1087
 
        p->set_opt_mode      = dtp92_set_opt_mode;
 
1304
        p->get_disptypesel   = dtp92_get_disptypesel;
 
1305
        p->set_disptype      = dtp92_set_disptype;
 
1306
        p->get_set_opt       = dtp92_get_set_opt;
1088
1307
        p->read_sample       = dtp92_read_sample;
1089
 
        p->needs_calibration = dtp92_needs_calibration;
 
1308
        p->read_refrate      = dtp92_read_refrate;
 
1309
        p->get_n_a_cals      = dtp92_get_n_a_cals;
1090
1310
        p->calibrate         = dtp92_calibrate;
1091
1311
        p->col_cor_mat       = dtp92_col_cor_mat;
 
1312
        p->get_refr_rate     = dtp92_get_refr_rate;
 
1313
        p->set_refr_rate     = dtp92_set_refr_rate;
1092
1314
        p->interp_error      = dtp92_interp_error;
1093
1315
        p->del               = dtp92_del;
1094
1316
 
1095
 
        p->itype = itype;
 
1317
        p->icom = icom;
 
1318
        p->itype = icom->itype;
 
1319
 
 
1320
        icmSetUnity3x3(p->ccmat);       /* Set the colorimeter correction matrix to do nothing */
 
1321
        set_base_disptype_list(p);
1096
1322
 
1097
1323
        return p;
1098
1324
}