diff options
Diffstat (limited to 'spectro/kleink10.c')
-rw-r--r-- | spectro/kleink10.c | 114 |
1 files changed, 88 insertions, 26 deletions
diff --git a/spectro/kleink10.c b/spectro/kleink10.c index 461cb28..9599972 100644 --- a/spectro/kleink10.c +++ b/spectro/kleink10.c @@ -62,7 +62,7 @@ #undef HIGH_SPEED /* [und] Use high speed flicker measure for refresh rate etc. */ #define AUTO_AVERAGE /* [def] Automatically average more readings for low light */ -#define RETRY_RANGE_ERROR 3 /* [3] Retry range error readings 3 times */ +#define RETRY_RANGE_ERROR 4 /* [4] Retry range error readings 4 times */ #undef PLOT_REFRESH /* [und] Plot refresh rate measurement info */ #undef PLOT_UPDELAY /* [und] Plot update delay measurement info */ @@ -81,6 +81,7 @@ static inst_code k10_read_flicker_samples(kleink10 *p, double duration, double * /* Decode a K10 error letter */ static int decodeK10err(char c) { +//printf("~1 decoding error code 0x%x\n",c); if (c == '0') { return K10_OK; } else if (c == 'B') { @@ -125,28 +126,34 @@ extract_ec(char *s, int *nlength, int bread) { if (*p == '>') break; } - if (p < s) + if (p < s) { +//printf("p %d < s %d ? %d\n", p, s, p < s); return K10_BAD_RETVAL; + } //printf("trailing is at %d '%s'\n",p - s, p); /* Find the leading '<' */ for (f = p-1; f >= (p-MAXECHARS-1) && f >= s; f--) { if (*f == '<') break; + /* Turns out the error code may be non-text */ +#ifdef NEVER if ((*f < '0' || *f > '9') && (*f < 'a' || *f > 'z') && (*f < 'A' || *f > 'Z')) return K10_BAD_RETVAL; +#endif /* NEVER */ } if (f < s || f < (p-MAXECHARS-1) || (p-f) <= 1) { -//printf("f < s ? %d, f < (p-MAXECHARS-1) ? %d, (p-f) <= 1 ? %d\n", -//f < s, f < (p-10), (p-f) <= 1); +//printf("f < s ? %d, f < (p-MAXECHARS-1) ? %d, (p-f) <= 1 ? %d\n", f < s, f < (p-10), (p-f) <= 1); return K10_BAD_RETVAL; } //printf("leading is at %d '%s'\n",f - s, f); - if (p-f-1 <= 0) + if (p-f-1 <= 0) { +//printf("p-f-1 %d <= 0 ? %d\n", p-f-1, p-f-1 <= 0); return K10_BAD_RETVAL; + } strncpy(tt, f+1, p-f-1); tt[p-f-1] = '\000'; @@ -155,7 +162,7 @@ extract_ec(char *s, int *nlength, int bread) { /* Interpret the error character(s) */ /* It's not clear if more than one error can be returned. */ /* We are only looking at the first character - we should */ - /* really prioritize them id more than one can occur. */ + /* really prioritize them if more than one can occur. */ for (p = tt; *p != '\000'; p++) { rv = decodeK10err(*p); break; @@ -467,7 +474,15 @@ k10_init_inst(inst *pp) { amutex_lock(p->lock); /* Make sure the target lights are off */ - if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 1.0)) != inst_ok) { + if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 1.0)) != inst_ok + /* Strangely the L0/1 command mat return irrelevant error codes... */ + && (ev & inst_imask) != K10_UNKNOWN + && (ev & inst_imask) != K10_BLACK_EXCESS + && (ev & inst_imask) != K10_BLACK_OVERDRIVE + && (ev & inst_imask) != K10_BLACK_ZERO + && (ev & inst_imask) != K10_OVER_HIGH_RANGE + && (ev & inst_imask) != K10_TOP_OVER_RANGE + && (ev & inst_imask) != K10_BOT_UNDER_RANGE) { amutex_unlock(p->lock); return ev; } @@ -510,14 +525,20 @@ k10_init_inst(inst *pp) { if (p->log->verb) { char *model = "Unknown"; switch (p->model) { + case k10_k1: + model = "K-1"; + break; + case k10_k8: + model = "K-8"; + break; case k10_k10: - model = "K10"; + model = "K-10"; break; case k10_k10a: - model = "K10-A"; + model = "K-10A"; break; case k10_kv10a: - model = "KV10-A"; + model = "KV-10A"; break; } a1logv(p->log, 1, " Model: '%s'\n",model); @@ -886,7 +907,7 @@ kleink10 *p) { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -static abort_flicker(kleink10 *p, int isnew, double *retbuf) { +static void abort_flicker(kleink10 *p, int isnew, double *retbuf) { char buf[MAX_MES_SIZE]; int bread; @@ -976,7 +997,15 @@ int usefast /* If nz use fast rate is possible */ /* Make sure the target lights are off */ if (p->lights) { int se; - if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok) { + if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok + /* Strangely the L0/1 command mat return irrelevant error codes... */ + && (ev & inst_imask) != K10_UNKNOWN + && (ev & inst_imask) != K10_BLACK_EXCESS + && (ev & inst_imask) != K10_BLACK_OVERDRIVE + && (ev & inst_imask) != K10_BLACK_ZERO + && (ev & inst_imask) != K10_OVER_HIGH_RANGE + && (ev & inst_imask) != K10_TOP_OVER_RANGE + && (ev & inst_imask) != K10_BOT_UNDER_RANGE) { amutex_unlock(p->lock); free(retbuf); a1logd(p->log, 1, "k10_read_flicker: L0 failed\n"); @@ -1182,9 +1211,9 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ int user_trig = 0; int bsize; inst_code rv = inst_protocol_error; - int range[3]; /* Range for RGB sensor values */ - int i, tries,ntav = 1; /* Number of readings to average */ - double v, vv, XYZ[3]; + int range[3]; /* Range for RGB sensor values */ + int i, tries, ntav = 1; /* Number of readings to average */ + double v, vv; if (!p->gotcoms) return inst_no_coms; @@ -1230,7 +1259,15 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ /* Make sure the target lights are off */ if (p->lights) { - if ((rv = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 1.0)) != inst_ok) { + if ((rv = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 1.0)) != inst_ok + /* Strangely the L0/1 command mat return irrelevant error codes... */ + && (rv & inst_imask) != K10_UNKNOWN + && (rv & inst_imask) != K10_BLACK_EXCESS + && (rv & inst_imask) != K10_BLACK_OVERDRIVE + && (rv & inst_imask) != K10_BLACK_ZERO + && (rv & inst_imask) != K10_OVER_HIGH_RANGE + && (rv & inst_imask) != K10_TOP_OVER_RANGE + && (rv & inst_imask) != K10_BOT_UNDER_RANGE) { amutex_unlock(p->lock); a1logd(p->log, 1, "k10_read_sample: L0 failed\n"); return rv; @@ -1256,7 +1293,7 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ if (rv == inst_ok || ( (rv & inst_imask) != K10_TOP_OVER_RANGE && (rv & inst_imask) != K10_BOT_UNDER_RANGE)) - break; + break; } if (rv == inst_ok) @@ -1273,7 +1310,6 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ if (val->XYZ[2] > v) v = val->XYZ[2]; - ntav = 1; #ifdef AUTO_AVERAGE if (!IMODETST(p->mode, inst_mode_emis_nonadaptive)) { /* Decide how many extra readings to average into result. */ @@ -1292,13 +1328,26 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ vv = 1.0 - (v - thr[2]) / (thr[3] - thr[2]); vv = vv * vv * vv; ntav = (int)(vv * (nav[2] - nav[3]) + nav[3] + 0.5); - } + } /* else default 1 */ } #endif + /* Measure extras up to ntav */ for (i = 1; i < ntav; i++) { - if ((rv = k10_command(p, "N5\r", buf, MAX_MES_SIZE, &bsize, 15, ec_ec, 2.0)) != inst_ok) + double XYZ[3]; + + for (tries = 0; tries < RETRY_RANGE_ERROR; tries++) { + rv = k10_command(p, "N5\r", buf, MAX_MES_SIZE, &bsize, 15, ec_ec, 2.0); + if (rv == inst_ok + || ( (rv & inst_imask) != K10_TOP_OVER_RANGE + && (rv & inst_imask) != K10_BOT_UNDER_RANGE)) + break; + } + + if (rv != inst_ok) { // An error, or retry failed break; + } + if ((rv = decodeN5(p, XYZ, range, buf, bsize)) != inst_ok) break; @@ -1321,10 +1370,6 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */ amutex_unlock(p->lock); - if ((rv = decodeN5(p, val->XYZ, range, buf, bsize)) != inst_ok) { - return rv; - } - /* Apply the calibration correction matrix */ icmMulBy3x3(val->XYZ, p->ccmat, val->XYZ); @@ -2396,6 +2441,7 @@ k10_del(inst *pp) { if (p->icom != NULL) p->icom->del(p->icom); amutex_del(p->lock); + p->vdel(pp); free(p); } } @@ -2741,14 +2787,30 @@ k10_get_set_opt(inst *pp, inst_opt_type m, ...) } if (state == 1) { /* Turn on */ - if ((ev = k10_command(p, "L1\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok) { + if ((ev = k10_command(p, "L1\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok + /* Strangely the L0/1 command mat return irrelevant error codes... */ + && (ev & inst_imask) != K10_UNKNOWN + && (ev & inst_imask) != K10_BLACK_EXCESS + && (ev & inst_imask) != K10_BLACK_OVERDRIVE + && (ev & inst_imask) != K10_BLACK_ZERO + && (ev & inst_imask) != K10_OVER_HIGH_RANGE + && (ev & inst_imask) != K10_TOP_OVER_RANGE + && (ev & inst_imask) != K10_BOT_UNDER_RANGE) { amutex_unlock(p->lock); a1logd(p->log, 1, "k10_get_set_opt: L1 failed\n"); return ev; } p->lights = 1; } else if (state == 0) { /* Turn off */ - if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok) { + if ((ev = k10_command(p, "L0\r", buf, MAX_MES_SIZE, NULL, 2+3, ec_ec, 0.5)) != inst_ok + /* Strangely the L0/1 command mat return irrelevant error codes... */ + && (ev & inst_imask) != K10_UNKNOWN + && (ev & inst_imask) != K10_BLACK_EXCESS + && (ev & inst_imask) != K10_BLACK_OVERDRIVE + && (ev & inst_imask) != K10_BLACK_ZERO + && (ev & inst_imask) != K10_OVER_HIGH_RANGE + && (ev & inst_imask) != K10_TOP_OVER_RANGE + && (ev & inst_imask) != K10_BOT_UNDER_RANGE) { amutex_unlock(p->lock); a1logd(p->log, 1, "k10_get_set_opt: L0 failed\n"); return ev; |