65
65
/* Configuration */
66
#define USE_THREAD /* Need to use thread, or there are 1.5 second internal */
66
#define USE_THREAD /* [Def] Need to use thread, or there are 1.5 second internal */
67
67
/* instrument delays ! */
68
#define ENABLE_NONVCAL /* Enable saving calibration state between program runs in a file */
69
#define ENABLE_NONLINCOR /* Enable non-linear correction */
68
#define ENABLE_NONVCAL /* [Def] Enable saving calibration state between program runs in a file */
69
#define ENABLE_NONLINCOR /* [Def] Enable non-linear correction */
70
70
/* NOTE :- high gain scaling will be stuffed if disabled! */
71
#define ENABLE_LEDTEMPC /* Enable LED temperature compensation */
72
#define ENABLE_SPOS_CHECK /* Chech the sensor position is reasonable for measurement */
73
#define CALTOUT (24 * 60 * 60) /* Calibration timeout in seconds */
74
#define MAXSCANTIME 15.0 /* Maximum scan time in seconds */
75
#define SW_THREAD_TIMEOUT (10 * 60.0) /* Switch read thread timeout */
76
//#define SW_THREAD_TIMEOUT (0.1) /* Switch read thread timeout */
71
#define ENABLE_LEDTEMPC /* [Def] Enable LED temperature compensation */
72
#define ENABLE_SPOS_CHECK /* [Def] Chech the sensor position is reasonable for measurement */
73
#define CALTOUT (24 * 60 * 60) /* [24 Hrs] Calibration timeout in seconds */
74
#define MAXSCANTIME 15.0 /* [14 Sec] Maximum scan time in seconds */
75
#define SW_THREAD_TIMEOUT (10 * 60.0) /* [10 Min] Switch read thread timeout */
78
#define SINGLE_READ /* Use a single USB read for scan to eliminate latency issues. */
79
#define HIGH_RES /* Enable high resolution spectral mode code. Disable */
77
#define SINGLE_READ /* [Def] Use a single USB read for scan to eliminate latency issues. */
78
#define HIGH_RES /* [Def] Enable high resolution spectral mode code. Disable */
80
79
/* to break dependency on rspl library. */
83
82
#undef DEBUG /* Turn on debug printfs */
84
83
#undef PLOT_DEBUG /* Use plot to show readings & processing */
85
84
#undef RAWR_DEBUG /* Print out raw reading processing values */
897
894
s->cal_valid = 0;
900
//printf("~1 idark_valid = %d, dark_valid = %d, cal_valid = %d\n",
901
//s->idark_valid,s->dark_valid,s->cal_valid);
902
//printf("~1 need_calib = %d, need_dcalib = %d, noautocalib = %d\n",
903
//s->need_calib,s->need_dcalib, m->noautocalib);
905
897
if ((s->emiss && s->adaptive && !s->idark_valid)
906
898
|| ((!s->emiss || !s->adaptive) && !s->dark_valid)
907
899
|| (s->need_dcalib && !m->noautocalib)
908
900
|| (s->reflective && !s->cal_valid)
909
901
|| (s->reflective && s->need_calib && !m->noautocalib)) {
910
//printf("~1 need cal ref white\n");
911
902
return inst_calt_ref_white;
913
904
} else if ( (s->trans && !s->cal_valid)
914
905
|| (s->trans && s->need_calib && !m->noautocalib)) {
915
//printf("~1 need cal trans white\n");
916
906
return inst_calt_trans_white;
918
908
} else if (s->emiss && !s->scan && !s->adaptive && !s->done_dintcal) {
919
//printf("~1 need cal disp/proj inttime\n");
920
909
if (s->projector)
921
910
return inst_calt_proj_int_time;
1001
990
*calc = inst_calc_man_cal_smode;
1002
991
return MUNKI_CAL_SETUP;
1004
if (!m->nosposcheck && spos != mk_spos_calib)
993
if (!m->nosposcheck && spos != mk_spos_calib) {
1005
994
return MUNKI_SPOS_CALIB;
1006
996
} else if (calt == inst_calt_em_dark) { /* Emissive Dark calib */
1008
998
if (*calc != inst_calc_man_cal_smode) {
1009
999
*calc = inst_calc_man_cal_smode;
1010
1000
return MUNKI_CAL_SETUP;
1012
if (!m->nosposcheck && spos != mk_spos_calib)
1002
if (!m->nosposcheck && spos != mk_spos_calib) {
1013
1003
return MUNKI_SPOS_CALIB;
1014
1005
} else if (calt == inst_calt_trans_dark) { /* Transmissive dark */
1015
1006
id[0] = '\000';
1016
1007
if (*calc != inst_calc_man_cal_smode) {
1017
1008
*calc = inst_calc_man_cal_smode;
1018
1009
return MUNKI_CAL_SETUP;
1020
if (!m->nosposcheck && spos != mk_spos_calib)
1011
if (!m->nosposcheck && spos != mk_spos_calib) {
1021
1012
return MUNKI_SPOS_CALIB;
1022
1014
} else if (calt == inst_calt_trans_white) { /* Transmissive white */
1023
1015
id[0] = '\000';
1024
1016
if (*calc != inst_calc_man_trans_white) {
1025
1017
*calc = inst_calc_man_trans_white;
1026
1018
return MUNKI_CAL_SETUP;
1028
if (!m->nosposcheck && spos != mk_spos_surf)
1020
if (!m->nosposcheck && spos != mk_spos_surf) {
1029
1021
return MUNKI_SPOS_SURF;
1025
/* Sanity check scan mode settings, in case something strange */
1026
/* has been restored from the persistence file. */
1027
if (s->scan && s->inttime > (2.1 * m->min_int_time)) {
1028
s->inttime = m->min_int_time; /* Maximize scan rate */
1032
1031
/* We are now either in inst_calc_man_cal_smode, */
1033
1032
/* inst_calc_man_trans_white, inst_calc_disp_white or inst_calc_proj_white */
1034
/* condition for it. */
1033
/* sequenced in that order, and in the appropriate condition for it. */
1036
/* Reflective uses on the fly black, but we need a black for white calib. */
1037
if (s->reflective && *calc == inst_calc_man_cal_smode) {
1035
/* Reflective uses on the fly black, even for adaptive. */
1036
/* Emiss and trans can use single black ref only for non-adaptive */
1037
/* using the current inttime & gainmode, while display mode */
1038
/* does an extra fallback black cal for bright displays. */
1039
if ((s->reflective && *calc == inst_calc_man_ref_white)
1040
|| (s->emiss && !s->adaptive && !s->scan && *calc == inst_calc_man_cal_smode)
1041
|| (s->trans && !s->adaptive && *calc == inst_calc_man_cal_smode)) {
1040
1044
nummeas = munki_comp_nummeas(p, s->dcaltime, s->inttime);
1042
DBG((dbgo,"Doing initial reflective black calibration with dcaltime %f, int_time %f, nummeas %d, gainmode %d\n", s->dcaltime, s->inttime, nummeas, s->gainmode))
1046
DBG((dbgo,"Doing initial display black calibration with dcaltime %f, int_time %f, nummeas %d, gainmode %d\n", s->dcaltime, s->inttime, nummeas, s->gainmode))
1043
1047
stm = msec_time();
1044
1048
if ((ev = munki_dark_measure(p, s->dark_data, nummeas, &s->inttime, s->gainmode))
1048
1052
if (p->debug) fprintf(stderr,"Execution time of dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1054
/* Special display mode alternate integration time black measurement */
1055
if (s->emiss && !s->scan && !s->adaptive) {
1056
nummeas = munki_comp_nummeas(p, s->dcaltime2, s->dark_int_time2);
1057
DBG((dbgo,"Doing 2nd initial black calibration with dcaltime2 %f, dark_int_time2 %f, nummeas %d, gainmode %d\n", s->dcaltime2, s->dark_int_time2, nummeas, s->gainmode))
1059
if ((ev = munki_dark_measure(p, s->dark_data2, nummeas, &s->dark_int_time2,
1060
s->gainmode)) != MUNKI_OK) {
1063
if (p->debug) fprintf(stderr,"Execution time of 2nd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1065
nummeas = munki_comp_nummeas(p, s->dcaltime3, s->dark_int_time3);
1066
DBG((dbgo,"Doing 3rd initial black calibration with dcaltime3 %f, dark_int_time3 %f, nummeas %d, gainmode %d\n", s->dcaltime3, s->dark_int_time3, nummeas, s->gainmode))
1067
nummeas = munki_comp_nummeas(p, s->dcaltime3, s->dark_int_time3);
1069
if ((ev = munki_dark_measure(p, s->dark_data3, nummeas, &s->dark_int_time3,
1070
s->gainmode)) != MUNKI_OK) {
1073
if (p->debug) fprintf(stderr,"Execution time of 3rd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1050
1076
s->dark_valid = 1;
1051
1077
s->need_dcalib = 0;
1052
1078
s->ddate = time(NULL);
1223
/* Emiss non-adaptive (display/projector) needs three pre-set black */
1224
/* references, so it has fallback intergration times. */
1225
if (s->emiss && !s->adaptive && !s->scan && *calc == inst_calc_man_cal_smode) {
1228
nummeas = munki_comp_nummeas(p, s->dcaltime, s->inttime);
1230
DBG((dbgo,"Doing initial display black calibration with dcaltime %f, int_time %f, nummeas %d, gainmode %d\n", s->dcaltime, s->inttime, nummeas, s->gainmode))
1232
if ((ev = munki_dark_measure(p, s->dark_data, nummeas, &s->inttime, s->gainmode))
1236
if (p->debug) fprintf(stderr,"Execution time of dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1238
nummeas = munki_comp_nummeas(p, s->dcaltime2, s->dark_int_time2);
1239
DBG((dbgo,"Doing 2nd initial black calibration with dcaltime2 %f, dark_int_time2 %f, nummeas %d, gainmode %d\n", s->dcaltime2, s->dark_int_time2, nummeas, s->gainmode))
1241
if ((ev = munki_dark_measure(p, s->dark_data2, nummeas, &s->dark_int_time2,
1242
s->gainmode)) != MUNKI_OK) {
1245
if (p->debug) fprintf(stderr,"Execution time of 2nd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1247
nummeas = munki_comp_nummeas(p, s->dcaltime3, s->dark_int_time3);
1248
DBG((dbgo,"Doing 3rd initial black calibration with dcaltime3 %f, dark_int_time3 %f, nummeas %d, gainmode %d\n", s->dcaltime3, s->dark_int_time3, nummeas, s->gainmode))
1249
nummeas = munki_comp_nummeas(p, s->dcaltime3, s->dark_int_time3);
1251
if ((ev = munki_dark_measure(p, s->dark_data3, nummeas, &s->dark_int_time3,
1252
s->gainmode)) != MUNKI_OK) {
1255
if (p->debug) fprintf(stderr,"Execution time of 3rd dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1244
/* Deal with an emissive/transmisive adaptive black reference */
1245
/* when in scan mode. */
1246
if ((s->emiss && s->adaptive && s->scan && *calc == inst_calc_man_cal_smode)
1247
|| (s->trans && s->adaptive && s->scan && *calc == inst_calc_man_cal_smode)) {
1249
/* We know scan is locked to the minimum integration time, */
1250
/* so we can measure the dark data at that integration time, */
1251
/* but we don't know what gain mode will be used, so measure both, */
1252
/* and choose the appropriate one on the fly. */
1254
s->idark_int_time[0] = s->inttime;
1255
nummeas = munki_comp_nummeas(p, s->dcaltime, s->idark_int_time[0]);
1256
DBG((dbgo,"Doing adaptive scan black calibration, dcaltime %f, idark_int_time[0] %f, nummeas %d, gainmode %d\n", s->dcaltime, s->idark_int_time[0], nummeas, s->gainmode))
1257
if ((ev = munki_dark_measure(p, s->idark_data[0], nummeas, &s->idark_int_time[0], 0))
1261
s->idark_int_time[2] = s->inttime;
1262
nummeas = munki_comp_nummeas(p, s->dcaltime, s->idark_int_time[2]);
1263
DBG((dbgo,"Doing adaptive scan black calibration, dcaltime %f, idark_int_time[2] %f, nummeas %d, gainmode %d\n", s->dcaltime, s->idark_int_time[2], nummeas, s->gainmode))
1264
if ((ev = munki_dark_measure(p, s->idark_data[2], nummeas, &s->idark_int_time[2], 1))
1269
s->iddate = time(NULL);
1272
for (j = 0; j < m->nraw; j++)
1273
s->dark_data[j] = s->idark_data[2][j];
1275
for (j = 0; j < m->nraw; j++)
1276
s->dark_data[j] = s->idark_data[0][j];
1257
1278
s->dark_valid = 1;
1258
1279
s->need_dcalib = 0;
1259
s->ddate = time(NULL);
1280
s->ddate = s->iddate;
1260
1281
s->dark_int_time = s->inttime;
1261
1282
s->dark_gain_mode = s->gainmode;
1284
DBG((dbgo,"Done adaptive scan black calibration\n"))
1263
1286
/* Save the calib to all similar modes */
1287
DBG((dbgo,"Saving adaptive scan black calib to similar modes\n"))
1264
1288
for (i = 0; i < mk_no_modes; i++) {
1265
1289
munki_state *ss = &m->ms[i];
1268
if (ss->emiss && !ss->adaptive && !ss->scan) {
1269
ss->dark_valid = s->dark_valid;
1292
if ((ss->emiss || ss->trans) && ss->adaptive && s->scan) {
1293
ss->idark_valid = s->idark_valid;
1270
1294
ss->need_dcalib = s->need_dcalib;
1271
ss->ddate = s->ddate;
1295
ss->iddate = s->iddate;
1272
1296
ss->dark_int_time = s->dark_int_time;
1273
1297
ss->dark_gain_mode = s->dark_gain_mode;
1274
for (k = 0; k < m->nraw; k++) {
1275
ss->dark_data[k] = s->dark_data[k];
1276
ss->dark_data2[k] = s->dark_data2[k];
1277
ss->dark_data3[k] = s->dark_data3[k];
1298
for (j = 0; j < 4; j++) {
1299
ss->idark_int_time[j] = s->idark_int_time[j];
1300
for (k = 0; k < m->nraw; k++)
1301
ss->idark_data[j][k] = s->idark_data[j][k];
1307
/* Reflective uses on the fly black, but we need a black for white calib */
1308
/* (because of the way the Munki subtracts the black ??) */
1309
if (s->reflective && *calc == inst_calc_man_cal_smode) {
1312
nummeas = munki_comp_nummeas(p, s->dcaltime, s->inttime);
1314
DBG((dbgo,"Doing initial reflective black calibration with dcaltime %f, int_time %f, nummeas %d, gainmode %d\n", s->dcaltime, s->inttime, nummeas, s->gainmode))
1316
if ((ev = munki_dark_measure(p, s->dark_data, nummeas, &s->inttime, s->gainmode))
1320
if (p->debug) fprintf(stderr,"Execution time of dark calib time %f sec = %d msec\n",s->inttime,msec_time() - stm);
1324
s->ddate = time(NULL);
1325
s->dark_int_time = s->inttime;
1326
s->dark_gain_mode = s->gainmode;
1283
1329
/* Now deal with white calibrations */
1285
1331
/* If we are doing a reflective white reference calibrate */
2051
2101
sprintf(cal_name, "color/.mk_%s.cal", m->serno);
2052
if ((cal_path = xdg_bds(NULL, xdg_cache, xdg_write, xdg_user, cal_name)) == NULL)
2053
return MUNKI_INT_CAL_SAVE;
2055
DBG((dbgo,"munki_save_calibration saving to file '%s'\n",cal_path));
2057
if (create_parent_directories(cal_path))
2058
return MUNKI_INT_CAL_SAVE;
2060
if ((fp = fopen(cal_path, nmode)) == NULL) {
2102
if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_write, xdg_user, cal_name)) < 1)
2103
return MUNKI_INT_CAL_SAVE;
2106
fprintf(stderr,"munki_save_calibration saving to file '%s'\n",cal_paths[0]);
2107
DBG((dbgo,"munki_save_calibration saving to file '%s'\n",cal_paths[0]));
2109
if (create_parent_directories(cal_paths[0])
2110
|| (fp = fopen(cal_paths[0], nmode)) == NULL) {
2061
2111
DBG((dbgo,"munki_save_calibration failed to open file for writing\n"));
2112
xdg_free(cal_paths, no_paths);
2063
2113
return MUNKI_INT_CAL_SAVE;
2165
2218
sprintf(cal_name, "color/.mk_%s.cal", m->serno);
2166
if ((cal_path = xdg_bds(NULL, xdg_cache, xdg_read, xdg_user, cal_name)) == NULL)
2219
if ((no_paths = xdg_bds(NULL, &cal_paths, xdg_cache, xdg_read, xdg_user, cal_name)) < 1)
2167
2220
return MUNKI_INT_CAL_RESTORE;
2169
DBG((dbgo,"munki_restore_calibration restoring from file '%s'\n",cal_path));
2223
fprintf(stderr,"munki_restore_calibration restoring from file '%s'\n",cal_paths[0]);
2224
DBG((dbgo,"munki_restore_calibration restoring from file '%s'\n",cal_paths[0]));
2171
if ((fp = fopen(cal_path, nmode)) == NULL) {
2226
if ((fp = fopen(cal_paths[0], nmode)) == NULL) {
2172
2227
DBG((dbgo,"munki_restore_calibration failed to open file for reading\n"));
2228
xdg_free(cal_paths, no_paths);
2174
2229
return MUNKI_INT_CAL_RESTORE;
2231
xdg_free(cal_paths, no_paths);