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

« back to all changes in this revision

Viewing changes to spectro/dtp41.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:
7
7
 * Author: Graeme W. Gill
8
8
 * Date:   10/3/2001
9
9
 *
10
 
 * Copyright 1996 - 2007, Graeme W. Gill
 
10
 * Copyright 1996 - 2013, Graeme W. Gill
11
11
 * All rights reserved.
12
12
 *
13
13
 * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :-
50
50
#endif /* !SALONEINSTLIB */
51
51
#include "xspect.h"
52
52
#include "insttypes.h"
 
53
#include "conv.h"
53
54
#include "icoms.h"
54
 
#include "conv.h"
55
55
#include "dtp41.h"
56
56
 
57
 
#undef DEBUG
58
 
 
59
57
/* Default flow control */
60
58
#define DEFFC fc_XonXOff
61
59
 
93
91
 
94
92
/* Interpret an icoms error into a DTP41 error */
95
93
static int icoms2dtp41_err(int se) {
96
 
        if (se & ICOM_USERM) {
97
 
                se &= ICOM_USERM;
98
 
                if (se == ICOM_USER)
99
 
                        return DTP41_USER_ABORT;
100
 
                if (se == ICOM_TERM)
101
 
                        return DTP41_USER_TERM;
102
 
                if (se == ICOM_TRIG)
103
 
                        return DTP41_USER_TRIG;
104
 
                if (se == ICOM_CMND)
105
 
                        return DTP41_USER_CMND;
106
 
        }
107
 
        if (se != ICOM_OK)
 
94
        if (se != ICOM_OK) {
 
95
                if (se & ICOM_TO)
 
96
                        return DTP41_TIMEOUT; 
108
97
                return DTP41_COMS_FAIL;
 
98
        }
109
99
        return DTP41_OK;
110
100
}
111
101
 
126
116
        int rv, se;
127
117
 
128
118
        if ((se = p->icom->write_read(p->icom, in, out, bsize, tc, ntc, to)) != 0) {
129
 
#ifdef DEBUG
130
 
                printf("dtp41 fcommand: serial i/o failure on write_read '%s'\n",icoms_fix(in));
131
 
#endif
 
119
                a1logd(p->log, 1, "dtp41_fcommand: serial i/o failure 0x%x on write_read '%s'\n",se,icoms_fix(in));
132
120
                return icoms2dtp41_err(se);
133
121
        }
134
122
        rv = DTP41_OK;
142
130
                        }
143
131
                }
144
132
        }
145
 
#ifdef DEBUG
146
 
        printf("command '%s'",icoms_fix(in));
147
 
        printf(" returned '%s', value 0x%x\n",icoms_fix(out),rv);
148
 
#endif
 
133
        a1logd(p->log, 4, "dtp41_fcommand: command '%s' returned '%s', value 0x%x\n",
 
134
                                                    icoms_fix(in), icoms_fix(out),rv);
149
135
        return rv;
150
136
}
151
137
 
161
147
/* Use the baud rate given, and timeout in to secs */
162
148
/* Return DTP_COMS_FAIL on failure to establish communications */
163
149
static inst_code
164
 
dtp41_init_coms(inst *pp, int port, baud_rate br, flow_control fc, double tout) {
 
150
dtp41_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
165
151
        dtp41 *p = (dtp41 *)pp;
166
152
        static char buf[MAX_MES_SIZE];
167
153
        baud_rate brt[9] = { baud_9600, baud_19200, baud_38400, baud_57600,
170
156
                             "4800BR\r", "2400BR\r", "1200BR\r", "600BR\r", "300BR\r" };
171
157
        char *fcc;
172
158
        unsigned int etime;
173
 
        int ci, bi, i, rv;
 
159
        int ci, bi, i, se;
174
160
        inst_code ev = inst_ok;
175
161
 
176
 
        if (p->debug)
177
 
                p->icom->debug = p->debug;      /* Turn on debugging */
 
162
        a1logd(p->log, 2, "dtp41_init_coms: About to init Serial I/O\n");
178
163
 
179
164
        /* Deal with flow control setting */
180
165
        if (fc == fc_nc)
211
196
 
212
197
                /* Until we time out, find the correct baud rate */
213
198
                for (i = ci; msec_time() < etime;) {
214
 
                        p->icom->set_ser_port(p->icom, port, fc_none, brt[i], parity_none, stop_1, length_8);
 
199
                        if ((se = p->icom->set_ser_port(p->icom, fc_none, brt[i], parity_none,
 
200
                                                                    stop_1, length_8)) != ICOM_OK) { 
 
201
                                a1logd(p->log, 1, "dtp41_init_coms: set_ser_port failed ICOM err 0x%x\n",se);
 
202
                                return dtp41_interp_code((inst *)p, icoms2dtp41_err(se));
 
203
                        }
215
204
                        if (((ev = dtp41_command(p, "\r", buf, MAX_MES_SIZE, 0.5)) & inst_mask)
216
 
                                                                              != inst_coms_fail)
217
 
                                break;          /* We've got coms or user abort */
 
205
                                                                                 != inst_coms_fail)
 
206
                                break;          /* We've got coms */
 
207
 
 
208
                        /* Check for user abort */
 
209
                        if (p->uicallback != NULL) {
 
210
                                inst_code ev;
 
211
                                if ((ev = p->uicallback(p->uic_cntx, inst_negcoms)) == inst_user_abort) {
 
212
                                        a1logd(p->log, 1, "dtp41_init_coms: user aborted\n");
 
213
                                        return inst_user_abort;
 
214
                                }
 
215
                        }
218
216
                        if (++i >= 9)
219
217
                                i = 0;
220
218
                }
221
 
 
222
 
                if ((ev & inst_mask) == inst_user_abort)
223
 
                        return ev;
224
 
 
225
219
                break;          /* Got coms */
226
220
        }
227
221
 
234
228
                return ev;
235
229
 
236
230
        /* Set the handshaking (cope with coms breakdown) */
237
 
        if ((rv = p->icom->write_read(p->icom, fcc, buf, MAX_MES_SIZE, '>', 1, 1.5)) != 0) {
 
231
        if ((se = p->icom->write_read(p->icom, fcc, buf, MAX_MES_SIZE, '>', 1, 1.5)) != 0) {
238
232
                if (extract_ec(buf) != DTP41_OK)
239
233
                        return inst_coms_fail;
240
234
        }
241
235
 
242
236
        /* Change the baud rate to the rate we've been told (cope with coms breakdown) */
243
 
        if ((rv = p->icom->write_read(p->icom, brc[bi], buf, MAX_MES_SIZE, '>', 1, 1.5)) != 0) {
 
237
        if ((se = p->icom->write_read(p->icom, brc[bi], buf, MAX_MES_SIZE, '>', 1, 1.5)) != 0) {
244
238
                if (extract_ec(buf) != DTP41_OK)
245
239
                        return inst_coms_fail;
246
240
        }
247
241
 
248
242
        /* Configure our baud rate and handshaking as well */
249
 
        p->icom->set_ser_port(p->icom, port, fc, brt[bi], parity_none, stop_1, length_8);
 
243
        if ((se = p->icom->set_ser_port(p->icom, fc, brt[bi], parity_none, stop_1, length_8))
 
244
                                                                                      != ICOM_OK) {
 
245
                a1logd(p->log, 1, "dtp41_init_coms: set_ser_port failed ICOM err 0x%x\n",se);
 
246
                return dtp41_interp_code((inst *)p, icoms2dtp41_err(se));
 
247
        }
250
248
 
251
249
        /* Loose a character (not sure why) */
252
250
        p->icom->write_read(p->icom, "\r", buf, MAX_MES_SIZE, '>', 1, 0.5);
253
251
 
254
252
        /* Check instrument is responding */
255
 
        if ((ev = dtp41_command(p, "\r", buf, MAX_MES_SIZE, 1.5)) != inst_ok)
 
253
        if ((ev = dtp41_command(p, "\r", buf, MAX_MES_SIZE, 1.5)) != inst_ok) {
 
254
                a1logd(p->log, 1, "dtp41_init_coms: instrument failed to respond\n");
256
255
                return inst_coms_fail;
257
 
 
258
 
#ifdef DEBUG
259
 
        printf("Got communications\n");
260
 
#endif
 
256
        }
 
257
 
 
258
        a1logd(p->log, 2, "dtp41_init_coms: init coms has suceeded\n");
 
259
 
261
260
        p->gotcoms = 1;
262
261
        return inst_ok;
263
262
}
298
297
 
299
298
        if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission) {
300
299
 
301
 
                if (twid >= 9999.5)
302
 
                        error ("build_strip given trailer length > 9999 mm");
 
300
                if (twid >= 9999.5) {
 
301
                        a1logw(p->log, "DTP41 build_strip given trailer length %f > 9999 mm\n",twid);
 
302
                        twid = 9999.0;
 
303
                }
303
304
                /* Trailer length in mm, dddd */
304
305
                sprintf(tp, "%04.0f",twid);
305
306
                tp += 4;
320
321
        static char tbuf[100], buf[MAX_MES_SIZE];
321
322
        inst_code ev = inst_ok;
322
323
 
 
324
        a1logd(p->log, 2, "dtp41_init_inst: called\n");
 
325
 
323
326
        if (p->gotcoms == 0)
324
327
                return inst_internal_error;             /* Must establish coms before calling init */
325
328
 
407
410
        /* Enable the read microswitch */
408
411
        if ((ev = dtp41_command(p, "01PB\r", buf, MAX_MES_SIZE, 1.5)) != inst_ok)
409
412
                return ev;
410
 
        p->trig = inst_opt_trig_keyb_switch;
 
413
        p->trig = inst_opt_trig_user_switch;
411
414
 
412
415
        /* Set dynamic measurement mode */
413
416
        if ((ev = dtp41_command(p, "0113CF\r", buf, MAX_MES_SIZE, 1.5)) != inst_ok)
438
441
        if ((ev = dtp41_command(p, tbuf, buf, MAX_MES_SIZE, 1.5)) != inst_ok)
439
442
                return ev;
440
443
 
441
 
#ifndef NEVER
 
444
#ifdef NEVER
442
445
        /* See what the transmission mode is up to */
443
446
        dtp41_command(p, "DEVELOPERPW\r", buf, MAX_MES_SIZE, 1.5);
444
447
        dtp41_command(p, "0119CF\r", buf, MAX_MES_SIZE, 1.5);
449
452
        /* We are configured in this mode now */
450
453
        p->mode = inst_mode_ref_strip;
451
454
 
452
 
        if (p->lastmode != p->mode)
453
 
                return activate_mode(p);
454
 
 
455
 
        if (ev == inst_ok)
456
 
                p->inited = 1;
 
455
        if (p->lastmode != p->mode) {
 
456
                if ((ev = activate_mode(p)) != inst_ok)
 
457
                        return ev;
 
458
        }
 
459
 
 
460
        p->inited = 1;
 
461
 
 
462
        a1logd(p->log, 2, "dtp41_init_inst: instrument inited OK\n");
457
463
 
458
464
        return inst_ok;
459
465
}
494
500
        if ((ev = dtp41_command(p, tbuf, buf, MAX_MES_SIZE, 1.5)) != inst_ok)
495
501
                return ev;
496
502
 
497
 
        if (p->trig == inst_opt_trig_keyb_switch) {
498
 
 
499
 
                /* Wait for the Read status, or a user abort/command - allow 5 minuits */
500
 
                if ((ev = dtp41_command(p, "", buf, MAX_MES_SIZE, 5 * 60.0)) != inst_ok) {
501
 
                        if ((ev & inst_mask) == inst_needs_cal)
502
 
                                p->need_cal = 1;
503
 
                        if ((ev & inst_mask) != inst_user_trig)
504
 
                                return ev;
505
 
                        user_trig = 1;
506
 
                } else {
507
 
                        switch_trig = 1;
508
 
                }
509
 
                if (p->trig_return)
510
 
                        printf("\n");
511
 
 
512
 
        } else if (p->trig == inst_opt_trig_keyb) {
513
 
                if ((se = icoms_poll_user(p->icom, 1)) != ICOM_TRIG) {
514
 
                        /* Abort, term or command */
515
 
                        return dtp41_interp_code((inst *)p, icoms2dtp41_err(se));
516
 
                }
517
 
                user_trig = 1;
518
 
                if (p->trig_return)
519
 
                        printf("\n");
 
503
        if (p->trig == inst_opt_trig_user_switch) {
 
504
 
 
505
                /* Wait for the Read status, or a user trigger/abort */
 
506
                for (;;) {
 
507
                        if ((ev = dtp41_command(p, "", buf, MAX_MES_SIZE, 0.5)) != inst_ok) {
 
508
                                if ((ev & inst_mask) == inst_needs_cal)
 
509
                                        p->need_cal = 1;
 
510
 
 
511
                                if ((ev & inst_imask) != DTP41_TIMEOUT) 
 
512
                                        return ev;                      /* Instrument or comms error */
 
513
 
 
514
                                /* Timed out */
 
515
                                if (p->uicallback != NULL) {    /* Check for user trigger */
 
516
                                        if ((ev = p->uicallback(p->uic_cntx, inst_armed)) != inst_ok) {
 
517
                                                if (ev == inst_user_abort)
 
518
                                                        return ev;              /* User abort */
 
519
                                                if (ev == inst_user_trig) {
 
520
                                                        user_trig = 1;
 
521
                                                        break;
 
522
                                                }
 
523
                                        }
 
524
                                }
 
525
 
 
526
                        } else {        /* Got read status - assume triggered */
 
527
                                switch_trig = 1;
 
528
                                break;                                  /* Switch activated */
 
529
                        }
 
530
                }
 
531
                /* Notify of trigger */
 
532
                if (p->uicallback)
 
533
                        p->uicallback(p->uic_cntx, inst_triggered); 
 
534
 
 
535
        } else if (p->trig == inst_opt_trig_user) {
 
536
 
 
537
                if (p->uicallback == NULL) {
 
538
                        a1logd(p->log, 1, "dtp41: inst_opt_trig_user but no uicallback function set!\n");
 
539
                        return inst_unsupported;
 
540
                }
 
541
 
 
542
                for (;;) {
 
543
                        if ((ev = p->uicallback(p->uic_cntx, inst_armed)) != inst_ok) {
 
544
                                if (ev == inst_user_abort)
 
545
                                        return ev;                              /* Abort */
 
546
                                if (ev == inst_user_trig) {
 
547
                                        user_trig = 1;
 
548
                                        break;                                  /* Trigger */
 
549
                                }
 
550
                        }
 
551
                        msec_sleep(200);
 
552
                }
 
553
                /* Notify of trigger */
 
554
                if (p->uicallback)
 
555
                        p->uicallback(p->uic_cntx, inst_triggered); 
 
556
 
 
557
        /* Progromatic Trigger */
 
558
        } else {
 
559
                /* Check for abort */
 
560
                if (p->uicallback != NULL
 
561
                 && (ev = p->uicallback(p->uic_cntx, inst_armed)) == inst_user_abort)
 
562
                        return ev;                              /* Abort */
520
563
        }
521
564
 
522
565
        /* Trigger a read if the switch has not been used */
549
592
                                return inst_protocol_error;
550
593
                        }
551
594
                }
 
595
                vals[i].loc[0] = '\000';
 
596
                if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission)
 
597
                        vals[i].mtype = inst_mrt_transmissive;
 
598
                else
 
599
                        vals[i].mtype = inst_mrt_reflective;
552
600
                vals[i].XYZ_v = 1;
553
 
                vals[i].aXYZ_v = 0;
554
 
                vals[i].Lab_v = 0;
555
601
                vals[i].sp.spec_n = 0;
556
602
                vals[i].duration = 0.0;
557
603
                tp += strlen(tp) + 1;
604
650
dtp41_read_sample(
605
651
inst *pp,
606
652
char *name,                     /* Strip name (7 chars) */
607
 
ipatch *val) {          /* Pointer to instrument patch value */
 
653
ipatch *val,            /* Pointer to instrument patch value */
 
654
instClamping clamp) {           /* NZ if clamp XYZ/Lab to be +ve */
608
655
        dtp41 *p = (dtp41 *)pp;
609
656
        char *tp;
610
657
        static char buf[MAX_RD_SIZE];
626
673
        if ((ev = dtp41_command(p, "0013CF\r", buf, MAX_MES_SIZE, 1.5)) != inst_ok)
627
674
                return ev;
628
675
 
629
 
        if (p->trig == inst_opt_trig_keyb_switch) {
630
 
 
631
 
                /* Wait for the Read status, or a user abort/command - allow 5 minuits */
632
 
                if ((ev = dtp41_command(p, "", buf, MAX_MES_SIZE, 5 * 60.0)) != inst_ok) {
633
 
                        if ((ev & inst_mask) == inst_needs_cal)
634
 
                                p->need_cal = 1;
635
 
                        if ((ev & inst_mask) != inst_user_trig)
636
 
                                return ev;
637
 
                        user_trig = 1;
638
 
                } else {
639
 
                        switch_trig = 1;
640
 
                }
641
 
                if (p->trig_return)
642
 
                        printf("\n");
643
 
 
644
 
        } else if (p->trig == inst_opt_trig_keyb) {
645
 
                if ((se = icoms_poll_user(p->icom, 1)) != ICOM_TRIG) {
646
 
                        /* Abort, term or command */
647
 
                        return dtp41_interp_code((inst *)p, icoms2dtp41_err(se));
648
 
                }
649
 
                user_trig = 1;
650
 
                if (p->trig_return)
651
 
                        printf("\n");
 
676
        if (p->trig == inst_opt_trig_user_switch) {
 
677
 
 
678
                /* Wait for the Read status, or a user trigger/abort */
 
679
                for (;;) {
 
680
                        if ((ev = dtp41_command(p, "", buf, MAX_MES_SIZE, 0.5)) != inst_ok) {
 
681
                                if ((ev & inst_mask) == inst_needs_cal)
 
682
                                        p->need_cal = 1;
 
683
 
 
684
                                if ((ev & inst_imask) != DTP41_TIMEOUT)
 
685
                                        return ev;                      /* Instrument or comms error */
 
686
 
 
687
                                /* Timed out */
 
688
                                if (p->uicallback != NULL) {    /* Check for user trigger */
 
689
                                        if ((ev = p->uicallback(p->uic_cntx, inst_armed)) != inst_ok) {
 
690
                                                if (ev == inst_user_abort)
 
691
                                                        return ev;              /* User abort */
 
692
                                                if (ev == inst_user_trig) {
 
693
                                                        user_trig = 1;
 
694
                                                        break;                          /* User trigger */
 
695
                                                }
 
696
                                        }
 
697
                                }
 
698
 
 
699
                        } else {                        /* Assume read status and trigger */
 
700
                                switch_trig = 1;
 
701
                                break;                                  /* Switch activated */
 
702
                        }
 
703
                }
 
704
                /* Notify of trigger */
 
705
                if (p->uicallback)
 
706
                        p->uicallback(p->uic_cntx, inst_triggered); 
 
707
 
 
708
        } else if (p->trig == inst_opt_trig_user) {
 
709
 
 
710
                if (p->uicallback == NULL) {
 
711
                        a1logd(p->log, 1, "dtp41: inst_opt_trig_user but no uicallback function set!\n");
 
712
                        return inst_unsupported;
 
713
                }
 
714
 
 
715
                for (;;) {
 
716
                        if ((ev = p->uicallback(p->uic_cntx, inst_armed)) != inst_ok) {
 
717
                                if (ev == inst_user_abort)
 
718
                                        return ev;                              /* Abort */
 
719
                                if (ev == inst_user_trig) {
 
720
                                        user_trig = 1;
 
721
                                        break;                                  /* Trigger */
 
722
                                }
 
723
                        }
 
724
                        msec_sleep(200);
 
725
                }
 
726
                /* Notify of trigger */
 
727
                if (p->uicallback)
 
728
                        p->uicallback(p->uic_cntx, inst_triggered); 
 
729
 
 
730
        /* Progromatic Trigger */
 
731
        } else {
 
732
                /* Check for abort */
 
733
                if (p->uicallback != NULL
 
734
                 && (ev = p->uicallback(p->uic_cntx, inst_armed)) == inst_user_abort)
 
735
                        return ev;                              /* Abort */
652
736
        }
653
737
 
654
738
        /* Trigger a read if the switch has not been used */
694
778
        val->XYZ[0] /= (double)p->nstaticr;
695
779
        val->XYZ[1] /= (double)p->nstaticr;
696
780
        val->XYZ[2] /= (double)p->nstaticr;
 
781
        /* This may not change anything since instrument may clamp */
 
782
        if (clamp)
 
783
                icmClamp3(val->XYZ, val->XYZ);
 
784
        val->loc[0] = '\000';
 
785
        if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission)
 
786
                val->mtype = inst_mrt_transmissive;
 
787
        else
 
788
                val->mtype = inst_mrt_reflective;
697
789
        val->XYZ_v = 1;
698
 
        val->aXYZ_v = 0;
699
 
        val->Lab_v = 0;
700
790
        val->sp.spec_n = 0;
701
791
        val->duration = 0.0;
702
792
 
755
845
        return inst_ok;
756
846
}
757
847
 
758
 
 
759
 
/* Determine if a calibration is needed. Returns inst_calt_none if not, */
760
 
/* inst_calt_unknown if it is unknown, or inst_calt_XXX if needs calibration, */
761
 
/* and the first type of calibration needed. */
762
 
/* Can't know ahead of time with the DTP41, but we track if an error */
763
 
/* was returned from a read. */
764
 
inst_cal_type dtp41_needs_calibration(inst *pp) {
 
848
/* Return needed and available inst_cal_type's */
 
849
static inst_code dtp41_get_n_a_cals(inst *pp, inst_cal_type *pn_cals, inst_cal_type *pa_cals) {
765
850
        dtp41 *p = (dtp41 *)pp;
766
 
        
767
 
        if (!p->gotcoms)
768
 
                return inst_no_coms;
769
 
        if (!p->inited)
770
 
                return inst_no_init;
771
 
 
772
 
        if (p->need_cal) {
773
 
                if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission)
774
 
                        return inst_calt_trans_white;   /* ??? */
775
 
                else
776
 
                        return inst_calt_ref_white;
 
851
        inst_cal_type n_cals = inst_calt_none;
 
852
        inst_cal_type a_cals = inst_calt_none;
 
853
                
 
854
        if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission) {
 
855
                if (p->need_cal)
 
856
                        n_cals |= inst_calt_trans_white;        /* ??? */
 
857
                a_cals |= inst_calt_trans_white;
 
858
        } else {
 
859
                if (p->need_cal)
 
860
                        n_cals |= inst_calt_ref_white;
 
861
                a_cals |= inst_calt_ref_white;
777
862
        }
778
 
        return inst_calt_unknown;
 
863
 
 
864
        if (pn_cals != NULL)
 
865
                *pn_cals = n_cals;
 
866
 
 
867
        if (pa_cals != NULL)
 
868
                *pa_cals = a_cals;
 
869
 
 
870
        return inst_ok;
779
871
}
780
872
 
781
873
/* Request an instrument calibration. */
787
879
/* user to do so, each time the error inst_cal_setup is returned. */
788
880
inst_code dtp41_calibrate(
789
881
inst *pp,
790
 
inst_cal_type calt,             /* Calibration type. inst_calt_all for all neeeded */
 
882
inst_cal_type *calt,    /* Calibration type to do/remaining */
791
883
inst_cal_cond *calc,    /* Current condition/desired condition */
792
884
char id[CALIDLEN]               /* Condition identifier (ie. white reference ID) */
793
885
) {
794
886
        dtp41 *p = (dtp41 *)pp;
 
887
        inst_code ev;
 
888
    inst_cal_type needed, available;
795
889
 
796
890
        if (!p->gotcoms)
797
891
                return inst_no_coms;
800
894
 
801
895
        id[0] = '\000';
802
896
 
 
897
        if ((ev = dtp41_get_n_a_cals((inst *)p, &needed, &available)) != inst_ok)
 
898
                return ev;
 
899
 
 
900
        /* Translate inst_calt_all/needed into something specific */
 
901
        if (*calt == inst_calt_all
 
902
         || *calt == inst_calt_needed
 
903
         || *calt == inst_calt_available) {
 
904
                if (*calt == inst_calt_all) 
 
905
                        *calt = (needed & inst_calt_n_dfrble_mask) | inst_calt_ap_flag;
 
906
                else if (*calt == inst_calt_needed)
 
907
                        *calt = needed & inst_calt_n_dfrble_mask;
 
908
                else if (*calt == inst_calt_available)
 
909
                        *calt = available & inst_calt_n_dfrble_mask;
 
910
 
 
911
                a1logd(p->log,4,"dtp41_calibrate: doing calt 0x%x\n",calt);
 
912
 
 
913
                if ((*calt & inst_calt_n_dfrble_mask) == 0)             /* Nothing todo */
 
914
                        return inst_ok;
 
915
        }
 
916
 
 
917
        /* See if it's a calibration we understand */
 
918
        if (*calt & ~available & inst_calt_all_mask) { 
 
919
                return inst_unsupported;
 
920
        }
 
921
 
 
922
 
803
923
        if ((p->mode & inst_mode_illum_mask) == inst_mode_transmission) {
 
924
                if (*calt & inst_calt_trans_white) {
804
925
 
805
 
                if (calt == inst_calt_all)
806
 
                        calt = inst_calt_trans_white;
 
926
                        if (*calc != inst_calc_uop_trans_white)
 
927
                                *calc = inst_calc_uop_trans_white;      /* Ask user to do calibration */
 
928
                                return inst_cal_setup;
 
929
                        }
807
930
        
808
 
                if (calt != inst_calt_trans_white)
809
 
                        return inst_unsupported;
810
 
 
811
 
                if (*calc == inst_calc_uop_trans_white) {
812
931
                        p->need_cal = 0;
813
 
                        return inst_ok;                                 /* Calibration done */
814
 
                }
 
932
                        *calt &= ~inst_calt_trans_white;
815
933
        
816
 
                *calc = inst_calc_uop_trans_white;      /* Need to ask user to do calibration */
817
 
 
818
934
        } else {
819
 
 
820
 
                if (calt == inst_calt_all)
821
 
                        calt = inst_calt_ref_white;
822
 
        
823
 
                if (calt != inst_calt_ref_white)
824
 
                        return inst_unsupported;
825
 
 
826
 
                if (*calc == inst_calc_uop_ref_white) {
 
935
                if (*calt & inst_calt_ref_white) {
 
936
 
 
937
                        if (*calc != inst_calc_uop_ref_white) {
 
938
                                *calc = inst_calc_uop_ref_white;        /* Ask user to do calibration */
 
939
                                return inst_cal_setup;
 
940
                        }
 
941
                
827
942
                        p->need_cal = 0;
828
 
                        return inst_ok;                                 /* Calibration done */
 
943
                        *calt &= ~inst_calt_ref_white;
829
944
                }
830
 
        
831
 
                *calc = inst_calc_uop_ref_white;        /* Need to ask user to do calibration */
832
945
        }
833
946
 
834
 
        return inst_cal_setup;
 
947
        return inst_ok;                                 /* Calibration done */
835
948
}
836
949
 
837
950
/* Error codes interpretation */
841
954
        ec &= inst_imask;
842
955
        switch (ec) {
843
956
 
844
 
                case DTP41_USER_ABORT:
845
 
                        return "User hit Abort key";
846
 
                case DTP41_USER_TERM:
847
 
                        return "User hit Terminate key";
848
 
                case DTP41_USER_TRIG:
849
 
                        return "User hit Trigger key";
850
 
                case DTP41_USER_CMND:
851
 
                        return "User hit a Command key";
852
957
                case DTP41_INTERNAL_ERROR:
853
958
                        return "Internal software error";
854
959
                case DTP41_COMS_FAIL:
875
980
                        return "One or more parameters are out of range";
876
981
                case DTP41_BUSY:
877
982
                        return "Instrument is busy - command ignored";
878
 
                case DTP41_USER_ABORT_ERROR:
879
 
                        return "User aborted process";
880
983
                case DTP41_MEASUREMENT_ERROR:
881
984
                        return "General measurement error";
882
985
                case DTP41_TIMEOUT:
959
1062
                case DTP41_DATA_PARSE_ERROR:
960
1063
                        return inst_protocol_error | ec;
961
1064
 
962
 
                case DTP41_USER_ABORT:
963
 
                        return inst_user_abort | ec;
964
 
                case DTP41_USER_TERM:
965
 
                        return inst_user_term | ec;
966
 
                case DTP41_USER_TRIG:
967
 
                        return inst_user_trig | ec;
968
 
                case DTP41_USER_CMND:
969
 
                        return inst_user_cmnd | ec;
970
 
 
971
1065
                case DTP41_BUSY:
972
1066
                case DTP41_TIMEOUT:
973
1067
                case DTP41_BAD_READING:
999
1093
        static char buf[MAX_MES_SIZE];
1000
1094
        inst_code rv = inst_ok;
1001
1095
 
1002
 
        p->cap = inst_ref_spot
1003
 
               | inst_ref_strip
1004
 
               | inst_colorimeter
1005
 
               | inst_spectral
 
1096
        p->cap = inst_mode_ref_spot
 
1097
               | inst_mode_ref_strip
 
1098
               | inst_mode_colorimeter
 
1099
               | inst_mode_spectral
1006
1100
               ;
1007
1101
 
1008
 
        p->cap2 = inst2_cal_ref_white           /* User operated though */
1009
 
            | inst2_prog_trig
1010
 
            | inst2_keyb_trig
1011
 
                | inst2_keyb_switch_trig
 
1102
        p->cap2 = inst2_prog_trig
 
1103
            | inst2_user_trig
 
1104
                | inst2_user_switch_trig
1012
1105
                ;
1013
1106
 
 
1107
        p->cap3 = inst3_none;
 
1108
 
1014
1109
        if (p->inited) {
1015
1110
                /* Check whether we have transmission capability */
1016
1111
                if ((rv = dtp41_command(p, "0119CF\r", buf, MAX_MES_SIZE, 1.5)) == inst_ok) {
1017
 
                        p->cap |= inst_trans_spot
1018
 
                               |  inst_trans_strip
 
1112
                        p->cap |= inst_mode_trans_spot
 
1113
                               |  inst_mode_trans_strip
1019
1114
                               ;
1020
 
        
1021
 
                        p->cap2 |= inst2_cal_trans_white;               /* User operated though */
1022
1115
                }
1023
1116
                /* Set back to reflectance mode */
1024
1117
                rv = dtp41_command(p, "0019CF\r", buf, MAX_MES_SIZE, 1.5);
1026
1119
}
1027
1120
 
1028
1121
/* Return the instrument capabilities */
1029
 
inst_capability dtp41_capabilities(inst *pp) {
1030
 
        dtp41 *p = (dtp41 *)pp;
1031
 
 
1032
 
        if (p->cap == inst_unknown)
1033
 
                discover_capabilities(p);
1034
 
        return p->cap;
1035
 
}
1036
 
 
1037
 
/* Return the instrument capabilities 2 */
1038
 
inst2_capability dtp41_capabilities2(inst *pp) {
1039
 
        dtp41 *p = (dtp41 *)pp;
1040
 
        inst2_capability rv;
1041
 
 
1042
 
        if (p->cap2 == inst2_unknown)
1043
 
                discover_capabilities(p);
1044
 
 
1045
 
        rv = p->cap2;
1046
 
 
1047
 
        return rv;
 
1122
void dtp41_capabilities(inst *pp,
 
1123
inst_mode *pcap1,
 
1124
inst2_capability *pcap2,
 
1125
inst3_capability *pcap3) {
 
1126
        dtp41 *p = (dtp41 *)pp;
 
1127
 
 
1128
        if (p->cap == inst_mode_none)
 
1129
                discover_capabilities(p);
 
1130
 
 
1131
        if (pcap1 != NULL)
 
1132
                *pcap1 = p->cap;
 
1133
        if (pcap2 != NULL)
 
1134
                *pcap2 = p->cap2;
 
1135
        if (pcap3 != NULL)
 
1136
                *pcap3 = p->cap3;
1048
1137
}
1049
1138
 
1050
1139
/* Activate the last set mode */
1084
1173
}
1085
1174
 
1086
1175
/* 
 
1176
 * check measurement mode
 
1177
 * We assume that the instrument has been initialised.
 
1178
 */
 
1179
static inst_code
 
1180
dtp41_check_mode(inst *pp, inst_mode m) {
 
1181
        dtp41 *p = (dtp41 *)pp;
 
1182
        inst_mode cap;
 
1183
 
 
1184
        pp->capabilities(pp, &cap, NULL, NULL);
 
1185
 
 
1186
        if (m & ~cap)           /* Simple elimination test */
 
1187
                return inst_unsupported;
 
1188
 
 
1189
        /* Check specific modes */
 
1190
        if (!IMODETST(m, inst_mode_ref_spot)
 
1191
         && !IMODETST(m, inst_mode_ref_strip)
 
1192
         && !IMODETST2(cap, m, inst_mode_trans_spot)
 
1193
         && !IMODETST2(cap, m, inst_mode_trans_strip)) {
 
1194
                return inst_unsupported;
 
1195
        }
 
1196
 
 
1197
        return inst_ok;
 
1198
}
 
1199
 
 
1200
/* 
1087
1201
 * set measurement mode
1088
1202
 * We assume that the instrument has been initialised.
1089
1203
 */
1090
1204
static inst_code
1091
1205
dtp41_set_mode(inst *pp, inst_mode m) {
1092
1206
        dtp41 *p = (dtp41 *)pp;
1093
 
        inst_capability cap = pp->capabilities(pp);
1094
 
        inst_mode mm;           /* Measurement mode */
1095
 
 
1096
 
        /* The measurement mode portion of the mode */
1097
 
        mm = m & inst_mode_measurement_mask;
1098
 
 
1099
 
        /* General check mode against specific capabilities logic: */
1100
 
        if (mm == inst_mode_ref_spot) {
1101
 
                if (!(cap & inst_ref_spot))
1102
 
                        return inst_unsupported;
1103
 
        } else if (mm == inst_mode_ref_strip) {
1104
 
                if (!(cap & inst_ref_strip))
1105
 
                        return inst_unsupported;
1106
 
        } else if (mm == inst_mode_ref_xy) {
1107
 
                if (!(cap & inst_ref_xy))
1108
 
                        return inst_unsupported;
1109
 
        } else if (mm == inst_mode_trans_spot) {
1110
 
                if (!(cap & inst_trans_spot))
1111
 
                        return inst_unsupported;
1112
 
        } else if (mm == inst_mode_trans_strip) {
1113
 
                if (!(cap & inst_trans_strip))
1114
 
                        return inst_unsupported;
1115
 
        } else if (mm == inst_mode_trans_xy) {
1116
 
                if (!(cap & inst_trans_xy))
1117
 
                        return inst_unsupported;
1118
 
        } else if (mm == inst_mode_emis_disp) {
1119
 
                if (!(cap & inst_emis_disp))
1120
 
                        return inst_unsupported;
1121
 
        } else {
1122
 
                return inst_unsupported;
1123
 
        }
1124
 
 
1125
 
        if (m & inst_mode_colorimeter)
1126
 
                if (!(cap & inst_colorimeter))
1127
 
                        return inst_unsupported;
1128
 
                
1129
 
        if (m & inst_mode_spectral)
1130
 
                if (!(cap & inst_spectral))
1131
 
                        return inst_unsupported;
 
1207
        inst_code ev;
 
1208
 
 
1209
        if ((ev = dtp41_check_mode(pp, m)) != inst_ok)
 
1210
                return ev;
1132
1211
 
1133
1212
        p->lastmode = m;
1134
 
 
1135
1213
        if (p->lastmode != p->mode) {
1136
1214
                return activate_mode(p);
1137
1215
        }
 
1216
 
1138
1217
        return inst_ok;
1139
1218
}
1140
1219
 
1143
1222
 
1144
1223
/* 
1145
1224
 * set or reset an optional mode
1146
 
 * We assume that the instrument has been initialised.
 
1225
 *
 
1226
 * Some options talk to the instrument, and these will
 
1227
 * error if it hasn't been initialised.
1147
1228
 */
1148
1229
static inst_code
1149
 
dtp41_set_opt_mode(inst *pp, inst_opt_mode m, ...)
 
1230
dtp41_get_set_opt(inst *pp, inst_opt_type m, ...)
1150
1231
{
1151
1232
        dtp41 *p = (dtp41 *)pp;
1152
1233
        inst_code rv = inst_ok;
1157
1238
        if (!p->inited)
1158
1239
                return inst_no_init;
1159
1240
 
1160
 
        /* Record the trigger mode */
 
1241
        /* Set the trigger mode */
1161
1242
        if (m == inst_opt_trig_prog
1162
 
         || m == inst_opt_trig_keyb
1163
 
         || m == inst_opt_trig_keyb_switch) {
 
1243
         || m == inst_opt_trig_user
 
1244
         || m == inst_opt_trig_user_switch) {
1164
1245
                p->trig = m;
1165
1246
 
1166
 
                if (m == inst_opt_trig_keyb_switch) {
 
1247
                if (m == inst_opt_trig_user_switch) {
1167
1248
                        /* Enable the read microswitch */
1168
1249
                        if ((rv = dtp41_command(p, "01PB\r", buf, MAX_MES_SIZE, 0.2)) != inst_ok)
1169
1250
                                return rv;
1175
1256
                return inst_ok;
1176
1257
        }
1177
1258
 
1178
 
        if (m == inst_opt_trig_return) {
1179
 
                p->trig_return = 1;
1180
 
                return inst_ok;
1181
 
        } else if (m == inst_opt_trig_no_return) {
1182
 
                p->trig_return = 0;
1183
 
                return inst_ok;
1184
 
        }
1185
 
 
1186
1259
        return inst_unsupported;
1187
1260
}
1188
1261
 
1189
1262
/* Constructor */
1190
 
extern dtp41 *new_dtp41(icoms *icom, instType itype, int debug, int verb)
1191
 
{
 
1263
extern dtp41 *new_dtp41(icoms *icom, instType itype) {
1192
1264
        dtp41 *p;
1193
 
        if ((p = (dtp41 *)calloc(sizeof(dtp41),1)) == NULL)
1194
 
                error("dtp41: malloc failed!");
1195
 
 
1196
 
        if (icom == NULL)
1197
 
                p->icom = new_icoms();
1198
 
        else
1199
 
                p->icom = icom;
1200
 
 
1201
 
        p->debug = debug;
1202
 
        p->verb = verb;
 
1265
        if ((p = (dtp41 *)calloc(sizeof(dtp41),1)) == NULL) {
 
1266
                a1loge(icom->log, 1, "new_dtp41: malloc failed!\n");
 
1267
                return NULL;
 
1268
        }
 
1269
 
 
1270
        p->log = new_a1log(icom->log, 0, 0, NULL, NULL, NULL, NULL);
1203
1271
 
1204
1272
        p->init_coms     = dtp41_init_coms;
1205
1273
        p->init_inst     = dtp41_init_inst;
1206
1274
        p->capabilities  = dtp41_capabilities;
1207
 
        p->capabilities2 = dtp41_capabilities2;
 
1275
        p->check_mode    = dtp41_check_mode;
1208
1276
        p->set_mode      = dtp41_set_mode;
1209
 
        p->set_opt_mode  = dtp41_set_opt_mode;
 
1277
        p->get_set_opt   = dtp41_get_set_opt;
1210
1278
        p->read_strip    = dtp41_read_strip;
1211
1279
        p->read_sample   = dtp41_read_sample;
1212
 
        p->needs_calibration = dtp41_needs_calibration;
 
1280
        p->get_n_a_cals  = dtp41_get_n_a_cals;
1213
1281
        p->calibrate     = dtp41_calibrate;
1214
1282
        p->interp_error  = dtp41_interp_error;
1215
1283
        p->del           = dtp41_del;
1216
1284
 
1217
 
        p->itype = itype;
1218
 
        p->cap = inst_unknown;                          /* Unknown until set */
1219
 
        p->mode = inst_mode_unknown;            /* Not in a known mode yet */
 
1285
        p->icom = icom;
 
1286
        p->itype = icom->itype;
 
1287
        p->cap = inst_mode_none;                        /* Unknown until set */
 
1288
        p->mode = inst_mode_none;                       /* Not in a known mode yet */
1220
1289
        p->nstaticr = 5;                                        /* Number of static readings */
1221
1290
 
1222
1291
        return p;