From 9491825ddff7a294d1f49061bae7044e426aeb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Fri, 6 Nov 2015 05:38:49 +0100 Subject: Imported Upstream version 1.8.3 --- spectro/i1d3.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 5 deletions(-) mode change 100644 => 100755 spectro/i1d3.c (limited to 'spectro/i1d3.c') diff --git a/spectro/i1d3.c b/spectro/i1d3.c old mode 100644 new mode 100755 index 689f328..df7d3f0 --- a/spectro/i1d3.c +++ b/spectro/i1d3.c @@ -34,6 +34,10 @@ and agreed to support. */ +/* TTBD: + +*/ + #include #include #include @@ -70,6 +74,8 @@ #define I1D3_MEAS_TIMEOUT 40.0 /* Longest reading timeout in seconds */ /* Typically 20.0 is the maximum needed. */ +#define I1D3_SAT_FREQ 100000.0 /* L2F sensor frequency limit */ + static inst_code i1d3_interp_code(inst *pp, int ec); static inst_code i1d3_check_unlock(i1d3 *p); @@ -105,6 +111,12 @@ static int icoms2i1d3_err(int se, int torc) { /* and byte 1 is the sub code for command 0x00 . The response is byte 0 */ /* error code, byte 1 echoing the major command number. */ /* Major code 00 works when locked ? */ +/* Response codes: + + 00 OK + 83 After pulse count measure in low light. Means ??? + + */ typedef enum { i1d3_getinfo = 0x0000, /* Product name + Firmware version + Firmware Date string */ i1d3_status = 0x0001, /* status number ?? */ @@ -174,7 +186,7 @@ static char *inst_desc(i1Disp3CC cc) { /* The i1d3 is set up as an HID device, which can ease the need */ /* for providing a kernel driver on MSWindows systems, */ /* but it doesn't seem to actually be used as an HID device. */ -/* We allow for communicating via libusb, or an HID driver. */ +/* We allow for communicating via usbio, or an HID driver. */ static inst_code i1d3_command( i1d3 *p, /* i1d3 object */ @@ -265,6 +277,21 @@ i1d3_command( rv = i1d3_interp_code((inst *)p, I1D3_BAD_RD_LENGTH); } + /* Hmm. Not sure about this bug workaround. Is this a rev B thing ? */ + /* May get status 0x83 on i1d3_measure2 when there are no transitions ? */ + /* If so, ignore the error. */ + if (rv == inst_ok && cc == i1d3_measure2 && recv[1] == 0x02 && recv[0] == 0x83) { + int i; + for (i = 2; i < 14; i++) { + if (recv[i] != 0) + break; + } + if (i >= 14) { /* returned all zero's */ + if (!nd) a1logd(p->log, 1, "i1d3_command: ignoring status byte = 0x%x\n",recv[0]); + recv[0] = 0x00; /* Fudge OK status */ + } + } + /* The first byte returned seems to be a command result error code. */ if (rv == inst_ok && recv[0] != 0x00) { if (!nd) a1logd(p->log, 1, "i1d3_command: status byte != 00 = 0x%x\n",recv[0]); @@ -756,7 +783,7 @@ static inst_code i1d3_freq_measure( i1d3 *p, /* Object */ double *inttime, /* Integration time in seconds. (Return clock rounded) */ - double rgb[3] /* Return the RGB values */ + double rgb[3] /* Return the RGB count values */ ) { int intclks; unsigned char todev[64]; @@ -1568,6 +1595,11 @@ i1d3_take_emis_measurement( } a1logd(p->log,3,"Got %f %f %f raw, %f %f %f Hz\n",rmeas[0],rmeas[1],rmeas[2],rgb[0],rgb[1],rgb[2]); + + for (i = 0; i < 3; i++) { + if (rgb[i] > I1D3_SAT_FREQ) + return i1d3_interp_code((inst *)p, I1D3_TOOBRIGHT); + } } /* If some period measurement will be done */ @@ -1863,6 +1895,11 @@ i1d3_take_emis_measurement( a1logd(p->log,3,"Got %f %f %f raw, %f %f %f Hz after re-measure\n",rmeas[0],rmeas[1],rmeas[2],rgb[0],rgb[1],rgb[2]); + for (i = 0; i < 3; i++) { + if (rgb[i] > I1D3_SAT_FREQ) + return i1d3_interp_code((inst *)p, I1D3_TOOBRIGHT); + } + } else { /* Use period measurement of the target number of edges */ /* (Note that if the patch isn't constant and drops compared to */ @@ -1907,6 +1944,11 @@ i1d3_take_emis_measurement( } a1logd(p->log,3,"Cooked RGB = %f %f %f\n",rgb[0],rgb[1],rgb[2]); + + for (i = 0; i < 3; i++) { + if (rgb[i] > I1D3_SAT_FREQ) + return i1d3_interp_code((inst *)p, I1D3_TOOBRIGHT); + } return inst_ok; } @@ -1983,7 +2025,7 @@ static inst_code i1d3_decode_intEE( p->serial_no[20] = '\000'; strncpy(p->vers_no, (char *)buf + 0x2C, 10); - p->serial_no[10] = '\000'; + p->vers_no[10] = '\000'; /* Read the black level offset */ for (i = 0; i < 3; i++) { @@ -2395,7 +2437,7 @@ i1d3_set_cal(i1d3 *p) { /* ------------------------------------------------------------------------ */ /* Establish communications with a I1D3 */ -/* Return DTP_COMS_FAIL on failure to establish communications */ +/* Return I1D3_COMS_FAIL on failure to establish communications */ static inst_code i1d3_init_coms(inst *pp, baud_rate br, flow_control fc, double tout) { i1d3 *p = (i1d3 *) pp; @@ -3287,6 +3329,9 @@ i1d3_interp_error(inst *pp, int ec) { case I1D3_INT_THREADFAILED: return "Starting diffuser position thread failed"; + case I1D3_TOOBRIGHT: + return "Too bright to read accuractly"; + case I1D3_NO_COMS: return "Communications hasn't been established";; case I1D3_NOT_INITED: @@ -3355,11 +3400,13 @@ i1d3_interp_code(inst *pp, int ec) { case I1D3_BAD_EX_CHSUM: return inst_hardware_fail | ec; + case I1D3_TOOBRIGHT: + return inst_misread | ec; + /* Unused: inst_notify inst_warning inst_unknown_model - inst_misread inst_nonesaved inst_nochmatch inst_needs_cal @@ -3411,6 +3458,7 @@ i1d3_del(inst *pp) { if (p->samples != NULL) free(p->samples); amutex_del(p->lock); + p->vdel(pp); free(p); } } -- cgit v1.2.3