804
839
if (p->dtype == 0)
805
840
return i1disp_interp_code((inst *)p, I1DISP_WRONG_DEVICE);
807
DBG((dbgo, "take_measurement_2 called with crtm = %d\n",crtm));
842
DBG((dbgo, "i1d2_take_measurement called with crtm = %d\n",crtm));
809
/* Do CRT frequency calibration/set integration time if needed */
844
/* Do refresh period measurement */
845
if (crtm && p->rrset == 0) {
811
846
if ((ev = i1disp_do_fcal_setit(p)) != inst_ok)
850
/* Quantize the sample time */
851
if (p->refperiod > 0.0) {
853
n = (int)ceil(p->dinttime/p->refperiod);
854
p->inttime = n * p->refperiod;
855
if (p->debug) fprintf(stderr,"i1disp: integration time quantize to %f secs\n",p->inttime);
857
p->inttime = p->dinttime;
858
if (p->debug) fprintf(stderr,"i1disp: integration time set to %f secs\n",p->inttime);
815
/* For CRT mode, do an initial set of syncromized measurements */
818
if ((ev = i1disp_take_first_raw_measurement_2(p, rgb)) != inst_ok)
862
// Do a frequency measurement first, to reduces chances of a light change causing delays.
863
// This makes LCD same as CRT as far as quantization errors in high level readings.
865
/* Do an initial fixed integration time frequency measurement. */
866
DBG((dbgo,"Doing fixed period frequency measurement over %f secs\n",p->inttime))
868
if ((ev = i1d2_freq_measure(p, &p->inttime, rmeas)) != inst_ok)
821
DBG((dbgo, "Raw initial CRT RGB = %f %f %f\n",rgb[0],rgb[1],rgb[2]))
871
for (i = 0; i < 3; i++)
872
rgb[i] = p->rgbadj[i] * 0.5 * rmeas[i]/p->inttime;
874
DBG((dbgo,"Got %f %f %f raw, %f %f %f Hz\n",
875
rmeas[0], rmeas[1], rmeas[2], rgb[0], rgb[1], rgb[2]))
823
877
/* Decide whether any channels need re-measuring, */
824
/* and computed cooked values. Threshold is typically 75 */
878
/* and computed cooked values. Threshold is a count of 75 */
825
879
for (i = 0; i < 3; i++) {
826
rem[i] = (rgb[i] <= (0.75 * (double)p->sampno)) ? 1 : 0;
827
rgb[i] = 0.5 * rgb[i] * p->rgbadj1[i]/(double)p->int_clocks;
880
if (rmeas[i] <= 75.0) {
881
mask |= (1 << i); /* Yes */
882
if (rmeas[i] >= 10.0) { /* Compute target edges */
883
cdgec[i] = (int)(2.0 * rgb[i] * p->inttime + 0.5);
886
else if (cdgec[i] < ME)
829
DBG((dbgo,"Re-measure flags = %d %d %d\n",rem[0],rem[1],rem[2]))
894
DBG((dbgo,"Re-measure mask = 0x%x\n",mask))
895
DBG((dbgo,"cdgec = %d %d %d\n",cdgec[0],cdgec[1],cdgec[2]))
832
897
/* If any need re-measuring */
833
if (rem[0] || rem[1] || rem[2]) {
836
/* Do a first or second set of measurements */
837
if ((ev = i1disp_take_raw_measurement_2(p, edgec, rgb2)) != inst_ok)
839
DBG((dbgo,"Raw initial/subsequent ecount %d %d %d RGB = %f %f %f\n",
840
edgec[0], edgec[1], edgec[2], rgb2[0], rgb2[1], rgb2[2]))
842
/* Compute adjusted edge count for channels we're remeasuring, */
843
/* aiming for count values of clk_freq (~1e6). */
844
for (i = 0; i < 3; i++) {
847
if (p->clk_freq > ((2000.0 - 0.5) * rgb2[i]))
848
ns = 2000.0; /* Maximum edge count */
850
ns = floor(p->clk_freq/rgb2[i]) + 0.5;
851
if (ns < ME) /* Minimum edge count */
858
/* If we compute a different edge count, read again */
859
if (edgec[0] > ME || edgec[1] > ME || edgec[2] > ME) {
860
double rgb3[3]; /* 2nd RGB Readings */
862
if ((ev = i1disp_take_raw_measurement_2(p, edgec, rgb3)) != inst_ok)
865
DBG((dbgo,"Raw subsequent2 ecount %d %d %d RGB = %f %f %f\n",
866
edgec[0], edgec[1], edgec[2], rgb3[0], rgb3[1], rgb3[2]))
868
/* Average readings if we repeated a measurement with the same threshold */
869
/* (Minor advantage, but may as well use it) */
870
for (i = 0; i < 3; i++) {
872
rgb2[i] = 0.5 * (rgb2[i] + rgb3[i]);
878
/* Compute adjusted readings, ovewritting initial cooked values */
879
for (i = 0; i < 3; i++) {
881
rgb[i] = (p->rgbadj2[i] * (double)edgec[i])/(rgb2[i] * 2.0 * p->clk_prd);
882
DBG((dbgo,"%d after scale = %f\n",i,rgb[i]))
884
rgb[i] -= p->reg103_F[i]; /* Subtract black level */
885
DBG((dbgo,"%d after sub black = %f\n",i,rgb[i]))
889
DBG((dbgo,"%d after limit min = %f\n",i,rgb[i]))
894
DBG((dbgo,"Cooked RGB = %f %f %f\n",rgb[0],rgb[1],rgb[2]))
900
/* See if we need to compute a target edge count */
901
for (i = 0; i < 3; i++) {
902
if ((mask & (1 << i)) && cdgec[i] == ME)
909
DBG((dbgo,"Doing 1st period pre-measurement mask 0x%x, edgec %d %d %d\n",
910
mask, edgec[0], edgec[1], edgec[2]))
912
/* Do an initial measurement of 1 edge to estimate the */
913
/* number of edges needed for the whole integration time. */
914
if ((ev = i1d2_period_measure(p, edgec, rmeas)) != inst_ok)
917
DBG((dbgo,"Got %f %f %f raw %f %f %f Hz\n",
918
rmeas[0], rmeas[1], rmeas[2],
919
(p->rgbadj[0] * 0.5 * (double)edgec[0] * p->clk_freq)/rmeas[0],
920
(p->rgbadj[1] * 0.5 * (double)edgec[1] * p->clk_freq)/rmeas[1],
921
(p->rgbadj[2] * 0.5 * (double)edgec[2] * p->clk_freq)/rmeas[2]))
923
/* Compute adjusted edge count for channels we're remeasuring, */
924
/* aiming for a values of int_clocks. */
925
for (i = 0; i < 3; i++) {
927
if ((mask & (1 << i)) == 0)
929
if (p->int_clocks > ((2000.0 - 0.5) * rmeas[i]))
930
ns = 2000.0; /* Maximum edge count */
932
ns = floor(p->inttime * edgec[i] * p->clk_freq/rmeas[i] + 0.5);
933
if (ns < ME) /* Minimum edge count */
940
/* Use frequency computed edge count if available */
941
for (i = 0; i < 3; i++) {
942
if ((mask & (1 << i)) == 0)
948
/* If we compute a different edge count, read again */
949
if (edgec[0] > ME || edgec[1] > ME || edgec[2] > ME) {
950
double rmeas2[3]; /* 2nd RGB Readings */
952
DBG((dbgo,"Doing period re-measurement mask 0x%x, edgec %d %d %d\n",
953
mask, edgec[0], edgec[1], edgec[2]))
955
if ((ev = i1d2_period_measure(p, edgec, rmeas2)) != inst_ok)
958
DBG((dbgo,"Got %f %f %f raw %f %f %f Hz\n",
959
rmeas[0], rmeas[1], rmeas[2],
960
(p->rgbadj[0] * 0.5 * (double)edgec[0] * p->clk_freq)/rmeas2[0],
961
(p->rgbadj[1] * 0.5 * (double)edgec[1] * p->clk_freq)/rmeas2[1],
962
(p->rgbadj[2] * 0.5 * (double)edgec[2] * p->clk_freq)/rmeas2[2]))
964
DBG((dbgo,"Int period %f %f %f secs\n",
965
rmeas2[0]/p->clk_freq, rmeas2[1]/p->clk_freq, rmeas2[2]/p->clk_freq))
967
/* Average readings if we repeated a measurement with the same count */
968
/* (Minor advantage, but may as well use it) */
969
for (i = 0; i < 3; i++) {
971
rmeas[i] = 0.5 * (rmeas[i] + rmeas2[i]);
973
rmeas[i] = rmeas2[i];
977
/* Compute adjusted readings, ovewritting initial cooked values */
978
for (i = 0; i < 3; i++) {
979
if ((mask & (1 << i)) == 0)
981
rgb[i] = (p->rgbadj[i] * 0.5 * (double)edgec[i] * p->clk_freq)/rmeas[i];
982
DBG((dbgo,"%d after scale = %f\n",i,rgb[i]))
984
rgb[i] -= p->reg103_F[i]; /* Subtract black level */
985
DBG((dbgo,"%d after sub black = %f\n",i,rgb[i]))
989
DBG((dbgo,"%d after limit min = %f\n",i,rgb[i]))
993
DBG((dbgo,"Cooked RGB Hz = %f %f %f\n",rgb[0],rgb[1],rgb[2]))
999
/* Less precise (worse quatization errors), but more robust */
1000
/* against excessive delays if the light level drops during measurement. */
1001
/* Limits period measurement to an edge count < 35, but that can */
1002
/* still take a long time in the dark. */
1004
/* Take a cooked measurement from the device for the i1d2 */
1006
i1d2_take_measurement(
1007
i1disp *p, /* Object */
1008
int crtm, /* Measure in crt mode flag */
1009
double rgb[3] /* Return the rgb values */
1012
double rmeas[3]; /* Raw measurement */
1013
int edgec[3] = {ME,ME,ME}; /* Measurement edge count for each channel */
1014
int cdgec[3] = {ME,ME,ME}; /* CRT computed edge count for re-measure */
1015
int fmask = 0x0; /* Freq re-measure mask */
1016
int mask = 0x0; /* Period measure mask */
1020
return i1disp_interp_code((inst *)p, I1DISP_NOT_INITED);
1023
return i1disp_interp_code((inst *)p, I1DISP_WRONG_DEVICE);
1025
DBG((dbgo, "i1d2_take_measurement called with crtm = %d\n",crtm));
1027
/* Do refresh period measurement */
1028
if (crtm && p->rrset == 0) {
1029
if ((ev = i1disp_do_fcal_setit(p)) != inst_ok)
1033
/* Quantize the sample time */
1034
if (p->refperiod > 0.0) {
1036
n = (int)ceil(p->dinttime/p->refperiod);
1037
p->inttime = n * p->refperiod;
1038
if (p->debug) fprintf(stderr,"i1disp: integration time quantize to %f secs\n",p->inttime);
1040
p->inttime = p->dinttime;
1041
if (p->debug) fprintf(stderr,"i1disp: integration time set to %f secs\n",p->inttime);
1045
/* Do an initial fixed integration time frequency measurement. */
1046
DBG((dbgo,"Doing fixed period frequency measurement over %f secs\n",p->inttime))
1048
if ((ev = i1d2_freq_measure(p, &p->inttime, rmeas)) != inst_ok)
1051
for (i = 0; i < 3; i++)
1052
rgb[i] = p->rgbadj[i] * 0.5 * rmeas[i]/p->inttime;
1054
DBG((dbgo,"Got %f %f %f raw, %f %f %f Hz\n",
1055
rmeas[0], rmeas[1], rmeas[2], rgb[0], rgb[1], rgb[2]))
1057
/* Decide whether any channels need re-measuring. */
1058
/* Threshold is a count of 75, and switch to period */
1059
/* measurement mode on count less than 37. */
1061
for (i = 0; i < 3; i++) {
1063
if (rmeas[i] <= 75.0) {
1064
fmask |= (1 << i); /* Yes, do another freq re-measure */
1066
if (rmeas[i] <= 37.5) {
1067
mask |= (1 << i); /* Do a period re-measure */
1068
fmask = 0; /* Don't bother with freq re-measure */
1070
if (rmeas[i] >= 10.0) { /* Compute target edges */
1071
cdgec[i] = (int)(2.0 * rgb[i] * p->inttime + 0.5);
1072
if (cdgec[i] > 2000)
1074
else if (cdgec[i] < ME)
1079
DBG((dbgo,"Freq mask = 0x%x, Period mask 0x%x\n",fmask, mask))
1080
DBG((dbgo,"cdgec = %d %d %d\n",cdgec[0],cdgec[1],cdgec[2]))
1082
/* If there is a frequency re-measure */
1083
/* ** This doesn't actually work. The quantization error */
1084
/* for each read is 0.5, but averaging 2 reads it drops */
1085
/* to 0.354, not the desired 0.25 that would have been */
1086
/* acheived with double the integration time. ** */
1088
DBG((dbgo,"Doing frequency re-measurement over %f secs\n",p->inttime))
1089
if ((ev = i1d2_freq_measure(p, &p->inttime, rmeas)) != inst_ok)
1092
for (i = 0; i < 3; i++) {
1093
rgb[i] += p->rgbadj[i] * 0.5 * rmeas[i]/p->inttime;
1097
DBG((dbgo,"Got %f %f %f raw, %f %f %f Avg. Hz\n",
1098
rmeas[0], rmeas[1], rmeas[2], rgb[0], rgb[1], rgb[2]))
1100
/* If there is a period re-measure */
1101
} else if (mask != 0) {
1103
/* See if we need to compute a target edge count */
1104
for (i = 0; i < 3; i++) {
1105
if ((mask & (1 << i)) && cdgec[i] == ME)
1112
DBG((dbgo,"Doing 1st period pre-measurement mask 0x%x, edgec %d %d %d\n",
1113
mask, edgec[0], edgec[1], edgec[2]))
1115
/* Do an initial measurement of 1 edge to estimate the */
1116
/* number of edges needed for the whole integration time. */
1117
if ((ev = i1d2_period_measure(p, edgec, rmeas)) != inst_ok)
1120
DBG((dbgo,"Got %f %f %f raw %f %f %f Hz\n",
1121
rmeas[0], rmeas[1], rmeas[2],
1122
(p->rgbadj[0] * 0.5 * (double)edgec[0] * p->clk_freq)/rmeas[0],
1123
(p->rgbadj[1] * 0.5 * (double)edgec[1] * p->clk_freq)/rmeas[1],
1124
(p->rgbadj[2] * 0.5 * (double)edgec[2] * p->clk_freq)/rmeas[2]))
1126
/* Compute adjusted edge count for channels we're remeasuring, */
1127
/* aiming for a values of int_clocks. */
1128
for (i = 0; i < 3; i++) {
1130
if ((mask & (1 << i)) == 0)
1132
if (p->int_clocks > ((2000.0 - 0.5) * rmeas[i]))
1133
ns = 2000.0; /* Maximum edge count */
1135
ns = floor(p->inttime * edgec[i] * p->clk_freq/rmeas[i] + 0.5);
1136
if (ns < ME) /* Minimum edge count */
1141
/* Sanity check cdgec value, in case light level has changed */
1142
if ((edgec[i] * 3) < (cdgec[i] * 2)) {
1143
cdgec[i] = edgec[i];
1148
/* Use frequency computed edge count if available */
1149
for (i = 0; i < 3; i++) {
1150
if ((mask & (1 << i)) == 0)
1153
edgec[i] = cdgec[i];
1156
/* If we compute a different edge count, read again */
1157
if (edgec[0] > ME || edgec[1] > ME || edgec[2] > ME) {
1158
double rmeas2[3]; /* 2nd RGB Readings */
1160
DBG((dbgo,"Doing period re-measurement mask 0x%x, edgec %d %d %d\n",
1161
mask, edgec[0], edgec[1], edgec[2]))
1163
if ((ev = i1d2_period_measure(p, edgec, rmeas2)) != inst_ok)
1166
DBG((dbgo,"Got %f %f %f raw %f %f %f Hz\n",
1167
rmeas[0], rmeas[1], rmeas[2],
1168
(p->rgbadj[0] * 0.5 * (double)edgec[0] * p->clk_freq)/rmeas2[0],
1169
(p->rgbadj[1] * 0.5 * (double)edgec[1] * p->clk_freq)/rmeas2[1],
1170
(p->rgbadj[2] * 0.5 * (double)edgec[2] * p->clk_freq)/rmeas2[2]))
1172
DBG((dbgo,"Int period %f %f %f secs\n",
1173
rmeas2[0]/p->clk_freq, rmeas2[1]/p->clk_freq, rmeas2[2]/p->clk_freq))
1175
/* Average readings if we repeated a measurement with the same count */
1176
/* (Minor advantage, but may as well use it) */
1177
for (i = 0; i < 3; i++) {
1179
rmeas[i] = 0.5 * (rmeas[i] + rmeas2[i]);
1181
rmeas[i] = rmeas2[i];
1185
/* Compute adjusted readings, ovewritting initial cooked values */
1186
for (i = 0; i < 3; i++) {
1187
if ((mask & (1 << i)) == 0)
1189
rgb[i] = (p->rgbadj[i] * 0.5 * (double)edgec[i] * p->clk_freq)/rmeas[i];
1190
DBG((dbgo,"%d after scale = %f\n",i,rgb[i]))
1192
rgb[i] -= p->reg103_F[i]; /* Subtract black level */
1193
DBG((dbgo,"%d after sub black = %f\n",i,rgb[i]))
1195
if (rgb[i] < 0.0001)
1197
DBG((dbgo,"%d after limit min = %f\n",i,rgb[i]))
1201
DBG((dbgo,"Cooked RGB Hz = %f %f %f\n",rgb[0],rgb[1],rgb[2]))
900
1208
/* . . . . . . . . . . . . . . . . . . . . . . . . */