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

« back to all changes in this revision

Viewing changes to spectro/munki.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:   12/1/2009
9
9
 *
10
 
 * Copyright 2006 - 2010, Graeme W. Gill
 
10
 * Copyright 2006 - 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 :-
51
51
#endif /* SALONEINSTLIB */
52
52
#include "xspect.h"
53
53
#include "insttypes.h"
 
54
#include "conv.h"
54
55
#include "icoms.h"
55
 
#include "conv.h"
56
56
#include "munki.h"
57
57
#include "munki_imp.h"
58
58
 
59
 
#undef DEBUG
60
 
 
61
 
#ifdef DEBUG
62
 
#define DBG(xxx) printf xxx ;
63
 
#else
64
 
#define DBG(xxx) 
65
 
#endif
66
 
 
67
59
#define MAX_MES_SIZE 500                /* Maximum normal message reply size */
68
60
#define MAX_RD_SIZE 5000                /* Maximum reading messagle reply size */
69
61
 
76
68
/* If it's a serial port, use the baud rate given, and timeout in to secs */
77
69
/* Return DTP_COMS_FAIL on failure to establish communications */
78
70
static inst_code
79
 
munki_init_coms(inst *pp, int port, baud_rate br, flow_control fc, double tout) {
 
71
munki_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) {
80
72
        munki *p = (munki *) pp;
 
73
        int se;
81
74
        icomuflags usbflags = icomuf_none;
82
75
#ifdef __APPLE__
83
76
        /* If the ColorMunki software has been installed, then there will */
94
87
        int retries = 0;
95
88
#endif /* !__APPLE__ */
96
89
 
97
 
        if (p->debug) {
98
 
                p->icom->debug = p->debug;      /* Turn on debugging */
99
 
                fprintf(stderr,"munki: About to init coms\n");
100
 
        }
101
 
 
102
 
        if (p->icom->is_usb_portno(p->icom, port) == instUnknown) {
103
 
                if (p->debug) fprintf(stderr,"munki: init_coms called to wrong device!\n");
104
 
 
 
90
        a1logd(p->log, 2, "munki_init_coms: called\n");
 
91
 
 
92
        if (p->icom->port_type(p->icom) != icomt_usb) {
 
93
                a1logd(p->log, 1, "munki_init_coms: wrong sort of coms!\n");
105
94
                return munki_interp_code(p, MUNKI_UNKNOWN_MODEL);
106
95
        }
107
96
 
108
 
        if (p->debug) fprintf(stderr,"munki: About to init USB\n");
 
97
        a1logd(p->log, 2, "munki_init_coms: about to init USB\n");
109
98
 
110
99
        /* Set config, interface, write end point, read end point, read quanta */
111
100
        /* ("serial" end points aren't used - the Munki uses USB control messages) */
112
 
        p->icom->set_usb_port(p->icom, port, 1, 0x00, 0x00, usbflags, retries, pnames); 
 
101
        if ((se = p->icom->set_usb_port(p->icom, 1, 0x00, 0x00, usbflags, retries, pnames))
 
102
                                                                                   != ICOM_OK) { 
 
103
                a1logd(p->log, 1, "munki_init_coms: failed ICOM err 0x%x\n",se);
 
104
                return munki_interp_code(p, icoms2munki_err(se));
 
105
        }
113
106
 
114
 
        if (p->debug) fprintf(stderr,"munki: init coms has suceeded\n");
 
107
        a1logd(p->log, 2, "munki_init_coms: init coms has suceeded\n");
115
108
 
116
109
        p->gotcoms = 1;
117
110
        return inst_ok;
118
111
}
119
112
 
120
113
static inst_code
121
 
munki_discover_capabilities(munki *p) {
 
114
munki_determine_capabilities(munki *p) {
122
115
 
123
116
        /* Set the Munki capabilities mask */
124
 
        p->cap |= inst_ref_spot
125
 
               |  inst_ref_strip
126
 
               |  inst_emis_spot
127
 
               |  inst_emis_disp
128
 
               |  inst_emis_proj                /* Support of a specific projector mode */
129
 
               |  inst_emis_tele
130
 
               |  inst_trans_spot               /* Support this manually using a light table */
131
 
               |  inst_trans_strip 
132
 
               |  inst_emis_strip               /* Also likely to be light table reading */
133
 
               |  inst_colorimeter
134
 
               |  inst_spectral
135
 
                   |  inst_emis_ambient
136
 
                   |  inst_emis_ambient_flash
 
117
        p->cap = inst_mode_ref_spot
 
118
               | inst_mode_ref_strip
 
119
               | inst_mode_emis_spot
 
120
               | inst_mode_emis_tele
 
121
               | inst_mode_trans_spot           /* Support this manually using a light table */
 
122
               | inst_mode_trans_strip 
 
123
               | inst_mode_emis_strip           /* Also likely to be light table reading */
 
124
                   | inst_mode_emis_ambient
 
125
                   | inst_mode_emis_ambient_flash
 
126
               | inst_mode_emis_nonadaptive
 
127
               | inst_mode_colorimeter
 
128
               | inst_mode_spectral
 
129
               | inst_mode_calibration          /* Can indicate cal configuration */
137
130
               ;
138
131
 
139
 
        p->cap2 |= inst2_cal_ref_white
140
 
                | inst2_cal_trans_white 
141
 
                | inst2_cal_disp_int_time 
142
 
                | inst2_cal_proj_int_time 
143
 
                | inst2_prog_trig 
144
 
                        | inst2_keyb_trig
145
 
                        | inst2_keyb_switch_trig
 
132
        if (munki_imp_highres(p))               /* Static */
 
133
                p->cap |= inst_mode_highres;
 
134
 
 
135
        p->cap2 = inst2_prog_trig 
 
136
                        | inst2_user_trig
 
137
                        | inst2_user_switch_trig
146
138
                        | inst2_bidi_scan
147
139
                        | inst2_has_scan_toll
148
140
                        | inst2_no_feedback
150
142
                        | inst2_has_sensmode
151
143
                ;
152
144
 
153
 
        if (munki_imp_highres(p))               /* Static */
154
 
                p->cap |= inst_highres;
155
 
 
156
 
        return inst_ok;
157
 
}
 
145
        if (p->m != NULL) {
 
146
                munkiimp *m = (munkiimp *)p->m;
 
147
                munki_state *s = &m->ms[m->mmode];
 
148
                if (s->emiss)
 
149
                        p->cap2 |= inst2_emis_refr_meas;
 
150
        }
 
151
 
 
152
        p->cap3 = inst3_none;
 
153
 
 
154
        return inst_ok;
 
155
}
 
156
 
 
157
/* Return current or given configuration available measurement modes. */
 
158
static inst_code munki_meas_config(
 
159
inst *pp,
 
160
inst_mode *mmodes,
 
161
inst_cal_cond *cconds,
 
162
int *conf_ix
 
163
) {
 
164
        munki *p = (munki *)pp;
 
165
        munki_code ev;
 
166
        mk_spos spos;
 
167
 
 
168
        if (mmodes != NULL)
 
169
                *mmodes = inst_mode_none;
 
170
        if (cconds != NULL)
 
171
                *cconds = inst_calc_none;
 
172
 
 
173
        if (conf_ix == NULL
 
174
         || *conf_ix < mk_spos_proj
 
175
         || *conf_ix > mk_spos_amb) {
 
176
                /* Return current configuration measrement modes */
 
177
                ev = munki_getstatus(p, &spos, NULL);
 
178
                if (ev != MUNKI_OK)
 
179
                        return munki_interp_code(p, ev);
 
180
        } else {
 
181
                /* Return given configuration measurement modes */
 
182
                spos = *conf_ix;
 
183
        }
 
184
 
 
185
        if (spos == mk_spos_proj) {
 
186
                if (mmodes != NULL)
 
187
                        *mmodes = inst_mode_emis_tele;
 
188
        } else if (spos == mk_spos_surf) {
 
189
                if (mmodes != NULL)
 
190
                        *mmodes = inst_mode_ref_spot
 
191
                                | inst_mode_ref_strip
 
192
                                | inst_mode_emis_spot
 
193
                                | inst_mode_trans_spot
 
194
                                | inst_mode_trans_strip;
 
195
        } else if (spos == mk_spos_calib) {
 
196
                if (cconds != NULL)
 
197
                        *cconds = inst_calc_man_cal_smode;
 
198
                if (mmodes != NULL)
 
199
                        *mmodes = inst_mode_calibration;
 
200
        } else if (spos == mk_spos_amb) {
 
201
                if (mmodes != NULL)
 
202
                        *mmodes = inst_mode_emis_ambient
 
203
                                | inst_mode_emis_ambient_flash;
 
204
        }
 
205
 
 
206
        /* Return configuration index returned */
 
207
        if (conf_ix != NULL)
 
208
                *conf_ix = (int)spos;
 
209
 
 
210
        /* Add the extra dependent and independent modes */
 
211
        if (mmodes != NULL)
 
212
                *mmodes |= inst_mode_emis_nonadaptive
 
213
                        | inst_mode_colorimeter
 
214
                        | inst_mode_spectral;
 
215
 
 
216
        return inst_ok;
 
217
}
 
218
 
158
219
 
159
220
/* Initialise the MUNKI */
160
221
/* return non-zero on an error, with dtp error code */
163
224
        munki *p = (munki *)pp;
164
225
        munki_code ev = MUNKI_OK;
165
226
 
166
 
        if (p->debug) fprintf(stderr,"munki: About to init instrument\n");
 
227
        a1logd(p->log, 2, "munki_init_inst: called\n");
167
228
 
168
229
        if (p->gotcoms == 0)
169
230
                return munki_interp_code(p, MUNKI_INT_NO_COMS); /* Must establish coms before calling init */
170
231
        if ((ev = munki_imp_init(p)) != MUNKI_OK) {
171
 
                if (p->debug) fprintf(stderr,"munki_imp_init() failed\n");
 
232
                a1logd(p->log, 1, "munki_init_inst: failed with 0x%x\n",ev);
172
233
                return munki_interp_code(p, ev);
173
234
        }
174
235
 
175
236
        p->inited = 1;
176
 
        munki_discover_capabilities(p);
 
237
        a1logd(p->log, 2, "munki_init_inst: instrument inited OK\n");
 
238
 
 
239
        munki_determine_capabilities(p);
177
240
 
178
241
        return munki_interp_code(p, ev);
179
242
}
210
273
        if (!p->inited)
211
274
                return inst_no_init;
212
275
 
213
 
        rv = munki_imp_measure(p, vals, npatch);
 
276
        rv = munki_imp_measure(p, vals, npatch, 1);
214
277
 
215
278
        return munki_interp_code(p, rv);
216
279
}
221
284
munki_read_sample(
222
285
inst *pp,
223
286
char *name,                     /* Strip name (7 chars) */
224
 
ipatch *val) {          /* Pointer to instrument patch value */
225
 
        munki *p = (munki *)pp;
226
 
        munki_code rv;
227
 
 
228
 
        if (!p->gotcoms)
229
 
                return inst_no_coms;
230
 
        if (!p->inited)
231
 
                return inst_no_init;
232
 
 
233
 
        rv = munki_imp_measure(p, val, 1);
234
 
 
235
 
        return munki_interp_code(p, rv);
236
 
}
237
 
 
238
 
/* Determine if a calibration is needed. Returns inst_calt_none if not, */
239
 
/* inst_calt_unknown if it is unknown, or inst_calt_XXX if needs calibration, */
240
 
/* and the first type of calibration needed. */
241
 
inst_cal_type munki_needs_calibration(inst *pp) {
242
 
        munki *p = (munki *)pp;
243
 
 
244
 
        if (!p->gotcoms)
245
 
                return inst_no_coms;
246
 
        if (!p->inited)
247
 
                return inst_no_init;
248
 
 
249
 
        return munki_imp_needs_calibration(p);
 
287
ipatch *val,            /* Pointer to instrument patch value */
 
288
instClamping clamp) {           /* Clamp XYZ/Lab to be +ve */
 
289
        munki *p = (munki *)pp;
 
290
        munki_code rv;
 
291
 
 
292
        if (!p->gotcoms)
 
293
                return inst_no_coms;
 
294
        if (!p->inited)
 
295
                return inst_no_init;
 
296
 
 
297
        rv = munki_imp_measure(p, val, 1, clamp);
 
298
 
 
299
        return munki_interp_code(p, rv);
 
300
}
 
301
 
 
302
/* Read an emissive refresh rate */
 
303
static inst_code
 
304
munki_read_refrate(
 
305
inst *pp,
 
306
double *ref_rate) {
 
307
        munki *p = (munki *)pp;
 
308
        munki_code rv;
 
309
 
 
310
        if (!p->gotcoms)
 
311
                return inst_no_coms;
 
312
        if (!p->inited)
 
313
                return inst_no_init;
 
314
 
 
315
        rv = munki_imp_meas_refrate(p, ref_rate);
 
316
 
 
317
        return munki_interp_code(p, rv);
 
318
}
 
319
 
 
320
/* Return needed and available inst_cal_type's */
 
321
static inst_code munki_get_n_a_cals(inst *pp, inst_cal_type *pn_cals, inst_cal_type *pa_cals) {
 
322
        munki *p = (munki *)pp;
 
323
        munki_code rv;
 
324
 
 
325
        rv = munki_imp_get_n_a_cals(p, pn_cals, pa_cals);
 
326
        return munki_interp_code(p, rv);
250
327
}
251
328
 
252
329
/* Request an instrument calibration. */
253
 
/* This is use if the user decides they want to do a calibration, */
254
 
/* in anticipation of a calibration (needs_calibration()) to avoid */
255
 
/* requiring one during measurement, or in response to measuring */
256
 
/* returning inst_needs_cal. Initially us an inst_cal_cond of inst_calc_none, */
257
 
/* and then be prepared to setup the right conditions, or ask the */
258
 
/* user to do so, each time the error inst_cal_setup is returned. */
259
330
inst_code munki_calibrate(
260
331
inst *pp,
261
 
inst_cal_type calt,             /* Calibration type. inst_calt_all for all neeeded */
 
332
inst_cal_type *calt,    /* Calibration type to do/remaining */
262
333
inst_cal_cond *calc,    /* Current condition/desired condition */
263
334
char id[CALIDLEN]               /* Condition identifier (ie. white reference ID) */
264
335
) {
271
342
                return inst_no_init;
272
343
 
273
344
        rv = munki_imp_calibrate(p, calt, calc, id);
 
345
 
274
346
        return munki_interp_code(p, rv);
275
347
}
276
348
 
290
362
                        return "Data from i1 Display didn't parse as expected";
291
363
 
292
364
                case MUNKI_USER_ABORT:
293
 
                        return "User hit Abort key";
294
 
                case MUNKI_USER_TERM:
295
 
                        return "User hit Terminate key";
 
365
                        return "User abort";
 
366
 
296
367
                case MUNKI_USER_TRIG:
297
 
                        return "User hit Trigger key";
298
 
                case MUNKI_USER_CMND:
299
 
                        return "User hit a Command key";
 
368
                        return "User trigger";
300
369
 
301
370
                case MUNKI_UNSUPPORTED:
302
371
                        return "Unsupported function";
306
375
                case MUNKI_OK:
307
376
                        return "No device error";
308
377
 
309
 
                case MUNKI_DATA_COUNT:
310
 
                        return "EEProm data count unexpected size";
311
378
                case MUNKI_DATA_RANGE:
312
379
                        return "EEProm data count location out of range";
313
380
                case MUNKI_DATA_MEMORY:
356
423
                        return "No flashes recognized";
357
424
                case MUNKI_RD_NOAMBB4FLASHES:
358
425
                        return "No ambient found before first flash";
 
426
                case MUNKI_RD_NOREFR_FOUND:
 
427
                        return "No refresh rate detected or failed to measure it";
359
428
 
360
429
                case MUNKI_SPOS_PROJ:
361
430
                        return "Sensor should be in projector position";
368
437
 
369
438
                case MUNKI_INT_NO_COMS:
370
439
                        return "Communications hasn't been established";
 
440
                case MUNKI_INT_EESIZE:
 
441
                        return "EEProm is not the expected size";
371
442
                case MUNKI_INT_EEOUTOFRANGE:
372
443
                        return "EEProm access is out of range";
373
444
                case MUNKI_INT_CALTOOSMALL:
389
460
                case MUNKI_INT_WRONGPATCHES:
390
461
                        return "Number of patches to match is wrong";
391
462
                case MUNKI_INT_MEASBUFFTOOSMALL:
392
 
                        return "Measurement read buffer is too small";
 
463
                        return "Measurement exceeded read buffer";
393
464
                case MUNKI_INT_NOTIMPLEMENTED:
394
465
                        return "Support not implemented";
395
466
                case MUNKI_INT_NOTCALIBRATED:
410
481
                        return "Unable to save calibration to file";
411
482
                case MUNKI_INT_CAL_RESTORE:
412
483
                        return "Unable to restore calibration from file";
 
484
                case MUNKI_INT_CAL_TOUCH:
 
485
                        return "Unable to update calibration file modification time";
 
486
                case MUNKI_INT_ASSERT:
 
487
                        return "Assert fail";
413
488
                default:
414
489
                        return "Unknown error code";
415
490
        }
437
512
                        return inst_protocol_error | ec;
438
513
 
439
514
                case MUNKI_USER_ABORT:
440
 
                        return inst_user_abort | ec;
441
 
                case MUNKI_USER_TERM:
442
 
                        return inst_user_term | ec;
 
515
                        return inst_user_abort;
 
516
 
443
517
                case MUNKI_USER_TRIG:
444
 
                        return inst_user_trig | ec;
445
 
                case MUNKI_USER_CMND:
446
 
                        return inst_user_cmnd | ec;
 
518
                        return inst_user_trig;
447
519
 
448
520
                case MUNKI_UNSUPPORTED:
449
521
                        return inst_unsupported | ec;
458
530
                case MUNKI_SPOS_PROJ:
459
531
                case MUNKI_SPOS_SURF:
460
532
                case MUNKI_SPOS_AMB:
461
 
                        return inst_wrong_sensor_pos | ec;
 
533
                        return inst_wrong_config | ec;
462
534
 
463
 
                case MUNKI_DATA_COUNT:
464
535
                case MUNKI_DATA_RANGE:
465
536
                case MUNKI_DATA_MEMORY:
466
537
                case MUNKI_HW_EE_SHORTREAD:
485
556
                case MUNKI_RD_NOTENOUGHSAMPLES:
486
557
                case MUNKI_RD_NOFLASHES:
487
558
                case MUNKI_RD_NOAMBB4FLASHES:
 
559
                case MUNKI_RD_NOREFR_FOUND:
488
560
                        return inst_misread | ec;
489
561
 
490
562
                case MUNKI_INTERNAL_ERROR:
491
563
                case MUNKI_INT_NO_COMS:
 
564
                case MUNKI_INT_EESIZE:
492
565
                case MUNKI_INT_EEOUTOFRANGE:
493
566
                case MUNKI_INT_CALTOOSMALL:
494
567
                case MUNKI_INT_CALTOOBIG:
508
581
                case MUNKI_INT_CREATE_EEPROM_STORE:
509
582
                case MUNKI_INT_NEW_RSPL_FAILED:
510
583
                case MUNKI_INT_CAL_SAVE:
 
584
                case MUNKI_INT_CAL_RESTORE:
 
585
                case MUNKI_INT_CAL_TOUCH:
511
586
                case MUNKI_INT_WRONGPATCHES:
512
 
                case MUNKI_INT_CAL_RESTORE:
 
587
                case MUNKI_INT_ASSERT:
513
588
                        return inst_internal_error | ec;
514
589
        }
515
590
        return inst_other_error | ec;
516
591
}
517
592
 
 
593
/* Convert instrument specific inst_wrong_config error to inst_config enum */
 
594
static inst_config munki_config_enum(inst *pp, int ec) {
 
595
//      munki *p = (munki *)pp;
 
596
 
 
597
        ec &= inst_imask;
 
598
        switch (ec) {
 
599
 
 
600
                case MUNKI_SPOS_PROJ:
 
601
                        return inst_conf_projector;
 
602
 
 
603
                case MUNKI_SPOS_SURF:
 
604
                        return inst_conf_surface;
 
605
 
 
606
                case MUNKI_SPOS_AMB:
 
607
                        return inst_conf_ambient;
 
608
 
 
609
                case MUNKI_SPOS_CALIB:
 
610
                        return inst_conf_calibration;
 
611
        }
 
612
        return inst_conf_unknown;
 
613
}
 
614
 
518
615
/* Return the instrument capabilities */
519
 
inst_capability munki_capabilities(inst *pp) {
520
 
        munki *p = (munki *)pp;
521
 
 
522
 
        return p->cap;
523
 
}
524
 
 
525
 
/* Return the instrument capabilities 2 */
526
 
inst2_capability munki_capabilities2(inst *pp) {
527
 
        munki *p = (munki *)pp;
528
 
        inst2_capability rv;
529
 
 
530
 
        rv = p->cap2;
531
 
 
532
 
        return rv;
 
616
void munki_capabilities(inst *pp,
 
617
inst_mode *pcap1,
 
618
inst2_capability *pcap2,
 
619
inst3_capability *pcap3) {
 
620
        munki *p = (munki *)pp;
 
621
 
 
622
        if (pcap1 != NULL)
 
623
                *pcap1 = p->cap;
 
624
        if (pcap2 != NULL)
 
625
                *pcap2 = p->cap2;
 
626
        if (pcap3 != NULL)
 
627
                *pcap3 = p->cap3;
 
628
 
 
629
        return;
 
630
}
 
631
 
 
632
/* Return the corresponding munki measurement mode, */
 
633
/* or mk_no_modes if invalid */
 
634
static mk_mode munki_convert_mode(munki *p, inst_mode m) {
 
635
        mk_mode mmode = 0;
 
636
 
 
637
        /* Simple test */
 
638
        if (m & ~p->cap)
 
639
                return mk_no_modes;
 
640
 
 
641
        if (IMODETST(m, inst_mode_ref_spot)) {
 
642
                mmode = mk_refl_spot;
 
643
        } else if (IMODETST(m, inst_mode_ref_strip)) {
 
644
                mmode = mk_refl_scan;
 
645
        } else if (IMODETST(m, inst_mode_trans_spot)) {
 
646
                mmode = mk_trans_spot;
 
647
        } else if (IMODETST(m, inst_mode_trans_strip)) {
 
648
                mmode = mk_trans_scan;
 
649
        } else if (IMODETST(m, inst_mode_emis_spot)) {
 
650
                if (IMODETST(m, inst_mode_emis_nonadaptive))
 
651
                        mmode = mk_emiss_spot_na;
 
652
                else
 
653
                        mmode = mk_emiss_spot;
 
654
        } else if (IMODETST(m, inst_mode_emis_tele)) {
 
655
                if (IMODETST(m, inst_mode_emis_nonadaptive))
 
656
                        mmode = mk_tele_spot_na;
 
657
                else
 
658
                        mmode = mk_tele_spot;
 
659
        } else if (IMODETST(m, inst_mode_emis_strip)) {
 
660
                mmode = mk_emiss_scan;
 
661
        } else if (IMODETST(m, inst_mode_emis_ambient)) {
 
662
                mmode = mk_amb_spot;
 
663
        } else if (IMODETST(m, inst_mode_emis_ambient_flash)) {
 
664
                mmode = mk_amb_flash;
 
665
        } else {
 
666
                return mk_no_modes;
 
667
        }
 
668
 
 
669
        return mmode;
 
670
}
 
671
 
 
672
/* Check device measurement mode */
 
673
inst_code munki_check_mode(inst *pp, inst_mode m) {
 
674
        munki *p = (munki *)pp;
 
675
        mk_mode mmode = 0;
 
676
 
 
677
        if (!p->gotcoms)
 
678
                return inst_no_coms;
 
679
        if (!p->inited)
 
680
                return inst_no_init;
 
681
 
 
682
        if (munki_convert_mode(p, m) == mk_no_modes)
 
683
                return inst_unsupported;
 
684
 
 
685
        return inst_ok;
533
686
}
534
687
 
535
688
/* Set device measurement mode */
536
689
inst_code munki_set_mode(inst *pp, inst_mode m) {
537
690
        munki *p = (munki *)pp;
538
 
        inst_mode mm;                   /* Request measurement mode */
539
 
        mk_mode mmode = -1;     /* Instrument measurement mode */
 
691
        mk_mode mmode = 0;
 
692
        inst_mode cap = p->cap;
 
693
        inst_code rv;
540
694
 
541
695
        if (!p->gotcoms)
542
696
                return inst_no_coms;
543
697
        if (!p->inited)
544
698
                return inst_no_init;
545
699
 
546
 
        /* The measurement mode portion of the mode */
547
 
        mm = m & inst_mode_measurement_mask;
548
 
 
549
 
        if ((mm & inst_mode_illum_mask) == inst_mode_reflection) {
550
 
                if ((mm & inst_mode_sub_mask) == inst_mode_spot) {
551
 
                        mmode = mk_refl_spot;
552
 
                } else if ((mm & inst_mode_sub_mask) == inst_mode_strip) {
553
 
                        mmode = mk_refl_scan;
554
 
                } else {
555
 
                        return inst_unsupported;
556
 
                }
557
 
        } else if ((mm & inst_mode_illum_mask) == inst_mode_transmission) {
558
 
                if ((mm & inst_mode_sub_mask) == inst_mode_spot) {
559
 
                        mmode = mk_trans_spot;
560
 
                } else if ((mm & inst_mode_sub_mask) == inst_mode_strip) {
561
 
                        mmode = mk_trans_scan;
562
 
                } else {
563
 
                        return inst_unsupported;
564
 
                }
565
 
        } else if ((mm & inst_mode_illum_mask) == inst_mode_emission) {
566
 
                if ((mm & inst_mode_sub_mask) == inst_mode_spot) {
567
 
                        if ((mm & inst_mode_mod_mask) == inst_mode_disp) {
568
 
                                mmode = mk_disp_spot;
569
 
                        } else {
570
 
                                mmode = mk_emiss_spot;
571
 
                        }
572
 
                } else if ((mm & inst_mode_sub_mask) == inst_mode_tele) {
573
 
                        if ((mm & inst_mode_mod_mask) == inst_mode_disp) {
574
 
                                mmode = mk_proj_spot;
575
 
                        } else {
576
 
                                mmode = mk_tele_spot;
577
 
                        }
578
 
                } else if ((mm & inst_mode_sub_mask) == inst_mode_strip) {
579
 
                        mmode = mk_emiss_scan;
580
 
                } else if ((mm & inst_mode_sub_mask) == inst_mode_ambient) {
581
 
                        mmode = mk_amb_spot;
582
 
                } else if ((mm & inst_mode_sub_mask) == inst_mode_ambient_flash) {
583
 
                        mmode = mk_amb_flash;
584
 
                } else {
585
 
                        return inst_unsupported;
586
 
                }
587
 
        } else {
 
700
        if ((mmode = munki_convert_mode(p, m)) == mk_no_modes)
588
701
                return inst_unsupported;
589
 
        }
590
 
        return munki_interp_code(p, munki_imp_set_mode(p, mmode, m & inst_mode_spectral));
591
 
}
592
 
 
593
 
/* Get a dynamic status */
594
 
static inst_code munki_get_status(
595
 
inst *pp,
596
 
inst_status_type m,     /* Requested status type */
597
 
...) {                          /* Status parameters */                             
598
 
        munki *p = (munki *)pp;
599
 
 
600
 
        if (!p->gotcoms)
601
 
                return inst_no_coms;
602
 
        if (!p->inited)
603
 
                return inst_no_init;
604
 
 
605
 
        /* Return the sensor mode */
606
 
        if (m == inst_stat_sensmode) {
607
 
                munki_code ev;
608
 
                inst_stat_smode *smode;
609
 
                va_list args;
610
 
                mk_spos spos;
611
 
 
612
 
                va_start(args, m);
613
 
                smode = va_arg(args, inst_stat_smode *);
614
 
                va_end(args);
615
 
 
616
 
                *smode = inst_stat_smode_unknown;
617
 
 
618
 
                /* Get the device status */
619
 
                ev = munki_getstatus(p, &spos, NULL);
620
 
                if (ev != MUNKI_OK)
621
 
                        return munki_interp_code(p, ev);
622
 
 
623
 
                if (spos == mk_spos_proj)
624
 
                        *smode = inst_stat_smode_proj;
625
 
                else if (spos == mk_spos_surf)
626
 
                        *smode = inst_stat_smode_ref | inst_stat_smode_disp;
627
 
                else if (spos == mk_spos_calib)
628
 
                        *smode = inst_stat_smode_calib;
629
 
                else if (spos == mk_spos_amb)
630
 
                        *smode = inst_stat_smode_amb;
631
 
 
632
 
                return inst_ok;
633
 
        }
634
 
 
635
 
        /* Return the filter */
636
 
        else if (m == inst_stat_get_filter) {
637
 
                inst_opt_filter *filt;
638
 
                va_list args;
639
 
 
640
 
                va_start(args, m);
641
 
                filt = va_arg(args, inst_opt_filter *);
642
 
                va_end(args);
643
 
 
644
 
                /* The ColorMunki is always UV cut */
645
 
                *filt = inst_opt_filter_UVCut;
646
 
 
647
 
                return inst_ok;
648
 
        }
649
 
 
650
 
        return inst_unsupported;
 
702
        
 
703
        if ((rv = munki_interp_code(p, munki_imp_set_mode(p, mmode, m & inst_mode_spectral)))
 
704
                                                                                      != inst_ok)
 
705
                return rv;
 
706
 
 
707
        munki_determine_capabilities(p);
 
708
 
 
709
        return inst_ok;
651
710
}
652
711
 
653
712
/* 
654
713
 * set or reset an optional mode
655
 
 * We assume that the instrument has been initialised.
 
714
 *
 
715
 * Some options talk to the instrument, and these will
 
716
 * error if it hasn't been initialised.
656
717
 */
657
718
static inst_code
658
 
munki_set_opt_mode(inst *pp, inst_opt_mode m, ...)
659
 
{
 
719
munki_get_set_opt(inst *pp, inst_opt_type m, ...) {
660
720
        munki *p = (munki *)pp;
661
721
 
662
 
        if (!p->gotcoms)
663
 
                return inst_no_coms;
664
 
        if (!p->inited)
665
 
                return inst_no_init;
666
 
 
667
 
        if (m == inst_opt_noautocalib) {
668
 
                munki_set_noautocalib(p, 1);
 
722
        if (m == inst_opt_noinitcalib) {
 
723
                va_list args;
 
724
                int losecs = 0;
 
725
 
 
726
                va_start(args, m);
 
727
                losecs = va_arg(args, int);
 
728
                va_end(args);
 
729
 
 
730
                munki_set_noinitcalib(p, 1, losecs);
669
731
                return inst_ok;
670
732
 
671
 
        } else if (m == inst_opt_autocalib) {
672
 
                munki_set_noautocalib(p, 0);
 
733
        } else if (m == inst_opt_initcalib) {
 
734
                munki_set_noinitcalib(p, 0, 0);
673
735
                return inst_ok;
674
736
 
675
737
        /* Record the trigger mode */
676
738
        } else if (m == inst_opt_trig_prog
677
 
         || m == inst_opt_trig_keyb
678
 
         || m == inst_opt_trig_keyb_switch) {
 
739
         || m == inst_opt_trig_user
 
740
         || m == inst_opt_trig_user_switch) {
679
741
                munki_set_trig(p, m);
680
742
                return inst_ok;
681
743
        }
682
 
        if (m == inst_opt_trig_return) {
683
 
                munki_set_trigret(p, 1);
684
 
                return inst_ok;
685
 
        } else if (m == inst_opt_trig_no_return) {
686
 
                munki_set_trigret(p, 0);
687
 
                return inst_ok;
 
744
 
 
745
        if (m == inst_opt_scan_toll) {
 
746
                va_list args;
 
747
                double toll_ratio = 1.0;
 
748
 
 
749
                va_start(args, m);
 
750
                toll_ratio = va_arg(args, double);
 
751
                va_end(args);
 
752
                return munki_interp_code(p, munki_set_scan_toll(p, toll_ratio));
688
753
        }
689
754
 
 
755
        if (!p->gotcoms)
 
756
                return inst_no_coms;
 
757
        if (!p->inited)
 
758
                return inst_no_init;
 
759
 
 
760
        /* Not sure if hires can be set before init */
690
761
        if (m == inst_opt_highres) {
691
762
                return munki_interp_code(p, munki_set_highres(p));
692
763
        } else if (m == inst_opt_stdres) {
693
764
                return munki_interp_code(p, munki_set_stdres(p));
694
765
        }
695
766
 
696
 
        if (m == inst_opt_scan_toll) {
697
 
                va_list args;
698
 
                double toll_ratio = 1.0;
699
 
 
700
 
                va_start(args, m);
701
 
                toll_ratio = va_arg(args, double);
702
 
                va_end(args);
703
 
                return munki_interp_code(p, munki_set_scan_toll(p, toll_ratio));
704
 
        }
705
 
 
706
767
        if (m == inst_opt_get_gen_ledmask) {
707
768
                va_list args;
708
769
                int *mask = NULL;
794
855
                return inst_ok;
795
856
        }
796
857
 
 
858
        /* Return the filter */
 
859
        if (m == inst_stat_get_filter) {
 
860
                inst_opt_filter *filt;
 
861
                va_list args;
 
862
 
 
863
                va_start(args, m);
 
864
                filt = va_arg(args, inst_opt_filter *);
 
865
                va_end(args);
 
866
 
 
867
                /* The ColorMunki is always UV cut */
 
868
                *filt = inst_opt_filter_UVCut;
 
869
 
 
870
                return inst_ok;
 
871
        }
 
872
 
 
873
        /* Use default implementation of other inst_opt_type's */
 
874
        {
 
875
                inst_code rv;
 
876
                va_list args;
 
877
 
 
878
                va_start(args, m);
 
879
                rv = inst_get_set_opt_def(pp, m, args);
 
880
                va_end(args);
 
881
 
 
882
                return rv;
 
883
        }
797
884
        return inst_unsupported;
798
885
}
799
886
 
809
896
}
810
897
 
811
898
/* Constructor */
812
 
extern munki *new_munki(icoms *icom, instType itype, int debug, int verb)
813
 
{
 
899
extern munki *new_munki(icoms *icom, instType itype) {
814
900
        munki *p;
815
 
        if ((p = (munki *)calloc(sizeof(munki),1)) == NULL)
816
 
                error("munki: malloc failed!");
817
 
 
818
 
        if (icom == NULL)
819
 
                p->icom = new_icoms();
820
 
        else
821
 
                p->icom = icom;
822
 
 
823
 
        /* Preliminary capabilities */
824
 
        munki_discover_capabilities(p);
825
 
        p->debug = debug;
826
 
        p->verb = verb;
827
 
 
828
 
        if (add_munkiimp(p) != MUNKI_OK) {
829
 
                free(p);
830
 
                error("munki: creating munkiimp");
 
901
        int rv;
 
902
        if ((p = (munki *)calloc(sizeof(munki),1)) == NULL) {
 
903
                a1loge(icom->log, 1, "new_munki: malloc failed!\n");
 
904
                return NULL;
831
905
        }
832
906
 
 
907
        p->log = new_a1log_d(icom->log);
 
908
 
833
909
        /* Inst methods */
834
910
        p->init_coms         = munki_init_coms;
835
911
        p->init_inst         = munki_init_inst;
836
912
        p->capabilities      = munki_capabilities;
837
 
        p->capabilities2     = munki_capabilities2;
 
913
        p->meas_config       = munki_meas_config;
838
914
        p->get_serial_no     = munki_get_serial_no;
 
915
        p->check_mode        = munki_check_mode;
839
916
        p->set_mode          = munki_set_mode;
840
 
        p->get_status        = munki_get_status;
841
 
        p->set_opt_mode      = munki_set_opt_mode;
 
917
        p->get_set_opt       = munki_get_set_opt;
842
918
        p->read_strip        = munki_read_strip;
843
919
        p->read_sample       = munki_read_sample;
844
 
        p->needs_calibration = munki_needs_calibration;
 
920
        p->read_refrate      = munki_read_refrate;
 
921
        p->get_n_a_cals      = munki_get_n_a_cals;
845
922
        p->calibrate         = munki_calibrate;
846
923
        p->interp_error      = munki_interp_error;
 
924
        p->config_enum       = munki_config_enum;
847
925
        p->del               = munki_del;
848
926
 
849
 
        p->itype = itype;
 
927
        p->icom = icom;
 
928
        p->itype = icom->itype;
 
929
 
 
930
        /* Preliminary capabilities */
 
931
        munki_determine_capabilities(p);
 
932
 
 
933
        if ((rv = add_munkiimp(p) != MUNKI_OK)) {
 
934
                free(p);
 
935
                a1loge(icom->log, 1, "new_munki: error %d creating munkiimp\n",rv);
 
936
        }
850
937
 
851
938
        return p;
852
939
}