summaryrefslogtreecommitdiff
path: root/spectro/inst.c
diff options
context:
space:
mode:
Diffstat (limited to 'spectro/inst.c')
-rwxr-xr-x[-rw-r--r--]spectro/inst.c191
1 files changed, 140 insertions, 51 deletions
diff --git a/spectro/inst.c b/spectro/inst.c
index 9aba1bd..ba12f9d 100644..100755
--- a/spectro/inst.c
+++ b/spectro/inst.c
@@ -51,6 +51,7 @@
#include "insttypes.h"
#include "icoms.h"
#include "inst.h"
+#include "rspec.h"
#include "insttypeinst.h"
#include "ccmx.h"
#include "ccss.h"
@@ -376,6 +377,44 @@ char id[CALIDLEN]) { /* Condition identifier (ie. white reference ID, filter ID)
return inst_unsupported;
}
+/* Return a description of the calibration type */
+char *calt2str(inst_cal_type calt) {
+ calt &= inst_calt_all_mask;
+
+ if (calt & inst_calt_all)
+ return "All";
+ if (calt & inst_calt_needed)
+ return "Needed";
+ if (calt & inst_calt_available)
+ return "Needed";
+ if (calt & inst_calt_wavelength)
+ return "Wavelength";
+ if (calt & inst_calt_ref_white)
+ return "Reflective White or Emissive Dark";
+ if (calt & inst_calt_ref_dark)
+ return "Reflective Light Trap (Black)";
+ if (calt & inst_calt_ref_dark_gl)
+ return "Reflective Gloss";
+ if (calt & inst_calt_emis_offset)
+ return "Emissive Offset";
+ if (calt & inst_calt_emis_ratio)
+ return "Emissive Ratio";
+ if (calt & inst_calt_em_dark)
+ return "Emissive Dark";
+ if (calt & inst_calt_trans_white)
+ return "Transmissive White";
+ if (calt & inst_calt_trans_vwhite)
+ return "Transmissive Variable White";
+ if (calt & inst_calt_trans_dark)
+ return "Transmissive Dark";
+ if (calt & inst_calt_emis_int_time)
+ return "Emissive Integration Time";
+ if (calt & inst_calt_ref_freq)
+ return "Display Refresh Rate";
+
+ return "None or Unknown";
+}
+
/* Measure a display update delay. It is assumed that a */
/* black to white change has been made to the displayed color, */
/* and this will measure the time it took for the update to */
@@ -569,11 +608,12 @@ void *cntx /* Context for callback */
}
+
/* Set instrument type from USB port, if not specified */
itype = icom->itype; /* Instrument type if its known from usb/hid */
#if defined(ENABLE_FAST_SERIAL)
- if (itype == instUnknown && !nocoms && icom->fast) {
+ if (itype == instUnknown && !nocoms && (icom->sattr & icom_fast)) {
itype = fast_ser_inst_type(icom, 1, uicallback, cntx); /* Else type from serial */
}
#endif /* ENABLE_FAST_SERIAL */
@@ -638,12 +678,14 @@ void *cntx /* Context for callback */
p = (inst *)new_spyd2(icom, itype);
else if (itype == instSpyder5)
p = (inst *)new_spyd2(icom, itype);
- else if (itype == instHuey)
+ else if (itype == instEX1)
+ p = (inst *)new_ex1(icom, itype);
+ if (itype == instHuey)
p = (inst *)new_huey(icom, itype);
else if (itype == instSmile)
p = (inst *)new_i1disp(icom, itype);
- else if (itype == instEX1)
- p = (inst *)new_ex1(icom, itype);
+ else if (itype == instSMCube)
+ p = (inst *)new_smcube(icom, itype);
else if (itype == instHCFR)
p = (inst *)new_hcfr(icom, itype);
else if (itype == instColorHug
@@ -801,14 +843,13 @@ static inst_disptypesel *expand_dlist(inst_disptypesel *list, int nlist, int *na
if already used,
remove it.
if no selector remain,
- allocate a free one.
+ allocate a free one from the fallback list.
mark all used selectors
We treat the first selector as more important
- than any aliases that come after it, so we need
- to do two passes to resolve what gets used.
-
- Use disptechs_set_sel() utility function to some of the work.
+ than any aliases that come after it, and the
+ aliases as more important than the fallback list,
+ so we need to do three passes through all the selections.
*/
/* Create the display type list */
@@ -823,6 +864,7 @@ int doccmx /* Add matching installed ccmx files */
int i, j, k, nlist = 0, nalist = 0;
char usels[256]; /* Used selectors */
static char *asels = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ int fail = 0;
/* free the old list */
inst_del_disptype_list(*pdtlist, *pndtlist);
@@ -830,25 +872,22 @@ int doccmx /* Add matching installed ccmx files */
*pndtlist = 0;
for (i = 0; i < 256; i++)
- usels[i] = 0;
+ usels[i] = ((char)-1);
k = 0; /* Next selector index */
/* Add entries from the static list and their primary selectors */
- /* Count the number in the static list */
+ /* (We're currently assuming that calibrations that the instrument */
+ /* returns are not custom) */
+ /* Count the number in the static list. */
for (i = 0; !(sdtlist[i].flags & inst_dtflags_end); i++) {
if ((list = expand_dlist(list, ++nlist, &nalist)) == NULL)
return inst_internal_error;
list[nlist-1] = sdtlist[i]; /* Struct copy */
-
- if (disptechs_set_sel(2, list[nlist-1].sel, usels, &k, asels)) {
- a1loge(p->log, 1, "inst_creat_disptype_list run out of selectors\n");
- break;
- }
}
- /* Add any ccss's */
+ /* Add any OEM and custom ccss's */
if (doccss) {
iccss *ss_list;
if ((ss_list = list_iccss(NULL)) == NULL) {
@@ -862,16 +901,13 @@ int doccmx /* Add matching installed ccmx files */
return inst_internal_error;
list[nlist-1].flags = inst_dtflags_ccss | inst_dtflags_ld | inst_dtflags_wr;
+ if (!ss_list[i].oem)
+ list[nlist-1].flags |= inst_dtflags_custom;
if (ss_list[i].sel != NULL) {
strncpy(list[nlist-1].sel, ss_list[i].sel, INST_DTYPE_SEL_LEN);
list[nlist-1].sel[INST_DTYPE_SEL_LEN-1] = '\000';
}
- if (disptechs_set_sel(2, list[nlist-1].sel, usels, &k, asels)) {
- a1loge(p->log, 1, "inst_creat_disptype_list run out of selectors\n");
- break;
- }
-
strncpy(list[nlist-1].desc, ss_list[i].desc, INST_DTYPE_DESC_LEN);
list[nlist-1].desc[INST_DTYPE_DESC_LEN-1] = '\000';
list[nlist-1].dtech = ss_list[i].dtech;
@@ -884,7 +920,7 @@ int doccmx /* Add matching installed ccmx files */
}
}
- /* Add any ccmx's */
+ /* Add any OEM and custom ccmx's */
if (doccmx) {
iccmx *ss_list;
@@ -899,7 +935,7 @@ int doccmx /* Add matching installed ccmx files */
/* Check that there is a matching base calibation */
for (j = 0; j < nlist; j++) {
if (ss_list[i].cc_cbid != 0
- && list[j].cbid == ss_list[i].cc_cbid)
+ && list[j].cbid == ss_list[i].cc_cbid)
break;
}
if (j >= nlist) {
@@ -911,15 +947,13 @@ int doccmx /* Add matching installed ccmx files */
return inst_internal_error;
list[nlist-1].flags = inst_dtflags_ccmx | inst_dtflags_ld | inst_dtflags_wr;
+ if (!ss_list[i].oem)
+ list[nlist-1].flags |= inst_dtflags_custom;
if (ss_list[i].sel != NULL) {
strncpy(list[nlist-1].sel, ss_list[i].sel, INST_DTYPE_SEL_LEN);
list[nlist-1].sel[INST_DTYPE_SEL_LEN-1] = '\000';
}
- if (disptechs_set_sel(2, list[nlist-1].sel, usels, &k, asels)) {
- a1loge(p->log, 1, "inst_creat_disptype_list run out of selectors\n");
- break;
- }
strncpy(list[nlist-1].desc, ss_list[i].desc, INST_DTYPE_DESC_LEN);
list[nlist-1].desc[INST_DTYPE_DESC_LEN-1] = '\000';
list[nlist-1].dtech = ss_list[i].dtech;
@@ -932,19 +966,37 @@ int doccmx /* Add matching installed ccmx files */
}
}
- /* Create needed selectors */
+ /* Set selectors from primary for cbid or custom first */
+ for (i = 0; i < nlist; i++) {
+ if (list[i].cbid > 0
+ || (list[i].flags & inst_dtflags_custom) != 0) {
+ disptechs_set_sel(0, i, list[i].sel, usels, &k, asels);
+ }
+ }
+
+ /* Set selectors from primary for rest */
for (i = 0; i < nlist; i++)
- disptechs_set_sel(4, list[i].sel, usels, &k, asels);
+ disptechs_set_sel(0, i, list[i].sel, usels, &k, asels);
- /* Verify or delete any secondary selectors */
+ /* Set remaining selectors from secondaries */
for (i = 0; i < nlist; i++)
- disptechs_set_sel(3, list[i].sel, usels, &k, asels);
+ disptechs_set_sel(1, i, list[i].sel, usels, &k, asels);
+
+ /* Set remaining from fallback (or give up and set to null) */
+ for (i = 0; i < nlist; i++) {
+ fail = disptechs_set_sel(3, i, list[i].sel, usels, &k, asels);
+ }
if (pndtlist != NULL)
*pndtlist = nlist;
if (pdtlist != NULL)
*pdtlist = list;
+ if (fail) {
+ a1loge(p->log, 1, "inst_creat_disptype_list run out of selectors\n");
+ return inst_internal_error;
+ }
+
return inst_ok;
}
@@ -1045,6 +1097,7 @@ iccmx *list_iccmx(instType itype, int *no) {
rv[j].dtech = dtech;
rv[j].refr = refr;
rv[j].sel = cs->sel; cs->sel = NULL;
+ rv[j].oem = cs->oem;
icmCpy3x3(rv[j].mat, cs->matrix);
cs->del(cs);
j++;
@@ -1056,6 +1109,7 @@ iccmx *list_iccmx(instType itype, int *no) {
rv[j].dtech = disptech_unknown;
rv[j].refr = -1;
rv[j].sel = NULL;
+ rv[j].oem = 0;
if (no != NULL)
*no = j;
@@ -1174,6 +1228,7 @@ iccss *list_iccss(int *no) {
rv[j].dtech = dtech;
rv[j].refr = refr;
rv[j].sel = cs->sel; cs->sel = NULL;
+ rv[j].oem = cs->oem;
rv[j].sets = cs->samples; cs->samples = NULL;
rv[j].no_sets = cs->no_samp; cs->no_samp = 0;
cs->del(cs);
@@ -1185,6 +1240,7 @@ iccss *list_iccss(int *no) {
rv[j].dtech = disptech_unknown;
rv[j].refr = -1;
rv[j].sel = NULL;
+ rv[j].oem = 0;
rv[j].sets = NULL;
rv[j].no_sets = 0;
if (no != NULL)
@@ -1233,7 +1289,8 @@ instType fast_ser_inst_type(
void *cntx /* Context for callback */
) {
instType rv = instUnknown;
- char buf[100];
+#define BUFSZ (128 + 10)
+ char buf[BUFSZ];
baud_rate brt[] = { baud_921600, baud_115200, baud_38400, baud_9600, baud_nc };
unsigned int etime;
unsigned int i;
@@ -1255,18 +1312,18 @@ instType fast_ser_inst_type(
if (!tryhard)
break; /* try only once */
}
+ a1logd(p->log, 5, "Trying %s baud\n",baud_rate_to_str(brt[i]));
+
if ((se = p->set_ser_port(p, fc_none, brt[i], parity_none,
stop_1, length_8)) != ICOM_OK) {
a1logd(p->log, 5, "fser_inst_type: set_ser_port failed with 0x%x\n",se);
return instUnknown; /* Give up */
}
-// a1logd(p->log, 5, "brt = %d\n",brt[i]);
-
if (brt[i] == baud_9600) {
/* See if it's a Klein K10 */
- if ((se = p->write_read(p, "P0\r", 0, buf, 100, NULL, ">", 1, 0.100)) != inst_ok) {
+ if ((se = p->write_read(p, "P0\r", 0, buf, BUFSZ, NULL, ">", 1, 0.100)) != inst_ok) {
/* Check for user abort */
if (uicallback != NULL) {
inst_code ev;
@@ -1279,19 +1336,50 @@ instType fast_ser_inst_type(
}
len = strlen(buf);
- a1logd(p->log, 5, "len = %d\n",len);
-
/* Is this a Klein K1/K8/K10 response ? */
if (strncmp(buf, "P0K-1 ", 6) == 0
|| strncmp(buf, "P0K-8 ", 6) == 0
|| strncmp(buf, "P0K-10", 6) == 0
|| strncmp(buf, "P0KV-10", 7) == 0) {
+ a1logd(p->log, 5, "fser_inst_type: found Klein K1/K8/K10\n");
rv = instKleinK10;
break;
}
- } else {
+ }
+ if (brt[i] == baud_38400)
+ {
+ int bread;
+
+ /* See if it's a SwatchMate Cube. */
+ /* The Cube uses RTS/CTS handshaking, but ignore this for identification. */
+ buf[0] = 0x7e;
+ buf[1] = 0x00;
+ buf[2] = 0x02; /* Ping command */
+ buf[3] = 0x00;
+ if ((se = p->write_read(p, buf, 4, buf, BUFSZ, &bread, NULL, 4, 0.100)) != inst_ok) {
+ /* Check for user abort */
+ if (uicallback != NULL) {
+ inst_code ev;
+ if ((ev = uicallback(cntx, inst_negcoms)) == inst_user_abort) {
+ a1logd(p->log, 5, "fser_inst_type: User aborted\n");
+ return instUnknown;
+ }
+ }
+ continue;
+ }
+ if (bread == 4) {
+ if (buf[0] == 0x7e && buf[1] == 0x20 && buf[2] == 0x02 && buf[3] == 0x00) {
+ a1logd(p->log, 5, "fser_inst_type: found SwatchMate Cube\n");
+ rv = instSMCube;
+ break;
+ }
+ }
+ }
+ /* Bluetooth only uses baud_115200 */
+ if ((p->sattr & icom_bt) == 0 || brt[i] == baud_115200) {
+
/* See if it's a JETI specbos */
- if ((se = p->write_read(p, "*idn?\r", 0, buf, 100, NULL, "\r", 1, 0.100)) != inst_ok) {
+ if ((se = p->write_read(p, "*idn?\r", 0, buf, BUFSZ, NULL, "\r", 1, 0.100)) != inst_ok) {
/* Check for user abort */
if (uicallback != NULL) {
inst_code ev;
@@ -1304,20 +1392,18 @@ instType fast_ser_inst_type(
}
len = strlen(buf);
- a1logd(p->log, 5, "len = %d\n",len);
-
/* JETI specbos returns "JETI_SBXXXX", where XXXX is the instrument type, */
/* except for the 1201 which returns "SB05" */
/* Is this a JETI specbos 1201 response ? */
if (strncmp(buf, "SB05", 4) == 0) {
-// a1logd(p->log, 5, "specbos1201\n");
+ a1logd(p->log, 5, "fser_inst_type: found JETI specbos 1201\n");
rv = instSpecbos1201;
break;
}
/* Is this a JETI specbos XXXX response ? */
if (len >= 11 && strncmp(buf, "JETI_SB", 7) == 0) {
-// a1logd(p->log, 5, "specbos\n");
+ a1logd(p->log, 5, "fser_inst_type: found JETI specbos\n");
rv = instSpecbos;
break;
}
@@ -1337,6 +1423,7 @@ instType fast_ser_inst_type(
return rv;
}
+#undef BUFSZ
#endif /* ENABLE_FAST_SERIAL */
@@ -1355,7 +1442,8 @@ static instType ser_inst_type(
void *cntx /* Context for callback */
) {
instType rv = instUnknown;
- char buf[100];
+#define BUFSZ (128 + 10)
+ char buf[BUFSZ];
baud_rate brt[] = { baud_9600, baud_19200, baud_4800, baud_2400,
baud_1200, baud_38400, baud_57600, baud_115200,
baud_600, baud_300, baud_110, baud_nc };
@@ -1374,7 +1462,7 @@ static instType ser_inst_type(
bi = 0;
/* The tick to give up on */
- etime = msec_time() + (long)(1000.0 * 20.0 + 0.5);
+ etime = msec_time() + (long)(20.0 * 1000.0 + 0.5);
a1logd(p->log, 1, "ser_inst_type: Trying different baud rates (%u msec to go)\n",etime - msec_time());
@@ -1388,9 +1476,9 @@ static instType ser_inst_type(
return instUnknown; /* Give up */
}
-// a1logd(p->log, 5, "brt = %d\n",brt[i]);
+ a1logd(p->log, 5, "Trying %s baud\n",baud_rate_to_str(brt[i]));
bread = 0;
- if ((se = p->write_read(p, ";D024\r\n", 0, buf, 100, &bread, "\r", 1, 0.5)) != inst_ok) {
+ if ((se = p->write_read(p, ";D024\r\n", 0, buf, BUFSZ, &bread, "\r", 1, 0.5)) != inst_ok) {
/* Check for user abort */
if (uicallback != NULL) {
inst_code ev;
@@ -1445,7 +1533,7 @@ static instType ser_inst_type(
/* SpectroScan */
if (ss) {
rv = instSpectroScan;
- if ((se = p->write_read(p, ";D030\r\n", 0, buf, 100, NULL, "\n", 1, 1.5)) == 0) {
+ if ((se = p->write_read(p, ";D030\r\n", 0, buf, BUFSZ, NULL, "\n", 1, 1.5)) == 0) {
if (strlen(buf) >= 41) {
hex2bin(&buf[5], 12);
// a1logd(p->log, 5, "spectroscan type = '%s'\n",buf);
@@ -1457,7 +1545,7 @@ static instType ser_inst_type(
if (xrite) {
/* Get the X-Rite model and version number */
- if ((se = p->write_read(p, "SV\r\n", 0, buf, 100, NULL, ">", 1, 2.5)) != 0)
+ if ((se = p->write_read(p, "SV\r\n", 0, buf, BUFSZ, NULL, ">", 1, 2.5)) != 0)
return instUnknown;
if (strlen(buf) >= 12) {
@@ -1486,6 +1574,7 @@ static instType ser_inst_type(
return rv;
}
+#undef BUFSZ
#endif /* ENABLE_SERIAL */
@@ -1567,7 +1656,7 @@ void inst_mode_to_sym(char sym[MAX_INST_MODE_SYM_SZ], inst_mode mode) {
*cp++ = '\000';
}
-/* Return a set of mode flags that correspondf to the symbolic encoding */
+/* Return a set of mode flags that correspond to the symbolic encoding */
/* Return nz if a symbol wasn't recognized */
int sym_to_inst_mode(inst_mode *mode, const char *sym) {
int i;